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