2 // HttpResponseMessageTest.cs
5 // Marek Safar <marek.safar@gmail.com>
7 // Copyright (C) 2011 Xamarin, Inc (http://www.xamarin.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
30 using System.Collections;
31 using System.Collections.Generic;
32 using System.Text.RegularExpressions;
33 using NUnit.Framework;
34 using System.Net.Http;
36 using System.Net.Http.Headers;
39 namespace MonoTests.System.Net.Http
42 public class HttpResponseMessageTest
45 public void Ctor_Invalid ()
48 new HttpResponseMessage ((HttpStatusCode) (-1));
50 } catch (ArgumentOutOfRangeException) {
55 public void Ctor_Default ()
57 var m = new HttpResponseMessage ();
58 Assert.IsNull (m.Content, "#1");
59 Assert.IsNotNull (m.Headers, "#2");
60 Assert.IsTrue (m.IsSuccessStatusCode, "#3");
61 Assert.AreEqual ("OK", m.ReasonPhrase, "#4");
62 Assert.IsNull (m.RequestMessage, "#5");
63 Assert.AreEqual (HttpStatusCode.OK, m.StatusCode, "#6");
64 Assert.AreEqual (new Version (1, 1), m.Version, "#7");
65 Assert.IsNull (m.Headers.CacheControl, "#8");
67 Assert.AreEqual ("StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: <null>, Headers:\r\n{\r\n}", m.ToString (), "#9");
71 public void Headers ()
73 HttpResponseMessage message = new HttpResponseMessage ();
74 HttpResponseHeaders headers = message.Headers;
76 headers.AcceptRanges.Add ("ac-v");
77 headers.Age = TimeSpan.MaxValue;
78 headers.CacheControl = new CacheControlHeaderValue () {
81 headers.Connection.Add ("test-value");
82 headers.ConnectionClose = true;
83 headers.Date = new DateTimeOffset (DateTime.Today);
84 headers.ETag = new EntityTagHeaderValue ("\"tag\"", true);
85 headers.Location = new Uri ("http://xamarin.com");
86 headers.Pragma.Add (new NameValueHeaderValue ("name", "value"));
87 headers.ProxyAuthenticate.Add (new AuthenticationHeaderValue ("proxy", "par"));
88 headers.RetryAfter = new RetryConditionHeaderValue (TimeSpan.MinValue);
89 headers.Server.Add (new ProductInfoHeaderValue ("(comment)"));
90 headers.Trailer.Add ("trailer-vvv");
91 headers.TransferEncoding.Add (new TransferCodingHeaderValue ("tchv"));
92 headers.TransferEncodingChunked = true;
93 headers.Upgrade.Add (new ProductHeaderValue ("prod", "ver"));
94 headers.Vary.Add ("vary");
95 headers.Via.Add (new ViaHeaderValue ("protocol", "rec-by"));
96 headers.Warning.Add (new WarningHeaderValue (5, "agent", "\"txt\""));
97 headers.WwwAuthenticate.Add (new AuthenticationHeaderValue ("www", "par"));
100 headers.Add ("age", "");
102 } catch (FormatException) {
106 headers.Add ("date", "");
107 Assert.Fail ("date");
108 } catch (FormatException) {
112 headers.Add ("etag", "");
113 Assert.Fail ("etag");
114 } catch (FormatException) {
118 headers.Add ("location", "extra");
119 Assert.Fail ("location");
120 } catch (FormatException) {
124 headers.Add ("retry-after", "extra");
125 Assert.Fail ("retry-after");
126 } catch (FormatException) {
129 headers.Add ("accept-ranges", "achs");
130 // TODO: headers.Add ("cache-control", "cache-value");
131 headers.Add ("connection", "ccc");
132 headers.Add ("pragma", "p");
133 headers.Add ("proxy-authenticate", "ttt");
134 headers.Add ("server", "server");
135 headers.Add ("trailer", "tt-r");
136 headers.Add ("transfer-encoding", "ttt");
137 headers.Add ("upgrade", "uuu");
138 headers.Add ("upgrade", "vvvvaa");
139 headers.Add ("vary", "vvaar");
140 headers.Add ("via", "prot v");
141 headers.Add ("warning", "4 ww \"t\"");
142 headers.Add ("www-Authenticate", "ww");
144 Assert.IsTrue (headers.AcceptRanges.SequenceEqual (
151 Assert.AreEqual (TimeSpan.MaxValue, headers.Age);
154 new CacheControlHeaderValue () {
156 // TODO Extensions = { new NameValueHeaderValue ("cache-value") }
157 }, headers.CacheControl);
159 Assert.IsTrue (headers.Connection.SequenceEqual (
160 new string[] { "test-value", "close", "ccc" }));
162 Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.Date);
164 Assert.AreEqual (new EntityTagHeaderValue ("\"tag\"", true), headers.ETag);
166 Assert.AreEqual (new Uri ("http://xamarin.com"), headers.Location);
168 Assert.IsTrue (headers.Pragma.SequenceEqual (
170 new NameValueHeaderValue ("name", "value"),
171 new NameValueHeaderValue ("p"),
174 Assert.IsTrue (headers.ProxyAuthenticate.SequenceEqual (
176 new AuthenticationHeaderValue ("proxy", "par"),
177 new AuthenticationHeaderValue ("ttt")
181 Assert.AreEqual (new RetryConditionHeaderValue (TimeSpan.MinValue), headers.RetryAfter);
183 Assert.IsTrue (headers.Server.SequenceEqual (
185 new ProductInfoHeaderValue ("(comment)"),
186 new ProductInfoHeaderValue (new ProductHeaderValue ("server"))
190 Assert.IsTrue (headers.Trailer.SequenceEqual (
196 Assert.IsTrue (headers.TransferEncoding.SequenceEqual (
198 new TransferCodingHeaderValue ("tchv"),
199 new TransferCodingHeaderValue ("chunked"),
200 new TransferCodingHeaderValue ("ttt")
204 Assert.IsTrue (headers.Upgrade.SequenceEqual (
206 new ProductHeaderValue ("prod", "ver"),
207 new ProductHeaderValue ("uuu"),
208 new ProductHeaderValue ("vvvvaa")
212 Assert.IsTrue (headers.Vary.SequenceEqual (
219 Assert.IsTrue (headers.Via.SequenceEqual (
221 new ViaHeaderValue ("protocol", "rec-by"),
222 new ViaHeaderValue ("prot", "v")
226 Assert.IsTrue (headers.Warning.SequenceEqual (
228 new WarningHeaderValue (5, "agent", "\"txt\""),
229 new WarningHeaderValue (4, "ww", "\"t\"")
233 Assert.IsTrue (headers.WwwAuthenticate.SequenceEqual (
235 new AuthenticationHeaderValue ("www", "par"),
236 new AuthenticationHeaderValue ("ww")
242 public void EnsureSuccessStatusCode ()
244 HttpResponseMessage message = new HttpResponseMessage ();
245 Assert.AreSame (message, message.EnsureSuccessStatusCode (), "#1");
247 message = new HttpResponseMessage (HttpStatusCode.BadRequest);
248 message.ReasonPhrase = "test reason";
250 message.EnsureSuccessStatusCode ();
252 } catch (HttpRequestException e) {
253 Assert.IsTrue (e.Message.Contains ("400 (test reason)"), "#3");
258 public void Headers_GetEnumerator ()
260 HttpResponseMessage message = new HttpResponseMessage ();
261 HttpResponseHeaders headers = message.Headers;
263 headers.Add ("a", new[] { "v1", "v2" });
264 headers.Add ("cache-control", "audio");
265 headers.Age = new TimeSpan (4444, 2, 3, 4, 5);
269 foreach (var entry in headers) {
272 Assert.AreEqual ("a", entry.Key);
273 values = entry.Value.ToList ();
274 Assert.AreEqual (2, values.Count);
275 Assert.AreEqual ("v1", values[0]);
278 Assert.AreEqual ("cache-control", entry.Key);
279 values = entry.Value.ToList ();
280 Assert.AreEqual (1, values.Count);
281 Assert.AreEqual ("audio", values[0]);
284 Assert.AreEqual ("Age", entry.Key);
285 values = entry.Value.ToList ();
286 Assert.AreEqual (1, values.Count);
287 Assert.AreEqual ("383968984", values[0]);
294 Assert.AreEqual (3, i, "#10");
298 public void Header_BaseImplementation ()
300 HttpResponseMessage message = new HttpResponseMessage ();
301 HttpResponseHeaders headers = message.Headers;
303 headers.Add ("a", "a-value");
304 headers.Add ("b", new List<string> { "v1", "v2" });
305 headers.Add ("c", null as string);
306 headers.Add ("d", new string[0]);
308 headers.TryAddWithoutValidation ("cache-control", "audio");
310 Assert.IsFalse (headers.Contains ("nn"), "#1a");
311 Assert.IsTrue (headers.Contains ("b"), "#1b");
313 var values = headers.GetValues ("b").ToList ();
314 Assert.AreEqual ("v1", values[0], "#2a");
315 Assert.AreEqual ("v2", values[1], "#2b");
317 Assert.IsFalse (headers.Remove ("p"), "#3a");
318 Assert.IsTrue (headers.Remove ("b"), "#3b");
319 Assert.IsFalse (headers.Contains ("b"), "#3b-c");
321 IEnumerable<string> values2;
322 Assert.IsTrue (headers.TryGetValues ("c", out values2));
323 values = values2.ToList ();
324 Assert.AreEqual ("", values[0], "#4a");
327 foreach (var i in headers) {
331 Assert.AreEqual (3, counter, "#5");
337 public void Headers_Invalid ()
339 HttpResponseMessage message = new HttpResponseMessage ();
340 HttpResponseHeaders headers = message.Headers;
343 headers.Add ("age", "");
345 } catch (FormatException) {
349 headers.Add (null, "");
351 } catch (ArgumentException) {
355 headers.Add ("mm", null as IEnumerable<string>);
357 } catch (ArgumentNullException) {
361 headers.Add ("Allow", "audio");
363 } catch (InvalidOperationException) {
366 Assert.IsFalse (headers.TryAddWithoutValidation ("Allow", ""), "#3");
368 Assert.IsFalse (headers.TryAddWithoutValidation (null, ""), "#4");
371 headers.Contains (null);
373 } catch (ArgumentException) {
377 headers.GetValues (null);
379 } catch (ArgumentException) {
383 headers.GetValues ("bbbb");
385 } catch (InvalidOperationException) {
389 headers.Add ("location", new[] { "google.com", "xamarin.com" });
391 } catch (FormatException) {
394 headers.TryAddWithoutValidation ("location", "a@a.com");
396 headers.Add ("location", "w3.org");
398 } catch (FormatException) {
403 public void Headers_Request ()
405 HttpResponseMessage message = new HttpResponseMessage ();
406 HttpResponseHeaders headers = message.Headers;
408 headers.Add ("accept", "audio");
409 Assert.AreEqual ("audio", headers.GetValues ("Accept").First (), "#1");
412 Assert.IsTrue (headers.TryAddWithoutValidation ("accept", "audio"), "#2a");
413 Assert.AreEqual ("audio", headers.GetValues ("Accept").First (), "#2");
417 public void Headers_ConnectionClose ()
419 HttpResponseMessage message = new HttpResponseMessage ();
420 HttpResponseHeaders headers = message.Headers;
421 Assert.IsNull (headers.ConnectionClose, "#1");
423 headers.ConnectionClose = false;
424 Assert.IsFalse (headers.ConnectionClose.Value, "#2");
428 headers.ConnectionClose = true;
429 Assert.IsTrue (headers.ConnectionClose.Value, "#3");
432 headers.Connection.Add ("Close");
433 Assert.IsTrue (headers.ConnectionClose.Value, "#4");
435 // .NET encloses the "Connection: Close" with two whitespaces.
436 var normalized = Regex.Replace (message.ToString (), @"\s", "");
437 Assert.AreEqual ("StatusCode:200,ReasonPhrase:'OK',Version:1.1,Content:<null>,Headers:{Connection:Close}", normalized, "#5");
441 public void Headers_Location ()
443 HttpResponseMessage message = new HttpResponseMessage ();
444 HttpResponseHeaders headers = message.Headers;
445 headers.TryAddWithoutValidation ("location", "http://w3.org");
446 Assert.AreEqual (new Uri ("http://w3.org"), headers.Location);
450 public void Headers_TransferEncoding ()
452 HttpResponseMessage message = new HttpResponseMessage ();
453 HttpResponseHeaders headers = message.Headers;
454 headers.TryAddWithoutValidation ("Transfer-Encoding", "mmm");
455 headers.TryAddWithoutValidation ("Transfer-Encoding", "▀");
456 headers.TryAddWithoutValidation ("Transfer-Encoding", "zz");
458 var a = headers.TransferEncoding;
459 Assert.AreEqual (2, a.Count, "#1");
461 // Assert.AreEqual ("mmm, zz, ▀", a.ToString (), "#2");
465 public void Headers_TransferEncodingChunked ()
467 HttpResponseMessage message = new HttpResponseMessage ();
468 HttpResponseHeaders headers = message.Headers;
469 Assert.IsNull (headers.TransferEncodingChunked, "#1");
471 headers.TransferEncodingChunked = false;
472 Assert.IsFalse (headers.TransferEncodingChunked.Value, "#2");
476 headers.TransferEncodingChunked = true;
477 Assert.IsTrue (headers.TransferEncodingChunked.Value, "#3");
478 Assert.AreEqual (1, headers.TransferEncoding.Count, "#3b");
481 Assert.IsTrue (headers.TryAddWithoutValidation ("Transfer-Encoding", "value"), "#4-0");
482 // Assert.AreEqual (false, headers.TransferEncodingChunked, "#4");
485 Assert.IsTrue (headers.TryAddWithoutValidation ("Transfer-Encoding", "chunked"), "#5-0");
486 Assert.AreEqual (true, headers.TransferEncodingChunked, "#5");
488 message = new HttpResponseMessage ();
489 headers = message.Headers;
490 Assert.IsTrue (headers.TryAddWithoutValidation ("Transfer-Encoding", "ß"), "#6-0");
491 Assert.IsNull (headers.TransferEncodingChunked, "#6");
495 public void Properties ()
497 var c = new HttpResponseMessage ();
499 c.ReasonPhrase = "rphr";
500 c.RequestMessage = new HttpRequestMessage ();
501 c.RequestMessage.Properties.Add ("a", "test");
502 c.StatusCode = HttpStatusCode.UnsupportedMediaType;
503 c.Version = HttpVersion.Version10;
505 Assert.IsNull (c.Content, "#1");
506 Assert.AreEqual ("rphr", c.ReasonPhrase, "#2");
507 Assert.AreEqual ("test", c.RequestMessage.Properties["a"], "#3");
508 Assert.AreEqual (HttpStatusCode.UnsupportedMediaType, c.StatusCode, "#4");
509 Assert.AreEqual (HttpVersion.Version10, c.Version, "#5");
510 Assert.IsFalse (c.IsSuccessStatusCode, "#6");
514 public void Properties_Invalid ()
516 var c = new HttpResponseMessage ();
519 c.StatusCode = (HttpStatusCode) (-1);
521 } catch (ArgumentException) {
527 } catch (ArgumentNullException) {