diff options
author | Marek Habersack <grendel@twistedcode.net> | 2009-07-02 18:25:27 +0400 |
---|---|---|
committer | Marek Habersack <grendel@twistedcode.net> | 2009-07-02 18:25:27 +0400 |
commit | de20f49d1299d36e18190b5895f6b106c70c7176 (patch) | |
tree | fedcfc9a806d5e2a0b432c72c46b7b94eeb11c24 | |
parent | 06d12726f3fe7912df36ada059f3e050f7960d97 (diff) |
Backport of a small fix for System.Web.Routing/PatternParser.cs (partial backport of r136875)
svn path=/branches/mono-2-4-2/mcs/; revision=137299
9 files changed, 374 insertions, 5 deletions
diff --git a/mcs/class/System.Web.Routing/System.Web.Routing/ChangeLog b/mcs/class/System.Web.Routing/System.Web.Routing/ChangeLog index 6f20c67c13d..772598c31d7 100644 --- a/mcs/class/System.Web.Routing/System.Web.Routing/ChangeLog +++ b/mcs/class/System.Web.Routing/System.Web.Routing/ChangeLog @@ -1,3 +1,10 @@ +2009-06-25 Marek Habersack <mhabersack@novell.com> + + * PatternParser.cs: parameter name lookups must be + case-insensitive. + Null and empty (string) parameters are skipped when building query + part of the action path. + 2009-06-04 Marek Habersack <mhabersack@novell.com> * RouteValueDictionaryExtensions.cs: if both values are strings in diff --git a/mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs b/mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs index d3a31866367..44f7e1ab289 100644 --- a/mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs +++ b/mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs @@ -82,7 +82,7 @@ namespace System.Web.Routing PatternToken tmpToken; segments = new PatternSegment [partsCount]; - parameterNames = new Dictionary <string, bool> (); + parameterNames = new Dictionary <string, bool> (StringComparer.OrdinalIgnoreCase); for (int i = 0; i < partsCount; i++) { if (haveSegmentWithCatchAll) @@ -495,13 +495,21 @@ namespace System.Web.Routing if (parameterNames.ContainsKey (parameterName) || defaultValues.Has (parameterName) || constraints.Has (parameterName)) continue; + object parameterValue = de.Value; + if (parameterValue == null) + continue; + + var parameterValueAsString = parameterValue as string; + if (parameterValueAsString != null && parameterValueAsString.Length == 0) + continue; + if (first) { ret.Append ('?'); first = false; } else ret.Append ('&'); - object parameterValue = de.Value; + ret.Append (Uri.EscapeDataString (parameterName)); ret.Append ('='); if (parameterValue != null) diff --git a/mcs/class/System.Web.Routing/System.Web.Routing_test.dll.sources b/mcs/class/System.Web.Routing/System.Web.Routing_test.dll.sources index d55d50a3045..5efc7e624c1 100644 --- a/mcs/class/System.Web.Routing/System.Web.Routing_test.dll.sources +++ b/mcs/class/System.Web.Routing/System.Web.Routing_test.dll.sources @@ -1,11 +1,14 @@ System.Web.Routing/AssertExtensions.cs +System.Web.Routing/FakeHttpWorkerRequest.cs System.Web.Routing/HttpMethodConstraintTest.cs +System.Web.Routing/KnownResponseHeader.cs System.Web.Routing/RouteCollectionTest.cs System.Web.Routing/RouteDataTest.cs System.Web.Routing/RouteTest.cs System.Web.Routing/RouteValueDictionaryTest.cs System.Web.Routing/StopRoutingHandlerTest.cs System.Web.Routing/TestStubTypes.cs +System.Web.Routing/UnknownResponseHeader.cs System.Web.Routing/UrlRoutingHandlerTest.cs System.Web.Routing/UrlRoutingModuleTest.cs System.Web.Routing/VirtualPathDataTest.cs diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/ChangeLog b/mcs/class/System.Web.Routing/Test/System.Web.Routing/ChangeLog index 53548f2bb16..a37598da676 100644 --- a/mcs/class/System.Web.Routing/Test/System.Web.Routing/ChangeLog +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/ChangeLog @@ -1,3 +1,8 @@ +2009-06-25 Marek Habersack <mhabersack@novell.com> + + * RouteCollectionTest.cs, RouteTest.cs: added new tests for + GetVirtualPath + 2009-06-04 Marek Habersack <mhabersack@novell.com> * RouteCollectionTest.cs: added two more test cases to the bug diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/FakeHttpWorkerRequest.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/FakeHttpWorkerRequest.cs new file mode 100644 index 00000000000..fc087ce5860 --- /dev/null +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/FakeHttpWorkerRequest.cs @@ -0,0 +1,223 @@ +// +// System.Web.HttpResponseTest.cs - Unit tests for System.Web.HttpResponse +// +// Author: +// Miguel de Icaza <miguel@ximian.com> +// +// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Text; +using System.Web; +using System; +using System.Collections; +using System.Collections.Specialized; +using NUnit.Framework; + +namespace MonoTests.Common +{ + + public class FakeHttpWorkerRequest : HttpWorkerRequest + { + const string appPath = "/"; + string queryString; + public Hashtable KnownResponseHeaders; + public Hashtable UnknownResponseHeaders; + public int return_kind; + + public FakeHttpWorkerRequest () + : this (1) + { + // for Mono + AppDomain.CurrentDomain.SetData (".appVPath", appPath); + } + + public FakeHttpWorkerRequest (int re) + { + KnownResponseHeaders = CollectionsUtil.CreateCaseInsensitiveHashtable (); + UnknownResponseHeaders = CollectionsUtil.CreateCaseInsensitiveHashtable (); + return_kind = re; + queryString = String.Empty; + } + + public override string GetUriPath () + { + return "/fake"; + } + + public override string GetFilePath () + { + return GetUriPath (); + } + + public override string GetQueryString () + { + return queryString; + } + + public void SetQueryString (string queryString) + { + this.queryString = queryString; + } + + public override string GetRawUrl () + { + return "GetRawUrl"; + } + + public override string GetHttpVerbName () + { + return "GET"; + } + + public override string GetHttpVersion () + { + if (return_kind == 1) + return "HTTP/1.0"; + else + return "HTTP/1.1"; + } + + public override string GetRemoteAddress () + { + return "__GetRemoteAddress"; + } + + public override int GetRemotePort () + { + return 1010; + } + + public override string GetLocalAddress () + { + return "GetLocalAddress"; + } + + public override string GetAppPath () + { + return appPath; + } + + public override int GetLocalPort () + { + return 2020; + } + + public override string MapPath (string virtualPath) + { +#if TARGET_DOTNET + return "c:\\fakefile"; +#else + return "/fakefile"; +#endif + } + + public bool status_sent; + public int status_code; + public string status_string; + + public override void SendStatus (int s, string x) + { + status_sent = true; + status_code = s; + status_string = x; + } + + void AddHeader (Hashtable table, string header_name, object header) + { + object o = table[header_name]; + if (o == null) + table.Add (header_name, header); + else { + ArrayList al = o as ArrayList; + if (al == null) { + al = new ArrayList (); + al.Add (o); + table[header_name] = al; + } else + al = o as ArrayList; + + al.Add (header); + } + } + + bool headers_sent; + public override void SendKnownResponseHeader (int x, string j) + { + string header_name = HttpWorkerRequest.GetKnownRequestHeaderName (x); + AddHeader (KnownResponseHeaders, header_name, new KnownResponseHeader (x, j)); + headers_sent = true; + } + + public override void SendUnknownResponseHeader (string a, string b) + { + AddHeader (UnknownResponseHeaders, a, new UnknownResponseHeader (a, b)); + headers_sent = true; + } + + bool data_sent; + public byte[] data; + public int data_len; + public int total = 0; + + public override void SendResponseFromMemory (byte[] arr, int x) + { + data_sent = true; + data = new byte[x]; + for (int i = 0; i < x; i++) + data[i] = arr[i]; + data_len = x; + total += data_len; + } + + public override void SendResponseFromFile (string a, long b, long c) + { + data_sent = true; + } + + public override void SendResponseFromFile (IntPtr a, long b, long c) + { + data_sent = true; + } + + public override void FlushResponse (bool x) + { + } + + public override void EndOfRequest () + { + } + + public override string GetKnownRequestHeader (int index) + { + return null; + } + + public bool OutputProduced + { + get + { + return headers_sent || data_sent; + } + } + } +} diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/KnownResponseHeader.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/KnownResponseHeader.cs new file mode 100644 index 00000000000..71806c33f74 --- /dev/null +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/KnownResponseHeader.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace MonoTests.Common +{ + class KnownResponseHeader + { + private int index; + private string value; + + public KnownResponseHeader (int index, string value) + { + this.index = index; + this.value = value; + } + + public int Index + { + get { return index; } + } + + public string Value + { + get { return value; } + } + } +} diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs index 02e5529a89f..7631d86d29b 100644 --- a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs @@ -32,6 +32,8 @@ using System.Web; using System.Web.Routing; using NUnit.Framework; +using MonoTests.Common; + namespace MonoTests.System.Web.Routing { [TestFixture] @@ -282,7 +284,7 @@ namespace MonoTests.System.Web.Routing rd = c.GetRouteData (hc); vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values); Assert.IsNotNull (vpd, "#B1"); - Assert.AreEqual ("//_modified", vpd.VirtualPath, "#B2"); + Assert.AreEqual ("/_modified", vpd.VirtualPath, "#B2"); Assert.AreEqual (0, vpd.DataTokens.Count, "#B3"); hc = new HttpContextStub2 ("~/Account/LogOn", String.Empty, String.Empty); @@ -484,7 +486,45 @@ namespace MonoTests.System.Web.Routing ); Assert.IsNull (vp, "#5"); } - + + [Test] + public void GetVirtualPath7 () + { + var c = new RouteCollection (); + + c.Add (new MyRoute ("{table}/{action}.aspx", new MyRouteHandler ()) { + Constraints = new RouteValueDictionary (new { action = "List|Details|Edit|Insert" }), + }); + + var req = new FakeHttpWorkerRequest (); + var ctx = new HttpContext (req); + HttpContext.Current = ctx; + var rd = new RouteData (); + var hc = new HttpContextWrapper (ctx); + + var vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary { + {"Table", "FooTable"}, + {"Action", "Details"} + }); + + Assert.IsNotNull (vp, "#A1"); + Assert.AreEqual ("/FooTable/Details.aspx", vp.VirtualPath, "#A1-1"); + + vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary { + {"Table", "FooTable"}, + {"Action", String.Empty} + }); + + Assert.IsNull (vp, "#B1"); + + vp = c.GetVirtualPath (new RequestContext (hc, rd), new RouteValueDictionary { + {"Table", "FooTable"}, + {"Action", null} + }); + + Assert.IsNull (vp, "#C1"); + } + [Test] [Ignore ("looks like RouteExistingFiles ( = false) does not affect... so this test needs more investigation")] public void GetVirtualPathToExistingFile () diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs index 748b560633e..cf88935d21f 100644 --- a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs @@ -934,7 +934,32 @@ namespace MonoTests.System.Web.Routing var vp = r.GetVirtualPath (new RequestContext (hc, rd), values); Assert.IsNull (vp); } - + + [Test] + public void GetVirtualPath14 () + { + var r = new MyRoute ("{table}/{action}.aspx", new MyRouteHandler ()); + var hc = new HttpContextStub2 ("~/x/y.aspx", String.Empty); + var rd = r.GetRouteData (hc); + + // override a value incompletely + var values = new RouteValueDictionary (new { + emptyValue = String.Empty, + nullValue = (string)null, + nonEmptyValue = "SomeValue" + }); + + var vp = r.GetVirtualPath (new RequestContext (hc, rd), values); + Assert.IsNotNull (vp, "#A1"); + Assert.AreEqual ("x/y.aspx?nonEmptyValue=SomeValue", vp.VirtualPath, "#A1-1"); + + values["nonEmptyValue"] = "Some Value + encoding &"; + vp = r.GetVirtualPath (new RequestContext (hc, rd), values); + Assert.IsNotNull (vp, "#B1"); + Assert.AreEqual ("x/y.aspx?nonEmptyValue=Some%20Value%20%2B%20encoding%20%26", vp.VirtualPath, "#B1-1"); + + } + // Bug #500739 [Test] public void RouteGetRequiredStringWithDefaults () diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/UnknownResponseHeader.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/UnknownResponseHeader.cs new file mode 100644 index 00000000000..20d3ce0a290 --- /dev/null +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/UnknownResponseHeader.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace MonoTests.Common +{ + class UnknownResponseHeader + { + private string name; + private string value; + + public UnknownResponseHeader (string name, string value) + { + this.name = name; + this.value = value; + } + + public string Name + { + get { return name; } + } + + public string Value + { + get { return value; } + } + } +} |