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