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 {
50 [ExpectedException (typeof (HttpRequestValidationException))]
51 public void ValidateInput_XSS ()
53 string problem = "http://server.com/attack2.aspx?test=<script>alert('vulnerability')</script>";
54 string decoded = HttpUtility.UrlDecode (problem);
55 int n = decoded.IndexOf ('?');
56 HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
57 request.ValidateInput ();
58 // the next statement throws
59 Assert.AreEqual ("<script>alert('vulnerability')</script>", request.QueryString ["test"], "QueryString");
63 // * this is to avoid a regression that would cause Mono to
64 // fail again on item #2 of the XSS vulnerabilities listed at:
65 // http://it-project.ru/andir/docs/aspxvuln/aspxvuln.en.xml
66 // * The author notes that Microsoft has decided not to fix
67 // this issue (hence the NotDotNet category).
70 [Category ("NotDotNet")]
71 [ExpectedException (typeof (HttpRequestValidationException))]
72 public void ValidateInput_XSS_Unicode ()
74 string problem = "http://server.com/attack2.aspx?test=%uff1cscript%uff1ealert('vulnerability')%uff1c/script%uff1e";
75 string decoded = HttpUtility.UrlDecode (problem);
76 int n = decoded.IndexOf ('?');
77 HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
78 request.ValidateInput ();
79 // the next statement throws
80 Assert.AreEqual ("\xff1cscript\xff1ealert('vulnerability')\xff1c/script\xff1e", request.QueryString ["test"], "QueryString");
83 // This has affected ASP.NET 1.1 but it seems fixed now
84 // http://secunia.com/advisories/9716/
85 // http://weblogs.asp.net/kaevans/archive/2003/11/12/37169.aspx
87 [ExpectedException (typeof (HttpRequestValidationException))]
88 public void ValidateInput_XSS_Null ()
90 string problem = "http://secunia.com/?test=<%00SCRIPT>alert(document.cookie)</SCRIPT>";
91 string decoded = HttpUtility.UrlDecode (problem);
92 int n = decoded.IndexOf ('?');
93 HttpRequest request = new HttpRequest (null, decoded.Substring (0,n), decoded.Substring (n+1));
94 request.ValidateInput ();
95 // the next statement throws
96 Assert.AreEqual ("<SCRIPT>alert(document.cookie)</SCRIPT>", request.QueryString ["test"], "QueryString");
100 // Tests the properties from the simple constructor.
102 public void Test_PropertiesSimpleConstructor ()
104 string url = "http://www.gnome.org/";
105 string qs = "key=value&key2=value%32second";
107 HttpRequest r = new HttpRequest ("file", url, qs);
109 Assert.AreEqual ("/?" + qs, r.RawUrl, "U1");
110 Assert.AreEqual (url, r.Url.ToString (), "U2");
112 r = new HttpRequest ("file", "http://www.gnome.org", qs);
113 Assert.AreEqual (url, r.Url.ToString (), "U3");
115 qs = "a&b=1&c=d&e&b=2&d=";
116 r = new HttpRequest ("file", url, qs);
117 NameValueCollection nvc = r.QueryString;
119 Assert.AreEqual ("a,e", nvc [null], "U4");
120 Assert.AreEqual ("1,2", nvc ["b"], "U5");
121 Assert.AreEqual ("d", nvc ["c"], "U5");
122 Assert.AreEqual ("", nvc ["d"], "U6");
123 Assert.AreEqual (4, nvc.Count, "U6");
125 Assert.AreEqual (null, r.ApplicationPath, "U7");
129 [ExpectedException(typeof(ArgumentNullException))]
130 public void Test_AccessToVars ()
132 string url = "http://www.gnome.org/";
133 string qs = "key=value&key2=value%32second";
135 HttpRequest r = new HttpRequest ("file", url, qs);
136 string s = r.PhysicalApplicationPath;
140 public void Test_QueryStringDecoding()
142 // Note: The string to encode must exist in default encoding language
143 // \r - will exist in all encodings
144 string url = "http://www.gnome.org/";
145 string qs = "umlaut=" + HttpUtility.UrlEncode("\r", Encoding.Default);
147 HttpRequest r = new HttpRequest ("file", url, qs);
148 Assert.AreEqual ("\r", r.QueryString["umlaut"]);
152 [Category ("NunitWeb")]
153 public void Test_PhysicalApplicationPath ()
155 WebTest t = new WebTest (new HandlerInvoker (new HandlerDelegate (
156 PhysicalApplicationPathDelegate)));
160 static public void PhysicalApplicationPathDelegate ()
162 HttpRequest r = HttpContext.Current.Request;
163 string pap = r.PhysicalApplicationPath;
164 Assert.IsTrue (pap.EndsWith (Path.DirectorySeparatorChar.ToString()), "#1");
165 Assert.AreEqual (Path.GetFullPath (pap), pap, "#2");
169 [Category ("NunitWeb")]
170 public void Test_MapPath ()
172 WebTest t = new WebTest (new HandlerInvoker (new HandlerDelegate (
177 static public void MapPathDelegate ()
179 HttpRequest r = HttpContext.Current.Request;
180 string appBase = r.PhysicalApplicationPath.TrimEnd (Path.DirectorySeparatorChar);
181 Assert.AreEqual (appBase, r.MapPath ("~"), "test1");
182 Assert.AreEqual (appBase, r.MapPath (null), "test1a");
183 Assert.AreEqual (appBase, r.MapPath (""), "test1b");
184 Assert.AreEqual (appBase, r.MapPath (" "), "test1c");
185 Assert.AreEqual (appBase + Path.DirectorySeparatorChar, r.MapPath ("~/"), "test1");
186 Assert.AreEqual (appBase, r.MapPath ("/NunitWeb"), "test1.1");
187 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
188 r.MapPath ("Web.config"), "test2");
189 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
190 r.MapPath ("~/Web.config"), "test3");
191 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
192 r.MapPath ("/NunitWeb/Web.config"), "test4");
193 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
194 r.MapPath ("Web.config", null, false), "test5");
195 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
196 r.MapPath ("Web.config", "", false), "test6");
197 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
198 r.MapPath ("Web.config", "/NunitWeb", false), "test7");
199 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
200 r.MapPath ("/NunitWeb/Web.config", "/NunitWeb", false), "test8");
202 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
203 r.MapPath ("Web.config", "/NunitWeb/", false), "test8");
204 Assert.AreEqual (Path.Combine (appBase, "Web.config"),
205 r.MapPath ("Web.config", "~", false), "test10");
206 Assert.AreEqual (Path.Combine (appBase, "DIR" + Path.DirectorySeparatorChar + "Web.config"),
207 r.MapPath ("Web.config", "~/DIR", false), "test11");
209 AssertExtensions.Throws<InvalidOperationException> (() => {
210 // Throws because the test's virtual dir is /NunitWeb and / is above it
211 r.MapPath ("/test.txt");
214 AssertExtensions.Throws<InvalidOperationException> (() => {
215 // Throws because the test's virtual dir is /NunitWeb and /NunitWeb1 does not match it
216 r.MapPath ("/NunitWeb1/test.txt");
219 AssertExtensions.Throws<ArgumentException> (() => {
220 r.MapPath ("/test.txt", "/", false);
223 AssertExtensions.Throws<ArgumentException> (() => {
224 r.MapPath ("/test.txt", "/NunitWeb", false);
227 Assert.AreEqual (Path.Combine (appBase, "test.txt"), r.MapPath ("/NunitWeb/test.txt", "/NunitWeb", true), "test16");
231 [Category ("NunitWeb")]
232 [ExpectedException (typeof (ArgumentException))]
233 public void Test_MapPath_InvalidBase_1 ()
235 WebTest t = new WebTest (new HandlerInvoker (new HandlerDelegate (
236 MapPathDelegate_InvalidBase_1)));
240 static public void MapPathDelegate_InvalidBase_1 ()
242 HttpContext.Current.Request.MapPath ("Web.config", "something", true);
246 [Category ("NunitWeb")]
247 [ExpectedException (typeof (ArgumentException))]
248 public void Test_MapPath_InvalidBase_2 ()
250 WebTest t = new WebTest (new HandlerInvoker (new HandlerDelegate (
251 MapPathDelegate_InvalidBase_2)));
255 static public void MapPathDelegate_InvalidBase_2 ()
257 HttpContext.Current.Request.MapPath ("Web.config", "something", false);
262 public class Test_HttpFakeRequest {
263 class FakeHttpWorkerRequest : HttpWorkerRequest {
264 public int return_kind;
266 [Conditional ("REQUEST_TEST_VERY_VERBOSE")]
269 Console.WriteLine (Environment.StackTrace);
273 public FakeHttpWorkerRequest (int re)
278 public override string GetFilePath()
281 return "/tmp/uri.aspx";
284 public override string GetUriPath()
290 public override string GetQueryString()
294 switch (return_kind) {
298 return "key1=value1&key2=value2";
301 return "mapa.x=10&mapa.y=20";
304 return "mapa.x=10&mapa=20";
306 return "mapa.x=10&mapa.y=20";
312 return "mapa.x=pi&mapa.y=20";
314 return "PlainString";
316 return "Plain&Arg=1";
320 return "GetQueryString";
324 public override string GetRawUrl()
330 public override string GetHttpVerbName()
333 if (return_kind == 25 || return_kind == 26)
335 if (return_kind == 30 || return_kind == 31)
340 public override string GetHttpVersion()
346 public override byte [] GetPreloadedEntityBody ()
348 if (return_kind != 30 && return_kind != 31)
349 return base.GetPreloadedEntityBody ();
351 return Encoding.UTF8.GetBytes (GetQueryString ());
354 public override bool IsEntireEntityBodyIsPreloaded ()
356 if (return_kind != 30 && return_kind != 31)
357 return base.IsEntireEntityBodyIsPreloaded ();
362 public override int GetRemotePort()
367 public override string GetLocalAddress()
372 public override string GetAppPath ()
377 public override string GetRemoteName ()
382 public override string GetRemoteAddress ()
384 return "RemoteAddress";
387 public override string GetServerName ()
392 public override int GetLocalPort()
397 public override void SendStatus(int s, string x)
401 public override void SendKnownResponseHeader(int x, string j)
405 public override void SendUnknownResponseHeader(string a, string b)
409 public override void SendResponseFromMemory(byte[] arr, int x)
413 public override void SendResponseFromFile(string a, long b , long c)
418 public override void SendResponseFromFile (IntPtr a, long b, long c)
422 public override void FlushResponse(bool x)
426 public override void EndOfRequest() {
429 public override string GetKnownRequestHeader (int index)
432 case HttpWorkerRequest.HeaderContentType:
433 switch (return_kind){
434 case 1: return "text/plain";
435 case 2: return "text/plain; charset=latin1";
436 case 3: return "text/plain; charset=iso-8859-1";
437 case 4: return "text/plain; charset=\"iso-8859-1\"";
438 case 5: return "text/plain; charset=\"iso-8859-1\" ; other";
441 return "application/x-www-form-urlencoded";
445 case HttpWorkerRequest.HeaderContentLength:
446 switch (return_kind){
447 case 0: return "1024";
448 case 1: return "-1024";
451 return GetQueryString ().Length.ToString ();
452 case -1: return "Blah";
457 case HttpWorkerRequest.HeaderCookie:
458 switch (return_kind){
459 case 10: return "Key=Value";
460 case 11: return "Key=<value>";
461 case 12: return "Key=>";
462 case 13: return "Key=\xff1c";
463 case 14: return "Key=\xff1e";
466 case HttpWorkerRequest.HeaderReferer:
467 switch (return_kind){
469 case 2: return "http://www.mono-project.com/test.aspx";
470 case 15: return "http://www.mono-project.com";
474 case HttpWorkerRequest.HeaderUserAgent:
475 switch (return_kind){
476 case 15: return "Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040913 Firefox/0.10";
479 case HttpWorkerRequest.HeaderAccept:
480 switch (return_kind){
481 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";
484 case HttpWorkerRequest.HeaderAcceptLanguage:
485 switch (return_kind){
486 case 21: return "en-us, en;q=0.5";
493 public override string [][] GetUnknownRequestHeaders ()
495 if (return_kind == 0)
496 return new string [0][];
498 if (return_kind == 3){
499 string [][] x = new string [4][];
500 x [0] = new string [] { "k1", "v1" };
501 x [1] = new string [] { "k2", "v2" };
502 x [2] = new string [] { "k3", "v3" };
503 x [3] = new string [] { "k4", "v4" };
508 if (return_kind == 4){
510 // This tests the bad values and the extra row with an error
512 string [][] x = new string [3][];
513 x [0] = new string [] { "k1", "" };
514 x [1] = new string [] { "k2", null };
515 x [2] = new string [] { "k3", " " };
520 if (return_kind == 2){
521 string [][] x = new string [2][];
522 x [0] = new string [] { "k1", "" };
524 // Returns an empty row.
532 HttpContext Cook (int re)
534 FakeHttpWorkerRequest f = new FakeHttpWorkerRequest (re);
535 HttpContext c = new HttpContext (f);
540 [Test] public void Test_BrokenContentLength ()
542 HttpContext c = Cook (-1);
543 Assert.AreEqual (0, c.Request.ContentLength, "C1");
546 Assert.AreEqual (0, c.Request.ContentLength, "C2");
551 [Ignore ("tests undocumented behavior that depends on implementation")]
552 [ExpectedException(typeof(NullReferenceException))]
553 public void Test_EmptyUnknownRow ()
555 HttpContext c = Cook (2);
556 NameValueCollection x = c.Request.Headers;
560 [Category ("NotWorking")]
561 public void Test_RequestFields ()
563 HttpContext c = Cook (1);
566 Assert.IsNull (c.Request.ApplicationPath, "A1");
568 Assert.AreEqual ("AppPath", c.Request.ApplicationPath, "A1");
570 Assert.AreEqual ("text/plain", c.Request.ContentType, "A2");
573 Assert.AreEqual (1024, c.Request.ContentLength, "A3");
576 Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A4");
577 NameValueCollection x = c.Request.Headers;
579 Assert.AreEqual ("v1", x ["k1"], "K1");
580 Assert.AreEqual ("v2", x ["k2"], "K2");
581 Assert.AreEqual ("v3", x ["k3"], "K3");
582 Assert.AreEqual ("v4", x ["k4"], "K4");
583 Assert.AreEqual ("text/plain; charset=iso-8859-1", x ["Content-Type"], "K4");
584 Assert.AreEqual (5, x.Count, "K5");
587 Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A5");
588 Assert.AreEqual ("text/plain; charset=latin1", c.Request.ContentType, "A5-1");
591 Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A6");
592 x = c.Request.Headers;
593 Assert.AreEqual ("", x ["k1"], "K6");
594 Assert.AreEqual (null, x ["k2"], "K7");
595 Assert.AreEqual (" ", x ["k3"], "K8");
596 Assert.AreEqual (4, x.Count, "K9");
599 Assert.AreEqual ("iso-8859-1", c.Request.ContentEncoding.WebName, "A7");
601 Assert.AreEqual ("RemoteName", c.Request.UserHostName, "A8");
602 Assert.AreEqual ("RemoteAddress", c.Request.UserHostAddress, "A9");
604 // Difference between Url property and RawUrl one: one is resolved, the other is not
605 Assert.AreEqual ("/bb.aspx", c.Request.RawUrl, "A10");
606 Assert.AreEqual ("http://localhost:2020/uri.aspx?GetQueryString", c.Request.Url.ToString (), "A11");
609 [Test] public void Test_Cookies ()
614 c.Request.ValidateInput ();
615 Assert.AreEqual ("Value", c.Request.Cookies ["Key"].Value, "cookie1");
619 [ExpectedException(typeof (HttpRequestValidationException))]
620 public void Test_DangerousCookie ()
625 c.Request.ValidateInput ();
626 object a = c.Request.Cookies;
630 public void Test_DangerousCookie2 ()
635 c.Request.ValidateInput ();
636 object a = c.Request.Cookies;
640 public void Test_DangerousCookie3 ()
645 c.Request.ValidateInput ();
646 object a = c.Request.Cookies;
650 public void Test_DangerousCookie4 ()
655 c.Request.ValidateInput ();
656 object a = c.Request.Cookies;
660 public void Test_MiscHeaders ()
662 HttpContext c = Cook (15);
664 // The uri ToString contains the trailing slash.
665 Assert.AreEqual ("http://www.mono-project.com/", c.Request.UrlReferrer.ToString (), "ref1");
667 Assert.AreEqual ("Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040913 Firefox/0.10", c.Request.UserAgent, "ref2");
669 // All the AcceptTypes and UserLanguages tests below here pass under MS
671 string [] at = c.Request.AcceptTypes;
672 string [] ul = c.Request.UserLanguages;
673 Assert.IsNull (at, "AT1");
674 Assert.IsNull (ul, "UL1");
676 at = c.Request.AcceptTypes;
677 Assert.IsNotNull (at, "AT2");
678 string [] expected = { "text/xml", "application/xml", "application/xhtml+xml", "text/html;q=0.9",
679 "text/plain;q=0.8", "image/png", "*/*;q=0.5" };
681 Assert.AreEqual (expected.Length, at.Length, "AT3");
682 for (int i = expected.Length - 1; i >= 0; i--)
683 Assert.AreEqual (expected [i], at [i], "AT" + (3 + i));
685 ul = c.Request.UserLanguages;
686 Assert.IsNotNull (ul, "UL2");
687 expected = new string [] { "en-us", "en;q=0.5" };
689 Assert.AreEqual (expected.Length, ul.Length, "UL3");
690 for (int i = expected.Length - 1; i >= 0; i--)
691 Assert.AreEqual (expected [i], ul [i], "UL" + (3 + i));
696 public void Empty_WorkerRequest_QueryString ()
698 HttpContext c = Cook (20);
701 // Checks that the following line does not throw an exception if
702 // the querystring returned by the HttpWorkerRequest is null.
704 NameValueCollection nvc = c.Request.QueryString;
708 public void Test_QueryString_ToString ()
710 HttpContext c = Cook (50);
712 Assert.AreEqual (c.Request.QueryString.ToString (), "PlainString", "QTS#1");
715 Assert.AreEqual (c.Request.QueryString.ToString (), "Plain&Arg=1", "QTS#2");
720 public void QueryString_NullTest ()
722 HttpRequest req = new HttpRequest ("file.aspx", "http://localhost/file.aspx", null);
724 Assert.AreEqual (req.QueryString.ToString (), "", "QSNT#1");
729 public void Leading_qm_in_QueryString ()
731 HttpContext c = Cook (16);
732 NameValueCollection nvc = c.Request.QueryString;
733 foreach (string id in nvc.AllKeys) {
734 if (id.StartsWith ("?"))
740 public void TestPath ()
742 HttpContext c = Cook (16);
744 // This used to crash, ifolder exposed this
745 string x = c.Request.Path;
749 public void MapImageCoordinatesHEAD ()
751 HttpContext c = Cook (25);
752 int [] coords = c.Request.MapImageCoordinates ("mapa");
753 Assert.IsNotNull (coords, "A1");
754 Assert.AreEqual (10, coords [0], "X");
755 Assert.AreEqual (20, coords [1], "Y");
758 coords = c.Request.MapImageCoordinates ("mapa");
759 Assert.AreEqual (null, coords, "coords");
763 public void MapImageCoordinatesGET ()
765 HttpContext c = Cook (27);
766 int [] coords = c.Request.MapImageCoordinates ("mapa");
767 Assert.AreEqual (10, coords [0], "X");
768 Assert.AreEqual (20, coords [1], "Y");
770 coords = c.Request.MapImageCoordinates ("m");
771 Assert.AreEqual (null, coords, "coords1");
774 coords = c.Request.MapImageCoordinates ("mapa");
775 Assert.AreEqual (null, coords, "coords2");
777 coords = c.Request.MapImageCoordinates ("mapa");
778 Assert.AreEqual (null, coords, "coords3");
780 coords = c.Request.MapImageCoordinates ("mapa");
781 Assert.AreEqual (null, coords, "coords4");
785 public void MapImageCoordinatesPOST ()
787 HttpContext c = Cook (30);
788 int [] coords = c.Request.MapImageCoordinates ("mapa");
789 Assert.IsNotNull (coords, "A1");
790 Assert.AreEqual (10, coords [0], "X");
791 Assert.AreEqual (20, coords [1], "Y");
794 coords = c.Request.MapImageCoordinates ("mapa");
795 Assert.AreEqual (null, coords, "coords2");
799 public void TestReferer ()
801 HttpContext c = Cook (1);
803 Assert.AreEqual (null, c.Request.UrlReferrer, "REF1");
806 Assert.AreEqual ("http://www.mono-project.com/test.aspx", c.Request.UrlReferrer.ToString (), "REF1");
809 Assert.AreEqual (null, c.Request.UrlReferrer, "REF1");
814 public void NegativeContentLength ()
816 HttpContext c = Cook (1);
817 HttpRequest req = c.Request;
818 Assert.AreEqual (0, req.ContentLength, "#01");
822 public void EmptyQueryValueParams ()
824 HttpContext c = Cook (52);
825 Assert.AreEqual ("", c.Request.Params["Empty"]);
829 // This class is defined here to make it easy to create fake
830 // HttpWorkerRequest-derived classes by only overriding the methods
831 // necessary for testing.
832 class BaseFakeHttpWorkerRequest : HttpWorkerRequest
834 public override void EndOfRequest()
838 public override void FlushResponse(bool finalFlush)
842 public override string GetHttpVerbName()
847 public override string GetHttpVersion()
852 public override string GetLocalAddress()
857 public override int GetLocalPort()
862 public override string GetQueryString()
867 public override string GetRawUrl()
869 string rawUrl = GetUriPath();
870 string queryString = GetQueryString();
871 if (queryString != null && queryString.Length > 0)
873 rawUrl += "?" + queryString;
878 public override string GetRemoteAddress()
883 public override int GetRemotePort()
888 public override string GetUriPath()
890 return "default.aspx";
893 public override void SendKnownResponseHeader(int index, string value)
897 public override void SendResponseFromFile(IntPtr handle, long offset, long length)
901 public override void SendResponseFromFile(string filename, long offset, long length)
905 public override void SendResponseFromMemory(byte[] data, int length)
909 public override void SendStatus(int statusCode, string statusDescription)
913 public override void SendUnknownResponseHeader(string name, string value)
918 // This test ensures accessing the Form property does not throw an
919 // exception when the length of data in the request exceeds the length
920 // as reported by the Content-Length header. This bug was discovered
921 // with an AJAX application using XMLHttpRequest to POST back to the
922 // server. The Content-Length header was two bytes less than the length
923 // of the buffer returned from GetPreloadedEntityBody. This was causing
924 // an exception to be thrown by Mono because it was trying to allocate
925 // a buffer that was -2 bytes in length.
927 public class Test_UrlEncodedBodyWithExtraCRLF
929 class FakeHttpWorkerRequest : BaseFakeHttpWorkerRequest
931 // This string is 9 bytes in length. That's 2 more than
932 // the Content-Length header says it should be.
933 string data = "foo=bar\r\n";
935 public override string GetKnownRequestHeader(int index)
939 case HttpWorkerRequest.HeaderContentLength:
940 return (data.Length - 2).ToString();
941 case HttpWorkerRequest.HeaderContentType:
942 return "application/x-www-form-urlencoded";
947 public override byte[] GetPreloadedEntityBody()
949 return Encoding.ASCII.GetBytes(data);
953 HttpContext context = null;
956 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
959 HttpWorkerRequest workerRequest = new FakeHttpWorkerRequest();
960 context = new HttpContext(workerRequest);
964 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
965 public void ContentLength()
967 Assert.AreEqual(7, context.Request.ContentLength);
971 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
972 public void Form_Count()
974 Assert.AreEqual(1, context.Request.Form.Count);
978 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
979 public void Form_Item()
981 // I would have expected the extra two characters to be stripped
982 // but Microsoft's CLR keeps them so Mono should, too.
983 //Assert.AreEqual("bar\r\n", context.Request.Form["foo"]);
984 Assert.AreEqual("bar", context.Request.Form["foo"]);
988 // This test ensures the HttpRequet object's Form property gets
989 // properly constructed and populated when the Content-Type header
990 // includes a charset parameter and that the charset parameter is
993 public class Test_UrlEncodedBodyWithUtf8CharsetParameter
995 class FakeHttpWorkerRequest : BaseFakeHttpWorkerRequest
997 // The two funny-looking characters are really a single
998 // accented "a" character encoded in UTF-8.
999 string data = "foo=b%C3%A1r";
1001 public override string GetKnownRequestHeader(int index)
1005 case HttpWorkerRequest.HeaderContentLength:
1006 return data.Length.ToString();
1007 case HttpWorkerRequest.HeaderContentType:
1008 return "application/x-www-form-urlencoded; charset=utf-8";
1010 return String.Empty;
1013 public override byte[] GetPreloadedEntityBody()
1015 return Encoding.ASCII.GetBytes(data);
1019 HttpContext context = null;
1022 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
1025 HttpWorkerRequest workerRequest = new FakeHttpWorkerRequest();
1026 context = new HttpContext(workerRequest);
1030 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
1031 public void Form_Count()
1033 Assert.AreEqual(1, context.Request.Form.Count);
1037 [Category ("NotDotNet")] // Cannot be runned on .net with no web context
1038 public void Form_Item()
1040 Assert.AreEqual("b\xE1r", context.Request.Form["foo"]);