Merge remote-tracking branch 'local/msvc-updates' into msvc-updates
[mono.git] / mcs / class / System.Net.Http / Test / System.Net.Http / HttpRequestMessageTest.cs
1 //
2 // HttpRequestMessageTest.cs
3 //
4 // Authors:
5 //      Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2011 Xamarin, Inc (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using NUnit.Framework;
33 using System.Net.Http;
34 using System.Net;
35 using System.Net.Http.Headers;
36 using System.Linq;
37
38 namespace MonoTests.System.Net.Http
39 {
40         [TestFixture]
41         public class HttpRequestMessageTest
42         {
43                 [Test]
44                 public void Ctor_Invalid ()
45                 {
46                         try {
47                                 new HttpRequestMessage (null, "");
48                                 Assert.Fail ("#1");
49                         } catch (ArgumentNullException) {
50                         }
51                 }
52
53                 [Test]
54                 public void Ctor_Default ()
55                 {
56                         var m = new HttpRequestMessage ();
57                         Assert.IsNull (m.Content, "#1");
58                         Assert.IsNotNull (m.Headers, "#2");
59                         Assert.AreEqual (HttpMethod.Get, m.Method, "#3");
60                         Assert.IsNotNull (m.Properties, "#4");
61                         Assert.IsNull (m.RequestUri, "#5");
62                         Assert.AreEqual (new Version (1, 1), m.Version, "#6");
63                 }
64
65                 [Test]
66                 public void Ctor_Uri ()
67                 {
68                         var c = new HttpRequestMessage (HttpMethod.Get, new Uri ("http://xamarin.com"));
69                         Assert.AreEqual ("http://xamarin.com/", c.RequestUri.AbsoluteUri, "#1");
70
71                         c = new HttpRequestMessage (HttpMethod.Get, new Uri ("https://xamarin.com"));
72                         Assert.AreEqual ("https://xamarin.com/", c.RequestUri.AbsoluteUri, "#2");
73
74                         c = new HttpRequestMessage (HttpMethod.Get, new Uri ("HTTP://xamarin.com:8080"));
75                         Assert.AreEqual ("http://xamarin.com:8080/", c.RequestUri.AbsoluteUri, "#3");
76
77                         var a = Uri.UriSchemeHttps;
78                         var b = new Uri ("http://xamarin.com");
79
80                         try {
81                                 new HttpRequestMessage (HttpMethod.Get, new Uri ("ftp://xamarin.com"));
82                                 Assert.Fail ("#4");
83                         } catch (ArgumentException) {
84                         }
85                 }
86
87                 [Test]
88                 public void Headers ()
89                 {
90                         HttpRequestMessage message = new HttpRequestMessage ();
91                         HttpRequestHeaders headers = message.Headers;
92
93                         headers.Accept.Add (new MediaTypeWithQualityHeaderValue ("audio/x"));
94                         headers.AcceptCharset.Add (new StringWithQualityHeaderValue ("str-v", 0.002));
95                         headers.AcceptEncoding.Add (new StringWithQualityHeaderValue ("str-enc", 0.44));
96                         headers.AcceptLanguage.Add (new StringWithQualityHeaderValue ("str-lang", 0.41));
97                         headers.Authorization = new AuthenticationHeaderValue ("sh-aut", "par");
98                         headers.CacheControl = new CacheControlHeaderValue () {
99                                 MaxAge = TimeSpan.MaxValue
100                         };
101                         headers.Connection.Add ("test-value");
102                         headers.ConnectionClose = true;
103                         headers.Date = new DateTimeOffset (DateTime.Today);
104                         headers.Expect.Add (new NameValueWithParametersHeaderValue ("en", "ev"));
105                         headers.ExpectContinue = true;
106                         headers.From = "webmaster@w3.org";
107                         headers.Host = "host";
108                         headers.IfMatch.Add (new EntityTagHeaderValue ("\"tag\"", true));
109                         headers.IfModifiedSince = new DateTimeOffset (DateTime.Today);
110                         headers.IfNoneMatch.Add (new EntityTagHeaderValue ("\"tag2\"", true));
111                         headers.IfRange = new RangeConditionHeaderValue (new DateTimeOffset (DateTime.Today));
112                         headers.IfUnmodifiedSince = new DateTimeOffset? (DateTimeOffset.Now);
113                         headers.MaxForwards = 0x15b3;
114                         headers.Pragma.Add (new NameValueHeaderValue ("name", "value"));
115                         headers.ProxyAuthorization = new AuthenticationHeaderValue ("s", "p");
116                         headers.Range = new RangeHeaderValue (5L, 30L);
117                         headers.Referrer = new Uri ("http://xamarin.com");
118                         headers.TE.Add (new TransferCodingWithQualityHeaderValue ("TE", 0.3));
119                         headers.Trailer.Add ("value");
120                         headers.TransferEncoding.Add (new TransferCodingHeaderValue ("tchv"));
121                         headers.TransferEncodingChunked = true;
122                         headers.Upgrade.Add (new ProductHeaderValue ("prod", "ver"));
123                         headers.UserAgent.Add (new ProductInfoHeaderValue ("(comment)"));
124                         headers.Via.Add (new ViaHeaderValue ("protocol", "rec-by"));
125                         headers.Warning.Add (new WarningHeaderValue (5, "agent", "\"txt\""));
126
127                         try {
128                                 headers.Add ("authorization", "");
129                                 Assert.Fail ("Authorization");
130                         } catch (FormatException) {
131                         }
132
133                         try {
134                                 headers.Add ("connection", "extra ß ");
135                                 Assert.Fail ("Date");
136                         } catch (FormatException) {
137                         }
138
139                         try {
140                                 headers.Add ("date", "");
141                                 Assert.Fail ("Date");
142                         } catch (FormatException) {
143                         }
144
145                         try {
146                                 headers.Add ("from", "a@w3.org");
147                                 Assert.Fail ("From");
148                         } catch (FormatException) {
149                         }
150
151                         try {
152                                 headers.Add ("hOst", "host");
153                                 Assert.Fail ("Host");
154                         } catch (FormatException) {
155                         }
156
157                         try {
158                                 headers.Add ("if-modified-since", "");
159                                 Assert.Fail ("if-modified-since");
160                         } catch (FormatException) {
161                         }
162
163                         try {
164                                 headers.Add ("if-range", "");
165                                 Assert.Fail ("if-range");
166                         } catch (FormatException) {
167                         }
168
169                         try {
170                                 headers.Add ("if-unmodified-since", "");
171                                 Assert.Fail ("if-unmodified-since");
172                         } catch (FormatException) {
173                         }
174
175                         try {
176                                 headers.Add ("max-forwards", "");
177                                 Assert.Fail ("max-forwards");
178                         } catch (FormatException) {
179                         }
180
181                         try {
182                                 headers.Add ("proxy-authorization", "");
183                                 Assert.Fail ("proxy-authorization");
184                         } catch (FormatException) {
185                         }
186
187                         try {
188                                 headers.Add ("range", "");
189                         } catch (FormatException) {
190                         }
191
192                         try {
193                                 headers.Add ("referer", "");
194                                 Assert.Fail ("referer");
195                         } catch (FormatException) {
196                         }
197
198                         headers.Add ("accept", "audio/y");
199                         headers.Add ("accept-charset", "achs");
200                         headers.Add ("accept-encoding", "aenc");
201                         headers.Add ("accept-language", "alan");
202                         headers.Add ("expect", "exp");
203                         headers.Add ("if-match", "\"v\"");
204                         headers.Add ("if-none-match", "\"v2\"");
205                         headers.Add ("pragma", "p");
206                         headers.Add ("TE", "0.8");
207                         headers.Add ("trailer", "value2");
208                         headers.Add ("transfer-encoding", "ttt");
209                         headers.Add ("upgrade", "uuu");
210                         headers.Add ("user-agent", "uaua");
211                         headers.Add ("via", "prot v");
212                         headers.Add ("warning", "4 ww \"t\"");
213
214                         Assert.IsTrue (headers.Accept.SequenceEqual (
215                                 new[] {
216                                         new MediaTypeWithQualityHeaderValue ("audio/x"),
217                                         new MediaTypeWithQualityHeaderValue ("audio/y")
218                                 }
219                         ));
220
221                         Assert.IsTrue (headers.AcceptCharset.SequenceEqual (
222                                 new[] {
223                                         new StringWithQualityHeaderValue ("str-v", 0.002),
224                                         new StringWithQualityHeaderValue ("achs")
225                                 }
226                         ));
227
228                         Assert.IsTrue (headers.AcceptEncoding.SequenceEqual (
229                                 new[] {
230                                         new StringWithQualityHeaderValue ("str-enc", 0.44),
231                                         new StringWithQualityHeaderValue ("aenc")
232                                 }
233                         ));
234
235                         Assert.IsTrue (headers.AcceptLanguage.SequenceEqual (
236                                 new[] {
237                                         new StringWithQualityHeaderValue ("str-lang", 0.41),
238                                         new StringWithQualityHeaderValue ("alan")
239                                 }
240                         ));
241
242                         Assert.AreEqual (new AuthenticationHeaderValue ("sh-aut", "par"), headers.Authorization);
243
244                         var cch = new CacheControlHeaderValue () {
245                                         MaxAge = TimeSpan.MaxValue,
246                                 };
247
248                         Assert.AreEqual (cch, headers.CacheControl);
249
250                         Assert.IsTrue (headers.Connection.SequenceEqual (
251                                 new string[] { "test-value", "close" }));
252
253                         Assert.AreEqual (headers.Date, new DateTimeOffset (DateTime.Today));
254
255                         Assert.IsTrue (headers.Expect.SequenceEqual (
256                                 new [] {
257                                         new NameValueWithParametersHeaderValue ("en", "ev"),
258                                         new NameValueWithParametersHeaderValue ("100-continue"),
259                                         new NameValueWithParametersHeaderValue ("exp")
260                                 }));
261
262                         Assert.AreEqual (headers.From, "webmaster@w3.org");
263
264                         Assert.IsTrue (headers.IfMatch.SequenceEqual (
265                                 new EntityTagHeaderValue[] {
266                                         new EntityTagHeaderValue ("\"tag\"", true),
267                                         new EntityTagHeaderValue ("\"v\"", false)
268                                 }
269                         ));
270
271                         Assert.AreEqual (headers.IfModifiedSince, new DateTimeOffset (DateTime.Today));
272                         Assert.IsTrue (headers.IfNoneMatch.SequenceEqual (new EntityTagHeaderValue[] { new EntityTagHeaderValue ("\"tag2\"", true), new EntityTagHeaderValue ("\"v2\"", false) }));
273                         Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.IfRange.Date);
274                         Assert.AreEqual (headers.MaxForwards, 0x15b3);
275                         Assert.IsTrue (headers.Pragma.SequenceEqual (new NameValueHeaderValue[] { new NameValueHeaderValue ("name", "value"), new NameValueHeaderValue ("p", null) }));
276                         Assert.AreEqual ("p", headers.ProxyAuthorization.Parameter);
277                         Assert.AreEqual ("s", headers.ProxyAuthorization.Scheme);
278                         Assert.AreEqual (5, headers.Range.Ranges.First ().From);
279                         Assert.AreEqual (30, headers.Range.Ranges.First ().To);
280                         Assert.AreEqual ("bytes", headers.Range.Unit);
281                         Assert.AreEqual (headers.Referrer, new Uri ("http://xamarin.com"));
282                         Assert.IsTrue (headers.TE.SequenceEqual (new TransferCodingWithQualityHeaderValue[] { new TransferCodingWithQualityHeaderValue ("TE", 0.3), new TransferCodingWithQualityHeaderValue ("0.8") }), "29");
283                         Assert.IsTrue (headers.Trailer.SequenceEqual (
284                                 new string[] {
285                                         "value", "value2"
286                                 }), "30");
287
288                         Assert.IsTrue (headers.TransferEncoding.SequenceEqual (
289                                 new[] {
290                                         new TransferCodingHeaderValue ("tchv"),
291                                         new TransferCodingHeaderValue ("chunked"),
292                                         new TransferCodingHeaderValue ("ttt")
293                                 }
294                         ));
295
296                         Assert.IsTrue (headers.Upgrade.SequenceEqual (
297                                 new[] {
298                                         new ProductHeaderValue ("prod", "ver"),
299                                         new ProductHeaderValue ("uuu")
300                                 }
301                         ));
302
303                         Assert.IsTrue (headers.UserAgent.SequenceEqual (
304                                 new[] {
305                                         new ProductInfoHeaderValue ("(comment)"),
306                                         new ProductInfoHeaderValue ("uaua", null)
307                                 }
308                         ));
309
310                         Assert.IsTrue (headers.Via.SequenceEqual (
311                                 new[] {
312                                         new ViaHeaderValue ("protocol", "rec-by"),
313                                         new ViaHeaderValue ("prot", "v")
314                                 }
315                         ));
316
317                         Assert.IsTrue (headers.Warning.SequenceEqual (
318                                 new[] {
319                                         new WarningHeaderValue (5, "agent", "\"txt\""),
320                                         new WarningHeaderValue (4, "ww", "\"t\"")
321                                 }
322                         ));
323
324                 }
325
326                 [Test]
327                 public void Header_BaseImplementation ()
328                 {
329                         HttpRequestMessage message = new HttpRequestMessage ();
330                         HttpRequestHeaders headers = message.Headers;
331
332                         headers.Add ("a", "a-value");
333                         headers.Add ("b", new List<string> { "v1", "v2" });
334                         headers.Add ("c", null as string);
335                         headers.Add ("d", new string[0]);
336
337                         headers.AddWithoutValidation ("accept", "audio");
338
339                         Assert.IsFalse (headers.Contains ("nn"), "#1a");
340                         Assert.IsTrue (headers.Contains ("b"), "#1b");
341
342                         var values = headers.GetValues ("b").ToList ();
343                         Assert.AreEqual ("v1", values[0], "#2a");
344                         Assert.AreEqual ("v2", values[1], "#2b");
345
346                         Assert.IsFalse (headers.Remove ("p"), "#3a");
347                         Assert.IsTrue (headers.Remove ("b"), "#3b");
348                         Assert.IsFalse (headers.Contains ("b"), "#3b-c");
349
350                         IEnumerable<string> values2;
351                         Assert.IsTrue (headers.TryGetValues ("c", out values2));
352                         values = values2.ToList ();
353                         Assert.AreEqual ("", values[0], "#4a");
354
355                         int counter = 0;
356                         foreach (var i in headers) {
357                                 ++counter;
358                         }
359
360                         Assert.AreEqual (3, counter, "#5");
361
362                         headers.Clear ();
363
364                         headers.Accept.Add (new MediaTypeWithQualityHeaderValue ("audio/x"));
365                         headers.AddWithoutValidation ("accept", "audio");
366
367                         values = headers.GetValues ("accept").ToList ();
368                         Assert.AreEqual (2, values.Count, "#6");
369                         Assert.AreEqual ("audio/x", values[0], "#6a");
370                         Assert.AreEqual ("audio", values[1], "#6b");
371                         Assert.AreEqual (1, headers.Accept.Count, "#6c");
372
373                         headers.Clear ();
374
375                         headers.AddWithoutValidation ("from", new[] { "a@a.com", "ssss@oo.com" });
376                         values = headers.GetValues ("from").ToList ();
377
378                         Assert.AreEqual (2, values.Count, "#7");
379                         Assert.AreEqual ("a@a.com", values[0], "#7a");
380                         Assert.AreEqual ("ssss@oo.com", values[1], "#7b");
381                         Assert.AreEqual ("a@a.com", headers.From, "#7c");
382
383                         headers.Clear ();
384
385                         headers.AddWithoutValidation ("Date", "wrong date");
386                         var value = headers.Date;
387                         Assert.IsNull (headers.Date, "#8");
388                 }
389
390                 [Test]
391                 public void Headers_Invalid ()
392                 {
393                         HttpRequestMessage message = new HttpRequestMessage ();
394                         HttpRequestHeaders headers = message.Headers;
395
396                         try {
397                                 headers.Add ("Allow", "");
398                                 Assert.Fail ("#1");
399                         } catch (InvalidOperationException) {
400                         }
401
402                         try {
403                                 headers.Add (null, "");
404                                 Assert.Fail ("#2");
405                         } catch (ArgumentException) {
406                         }
407
408                         try {
409                                 headers.Add ("mm", null as IEnumerable<string>);
410                                 Assert.Fail ("#2b");
411                         } catch (ArgumentNullException) {
412                         }
413
414                         try {
415                                 headers.Add ("accept", "audio");
416                                 Assert.Fail ("#2c");
417                         } catch (FormatException) {
418                         }
419
420                         try {
421                                 headers.AddWithoutValidation ("Allow", "");
422                                 Assert.Fail ("#3");
423                         } catch (InvalidOperationException) {
424                         }
425
426                         try {
427                                 headers.AddWithoutValidation (null, "");
428                                 Assert.Fail ("#4");
429                         } catch (ArgumentException) {
430                         }
431
432                         try {
433                                 headers.Contains (null);
434                                 Assert.Fail ("#5");
435                         } catch (ArgumentException) {
436                         }
437
438                         try {
439                                 headers.GetValues (null);
440                                 Assert.Fail ("#6a");
441                         } catch (ArgumentException) {
442                         }
443
444                         try {
445                                 headers.GetValues ("bbbb");
446                                 Assert.Fail ("#6b");
447                         } catch (InvalidOperationException) {
448                         }
449
450                         try {
451                                 headers.Add ("from", new[] { "a@a.com", "ssss@oo.com" });
452                                 Assert.Fail ("#7a");
453                         } catch (FormatException) {
454                         }
455
456                         headers.AddWithoutValidation ("from", "a@a.com");
457                         try {
458                                 headers.Add ("from", "valid@w3.org");
459                                 Assert.Fail ("#7b");
460                         } catch (FormatException) {
461                         }
462                 }
463
464                 [Test]
465                 public void Headers_Response ()
466                 {
467                         HttpRequestMessage message = new HttpRequestMessage ();
468                         HttpRequestHeaders headers = message.Headers;
469
470                         headers.Add ("Age", "vv");
471                         Assert.AreEqual ("vv", headers.GetValues ("Age").First (), "#1");
472
473                         headers.Clear ();
474                         headers.AddWithoutValidation ("Age", "vv");
475                         Assert.AreEqual ("vv", headers.GetValues ("Age").First (), "#2");
476                 }
477
478                 [Test]
479                 public void Headers_ExpectContinue ()
480                 {
481                         HttpRequestMessage message = new HttpRequestMessage ();
482                         HttpRequestHeaders headers = message.Headers;
483                         Assert.IsNull (headers.ExpectContinue, "#1");
484
485                         headers.ExpectContinue = false;
486                         Assert.IsFalse (headers.ExpectContinue.Value, "#2");
487
488                         headers.Clear ();
489
490                         headers.ExpectContinue = true;
491                         headers.ExpectContinue = true;
492                         headers.ExpectContinue = true;
493                         headers.ExpectContinue = true;
494                         Assert.IsTrue (headers.ExpectContinue.Value, "#3");
495                         Assert.AreEqual (1, headers.GetValues ("expect").ToList ().Count, "#4");
496
497                         headers.Clear ();
498                         headers.Expect.Add (new NameValueWithParametersHeaderValue ("100-conTinuE"));
499                         Assert.IsTrue (headers.ExpectContinue.Value, "#5");
500                 }
501
502                 [Test]
503                 public void Headers_ConnectionClose ()
504                 {
505                         HttpRequestMessage message = new HttpRequestMessage ();
506                         HttpRequestHeaders headers = message.Headers;
507                         Assert.IsNull (headers.ConnectionClose, "#1");
508
509                         headers.ConnectionClose = false;
510                         Assert.IsFalse (headers.ConnectionClose.Value, "#2");
511
512                         headers.Clear ();
513
514                         headers.ConnectionClose = true;
515                         Assert.IsTrue (headers.ConnectionClose.Value, "#3");
516
517                         headers.Clear ();
518                         headers.Connection.Add ("Close");
519                         Assert.IsTrue (headers.ConnectionClose.Value, "#4");
520                 }
521
522                 [Test]
523                 public void Headers_From_Invalid ()
524                 {
525                         HttpRequestMessage message = new HttpRequestMessage ();
526                         HttpRequestHeaders headers = message.Headers;
527                         headers.From = null;
528                         headers.From = "";
529                         try {
530                                 headers.From = " ";
531                                 Assert.Fail ("#1");
532                         } catch (FormatException) {
533                         }
534                         try {
535                                 headers.From = "test";
536                                 Assert.Fail ("#2");
537                         } catch (FormatException) {
538                         }
539                 }
540
541                 [Test]
542                 public void Headers_TransferEncodingChunked ()
543                 {
544                         HttpRequestMessage message = new HttpRequestMessage ();
545                         HttpRequestHeaders headers = message.Headers;
546                         Assert.IsNull (headers.TransferEncodingChunked, "#1");
547
548                         headers.TransferEncodingChunked = false;
549                         Assert.IsFalse (headers.TransferEncodingChunked.Value, "#2");
550
551                         headers.Clear ();
552
553                         headers.TransferEncodingChunked = true;
554                         Assert.IsTrue (headers.TransferEncodingChunked.Value, "#3");
555                         Assert.AreEqual (1, headers.TransferEncoding.Count, "#3b");
556                 }
557
558                 [Test]
559                 public void Properties ()
560                 {
561                         var c = new HttpRequestMessage ();
562                         c.Content = null;
563                         c.Method = HttpMethod.Post;
564                         c.Properties.Add ("a", "test");
565                         c.RequestUri = null;
566                         c.Version = HttpVersion.Version10;
567
568                         Assert.IsNull (c.Content, "#1");
569                         Assert.AreEqual (HttpMethod.Post, c.Method, "#2");
570                         Assert.AreEqual ("test", c.Properties["a"], "#3");
571                         Assert.IsNull (c.RequestUri, "#4");
572                         Assert.AreEqual (HttpVersion.Version10, c.Version, "#5");
573                 }
574
575                 [Test]
576                 public void Properties_Invalid ()
577                 {
578                         var c = new HttpRequestMessage ();
579                         try {
580                                 c.Method = null;
581                                 Assert.Fail ("#1");
582                         } catch (ArgumentNullException) {
583                         }
584
585                         try {
586                                 c.RequestUri = new Uri ("ftp://xamarin.com");
587                                 Assert.Fail ("#2");
588                         } catch (ArgumentException) {
589                         }
590
591                         try {
592                                 c.Version = null;
593                                 Assert.Fail ("#3");
594                         } catch (ArgumentNullException) {
595                         }
596                 }
597         }
598 }