2 // WebHeaderCollectionTest.cs - NUnit Test Cases for System.Net.WebHeaderCollection
5 // Lawrence Pit (loz@cable.a2000.nl)
6 // Martin Willemoes Hansen (mwh@sysrq.dk)
7 // Gert Driesen (drieseng@users.sourceforge.net)
8 // Gonzalo Paniagua Javier (gonzalo@novell.com)
9 // Marek Safar <marek.safar@gmail.com>
11 // (C) 2003 Martin Willemoes Hansen
15 using System.Collections;
16 using System.Collections.Specialized;
19 using System.Runtime.Serialization;
20 using System.Runtime.Serialization.Formatters;
21 using System.Runtime.Serialization.Formatters.Binary;
23 using NUnit.Framework;
26 namespace MonoTests.System.Net
29 public class WebHeaderCollectionTest
31 WebHeaderCollection col;
34 public void GetReady ()
36 col = new WebHeaderCollection ();
37 col.Add ("Name1: Value1");
38 col.Add ("Name2: Value2");
47 } catch (ArgumentNullException) { }
51 } catch (ArgumentException) { }
55 } catch (ArgumentException) { }
59 } catch (ArgumentException) { }
63 } catch (ArgumentException) { }
66 col.Add ("XHost: foo");
67 } catch (ArgumentException) {
73 col.Add ("XHost" + ((char) 0xa9) + ": foo");
75 } catch (ArgumentException) { }
77 col.Add ("XHost: foo" + (char) 0xa9);
78 } catch (ArgumentException) {
82 col.Add ("XHost: foo" + (char) 0x7f);
84 } catch (ArgumentException) {
89 } catch (ArgumentException) {
93 col.Add ("XHost", null);
94 } catch (ArgumentException) {
99 } catch (ArgumentException) {
105 public void AddRequestHeader ()
107 col.Add (HttpRequestHeader.Host, "hh");
110 col.Add (HttpResponseHeader.Age, "aa");
112 } catch (InvalidOperationException) {
117 public void AddRestrictedDisabled ()
119 col.Add ("Accept", "aa");
120 col.Add ("Content-Length", "bb");
121 col.Add ("Keep-Alive", "cc");
122 col.Add ("If-Modified-Since", "dd");
123 col.Add ("aaany", null);
127 public void AddRestricted ()
129 col = CreateRestrictedHeaders ();
132 col.Add ("Accept", "cc");
134 } catch (ArgumentException) {
138 col.Add (HttpRequestHeader.Host, "dd");
140 } catch (ArgumentException) {
145 public void GetValues ()
147 WebHeaderCollection w = new WebHeaderCollection ();
148 w.Add ("Hello", "H1");
149 w.Add ("Hello", "H2");
150 w.Add ("Hello", "H3,H4");
152 string [] sa = w.GetValues ("Hello");
153 Assert.AreEqual (3, sa.Length, "#1");
154 Assert.AreEqual ("H1,H2,H3,H4", w.Get ("Hello"), "#2");
156 w = new WebHeaderCollection ();
157 w.Add ("Accept", "H1");
158 w.Add ("Accept", "H2");
159 w.Add ("Accept", "H3, H4 ");
160 Assert.AreEqual (3, w.GetValues (0).Length, "#3a");
161 Assert.AreEqual (4, w.GetValues ("Accept").Length, "#3b");
162 Assert.AreEqual ("H4", w.GetValues ("Accept")[3], "#3c");
163 Assert.AreEqual ("H1,H2,H3, H4", w.Get ("Accept"), "#4");
165 w = new WebHeaderCollection ();
166 w.Add ("Allow", "H1");
167 w.Add ("Allow", "H2");
168 w.Add ("Allow", "H3,H4");
169 sa = w.GetValues ("Allow");
170 Assert.AreEqual (4, sa.Length, "#5");
171 Assert.AreEqual ("H1,H2,H3,H4", w.Get ("Allow"), "#6");
173 w = new WebHeaderCollection ();
174 w.Add ("AUTHorization", "H1, H2, H3");
175 sa = w.GetValues ("authorization");
176 Assert.AreEqual (3, sa.Length, "#9");
178 w = new WebHeaderCollection ();
179 w.Add ("proxy-authenticate", "H1, H2, H3");
180 sa = w.GetValues ("Proxy-Authenticate");
181 Assert.AreEqual (3, sa.Length, "#9");
183 w = new WebHeaderCollection ();
184 w.Add ("expect", "H1,\tH2, H3 ");
185 sa = w.GetValues ("EXPECT");
186 Assert.AreEqual (3, sa.Length, "#10");
187 Assert.AreEqual ("H2", sa [1], "#11");
188 Assert.AreEqual ("H3", sa [2], "#12");
193 } catch (ArgumentNullException) { }
194 Assert.AreEqual (null, w.GetValues (""), "#14");
195 Assert.AreEqual (null, w.GetValues ("NotExistent"), "#15");
197 w = new WebHeaderCollection ();
198 w.Add ("Accept", null);
199 Assert.AreEqual (1, w.GetValues ("Accept").Length, "#16");
201 w = new WebHeaderCollection ();
202 w.Add ("Accept", ",,,");
203 Assert.AreEqual (3, w.GetValues ("Accept").Length, "#17");
207 public void Indexers ()
209 Assert.AreEqual ("Value1", ((NameValueCollection)col)[0], "#1.1");
210 WebHeaderCollection w = new WebHeaderCollection ();
211 w [HttpRequestHeader.CacheControl] = "Value2";
212 Assert.AreEqual ("Value2", w[HttpRequestHeader.CacheControl], "#1.2");
215 w[HttpResponseHeader.Pragma] = "Value3";
216 Assert.Fail ("#1.3");
217 } catch (InvalidOperationException) {
222 public void Remove ()
224 col.Remove ("Name1");
225 col.Remove ("NameNotExist");
226 Assert.AreEqual (1, col.Count, "#1");
230 public void RemoveRestricted ()
232 col = CreateRestrictedHeaders ();
235 col.Add ("Host", "foo");
237 Assert.Fail ("#2: should fail according to spec");
238 } catch (ArgumentException) {}
244 col.Add ("Name1", "Value1b");
245 col.Set ("Name1", "\t X \t");
246 Assert.AreEqual ("X", col.Get ("Name1"), "#1");
250 public void IsRestricted ()
252 Assert.IsTrue (!WebHeaderCollection.IsRestricted ("Xhost"), "#1");
253 Assert.IsTrue (WebHeaderCollection.IsRestricted ("Host"), "#2");
254 Assert.IsTrue (WebHeaderCollection.IsRestricted ("HOST"), "#3");
255 Assert.IsTrue (WebHeaderCollection.IsRestricted ("Transfer-Encoding"), "#4");
256 Assert.IsTrue (WebHeaderCollection.IsRestricted ("user-agent"), "#5");
257 Assert.IsTrue (WebHeaderCollection.IsRestricted ("accept"), "#6");
258 Assert.IsTrue (!WebHeaderCollection.IsRestricted ("accept-charset"), "#7");
262 public void ToStringTest ()
264 col.Add ("Name1", "Value1b");
265 col.Add ("Name3", "Value3a\r\n Value3b");
266 col.Add ("Name4", " Value4 ");
267 Assert.AreEqual ("Name1: Value1,Value1b\r\nName2: Value2\r\nName3: Value3a\r\n Value3b\r\nName4: Value4\r\n\r\n", col.ToString (), "#1");
268 WebHeaderCollection w;
269 w = new WebHeaderCollection ();
270 w.Add (HttpResponseHeader.KeepAlive, "Value1");
271 w.Add (HttpResponseHeader.WwwAuthenticate, "Value2");
272 Assert.AreEqual ("Keep-Alive: Value1\r\nWWW-Authenticate: Value2\r\n\r\n", w.ToString (), "#2");
273 w = new WebHeaderCollection ();
274 w.Add (HttpRequestHeader.UserAgent, "Value1");
275 w.Add (HttpRequestHeader.ContentMd5, "Value2");
276 Assert.AreEqual ("User-Agent: Value1\r\nContent-MD5: Value2\r\n\r\n", w.ToString (), "#3");
280 public void GetObjectData ()
282 SerializationInfo si = new SerializationInfo (typeof (WebHeaderCollection),
283 new FormatterConverter ());
285 WebHeaderCollection headers = new WebHeaderCollection ();
286 headers.Add ("Content-Type", "image/png");
287 headers.Add ("No-Cache:off");
288 headers.Add ("Disposition", "attach");
290 ((ISerializable) headers).GetObjectData (si, new StreamingContext ());
291 Assert.AreEqual (7, si.MemberCount, "#A");
293 foreach (SerializationEntry entry in si) {
294 Assert.IsNotNull (entry.Name, "#B1:" + i);
295 Assert.IsNotNull (entry.ObjectType, "#B2:" + i);
296 Assert.IsNotNull (entry.Value, "#B3:" + i);
300 Assert.AreEqual ("Count", entry.Name, "#B4:" + i);
301 Assert.AreEqual (typeof (int), entry.ObjectType, "#B5:" + i);
302 Assert.AreEqual (3, entry.Value, "#B6:" + i);
305 Assert.AreEqual ("0", entry.Name, "#B4:" + i);
306 Assert.AreEqual (typeof (string), entry.ObjectType, "#B5:" + i);
307 Assert.AreEqual ("Content-Type", entry.Value, "#B6:" + i);
310 Assert.AreEqual ("3", entry.Name, "#B4:" + i);
311 Assert.AreEqual (typeof (string), entry.ObjectType, "#B5:" + i);
312 Assert.AreEqual ("image/png", entry.Value, "#B6:" + i);
315 Assert.AreEqual ("1", entry.Name, "#B4:" + i);
316 Assert.AreEqual (typeof (string), entry.ObjectType, "#B5:" + i);
317 Assert.AreEqual ("No-Cache", entry.Value, "#B6:" + i);
320 Assert.AreEqual ("4", entry.Name, "#B4:" + i);
321 Assert.AreEqual (typeof (string), entry.ObjectType, "#B5:" + i);
322 Assert.AreEqual ("off", entry.Value, "#B6:" + i);
325 Assert.AreEqual ("2", entry.Name, "#B4:" + i);
326 Assert.AreEqual (typeof (string), entry.ObjectType, "#B5:" + i);
327 Assert.AreEqual ("Disposition", entry.Value, "#B6:" + i);
330 Assert.AreEqual ("5", entry.Name, "#B4:" + i);
331 Assert.AreEqual (typeof (string), entry.ObjectType, "#B5:" + i);
332 Assert.AreEqual ("attach", entry.Value, "#B6:" + i);
340 public void Serialize ()
342 WebHeaderCollection headers = new WebHeaderCollection ();
343 headers.Add ("Content-Type", "image/png");
344 headers.Add ("No-Cache:off");
345 headers.Add ("Disposition", "attach");
347 BinaryFormatter bf = new BinaryFormatter ();
348 bf.AssemblyFormat = FormatterAssemblyStyle.Full;
350 MemoryStream ms = new MemoryStream ();
351 bf.Serialize (ms, headers);
354 byte [] buffer = new byte [ms.Length];
355 ms.Read (buffer, 0, buffer.Length);
356 Assert.AreEqual (_serialized, buffer);
360 public void Deserialize ()
362 MemoryStream ms = new MemoryStream ();
363 ms.Write (_serialized, 0, _serialized.Length);
366 BinaryFormatter bf = new BinaryFormatter ();
367 WebHeaderCollection headers = (WebHeaderCollection) bf.Deserialize (ms);
370 private static readonly byte [] _serialized = new byte [] {
371 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00,
373 0x49, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2c, 0x20, 0x56, 0x65,
375 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x32, 0x2e, 0x30, 0x2e, 0x35,
377 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x34, 0x2e, 0x30, 0x2e, 0x30,
379 0x2e, 0x30, 0x2c, 0x20, 0x43, 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65,
380 0x3d, 0x6e, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6c, 0x2c, 0x20, 0x50,
381 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x6b,
383 0x65, 0x6e, 0x3d, 0x37, 0x63, 0x65, 0x63, 0x38, 0x35, 0x64, 0x37,
384 0x62, 0x65, 0x61, 0x37, 0x37, 0x39, 0x38, 0x65, 0x05, 0x01, 0x00,
386 0x65, 0x6e, 0x3d, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36,
387 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00,
389 0x00, 0x00, 0x1e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x4e,
390 0x65, 0x74, 0x2e, 0x57, 0x65, 0x62, 0x48, 0x65, 0x61, 0x64, 0x65,
391 0x72, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
392 0x07, 0x00, 0x00, 0x00, 0x05, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x01,
393 0x30, 0x01, 0x33, 0x01, 0x31, 0x01, 0x34, 0x01, 0x32, 0x01, 0x35,
394 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x02, 0x00, 0x00,
395 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x0c,
396 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70,
397 0x65, 0x06, 0x04, 0x00, 0x00, 0x00, 0x09, 0x69, 0x6d, 0x61, 0x67,
398 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x06, 0x05, 0x00, 0x00, 0x00, 0x08,
399 0x4e, 0x6f, 0x2d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x06, 0x06, 0x00,
400 0x00, 0x00, 0x03, 0x6f, 0x66, 0x66, 0x06, 0x07, 0x00, 0x00, 0x00,
401 0x0b, 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
402 0x6e, 0x06, 0x08, 0x00, 0x00, 0x00, 0x06, 0x61, 0x74, 0x74, 0x61,
407 public void IsRestricted_InvalidChars_1 ()
419 int [] singles = new int [] { 34, 44, 47, 123, 125 };
420 foreach (int single in singles) {
422 WebHeaderCollection.IsRestricted (new string ((char) single, 1));
423 Assert.Fail (String.Format ("{0}: {1}", single, (char) single));
424 } catch (ArgumentException) {
427 for (int i = 0; i <= 32; i++) {
429 WebHeaderCollection.IsRestricted (new string ((char) i, 1));
430 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
431 } catch (ArgumentException) {
434 for (int i = 39; i <= 41; i++) {
436 WebHeaderCollection.IsRestricted (new string ((char) i, 1));
437 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
438 } catch (ArgumentException) {
441 for (int i = 91; i <= 93; i++) {
443 WebHeaderCollection.IsRestricted (new string ((char) i, 1));
444 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
445 } catch (ArgumentException) {
448 for (int i = 127; i <= 255; i++) {
450 WebHeaderCollection.IsRestricted (new string ((char) i, 1));
451 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
452 } catch (ArgumentException) {
458 public void IsRestricted_InvalidChars_Request_2 ()
470 int [] singles = new int [] { 34, 44, 47, 123, 125 };
471 foreach (int single in singles) {
473 WebHeaderCollection.IsRestricted (new string ((char) single, 1), false);
474 Assert.Fail (String.Format ("{0}: {1}", single, (char) single));
475 } catch (ArgumentException) {
478 for (int i = 0; i <= 32; i++) {
480 WebHeaderCollection.IsRestricted (new string ((char) i, 1), false);
481 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
482 } catch (ArgumentException) {
485 for (int i = 39; i <= 41; i++) {
487 WebHeaderCollection.IsRestricted (new string ((char) i, 1), false);
488 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
489 } catch (ArgumentException) {
492 for (int i = 91; i <= 93; i++) {
494 WebHeaderCollection.IsRestricted (new string ((char) i, 1), false);
495 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
496 } catch (ArgumentException) {
499 for (int i = 127; i <= 255; i++) {
501 WebHeaderCollection.IsRestricted (new string ((char) i, 1), false);
502 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
503 } catch (ArgumentException) {
509 public void IsRestricted_InvalidChars_Response_2 ()
521 int [] singles = new int [] { 34, 44, 47, 123, 125 };
522 foreach (int single in singles) {
524 WebHeaderCollection.IsRestricted (new string ((char) single, 1), true);
525 Assert.Fail (String.Format ("{0}: {1}", single, (char) single));
526 } catch (ArgumentException) {
529 for (int i = 0; i <= 32; i++) {
531 WebHeaderCollection.IsRestricted (new string ((char) i, 1), true);
532 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
533 } catch (ArgumentException) {
536 for (int i = 39; i <= 41; i++) {
538 WebHeaderCollection.IsRestricted (new string ((char) i, 1), true);
539 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
540 } catch (ArgumentException) {
543 for (int i = 91; i <= 93; i++) {
545 WebHeaderCollection.IsRestricted (new string ((char) i, 1), true);
546 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
547 } catch (ArgumentException) {
550 for (int i = 127; i <= 255; i++) {
552 WebHeaderCollection.IsRestricted (new string ((char) i, 1), true);
553 Assert.Fail (String.Format ("{0}: {1}", i, (char) i));
554 } catch (ArgumentException) {
559 static string [] request_headers = new string [] {
560 "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", "Accept-Ranges", "Authorization",
561 "Cache-Control", "Connection", "Cookie", "Content-Length", "Content-Type", "Date",
562 "Expect", "From", "Host", "If-Match", "If-Modified-Since", "If-None-Match",
563 "If-Range", "If-Unmodified-Since", "Max-Forwards", "Pragma", "Proxy-Authorization", "Proxy-Connection",
564 "Range", "Referer", "TE", "Transfer-Encoding", "Upgrade", "User-Agent", "Via", "Warn" };
566 static string [] response_headers = new string [] {
567 "Accept-Ranges", "Age", "Allow", "Cache-Control", "Content-Encoding", "Content-Language",
568 "Content-Length", "Content-Location", "Content-Disposition", "Content-MD5", "Content-Range",
569 "Content-Type", "Date", "ETag", "Expires", "Keep-Alive", "Last-Modified", "Location", "Pragma",
570 "Proxy-Authenticate", "Retry-After", "Server", "Set-Cookie", "Trailer",
571 "Transfer-Encoding", "Vary", "Via", "Warn", "WWW-Authenticate" };
573 static string [] restricted_request_request = new string [] {
574 "Accept", "Connection", "Content-Length", "Content-Type", "Date",
575 "Expect", "Host", "If-Modified-Since", "Proxy-Connection", "Range", "Referer",
576 "Transfer-Encoding", "User-Agent" };
577 static string [] restricted_response_request = new string [] {
578 "Content-Length", "Content-Type", "Date", "Transfer-Encoding" };
580 static string [] restricted_request_response = new string [] {
581 "Content-Length", "Transfer-Encoding" };
582 static string [] restricted_response_response = new string [] {
583 "Content-Length", "Keep-Alive", "Transfer-Encoding", "WWW-Authenticate" };
586 public void IsRestricted_2_0_RequestRequest ()
589 foreach (string str in request_headers) {
590 if (WebHeaderCollection.IsRestricted (str, false)) {
591 Assert.IsTrue (Array.IndexOf (restricted_request_request, str) != -1, "restricted " + str);
594 Assert.IsTrue (Array.IndexOf (restricted_request_request, str) == -1, str);
597 Assert.IsTrue (count == restricted_request_request.Length, "req-req length");
601 public void IsRestricted_2_0_ResponseRequest ()
604 foreach (string str in response_headers) {
605 if (WebHeaderCollection.IsRestricted (str, false)) {
606 Assert.IsTrue (Array.IndexOf (restricted_response_request, str) != -1, "restricted " + str);
609 Assert.IsTrue (Array.IndexOf (restricted_response_request, str) == -1, str);
612 Assert.IsTrue (count == restricted_response_request.Length, "length");
616 public void IsRestricted_2_0_RequestResponse ()
619 foreach (string str in request_headers) {
620 if (WebHeaderCollection.IsRestricted (str, true)) {
621 Assert.IsTrue (Array.IndexOf (restricted_request_response, str) != -1, "restricted " + str);
624 Assert.IsTrue (Array.IndexOf (restricted_request_response, str) == -1, str);
627 Assert.IsTrue (count == restricted_request_response.Length, "length");
631 public void IsRestricted_2_0_ResponseResponse ()
634 foreach (string str in response_headers) {
635 if (WebHeaderCollection.IsRestricted (str, true)) {
636 Assert.IsTrue (Array.IndexOf (restricted_response_response, str) != -1, "restricted " + str);
639 Assert.IsTrue (Array.IndexOf (restricted_response_response, str) == -1, str);
642 Assert.IsTrue (count == restricted_response_response.Length, "length");
645 static WebHeaderCollection CreateRestrictedHeaders ()
647 var factory = Activator.CreateInstance (typeof (IWebRequestCreate).Assembly.GetType ("System.Net.HttpRequestCreator"), true) as IWebRequestCreate;
648 return factory.Create (new Uri ("http://localhost")).Headers;