2 // System.Web.HttpRequestTest.cs - Unit tests for System.Web.HttpRequest
5 // Sebastien Pouliot <sebastien@ximian.com>
6 // Miguel de Icaza <miguel@novell.com>
7 // Gonzalo Paniagua Javier <gonzalo@novell.com>
9 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections.Specialized;
34 using NUnit.Framework;
35 using System.Diagnostics;
36 using MonoTests.SystemWeb.Framework;
38 using System.Threading;
39 using System.Globalization;
41 using MonoTests.Common;
43 namespace MonoTests.System.Web {
46 public class HttpRequestTest {
49 [ExpectedException (typeof (HttpRequestValidationException))]
50 public void ValidateInput_XSS ()
52 string problem = "http://server.com/attack2.aspx?test=<script>alert('vulnerability')</script>";
53 string decoded = HttpUtility.UrlDecode (problem);
54 int n = decoded.IndexOf ('?');
55 HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
56 request.ValidateInput ();
57 // the next statement throws
58 Assert.AreEqual ("<script>alert('vulnerability')</script>", request.QueryString ["test"], "QueryString");
62 // * this is to avoid a regression that would cause Mono to
63 // fail again on item #2 of the XSS vulnerabilities listed at:
64 // http://it-project.ru/andir/docs/aspxvuln/aspxvuln.en.xml
65 // * The author notes that Microsoft has decided not to fix
66 // this issue (hence the NotDotNet category).
69 [Category ("NotDotNet")]
70 [ExpectedException (typeof (HttpRequestValidationException))]
71 public void ValidateInput_XSS_Unicode ()
73 string problem = "http://server.com/attack2.aspx?test=%uff1cscript%uff1ealert('vulnerability')%uff1c/script%uff1e";
74 string decoded = HttpUtility.UrlDecode (problem);
75 int n = decoded.IndexOf ('?');
76 HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
77 request.ValidateInput ();
78 // the next statement throws
79 Assert.AreEqual ("\xff1cscript\xff1ealert('vulnerability')\xff1c/script\xff1e", request.QueryString ["test"], "QueryString");
82 // This has affected ASP.NET 1.1 but it seems fixed now
83 // http://secunia.com/advisories/9716/
84 // http://weblogs.asp.net/kaevans/archive/2003/11/12/37169.aspx
86 [ExpectedException (typeof (HttpRequestValidationException))]
87 public void ValidateInput_XSS_Null ()
89 string problem = "http://secunia.com/?test=<%00SCRIPT>alert(document.cookie)</SCRIPT>";
90 string decoded = HttpUtility.UrlDecode (problem);
91 int n = decoded.IndexOf ('?');
92 HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
93 request.ValidateInput ();
94 // the next statement throws
95 Assert.AreEqual ("<SCRIPT>alert(document.cookie)</SCRIPT>", request.QueryString ["test"], "QueryString");
98 // Tests the properties from the simple constructor.
100 public void Test_PropertiesSimpleConstructor ()
102 string url = "http://www.gnome.org/";
103 string qs = "key=value&key2=value%32second";
105 HttpRequest r = new HttpRequest ("file", url, qs);
107 Assert.AreEqual ("/?" + qs, r.RawUrl, "U1");
108 Assert.AreEqual (url, r.Url.ToString (), "U2");
110 r = new HttpRequest ("file", "http://www.gnome.org", qs);
111 Assert.AreEqual (url, r.Url.ToString (), "U3");
113 qs = "a&b=1&c=d&e&b=2&d=";
114 r = new HttpRequest ("file", url, qs);
115 NameValueCollection nvc = r.QueryString;
117 Assert.AreEqual ("a,e", nvc [null], "U4");
118 Assert.AreEqual ("1,2", nvc ["b"], "U5");
119 Assert.AreEqual ("d", nvc ["c"], "U5");
120 Assert.AreEqual ("", nvc ["d"], "U6");
121 Assert.AreEqual (4, nvc.Count, "U6");
123 Assert.AreEqual (null, r.ApplicationPath, "U7");
127 [ExpectedException(typeof(ArgumentNullException))]
128 public void Test_AccessToVars ()
130 string url = "http://www.gnome.org/";
131 string qs = "key=value&key2=value%32second";
133 HttpRequest r = new HttpRequest ("file", url, qs);
134 string s = r.PhysicalApplicationPath;
138 public void Test_QueryStringDecoding()
140 // Note: The string to encode must exist in default encoding language
141 // \r - will exist in all encodings
142 string url = "http://www.gnome.org/";
143 string qs = "umlaut=" + HttpUtility.UrlEncode("\r", Encoding.Default);
145 HttpRequest r = new HttpRequest ("file", url, qs);
146 Assert.AreEqual ("\r", r.QueryString["umlaut"]);
150 [Category ("NunitWeb")]
151 public void Test_PhysicalApplicationPath ()
153 WebTest t = new WebTest (new HandlerInvoker (new HandlerDelegate (
154 PhysicalApplicationPathDelegate)));
158 static public void PhysicalApplicationPathDelegate ()
160 HttpRequest r = HttpContext.Current.Request;
161 string pap = r.PhysicalApplicationPath;
162 Assert.IsTrue (pap.EndsWith (Path.DirectorySeparatorChar.ToString()), "#1");
163 Assert.AreEqual (Path.GetFullPath (pap), pap, "#2");
167 [Category ("NunitWeb")]
168 public void Test_MapPath ()
170 WebTest t = new WebTest (new HandlerInvoker (new HandlerDelegate (
175 static public void MapPathDelegate ()
177 HttpRequest r = HttpContext.Current.Request;
178 string appBase = r.PhysicalApplicationPath.TrimEnd (Path.DirectorySeparatorChar);
179 Assert.AreEqual (appBase, r.MapPath ("~"), "test1");
180 Assert.AreEqual (appBase, r.MapPath (null), "test1a");
181 Assert.AreEqual (appBase, r.MapPath (""), "test1b");
182 Assert.AreEqual (appBase, r.MapPath (" "), "test1c");
183 Assert.AreEqual (appBase + Path.DirectorySeparatorChar, r.MapPath ("~/"), "test1");
184 Assert.AreEqual (appBase, r.MapPath ("/NunitWeb"), "test1.1");
185 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
186 r.MapPath ("Web.config"), "test2");
187 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
188 r.MapPath ("~/Web.config"), "test3");
189 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
190 r.MapPath ("/NunitWeb/Web.config"), "test4");
191 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
192 r.MapPath ("Web.config", null, false), "test5");
193 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
194 r.MapPath ("Web.config", "", false), "test6");
195 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
196 r.MapPath ("Web.config", "/NunitWeb", false), "test7");
197 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
198 r.MapPath ("/NunitWeb/Web.config", "/NunitWeb", false), "test8");
200 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
201 r.MapPath ("Web.config", "/NunitWeb/", false), "test8");
202 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
203 r.MapPath ("Web.config", "~", false), "test10");
204 Assert.AreEqual (Path.Combine (appBase, "DIR" + Path.DirectorySeparatorChar + "Web.config"),
205 r.MapPath ("Web.config", "~/DIR", false), "test11");
207 AssertExtensions.Throws<InvalidOperationException> (() => {
208 // Throws because the test's virtual dir is /NunitWeb and / is above it
209 r.MapPath ("/test.txt");
212 AssertExtensions.Throws<InvalidOperationException> (() => {
213 // Throws because the test's virtual dir is /NunitWeb and /NunitWeb1 does not match it
214 r.MapPath ("/NunitWeb1/test.txt");
217 AssertExtensions.Throws<ArgumentException> (() => {
218 r.MapPath ("/test.txt", "/", false);
221 AssertExtensions.Throws<ArgumentException> (() => {
222 r.MapPath ("/test.txt", "/NunitWeb", false);
225 Assert.AreEqual (Path.Combine (appBase, "test.txt"), r.MapPath ("/NunitWeb/test.txt", "/NunitWeb", true), "test16");
229 [Category ("NunitWeb")]
230 [ExpectedException (typeof (ArgumentException))]
231 public void Test_MapPath_InvalidBase_1 ()
233 WebTest t = new WebTest (new HandlerInvoker (new HandlerDelegate (
234 MapPathDelegate_InvalidBase_1)));
238 static public void MapPathDelegate_InvalidBase_1 ()
240 HttpContext.Current.Request.MapPath ("Web.config", "something", true);
244 [Category ("NunitWeb")]
245 [ExpectedException (typeof (ArgumentException))]
246 public void Test_MapPath_InvalidBase_2 ()
248 WebTest t = new WebTest (new HandlerInvoker (new HandlerDelegate (
249 MapPathDelegate_InvalidBase_2)));
253 static public void MapPathDelegate_InvalidBase_2 ()
255 HttpContext.Current.Request.MapPath ("Web.config", "something", false);
260 public class Test_HttpFakeRequest {
261 class FakeHttpWorkerRequest : HttpWorkerRequest {
262 public int return_kind;
264 [Conditional ("REQUEST_TEST_VERY_VERBOSE")]
267 Console.WriteLine (Environment.StackTrace);
271 public FakeHttpWorkerRequest (int re)
276 public override string GetFilePath()
279 return "/tmp/uri.aspx";
282 public override string GetUriPath()
288 public override string GetQueryString()
292 switch (return_kind) {
296 return "key1=value1&key2=value2";
299 return "mapa.x=10&mapa.y=20";
302 return "mapa.x=10&mapa=20";
304 return "mapa.x=10&mapa.y=20";
310 return "mapa.x=pi&mapa.y=20";
312 return "PlainString";
314 return "Plain&Arg=1";
318 return "GetQueryString";
322 public override string GetRawUrl()
328 public override string GetHttpVerbName()
331 if (return_kind == 25 || return_kind == 26)
333 if (return_kind == 30 || return_kind == 31)
338 public override string GetHttpVersion()
344 public override byte [] GetPreloadedEntityBody ()
346 if (return_kind != 30 && return_kind != 31)
347 return base.GetPreloadedEntityBody ();
349 return Encoding.UTF8.GetBytes (GetQueryString ());
352 public override bool IsEntireEntityBodyIsPreloaded ()
354 if (return_kind != 30 && return_kind != 31)
355 return base.IsEntireEntityBodyIsPreloaded ();
360 public override int GetRemotePort()
365 public override string GetLocalAddress()
370 public override string GetAppPath ()
375 public override string GetRemoteName ()
380 public override string GetRemoteAddress ()
382 return "RemoteAddress";
385 public override string GetServerName ()
390 public override int GetLocalPort()
395 public override void SendStatus(int s, string x)
399 public override void SendKnownResponseHeader(int x, string j)
403 public override void SendUnknownResponseHeader(string a, string b)
407 public override void SendResponseFromMemory(byte[] arr, int x)
411 public override void SendResponseFromFile(string a, long b , long c)
416 public override void SendResponseFromFile (IntPtr a, long b, long c)
420 public override void FlushResponse(bool x)
424 public override void EndOfRequest() {
427 public override string GetKnownRequestHeader (int index)
430 case HttpWorkerRequest.HeaderContentType:
431 switch (return_kind){
432 case 1: return "text/plain";
433 case 2: return "text/plain; charset=latin1";
434 case 3: return "text/plain; charset=iso-8859-1";
435 case 4: return "text/plain; charset=\"iso-8859-1\"";
436 case 5: return "text/plain; charset=\"iso-8859-1\" ; other";
439 return "application/x-www-form-urlencoded";
443 case HttpWorkerRequest.HeaderContentLength:
444 switch (return_kind){
445 case 0: return "1024";
446 case 1: return "-1024";
449 return GetQueryString ().Length.ToString ();
450 case -1: return "Blah";
455 case HttpWorkerRequest.HeaderCookie:
456 switch (return_kind){
457 case 10: return "Key=Value";
458 case 11: return "Key=<value>";
459 case 12: return "Key=>";
460 case 13: return "Key=\xff1c";
461 case 14: return "Key=\xff1e";
464 case HttpWorkerRequest.HeaderReferer:
465 switch (return_kind){
467 case 2: return "http://www.mono-project.com/test.aspx";
468 case 15: return "http://www.mono-project.com";
472 case HttpWorkerRequest.HeaderUserAgent:
473 switch (return_kind){
474 case 15: return "Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040913 Firefox/0.10";
477 case HttpWorkerRequest.HeaderAccept:
478 switch (return_kind){
479 case 21: return "text/xml,application/xml, application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
482 case HttpWorkerRequest.HeaderAcceptLanguage:
483 switch (return_kind){
484 case 21: return "en-us, en;q=0.5";
491 public override string [][] GetUnknownRequestHeaders ()
493 if (return_kind == 0)
494 return new string [0][];
496 if (return_kind == 3){
497 string [][] x = new string [4][];
498 x [0] = new string [] { "k1", "v1" };
499 x [1] = new string [] { "k2", "v2" };
500 x [2] = new string [] { "k3", "v3" };
501 x [3] = new string [] { "k4", "v4" };
506 if (return_kind == 4){
508 // This tests the bad values and the extra row with an error
510 string [][] x = new string [3][];
511 x [0] = new string [] { "k1", "" };
512 x [1] = new string [] { "k2", null };
513 x [2] = new string [] { "k3", " " };
518 if (return_kind == 2){
519 string [][] x = new string [2][];
520 x [0] = new string [] { "k1", "" };
522 // Returns an empty row.
530 HttpContext Cook (int re)
532 FakeHttpWorkerRequest f = new FakeHttpWorkerRequest (re);
533 HttpContext c = new HttpContext (f);
538 [Test] public void Test_BrokenContentLength ()
540 HttpContext c = Cook (-1);
541 Assert.AreEqual (0, c.Request.ContentLength, "C1");
544 Assert.AreEqual (0, c.Request.ContentLength, "C2");
549 [Ignore ("tests undocumented behavior that depends on implementation")]
550 [ExpectedException(typeof(NullReferenceException))]
551 public void Test_EmptyUnknownRow ()
553 HttpContext c = Cook (2);
554 NameValueCollection x = c.Request.Headers;
558 [Category ("NotWorking")]
559 public void Test_RequestFields ()
561 HttpContext c = Cook (1);
564 Assert.IsNull (c.Request.ApplicationPath, "A1");
566 Assert.AreEqual ("AppPath", c.Request.ApplicationPath, "A1");
568 Assert.AreEqual ("text/plain", c.Request.ContentType, "A2");
571 Assert.AreEqual (1024, c.Request.ContentLength, "A3");
574 Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A4");
575 NameValueCollection x = c.Request.Headers;
577 Assert.AreEqual ("v1", x ["k1"], "K1");
578 Assert.AreEqual ("v2", x ["k2"], "K2");
579 Assert.AreEqual ("v3", x ["k3"], "K3");
580 Assert.AreEqual ("v4", x ["k4"], "K4");
581 Assert.AreEqual ("text/plain; charset=iso-8859-1", x ["Content-Type"], "K4");
582 Assert.AreEqual (5, x.Count, "K5");
585 Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A5");
586 Assert.AreEqual ("text/plain; charset=latin1", c.Request.ContentType, "A5-1");
589 Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A6");
590 x = c.Request.Headers;
591 Assert.AreEqual ("", x ["k1"], "K6");
592 Assert.AreEqual (null, x ["k2"], "K7");
593 Assert.AreEqual (" ", x ["k3"], "K8");
594 Assert.AreEqual (4, x.Count, "K9");
597 Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A7");
599 Assert.AreEqual ("RemoteName", c.Request.UserHostName, "A8");
600 Assert.AreEqual ("RemoteAddress", c.Request.UserHostAddress, "A9");
602 // Difference between Url property and RawUrl one: one is resolved, the other is not
603 Assert.AreEqual ("/bb.aspx", c.Request.RawUrl, "A10");
604 Assert.AreEqual ("http://localhost:2020/uri.aspx?GetQueryString", c.Request.Url.ToString (), "A11");
607 [Test] public void Test_Cookies ()
612 c.Request.ValidateInput ();
613 Assert.AreEqual ("Value", c.Request.Cookies ["Key"].Value, "cookie1");
617 [ExpectedException(typeof (HttpRequestValidationException))]
618 public void Test_DangerousCookie ()
623 c.Request.ValidateInput ();
624 object a = c.Request.Cookies;
628 public void Test_DangerousCookie2 ()
633 c.Request.ValidateInput ();
634 object a = c.Request.Cookies;
638 public void Test_DangerousCookie3 ()
643 c.Request.ValidateInput ();
644 object a = c.Request.Cookies;
648 public void Test_DangerousCookie4 ()
653 c.Request.ValidateInput ();
654 object a = c.Request.Cookies;
658 public void Test_MiscHeaders ()
660 HttpContext c = Cook (15);
662 // The uri ToString contains the trailing slash.
663 Assert.AreEqual ("http://www.mono-project.com/", c.Request.UrlReferrer.ToString (), "ref1");
665 Assert.AreEqual ("Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040913 Firefox/0.10", c.Request.UserAgent, "ref2");
667 // All the AcceptTypes and UserLanguages tests below here pass under MS
669 string [] at = c.Request.AcceptTypes;
670 string [] ul = c.Request.UserLanguages;
671 Assert.IsNull (at, "AT1");
672 Assert.IsNull (ul, "UL1");
674 at = c.Request.AcceptTypes;
675 Assert.IsNotNull (at, "AT2");
676 string [] expected = { "text/xml", "application/xml", "application/xhtml+xml", "text/html;q=0.9",
677 "text/plain;q=0.8", "image/png", "*/*;q=0.5" };
679 Assert.AreEqual (expected.Length, at.Length, "AT3");
680 for (int i = expected.Length - 1; i >= 0; i--)
681 Assert.AreEqual (expected [i], at [i], "AT" + (3 + i));
683 ul = c.Request.UserLanguages;
684 Assert.IsNotNull (ul, "UL2");
685 expected = new string [] { "en-us", "en;q=0.5" };
687 Assert.AreEqual (expected.Length, ul.Length, "UL3");
688 for (int i = expected.Length - 1; i >= 0; i--)
689 Assert.AreEqual (expected [i], ul [i], "UL" + (3 + i));
694 public void Empty_WorkerRequest_QueryString ()
696 HttpContext c = Cook (20);
699 // Checks that the following line does not throw an exception if
700 // the querystring returned by the HttpWorkerRequest is null.
702 NameValueCollection nvc = c.Request.QueryString;
706 public void Test_QueryString_ToString ()
708 HttpContext c = Cook (50);
710 Assert.AreEqual (c.Request.QueryString.ToString (), "PlainString", "QTS#1");
713 Assert.AreEqual (c.Request.QueryString.ToString (), "Plain&Arg=1", "QTS#2");
718 public void QueryString_NullTest ()
720 HttpRequest req = new HttpRequest ("file.aspx", "http://localhost/file.aspx", null);
722 Assert.AreEqual (req.QueryString.ToString (), "", "QSNT#1");
727 public void Leading_qm_in_QueryString ()
729 HttpContext c = Cook (16);
730 NameValueCollection nvc = c.Request.QueryString;
731 foreach (string id in nvc.AllKeys) {
732 if (id.StartsWith ("?"))
738 public void TestPath ()
740 HttpContext c = Cook (16);
742 // This used to crash, ifolder exposed this
743 string x = c.Request.Path;
747 public void MapImageCoordinatesHEAD ()
749 HttpContext c = Cook (25);
750 int [] coords = c.Request.MapImageCoordinates ("mapa");
751 Assert.IsNotNull (coords, "A1");
752 Assert.AreEqual (10, coords [0], "X");
753 Assert.AreEqual (20, coords [1], "Y");
756 coords = c.Request.MapImageCoordinates ("mapa");
757 Assert.AreEqual (null, coords, "coords");
761 public void MapImageCoordinatesGET ()
763 HttpContext c = Cook (27);
764 int [] coords = c.Request.MapImageCoordinates ("mapa");
765 Assert.AreEqual (10, coords [0], "X");
766 Assert.AreEqual (20, coords [1], "Y");
768 coords = c.Request.MapImageCoordinates ("m");
769 Assert.AreEqual (null, coords, "coords1");
772 coords = c.Request.MapImageCoordinates ("mapa");
773 Assert.AreEqual (null, coords, "coords2");
775 coords = c.Request.MapImageCoordinates ("mapa");
776 Assert.AreEqual (null, coords, "coords3");
778 coords = c.Request.MapImageCoordinates ("mapa");
779 Assert.AreEqual (null, coords, "coords4");
783 public void MapImageCoordinatesPOST ()
785 HttpContext c = Cook (30);
786 int [] coords = c.Request.MapImageCoordinates ("mapa");
787 Assert.IsNotNull (coords, "A1");
788 Assert.AreEqual (10, coords [0], "X");
789 Assert.AreEqual (20, coords [1], "Y");
792 coords = c.Request.MapImageCoordinates ("mapa");
793 Assert.AreEqual (null, coords, "coords2");
797 public void TestReferer ()
799 HttpContext c = Cook (1);
801 Assert.AreEqual (null, c.Request.UrlReferrer, "REF1");
804 Assert.AreEqual ("http://www.mono-project.com/test.aspx", c.Request.UrlReferrer.ToString (), "REF1");
807 Assert.AreEqual (null, c.Request.UrlReferrer, "REF1");
812 public void NegativeContentLength ()
814 HttpContext c = Cook (1);
815 HttpRequest req = c.Request;
816 Assert.AreEqual (0, req.ContentLength, "#01");
820 public void EmptyQueryValueParams ()
822 HttpContext c = Cook (52);
823 Assert.AreEqual ("", c.Request.Params["Empty"]);
827 // This class is defined here to make it easy to create fake
828 // HttpWorkerRequest-derived classes by only overriding the methods
829 // necessary for testing.
830 class BaseFakeHttpWorkerRequest : HttpWorkerRequest
832 public override void EndOfRequest()
836 public override void FlushResponse(bool finalFlush)
840 public override string GetHttpVerbName()
845 public override string GetHttpVersion()
850 public override string GetLocalAddress()
855 public override int GetLocalPort()
860 public override string GetQueryString()
865 public override string GetRawUrl()
867 string rawUrl = GetUriPath();
868 string queryString = GetQueryString();
869 if (queryString != null && queryString.Length > 0)
871 rawUrl += "?" + queryString;
876 public override string GetRemoteAddress()
881 public override int GetRemotePort()
886 public override string GetUriPath()
888 return "default.aspx";
891 public override void SendKnownResponseHeader(int index, string value)
895 public override void SendResponseFromFile(IntPtr handle, long offset, long length)
899 public override void SendResponseFromFile(string filename, long offset, long length)
903 public override void SendResponseFromMemory(byte[] data, int length)
907 public override void SendStatus(int statusCode, string statusDescription)
911 public override void SendUnknownResponseHeader(string name, string value)
916 // This test ensures accessing the Form property does not throw an
917 // exception when the length of data in the request exceeds the length
918 // as reported by the Content-Length header. This bug was discovered
919 // with an AJAX application using XMLHttpRequest to POST back to the
920 // server. The Content-Length header was two bytes less than the length
921 // of the buffer returned from GetPreloadedEntityBody. This was causing
922 // an exception to be thrown by Mono because it was trying to allocate
923 // a buffer that was -2 bytes in length.
925 public class Test_UrlEncodedBodyWithExtraCRLF
927 class FakeHttpWorkerRequest : BaseFakeHttpWorkerRequest
929 // This string is 9 bytes in length. That's 2 more than
930 // the Content-Length header says it should be.
931 string data = "foo=bar\r\n";
933 public override string GetKnownRequestHeader(int index)
937 case HttpWorkerRequest.HeaderContentLength:
938 return (data.Length - 2).ToString();
939 case HttpWorkerRequest.HeaderContentType:
940 return "application/x-www-form-urlencoded";
945 public override byte[] GetPreloadedEntityBody()
947 return Encoding.ASCII.GetBytes(data);
951 HttpContext context = null;
954 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
957 HttpWorkerRequest workerRequest = new FakeHttpWorkerRequest();
958 context = new HttpContext(workerRequest);
962 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
963 public void ContentLength()
965 Assert.AreEqual(7, context.Request.ContentLength);
969 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
970 public void Form_Count()
972 Assert.AreEqual(1, context.Request.Form.Count);
976 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
977 public void Form_Item()
979 // I would have expected the extra two characters to be stripped
980 // but Microsoft's CLR keeps them so Mono should, too.
981 //Assert.AreEqual("bar\r\n", context.Request.Form["foo"]);
982 Assert.AreEqual("bar", context.Request.Form["foo"]);
986 // This test ensures the HttpRequet object's Form property gets
987 // properly constructed and populated when the Content-Type header
988 // includes a charset parameter and that the charset parameter is
991 public class Test_UrlEncodedBodyWithUtf8CharsetParameter
993 class FakeHttpWorkerRequest : BaseFakeHttpWorkerRequest
995 // The two funny-looking characters are really a single
996 // accented "a" character encoded in UTF-8.
997 string data = "foo=b%C3%A1r";
999 public override string GetKnownRequestHeader(int index)
1003 case HttpWorkerRequest.HeaderContentLength:
1004 return data.Length.ToString();
1005 case HttpWorkerRequest.HeaderContentType:
1006 return "application/x-www-form-urlencoded; charset=utf-8";
1008 return String.Empty;
1011 public override byte[] GetPreloadedEntityBody()
1013 return Encoding.ASCII.GetBytes(data);
1017 HttpContext context = null;
1020 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
1023 HttpWorkerRequest workerRequest = new FakeHttpWorkerRequest();
1024 context = new HttpContext(workerRequest);
1028 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
1029 public void Form_Count()
1031 Assert.AreEqual(1, context.Request.Form.Count);
1035 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
1036 public void Form_Item()
1038 Assert.AreEqual("b\xE1r", context.Request.Form["foo"]);