2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / System.Web / Test / System.Web / HttpResponseTest.cs
1 //
2 // System.Web.HttpResponseTest.cs - Unit tests for System.Web.HttpResponse
3 //
4 // Author:
5 //      Miguel de Icaza  <miguel@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.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.Specialized;
32 using System.IO;
33 using System.Text;
34 using System.Web;
35
36 using NUnit.Framework;
37
38 namespace MonoTests.System.Web {
39
40         public class FakeHttpWorkerRequest2 : HttpWorkerRequest {
41                 public Hashtable KnownResponseHeaders;
42                 public Hashtable UnknownResponseHeaders;
43                 public int return_kind;
44                 
45                 public FakeHttpWorkerRequest2 (int re)
46                 {
47                         KnownResponseHeaders = CollectionsUtil.CreateCaseInsensitiveHashtable();
48                         UnknownResponseHeaders = CollectionsUtil.CreateCaseInsensitiveHashtable();
49                         return_kind = re;
50                 }
51                 
52                 public override string GetUriPath()
53                 {
54                         return "/fake";
55                 }
56                 
57                 public override string GetQueryString()
58                 {
59                         return "GetQueryString";
60                 }
61                 
62                 public override string GetRawUrl()
63                 {
64                         return "GetRawUrl";
65                 }
66                 
67                 public override string GetHttpVerbName()
68                 {
69                         return "GET";
70                 }
71                 
72                 public override string GetHttpVersion()
73                 {
74                         if (return_kind == 1)
75                                 return "HTTP/1.0";
76                         else
77                                 return "HTTP/1.1";
78                 }
79                 
80                 public override string GetRemoteAddress()
81                 {
82                         return "__GetRemoteAddress";
83                         }
84         
85                 public override int GetRemotePort()
86                 {
87                         return 1010;
88                 }
89                 
90                 public override string GetLocalAddress()
91                 {
92                         return "GetLocalAddress";
93                 }
94                 
95                 public override string GetAppPath ()
96                 {
97                         return "AppPath";
98                 }
99                 
100                 public override int GetLocalPort()
101                 {
102                         return 2020;
103                 }
104
105                 public bool status_sent;
106                 public int status_code;
107                 public string status_string;
108                 
109                 public override void SendStatus(int s, string x)
110                 {
111                         status_sent = true;
112                         status_code = s;
113                         status_string = x;
114                 }
115
116                 void AddHeader (Hashtable table, string header_name, object header)
117                 {
118                         object o = table [header_name];
119                         if (o == null)
120                                 table.Add (header_name, header);
121                         else {
122                                 ArrayList al = o as ArrayList;
123                                 if (al == null) {
124                                         al = new ArrayList ();
125                                         al.Add (o);
126                                         table [header_name] = al;
127                                 } else
128                                         al = o as ArrayList;
129                                 
130                                 al.Add (header);
131                         }
132                 }
133                 
134                 bool headers_sent;
135                 public override void SendKnownResponseHeader(int x, string j)
136                 {
137                         string header_name = HttpWorkerRequest.GetKnownRequestHeaderName (x);
138                         AddHeader (KnownResponseHeaders, header_name, new KnownResponseHeader (x, j));
139                         headers_sent = true;
140                 }
141                 
142                 public override void SendUnknownResponseHeader(string a, string b)
143                 {
144                         AddHeader (UnknownResponseHeaders, a, new UnknownResponseHeader (a, b));
145                         headers_sent = true;
146                 }
147
148                 bool data_sent;
149                 public byte [] data;
150                 public int data_len;
151                 public int total = 0;
152                 
153                 public override void SendResponseFromMemory(byte[] arr, int x)
154                 {
155                         data_sent = true;
156                         if (data != null) {
157                                 byte [] tmp = new byte [data.Length + x];
158                                 Array.Copy (data, tmp, data.Length);
159                                 Array.Copy (arr, 0, tmp, data.Length, x);
160                                 data = tmp;
161                                 data_len = data.Length;
162                         } else {
163                                 data = new byte [x];
164                                 for (int i = 0; i < x; i++)
165                                         data [i] = arr [i];
166                                 data_len = x;
167                         }
168                         total += x;
169                 }
170                 
171                 public override void SendResponseFromFile(string a, long b , long c)
172                 {
173                         data_sent = true;
174                 }
175                 
176                 public override void SendResponseFromFile (IntPtr a, long b, long c)
177                 {
178                         data_sent = true;
179                 }
180                 
181                 public override void FlushResponse(bool x)
182                 {
183                 }
184                 
185                 public override void EndOfRequest() {
186                 }
187                 
188                 public override string GetKnownRequestHeader (int index)
189                 {
190                         return null;
191                 }
192
193                 public bool OutputProduced {
194                         get {
195                                 return headers_sent || data_sent;
196                         }
197                 }
198         }
199
200         class KnownResponseHeader
201         {
202                 private int index;
203                 private string value;
204
205                 public KnownResponseHeader (int index, string value)
206                 {
207                         this.index = index;
208                         this.value = value;
209                 }
210
211                 public int Index {
212                         get { return index; }
213                 }
214
215                 public string Value {
216                         get { return value; }
217                 }
218         }
219
220         class UnknownResponseHeader
221         {
222                 private string name;
223                 private string value;
224
225                 public UnknownResponseHeader (string name, string value)
226                 {
227                         this.name = name;
228                         this.value = value;
229                 }
230
231                 public string Name {
232                         get { return name; }
233                 }
234
235                 public string Value {
236                         get { return value; }
237                 }
238         }
239
240         [TestFixture]
241         public class HttpResponseTest {
242                 HttpContext Cook (int re, out FakeHttpWorkerRequest2 f)
243                 {
244                         f = new FakeHttpWorkerRequest2 (re);
245                         HttpContext c = new HttpContext (f);
246
247                         return c;
248                 }
249
250                 [SetUp]
251                 public void SetUp ()
252                 {
253 #if NET_2_0
254                         AppDomain.CurrentDomain.SetData (".appPath", AppDomain.CurrentDomain.BaseDirectory);
255 #endif
256                 }
257
258                 [Test]
259 #if TARGET_JVM
260                 [Category ("NotWorking")] // char output stream in gh make this test fail
261 #endif
262                 public void Test_Response ()
263                 {
264                         FakeHttpWorkerRequest2 f;
265                         HttpContext c = Cook (1, out f);
266
267                         c.Response.Write ("a");
268                         Assert.AreEqual (false, f.OutputProduced, "T1");
269                         c.Response.Flush ();
270                         Assert.AreEqual (1, f.data_len, "T2");
271                         c.Response.Write ("Hola");
272                         Assert.AreEqual (1, f.data_len, "T3");
273                         c.Response.Flush ();
274                         Assert.AreEqual (5, f.data_len, "T4");
275                         Assert.AreEqual ((byte) 'a', f.data [0], "T5");
276                         Assert.AreEqual ((byte) 'H', f.data [1], "T6");
277                         Assert.AreEqual ((byte) 'o', f.data [2], "T7");
278                         Assert.AreEqual ((byte) 'l', f.data [3], "T8");
279                         Assert.AreEqual ((byte) 'a', f.data [4], "T9");
280                 }
281
282                 [Test]
283 #if TARGET_JVM
284                 [Category ("NotWorking")] // char output stream in gh make this test fail
285 #endif
286                 public void TestResponse_Chunked ()
287                 {
288                         FakeHttpWorkerRequest2 f;
289                         HttpContext c = Cook (2, out f);
290
291                         c.Response.Write ("a");
292                         Assert.AreEqual (false, f.OutputProduced, "CT1");
293                         c.Response.Flush ();
294                         Assert.AreEqual (6, f.total, "CT2");
295                         c.Response.Write ("Hola");
296                         Assert.AreEqual (6, f.total, "CT3");
297                         c.Response.Flush ();
298                         
299                 }
300
301                 [Test]
302                 public void Status1 ()
303                 {
304                         FakeHttpWorkerRequest2 f;
305                         HttpContext c = Cook (2, out f);
306
307                         HttpResponse resp = c.Response;
308                         resp.Status = "200 Lalala";
309                         Assert.AreEqual (200, resp.StatusCode, "ST1");
310                         Assert.AreEqual ("Lalala", resp.StatusDescription, "ST2");
311
312                         resp.Status = "10000 La la la";
313                         Assert.AreEqual (10000, resp.StatusCode, "ST3");
314                         Assert.AreEqual ("La la la", resp.StatusDescription, "ST4");
315
316                         resp.Status = "-1 La la la";
317                         Assert.AreEqual (-1, resp.StatusCode, "ST5");
318                         Assert.AreEqual ("La la la", resp.StatusDescription, "ST6");
319
320                         resp.Status = "-200 La la la";
321                         Assert.AreEqual (-200, resp.StatusCode, "ST7");
322                         Assert.AreEqual ("La la la", resp.StatusDescription, "ST8");
323
324                         resp.Status = "200 ";
325                         Assert.AreEqual (200, resp.StatusCode, "ST7");
326                         Assert.AreEqual ("", resp.StatusDescription, "ST8");
327                 }
328
329                 [Test]
330                 public void Status2 ()
331                 {
332                         FakeHttpWorkerRequest2 f;
333                         HttpContext c = Cook (2, out f);
334
335                         HttpResponse resp = c.Response;
336                         try {
337                                 resp.Status = "200";
338                                 Assert.Fail ("#1");
339                         } catch (HttpException) {
340                         }
341                 }
342
343                 [Test]
344                 public void Status3 ()
345                 {
346                         FakeHttpWorkerRequest2 f;
347                         HttpContext c = Cook (2, out f);
348
349                         HttpResponse resp = c.Response;
350                         try {
351                                 resp.Status = "200\t";
352                                 Assert.Fail ("#1");
353                         } catch (HttpException) {
354                         }
355                 }
356
357                 [Test]
358                 public void Status4 ()
359                 {
360                         FakeHttpWorkerRequest2 f;
361                         HttpContext c = Cook (2, out f);
362
363                         HttpResponse resp = c.Response;
364
365                         Assert.AreEqual (200, resp.StatusCode, "STT1");
366                         Assert.AreEqual (HttpWorkerRequest.GetStatusDescription (200), resp.StatusDescription, "STT2");
367
368                         resp.StatusCode = 400;
369                         Assert.AreEqual (400, resp.StatusCode, "STT3");
370                         Assert.AreEqual (HttpWorkerRequest.GetStatusDescription (400), resp.StatusDescription, "STT4");
371
372                         resp.StatusDescription = "Something else";
373                         Assert.AreEqual (400, resp.StatusCode, "STT5");
374                         Assert.AreEqual ("Something else", resp.StatusDescription, "STT6");
375
376                         resp.StatusDescription = null;
377                         Assert.AreEqual (400, resp.StatusCode, "STT7");
378                         Assert.AreEqual (HttpWorkerRequest.GetStatusDescription (400), resp.StatusDescription, "STT8");
379                 }
380
381                 //
382                 // TODO: Add test for BinaryWrite and the various writes to check for Chunked Mode
383                 //`
384
385                 [Test]
386                 public void SetCacheability ()
387                 {
388                         FakeHttpWorkerRequest2 f;
389                         HttpContext c = Cook (1, out f);
390
391                         //
392                         // Basically the values from CacheControl are useless once Response.Cache is used
393                         //
394                         c.Response.Cache.SetCacheability (HttpCacheability.ServerAndNoCache);
395                         Assert.AreEqual ("private", c.Response.CacheControl, "C1");
396                         
397                         c.Response.Cache.SetCacheability (HttpCacheability.ServerAndPrivate);
398                         Assert.AreEqual ("private", c.Response.CacheControl, "C2");
399                         
400                         c.Response.Cache.SetCacheability (HttpCacheability.NoCache);
401                         Assert.AreEqual ("private", c.Response.CacheControl, "C3");
402                         
403                         c.Response.Cache.SetCacheability (HttpCacheability.Private);
404                         Assert.AreEqual ("private", c.Response.CacheControl, "C4");
405                         
406                         c.Response.Cache.SetCacheability (HttpCacheability.Server);
407                         Assert.AreEqual ("private", c.Response.CacheControl, "C5");
408                         
409                         c.Response.Cache.SetCacheability (HttpCacheability.Public);
410                         Assert.AreEqual ("private", c.Response.CacheControl, "C6");
411                 }
412
413                 //
414                 // Test the values allowed;  .NET only documents private and public, but
415                 // "no-cache" from the spec is also allowed
416                 //
417                 [Test]
418                 public void CacheControl ()
419                 {
420                         FakeHttpWorkerRequest2 f;
421                         HttpContext c = Cook (1, out f);
422
423                         // Default value.
424                         Assert.AreEqual ("private", c.Response.CacheControl, "D1");
425                                          
426                         c.Response.CacheControl = "private";
427                         Assert.AreEqual ("private", c.Response.CacheControl, "D2");
428
429                         c.Response.CacheControl = "public";
430                         Assert.AreEqual ("public", c.Response.CacheControl, "D3");
431                         
432                         c.Response.CacheControl = "no-cache";
433                         Assert.AreEqual ("no-cache", c.Response.CacheControl, "D4");
434
435                         c.Response.CacheControl = null;
436                         Assert.AreEqual ("private", c.Response.CacheControl, "D5");
437
438                         c.Response.CacheControl = "";
439                         Assert.AreEqual ("private", c.Response.CacheControl, "D6");
440                 }
441
442                 //
443                 // Just checks if the AddFileDepend* methods accept values, added after bug #342511
444                 [Test]
445                 public void AddFileDependencies ()
446                 {
447                         FakeHttpWorkerRequest2 f;
448                         HttpContext c = Cook (1, out f);
449
450                         ArrayList a = new ArrayList (1);
451                         a.Add ("somefile.txt");
452                         c.Response.AddFileDependencies (a);
453
454 #if NET_2_0
455                         string[] sa = new string [1] {"somefile.txt"};
456                         c = Cook (1, out f);
457                         c.Response.AddFileDependencies (sa);
458 #endif
459
460                         c = Cook (1, out f);
461                         c.Response.AddFileDependency ("somefile.txt");
462                 }
463
464                 [Test] // bug #488702
465                 public void WriteHeaders ()
466                 {
467                         FakeHttpWorkerRequest2 f;
468                         HttpContext c = Cook (2, out f);
469
470                         HttpResponse resp = c.Response;
471                         resp.CacheControl = "public";
472                         resp.Cache.SetCacheability (HttpCacheability.NoCache);
473                         resp.ContentType = "text/xml";
474                         resp.AppendHeader ("Content-Disposition", "inline");
475                         resp.AppendHeader ("Content-Type", "application/ms-word");
476                         resp.AppendHeader ("Content-Length", "40");
477                         resp.AppendHeader ("Transfer-Encoding", "compress");
478                         resp.AppendHeader ("My-Custom-Header", "never");
479                         resp.AppendHeader ("My-Custom-Header", "always");
480
481                         Assert.AreEqual ("public", resp.CacheControl, "#A1");
482                         Assert.AreEqual ("application/ms-word", resp.ContentType, "#A2");
483                         Assert.AreEqual (0, f.KnownResponseHeaders.Count, "#A3");
484                         Assert.AreEqual (0, f.UnknownResponseHeaders.Count, "#A4");
485
486                         resp.Flush ();
487
488                         KnownResponseHeader known;
489
490                         Assert.AreEqual (6, f.KnownResponseHeaders.Count, "#B1");
491                         
492                         known = (KnownResponseHeader)f.KnownResponseHeaders ["Content-Length"];
493                         Assert.AreEqual (HttpWorkerRequest.HeaderContentLength, known.Index, "#B2");
494                         Assert.AreEqual ("40", known.Value, "#B3");
495                         
496                         known = (KnownResponseHeader)f.KnownResponseHeaders["Transfer-Encoding"];
497                         Assert.AreEqual (HttpWorkerRequest.HeaderTransferEncoding, known.Index, "#B4");
498                         Assert.AreEqual ("compress", known.Value, "#B5");
499                         
500                         known = (KnownResponseHeader)f.KnownResponseHeaders["Cache-Control"];
501                         Assert.AreEqual (HttpWorkerRequest.HeaderCacheControl, known.Index, "#B6");
502                         Assert.AreEqual ("no-cache", known.Value, "#B7");
503                         
504                         known = (KnownResponseHeader)f.KnownResponseHeaders["Pragma"];
505                         Assert.AreEqual (HttpWorkerRequest.HeaderPragma, known.Index, "#B8");
506                         Assert.AreEqual ("no-cache", known.Value, "#B9");
507                         
508                         known = (KnownResponseHeader)f.KnownResponseHeaders["Expires"];
509                         Assert.AreEqual (HttpWorkerRequest.HeaderExpires, known.Index, "#B10");
510                         Assert.AreEqual ("-1", known.Value, "#B11");
511                         
512                         known = (KnownResponseHeader)f.KnownResponseHeaders["Content-Type"];
513                         Assert.AreEqual (HttpWorkerRequest.HeaderContentType, known.Index, "#B12");
514                         Assert.AreEqual ("application/ms-word", known.Value, "#B13");
515
516                         UnknownResponseHeader unknown;
517
518                         Assert.AreEqual (3, f.UnknownResponseHeaders.Count, "#C1");
519
520                         unknown = (UnknownResponseHeader) f.UnknownResponseHeaders ["X-AspNet-Version"];
521                         Assert.AreEqual ("X-AspNet-Version", unknown.Name, "#C2");
522                         Assert.AreEqual (Environment.Version.ToString (3), unknown.Value, "#C3");
523
524                         unknown = (UnknownResponseHeader) f.UnknownResponseHeaders ["Content-Disposition"];
525                         Assert.AreEqual ("Content-Disposition", unknown.Name, "#C4");
526                         Assert.AreEqual ("inline", unknown.Value, "#C5");
527
528                         ArrayList al = f.UnknownResponseHeaders ["My-Custom-Header"] as ArrayList;
529                         Assert.AreEqual (2, al.Count, "#C6");
530
531                         unknown = (UnknownResponseHeader) al [0];
532                         Assert.AreEqual ("My-Custom-Header", unknown.Name, "#C7");
533                         Assert.AreEqual ("never", unknown.Value, "#C8");
534
535                         unknown = (UnknownResponseHeader) al [1];
536                         Assert.AreEqual ("My-Custom-Header", unknown.Name, "#C9");
537                         Assert.AreEqual ("always", unknown.Value, "#C10");
538                 }
539
540                 [Test] // bug #485557
541                 [Category ("NotWorking")] // bug #488702
542                 public void ClearHeaders ()
543                 {
544                         FakeHttpWorkerRequest2 f;
545                         HttpContext c = Cook (2, out f);
546
547                         HttpResponse resp = c.Response;
548                         resp.CacheControl = "public";
549                         resp.Cache.SetCacheability (HttpCacheability.NoCache);
550                         resp.ContentType = "text/xml";
551                         resp.AppendHeader ("Content-Disposition", "inline");
552                         resp.AppendHeader ("Content-Type", "application/ms-word");
553                         resp.AppendHeader ("Content-Length", "40");
554                         resp.AppendHeader ("Transfer-Encoding", "compress");
555                         resp.AppendHeader ("My-Custom-Header", "never");
556                         resp.AppendHeader ("My-Custom-Header", "always");
557                         resp.ClearHeaders ();
558
559                         Assert.AreEqual ("private", resp.CacheControl, "#A1");
560                         Assert.AreEqual ("text/html", resp.ContentType, "#A2");
561                         Assert.AreEqual (0, f.KnownResponseHeaders.Count, "#A3");
562                         Assert.AreEqual (0, f.UnknownResponseHeaders.Count, "#A4");
563
564                         resp.Flush ();
565
566                         KnownResponseHeader known;
567
568                         Assert.AreEqual (3, f.KnownResponseHeaders.Count, "#B1");
569                         
570                         known = (KnownResponseHeader) f.KnownResponseHeaders ["Transfer-Encoding"];
571                         Assert.AreEqual (HttpWorkerRequest.HeaderTransferEncoding, known.Index, "#B2");
572                         Assert.AreEqual ("chunked", known.Value, "#B3");
573                         
574                         known = (KnownResponseHeader) f.KnownResponseHeaders ["Cache-Control"];
575                         Assert.AreEqual (HttpWorkerRequest.HeaderCacheControl, known.Index, "#B4");
576                         Assert.AreEqual ("private", known.Value, "#B5");
577                         
578                         known = (KnownResponseHeader) f.KnownResponseHeaders ["Content-Type"];
579                         Assert.AreEqual (HttpWorkerRequest.HeaderContentType, known.Index, "#B6");
580                         Assert.AreEqual ("text/html", known.Value, "#B7");
581
582 #if NET_2_0
583                         Assert.AreEqual (1, f.UnknownResponseHeaders.Count, "#C1");
584                         UnknownResponseHeader unknown = (UnknownResponseHeader) f.UnknownResponseHeaders ["X-AspNet-Version"];
585                         Assert.AreEqual ("X-AspNet-Version", unknown.Name, "#C2");
586                         Assert.AreEqual (Environment.Version.ToString (3), unknown.Value, "#C3");
587 #else
588                         Assert.AreEqual (0, f.UnknownResponseHeaders.Count, "#C1");
589 #endif
590                 }
591         }
592
593         [TestFixture]
594         public class HttpResponseOutputStreamTest
595         {
596                 FakeHttpWorkerRequest2 worker;
597                 HttpContext context;
598                 HttpResponse response;
599                 Stream out_stream;
600
601                 [SetUp]
602                 public void Setup ()
603                 {
604                         context = Cook (2, out worker);
605                         response = context.Response;
606                         out_stream = response.OutputStream;
607                 }
608
609                 [TearDown]
610                 public void TearDown ()
611                 {
612                         if (response != null)
613                                 response.Close ();
614                 }
615
616                 [Test]
617                 public void CanRead ()
618                 {
619                         Assert.IsFalse (out_stream.CanRead, "#1");
620                         out_stream.Close ();
621                         Assert.IsFalse (out_stream.CanRead, "#2");
622                 }
623
624                 [Test]
625                 public void CanSeek ()
626                 {
627                         Assert.IsFalse (out_stream.CanSeek, "#1");
628                         out_stream.Close ();
629                         Assert.IsFalse (out_stream.CanSeek, "#2");
630                 }
631
632                 [Test]
633                 public void CanWrite ()
634                 {
635                         Assert.IsTrue (out_stream.CanWrite, "#1");
636                         out_stream.Close ();
637                         Assert.IsTrue (out_stream.CanWrite, "#2");
638                 }
639
640                 [Test]
641                 public void Flush ()
642                 {
643                         byte [] buffer = Encoding.UTF8.GetBytes ("mono");
644                         out_stream.Write (buffer, 0, buffer.Length);
645                         out_stream.Flush ();
646                         Assert.AreEqual (0, worker.data_len);
647                 }
648
649                 [Test]
650                 public void Length ()
651                 {
652                         try {
653                                 long len = out_stream.Length;
654                                 Assert.Fail ("#1:" + len);
655                         } catch (NotSupportedException ex) {
656                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
657                                 Assert.IsNull (ex.InnerException, "#3");
658                                 Assert.IsNotNull (ex.Message, "#4");
659                         }
660                 }
661
662                 [Test]
663                 public void Position ()
664                 {
665                         try {
666                                 long pos = out_stream.Position;
667                                 Assert.Fail ("#A1:" + pos);
668                         } catch (NotSupportedException ex) {
669                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#A2");
670                                 Assert.IsNull (ex.InnerException, "#A3");
671                                 Assert.IsNotNull (ex.Message, "#A4");
672                         }
673
674                         try {
675                                 out_stream.Position = 0;
676                                 Assert.Fail ("#B1");
677                         } catch (NotSupportedException ex) {
678                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#B2");
679                                 Assert.IsNull (ex.InnerException, "#B3");
680                                 Assert.IsNotNull (ex.Message, "#B4");
681                         }
682                 }
683
684                 [Test]
685                 public void Read ()
686                 {
687                         byte [] buffer = new byte [5];
688
689                         try {
690                                 out_stream.Read (buffer, 0, buffer.Length);
691                                 Assert.Fail ("#1");
692                         } catch (NotSupportedException ex) {
693                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
694                                 Assert.IsNull (ex.InnerException, "#3");
695                                 Assert.IsNotNull (ex.Message, "#4");
696                         }
697                 }
698
699                 [Test]
700                 public void Seek ()
701                 {
702                         try {
703                                 out_stream.Seek (5, SeekOrigin.Begin);
704                                 Assert.Fail ("#1");
705                         } catch (NotSupportedException ex) {
706                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
707                                 Assert.IsNull (ex.InnerException, "#3");
708                                 Assert.IsNotNull (ex.Message, "#4");
709                         }
710                 }
711
712                 [Test]
713                 public void SetLength ()
714                 {
715                         try {
716                                 out_stream.SetLength (5L);
717                                 Assert.Fail ("#1");
718                         } catch (NotSupportedException ex) {
719                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
720                                 Assert.IsNull (ex.InnerException, "#3");
721                                 Assert.IsNotNull (ex.Message, "#4");
722                         }
723                 }
724
725                 [Test]
726                 public void Write ()
727                 {
728                         byte [] buffer;
729
730                         buffer = Encoding.UTF8.GetBytes ("mono");
731                         out_stream.Write (buffer, 0, buffer.Length);
732                         buffer = Encoding.UTF8.GetBytes ("just rocks!!");
733                         out_stream.Write (buffer, 5, 6);
734                         out_stream.Write (buffer, 0, 4);
735                         Assert.IsFalse (worker.OutputProduced, "#1");
736                         response.Flush ();
737                         Assert.IsTrue (worker.OutputProduced, "#2");
738
739                         string output = Encoding.UTF8.GetString (worker.data);
740                         Assert.AreEqual ("e\r\nmonorocks!just\r\n", output);
741                 }
742
743                 [Test]
744                 public void Write_Buffer_Null ()
745                 {
746                         try {
747                                 out_stream.Write ((byte []) null, 0, 0);
748                                 Assert.Fail ("#1");
749 #if NET_2_0
750                         } catch (ArgumentNullException ex) {
751                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
752                                 Assert.IsNull (ex.InnerException, "#3");
753                                 Assert.IsNotNull (ex.Message, "#4");
754                                 Assert.AreEqual ("buffer", ex.ParamName, "#5");
755                         }
756 #else
757                         } catch (NullReferenceException) {
758                         }
759 #endif
760                 }
761
762                 [Test]
763                 public void Write_Count_Negative ()
764                 {
765                         byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
766
767                         // offset < 0
768                         try {
769                                 out_stream.Write (buffer, 1, -1);
770                                 Assert.Fail ("#1");
771                         } catch (ArgumentOutOfRangeException ex) {
772                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
773                                 Assert.IsNull (ex.InnerException, "#3");
774                                 Assert.IsNotNull (ex.Message, "#4");
775                                 Assert.AreEqual ("count", ex.ParamName, "#5");
776                         }
777                 }
778
779                 [Test]
780                 public void Write_Count_Overflow ()
781                 {
782                         byte [] buffer;
783
784                         buffer = Encoding.UTF8.GetBytes ("Mono");
785                         out_stream.Write (buffer, 0, buffer.Length + 5);
786                         buffer = Encoding.UTF8.GetBytes ("Just Rocks!!");
787                         out_stream.Write (buffer, 5, buffer.Length - 2);
788                         response.Flush ();
789
790                         string output = Encoding.UTF8.GetString (worker.data);
791                         Assert.AreEqual ("b\r\nMonoRocks!!\r\n", output);
792                 }
793
794                 [Test]
795                 public void Write_Offset_Negative ()
796                 {
797                         byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
798
799                         // offset < 0
800                         try {
801                                 out_stream.Write (buffer, -1, 0);
802                                 Assert.Fail ("#1");
803                         } catch (ArgumentOutOfRangeException ex) {
804                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
805                                 Assert.IsNull (ex.InnerException, "#3");
806                                 Assert.IsNotNull (ex.Message, "#4");
807                                 Assert.AreEqual ("offset", ex.ParamName, "#5");
808                         }
809                 }
810
811                 [Test]
812                 public void Write_Offset_Overflow ()
813                 {
814                         byte [] buffer = new byte [] { 0x0a, 0x1f, 0x2d };
815
816                         // offset == buffer length
817 #if NET_2_0
818                         try {
819                                 out_stream.Write (buffer, buffer.Length, 0);
820                                 Assert.Fail ("#A1");
821                         } catch (ArgumentOutOfRangeException ex) {
822                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#A2");
823                                 Assert.IsNull (ex.InnerException, "#A3");
824                                 Assert.IsNotNull (ex.Message, "#A4");
825                                 Assert.AreEqual ("offset", ex.ParamName, "#A5");
826                         }
827 #else
828                         out_stream.Write (buffer, buffer.Length, 0);
829 #endif
830
831                         // offset > buffer length
832 #if NET_2_0
833                         try {
834                                 out_stream.Write (buffer, buffer.Length + 1, 0);
835                                 Assert.Fail ("#B1");
836                         } catch (ArgumentOutOfRangeException ex) {
837                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#B2");
838                                 Assert.IsNull (ex.InnerException, "#B3");
839                                 Assert.IsNotNull (ex.Message, "#B4");
840                                 Assert.AreEqual ("offset", ex.ParamName, "#B5");
841                         }
842 #else
843                         out_stream.Write (buffer, buffer.Length + 1, 0);
844 #endif
845
846                         response.Flush ();
847                         Assert.AreEqual (0, worker.data_len);
848                 }
849
850                 [Test]
851                 public void Write_Stream_Closed ()
852                 {
853                         byte [] buffer = Encoding.UTF8.GetBytes ("mono");
854                         out_stream.Close ();
855                         out_stream.Write (buffer, 0, buffer.Length);
856                         response.Flush ();
857
858                         string output = Encoding.UTF8.GetString (worker.data);
859                         Assert.AreEqual ("4\r\nmono\r\n", output);
860                 }
861
862                 HttpContext Cook (int re, out FakeHttpWorkerRequest2 f)
863                 {
864                         f = new FakeHttpWorkerRequest2 (re);
865                         return new HttpContext (f);
866                 }
867         }
868 }