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

Reply via email to