Hi, These are the separate and slightly refactored patches for HttpUtility.cs, HttpRequest.cs and HttpRequestTest.cs:
2006-05-28 Juraj Skripsky <[EMAIL PROTECTED]> * HttpUtility.cs (ParseQueryString): move core of ParseQueryString into internal method to make it available to HttpRequest. Use Encoding.Default if no encoding is given as that's what MS does. 2006-05-28 Juraj Skripsky <[EMAIL PROTECTED]> * HttpRequest.cs: simplify code around uri_builder (and rename to url_components). Move storage of query_string into uri_builder.Query and initialize it lazily using worker_request.GetQueryStringRawBytes() or GetQueryString(). (QueryString): Use HttpUtility.ParseQueryString instead of duplicating its functionality. 2006-05-28 Juraj Skripsky <[EMAIL PROTECTED]> * HttpRequestTest.cs: add test case to verify that the correct encoding is used during url-decoding of the query string. All NUnit tests pass, xsp and mod_mono seem to be happy as well. May I commit? - Juraj On Fri, 2006-05-26 at 09:55 -0400, Gonzalo Paniagua Javier wrote: > On Fri, 2006-05-26 at 15:26 +0200, Juraj Skripsky wrote: > > I will do some more testing with a few websites of our own. If > > everything works fine, I would like to commit the changes. > > I would prefer to get separated patches with a ChangeLog. Also the > changes that involve UriBuilder might break PathInfo. Make sure you test > those with apache/mod_mono and xsp. > > Thanks. > > -Gonzalo
Index: HttpUtility.cs =================================================================== --- HttpUtility.cs (revision 61128) +++ HttpUtility.cs (working copy) @@ -965,7 +965,7 @@ #if NET_2_0 public static NameValueCollection ParseQueryString (string query) { - return ParseQueryString (query, Encoding.UTF8); + return ParseQueryString (query, Encoding.Default); } public static NameValueCollection ParseQueryString (string query, Encoding encoding) @@ -978,9 +978,19 @@ return new NameValueCollection (); if (query[0] == '?') query = query.Substring (1); + + NameValueCollection result = new NameValueCollection (); + ParseQueryString (query, encoding, result); + return result; + } +#endif + internal static void ParseQueryString (string query, Encoding encoding, NameValueCollection result) + { + if (query.Length == 0) + return; + int namePos = 0; - NameValueCollection collection = new NameValueCollection (); while (namePos <= query.Length) { int valuePos = -1, valueEnd = -1; for (int q = namePos; q < query.Length; q++) { @@ -997,7 +1007,7 @@ name = null; valuePos = namePos; } else { - name = System.Web.HttpUtility.UrlDecode (query.Substring (namePos, valuePos - namePos - 1), encoding); + name = UrlDecode (query.Substring (namePos, valuePos - namePos - 1), encoding); } if (valueEnd < 0) { namePos = -1; @@ -1005,14 +1015,12 @@ } else { namePos = valueEnd + 1; } - value = System.Web.HttpUtility.UrlDecode (query.Substring (valuePos, valueEnd - valuePos), encoding); + value = UrlDecode (query.Substring (valuePos, valueEnd - valuePos), encoding); - collection.Add (name, value); + result.Add (name, value); if (namePos == -1) break; } - return collection; } -#endif #endregion // Methods } }
Index: HttpRequest.cs =================================================================== --- HttpRequest.cs (revision 61128) +++ HttpRequest.cs (working copy) @@ -51,8 +51,9 @@ WebROCollection query_string_nvc; // - string filename, query_string; - UriBuilder uri_builder; + string filename; + string orig_url = null; + UriBuilder url_components; string client_target; @@ -97,28 +98,38 @@ this.filename = filename; - uri_builder = new UriBuilder (url); - query_string = queryString; + orig_url = url; + url_components = new UriBuilder (url); + url_components.Query = queryString; + + query_string_nvc = new WebROCollection (); + HttpUtility.ParseQueryString (queryString, Encoding.Default, query_string_nvc); + query_string_nvc.Protect (); } - void InitUriBuilder () - { - uri_builder = new UriBuilder (); - uri_builder.Scheme = worker_request.GetProtocol (); - uri_builder.Host = worker_request.GetServerName (); - int port = worker_request.GetLocalPort (); - uri_builder.Port = port; - uri_builder.Path = worker_request.GetUriPath (); - if (query_string != null && query_string != "") - uri_builder.Query = query_string; + UriBuilder UrlComponents { + get { + if (url_components == null) { + url_components = new UriBuilder (); + url_components.Scheme = worker_request.GetProtocol (); + url_components.Host = worker_request.GetServerName (); + url_components.Port = worker_request.GetLocalPort (); + url_components.Path = worker_request.GetUriPath (); + + byte[] queryStringRaw = worker_request.GetQueryStringRawBytes(); + if(queryStringRaw != null) + url_components.Query = ContentEncoding.GetString(queryStringRaw); + else + url_components.Query = worker_request.GetQueryString(); + } + return url_components; + } } internal HttpRequest (HttpWorkerRequest worker_request, HttpContext context) { this.worker_request = worker_request; this.context = context; - if (worker_request != null) - query_string = worker_request.GetQueryString (); } string [] SplitHeader (int header_index) @@ -878,10 +889,7 @@ public string Path { get { - if (uri_builder == null) - InitUriBuilder (); - - return uri_builder.Path; + return UrlComponents.Path; } } @@ -944,27 +952,13 @@ public NameValueCollection QueryString { get { if (query_string_nvc == null){ - query_string_nvc = new WebROCollection (); + string q = UrlComponents.Query; + if (q.Length != 0) + q = q.Remove(0, 1); - if (uri_builder == null) - InitUriBuilder (); - - string q = query_string; - if (q != null && q != ""){ - string [] components = q.Split ('&'); - foreach (string kv in components){ - int pos = kv.IndexOf ('='); - if (pos == -1){ - query_string_nvc.Add (null, HttpUtility.UrlDecode (kv)); - } else { - string key = HttpUtility.UrlDecode (kv.Substring (0, pos)); - string val = HttpUtility.UrlDecode (kv.Substring (pos+1)); - - query_string_nvc.Add (key, val); - } - } - } - query_string_nvc.Protect (); + query_string_nvc = new WebROCollection (); + HttpUtility.ParseQueryString (q, ContentEncoding, query_string_nvc); + query_string_nvc.Protect(); } if (validate_query_string && !checked_query_string) { @@ -980,12 +974,8 @@ get { if (worker_request != null) return worker_request.GetRawUrl (); - else { - if (query_string != null && query_string != "") - return uri_builder.Path + "?" + query_string; - else - return uri_builder.Path; - } + else + return UrlComponents.Path + UrlComponents.Query; } } @@ -1029,14 +1019,14 @@ public Uri Url { get { - if (uri_builder == null) - InitUriBuilder (); - if (cached_url == null) { - UriBuilder builder = new UriBuilder (uri_builder.Uri); - cached_url = builder.Uri; + if (orig_url == null) + cached_url = UrlComponents.Uri; + else + cached_url = new Uri (orig_url); } - return cached_url; + + return cached_url; } } @@ -1185,12 +1175,9 @@ string path = "/"; if (worker_request != null) { version = worker_request.GetHttpVersion (); - InitUriBuilder (); - path = uri_builder.Path; + path = UrlComponents.Path; } - string qs = null; - if (query_string != null && query_string != "") - qs = "?" + query_string; + string qs = UrlComponents.Query; sb.AppendFormat ("{0} {1}{2} {3}\r\n", HttpMethod, path, qs, version); NameValueCollection coll = Headers; @@ -1261,19 +1248,17 @@ file_path = path; } - internal void SetCurrentExePath (string path) - { + internal void SetCurrentExePath (string path) + { cached_url = null; current_exe_path = path; file_path = path; - if (uri_builder == null) - InitUriBuilder (); - uri_builder.Path = path; + UrlComponents.Path = path; // recreated on demand root_virtual_dir = null; base_virtual_dir = null; physical_path = null; - } + } internal void SetPathInfo (string pi) { @@ -1293,20 +1278,13 @@ // Notice: there is nothing raw about this querystring. internal string QueryStringRaw { get { - if (uri_builder == null) - InitUriBuilder (); - - return query_string; + return UrlComponents.Query; } set { - if (uri_builder == null) - InitUriBuilder (); - - query_string = value; + UrlComponents.Query = value; + cached_url = null; query_string_nvc = null; - if (uri_builder != null) - uri_builder.Query = value; } }
Index: System.Web/HttpRequestTest.cs =================================================================== --- System.Web/HttpRequestTest.cs (revision 61128) +++ System.Web/HttpRequestTest.cs (working copy) @@ -129,7 +129,18 @@ HttpRequest r = new HttpRequest ("file", url, qs); string s = r.PhysicalApplicationPath; } + + [Test] + public void Test_QueryStringDecoding() + { + string url = "http://www.gnome.org/"; + string qs = "umlaut=" + HttpUtility.UrlEncode("\u00e4", Encoding.Default); + + HttpRequest r = new HttpRequest ("file", url, qs); + Assert.AreEqual("\u00e4", r.QueryString["umlaut"]); + } } + [TestFixture] public class Test_HttpFakeRequest {
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list