2010-05-05 Marek Habersack <mhabersack@novell.com>
authorMarek Habersack <grendel@twistedcode.net>
Wed, 5 May 2010 00:43:57 +0000 (00:43 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Wed, 5 May 2010 00:43:57 +0000 (00:43 -0000)
* RouteValueDictionary.cs: do not process type fields in
RouteValueDictionary (object)

* RouteCollection.cs: GetRouteData throws an exception if Request
is null in the passed context.
Added Ignore* and MapPageRoute* 4.0 APIs

* RequestContext.cs: 4.0 API update

* PatternParser.cs: match parser rewrite to encompass 4.0 bug
fixes. We don't emulate some of the pre-4.0 routing bugs anymore.

svn path=/trunk/mcs/; revision=156695

15 files changed:
mcs/class/System.Web.Routing/System.Web.Routing/ChangeLog
mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs
mcs/class/System.Web.Routing/System.Web.Routing/RequestContext.cs
mcs/class/System.Web.Routing/System.Web.Routing/Route.cs
mcs/class/System.Web.Routing/System.Web.Routing/RouteCollection.cs
mcs/class/System.Web.Routing/System.Web.Routing/RouteValueDictionary.cs
mcs/class/System.Web.Routing/System.Web.Routing/UrlRoutingHandler.cs
mcs/class/System.Web.Routing/System.Web.Routing_test.dll.sources
mcs/class/System.Web.Routing/Test/System.Web.Routing/FakeHttpWorkerRequest.cs
mcs/class/System.Web.Routing/Test/System.Web.Routing/RequestContext.cs [new file with mode: 0644]
mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs
mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs
mcs/class/System.Web.Routing/Test/System.Web.Routing/TestStubTypes.cs
mcs/class/System.Web.Routing/Test/System.Web.Routing/UrlRoutingModuleTest.cs
mcs/class/System.Web/System.Web.Routing/PageRouteHandler.cs

index 5f16009ed9a89d64b046a5e7ec7a33eb530ce6a7..794c2d66010f850e11830f0d34964f16055c847f 100644 (file)
@@ -1,3 +1,17 @@
+2010-05-05  Marek Habersack  <mhabersack@novell.com>
+
+       * RouteValueDictionary.cs: do not process type fields in
+       RouteValueDictionary (object)
+
+       * RouteCollection.cs: GetRouteData throws an exception if Request
+       is null in the passed context.
+       Added Ignore* and MapPageRoute* 4.0 APIs
+
+       * RequestContext.cs: 4.0 API update
+
+       * PatternParser.cs: match parser rewrite to encompass 4.0 bug
+       fixes. We don't emulate some of the pre-4.0 routing bugs anymore.
+
 2009-11-23  Marek Habersack  <mhabersack@novell.com>
 
        * Route.cs: GetRouteData throws NotImplementedException only when
index 1cb0a0395660c2d0138501da6440c462805740df..72692dc6a73936937f7b3c0741d4ee87bb01de34 100644 (file)
@@ -5,7 +5,7 @@
 //      Atsushi Enomoto <atsushi@ximian.com>
 //      Marek Habersack <mhabersack@novell.com>
 //
-// Copyright (C) 2008-2009 Novell Inc. http://novell.com
+// Copyright (C) 2008-2010 Novell Inc. http://novell.com
 //
 
 //
@@ -206,7 +206,85 @@ namespace System.Web.Routing
 
                        return dict;
                }
-               
+
+               bool MatchSegment (int segIndex, int argsCount, string[] argSegs, List <PatternToken> tokens, RouteValueDictionary ret)
+               {
+                       string pathSegment = argSegs [segIndex];
+                       int pathSegmentLength = pathSegment != null ? pathSegment.Length : -1;
+                       int startIndex = pathSegmentLength - 1;
+                       PatternTokenType tokenType;
+                       int tokensCount = tokens.Count;
+                       PatternToken token;
+                       string tokenName;
+
+                       for (int tokenIndex = tokensCount - 1; tokenIndex > -1; tokenIndex--) {
+                               token = tokens [tokenIndex];
+                               if (startIndex < 0)
+                                       return false;
+
+                               tokenType = token.Type;
+                               tokenName = token.Name;
+
+                               if (segIndex > segmentCount - 1 || tokenType == PatternTokenType.CatchAll) {
+                                       var sb = new StringBuilder ();
+
+                                       for (int j = segIndex; j < argsCount; j++) {
+                                               if (j > segIndex)
+                                                       sb.Append ('/');
+                                               sb.Append (argSegs [j]);
+                                       }
+                                               
+                                       ret.Add (tokenName, sb.ToString ());
+                                       break;
+                               }
+
+                               int scanIndex;
+                               if (token.Type == PatternTokenType.Literal) {
+                                       int nameLen = tokenName.Length;
+                                       if (startIndex + 1 < nameLen)
+                                               return false;
+                                       scanIndex = startIndex - nameLen + 1;
+                                       if (String.Compare (pathSegment, scanIndex, tokenName, 0, nameLen, StringComparison.OrdinalIgnoreCase) != 0)
+                                               return false;
+                                       startIndex = scanIndex - 1;
+                                       continue;
+                               }
+
+                               // Standard token
+                               int nextTokenIndex = tokenIndex - 1;
+                               if (nextTokenIndex < 0) {
+                                       // First token
+                                       ret.Add (tokenName, pathSegment.Substring (0, startIndex + 1));
+                                       continue;
+                               }
+
+                               if (startIndex == 0)
+                                       return false;
+                               
+                               var nextToken = tokens [nextTokenIndex];
+                               string nextTokenName = nextToken.Name;
+
+                               // Skip one char, since there can be no empty segments and if the
+                               // current token's value happens to be the same as preceeding
+                               // literal text, we'll save some time and complexity.
+                               scanIndex = startIndex - 1;
+                               int lastIndex = pathSegment.LastIndexOf (nextTokenName, scanIndex, StringComparison.OrdinalIgnoreCase);
+                               if (lastIndex == -1)
+                                       return false;
+
+                               lastIndex += nextTokenName.Length - 1;
+                                               
+                               string sectionValue = pathSegment.Substring (lastIndex + 1, startIndex - lastIndex);
+                               if (String.IsNullOrEmpty (sectionValue))
+                                       return false;
+
+                               ret.Add (tokenName, sectionValue);
+                               startIndex = lastIndex;
+                       }
+                       
+                       return true;
+               }
+
                public RouteValueDictionary Match (string path, RouteValueDictionary defaults)
                {
                        var ret = new RouteValueDictionary ();
@@ -247,73 +325,8 @@ namespace System.Web.Routing
                                        continue;
                                }
 
-                               string pathSegment = argSegs [i];
-                               int pathSegmentLength = pathSegment != null ? pathSegment.Length : -1;
-                               int pathIndex = 0;
-                               PatternTokenType tokenType;
-                               List <PatternToken> tokens = segment.Tokens;
-                               int tokensCount = tokens.Count;
-                               
-                               // Process the path segments ignoring the defaults
-                               for (int tokenIndex = 0; tokenIndex < tokensCount; tokenIndex++) {
-                                       var token = tokens [tokenIndex];
-                                       if (pathIndex > pathSegmentLength - 1)
-                                               return null;
-
-                                       tokenType = token.Type;
-                                       var tokenName = token.Name;
-
-                                       // Catch-all
-                                       if (i > segmentCount - 1 || tokenType == PatternTokenType.CatchAll) {
-                                               if (tokenType != PatternTokenType.CatchAll)
-                                                       return null;
-
-                                               StringBuilder sb = new StringBuilder ();
-                                               for (int j = i; j < argsCount; j++) {
-                                                       if (j > i)
-                                                               sb.Append ('/');
-                                                       sb.Append (argSegs [j]);
-                                               }
-                                               
-                                               ret.Add (tokenName, sb.ToString ());
-                                               break;
-                                       }
-
-                                       // Literal sections
-                                       if (token.Type == PatternTokenType.Literal) {
-                                               int nameLen = tokenName.Length;
-                                               if (pathSegmentLength < nameLen || String.Compare (pathSegment, pathIndex, tokenName, 0, nameLen, StringComparison.OrdinalIgnoreCase) != 0)
-                                                       return null;
-                                               pathIndex += nameLen;
-                                               continue;
-                                       }
-
-                                       int nextTokenIndex = tokenIndex + 1;
-                                       if (nextTokenIndex >= tokensCount) {
-                                               // Last token
-                                               ret.Add (tokenName, pathSegment.Substring (pathIndex));
-                                               continue;
-                                       }
-
-                                       // Next token is a literal - greedy matching. It seems .NET
-                                       // uses a simple and naive algorithm here which finds the
-                                       // last ocurrence of the next section literal and assigns
-                                       // everything before that to this token. See the
-                                       // GetRouteData28 test in RouteTest.cs
-                                       var nextToken = tokens [nextTokenIndex];
-                                       string nextTokenName = nextToken.Name;
-                                       int lastIndex = pathSegment.LastIndexOf (nextTokenName, pathSegmentLength - 1, pathSegmentLength - pathIndex, StringComparison.OrdinalIgnoreCase);
-                                       if (lastIndex == -1)
-                                               return null;
-                                       
-                                       int copyLength = lastIndex - pathIndex;
-                                       string sectionValue = pathSegment.Substring (pathIndex, copyLength);
-                                       if (String.IsNullOrEmpty (sectionValue))
-                                               return null;
-                                       
-                                       ret.Add (tokenName, sectionValue);
-                                       pathIndex += copyLength;
-                               }
+                               if (!MatchSegment (i, argsCount, argSegs, segment.Tokens, ret))
+                                       return null;
                                i++;
                        }
 
index c0c573f8761b28a4d7bb0b135a892ecb8649fc0c..b4ac0c209e08dbd37f679bcc9236ab363e577610 100644 (file)
@@ -41,6 +41,13 @@ namespace System.Web.Routing
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public class RequestContext
        {
+#if NET_4_0
+               public RequestContext ()
+               {
+                       HttpContext = null;
+                       RouteData = null;
+               }
+#endif
                public RequestContext (HttpContextBase httpContext, RouteData routeData)
                {
                        if (httpContext == null)
@@ -52,8 +59,12 @@ namespace System.Web.Routing
                        RouteData = routeData;
                }
 
+#if NET_4_0
+               public virtual HttpContextBase HttpContext { get; set; }
+               public virtual RouteData RouteData { get; set; }
+#else
                public HttpContextBase HttpContext { get; private set; }
-
                public RouteData RouteData { get; private set; }
+#endif
        }
 }
index 182120aa36681d3fd55dcd0740f1d0bf9fd34018..cd255453ec1d117df2ad23f27d50752fe21247c4 100644 (file)
@@ -99,11 +99,12 @@ namespace System.Web.Routing
                        if (values == null)
                                return null;
 
-                       if (Constraints != null)
-                               foreach (var p in Constraints)
+                       RouteValueDictionary constraints = Constraints;
+                       if (constraints != null)
+                               foreach (var p in constraints)
                                        if (!ProcessConstraint (httpContext, p.Value, p.Key, values, RouteDirection.IncomingRequest))
                                                return null;
-
+                       
                        var rd = new RouteData (this, RouteHandler);
                        RouteValueDictionary rdValues = rd.Values;
                        
@@ -171,7 +172,12 @@ namespace System.Web.Routing
                        bool ret = ProcessConstraintInternal (httpContext, this, constraint, parameterName, values, routeDirection, out invalidConstraint);
                        
                        if (invalidConstraint)
-                               throw new InvalidOperationException (String.Format ("Constraint parameter '{0}' must be either a string or an IRouteConstraint instance", parameterName));
+                               throw new InvalidOperationException (
+                                       String.Format (
+                                               "Constraint parameter '{0}' on the route with URL '{1}' must have a string value type or be a type which implements IRouteConstraint",
+                                               parameterName, Url
+                                       )
+                               );
 
                        return ret;
                }
index c140ffac213a23f44c8ca016c22e44165ce163e6..d656feb32576d787b1e6e434fa5dbdfb95ec1f67 100644 (file)
@@ -121,16 +121,22 @@ namespace System.Web.Routing
                        if (httpContext == null)
                                throw new ArgumentNullException ("httpContext");
 
+                       if (httpContext.Request == null)
+                               throw new ArgumentException ("The context does not contain any request data.", "httpContext");
+#if NET_4_0
+                       if (Count == 0)
+                               return null;
+#endif                 
                        if (!RouteExistingFiles) {
                                var path = httpContext.Request.AppRelativeCurrentExecutionFilePath;
                                VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
                                if (path != "~/" && vpp != null && (vpp.FileExists (path) || vpp.DirectoryExists (path)))
                                        return null;
                        }
-                       
+#if !NET_4_0
                        if (Count == 0)
                                return null;
-
+#endif
                        foreach (RouteBase rb in this) {
                                var rd = rb.GetRouteData (httpContext);
                                if (rd != null)
@@ -183,7 +189,54 @@ namespace System.Web.Routing
                {
                        return write_lock;
                }
+#if NET_4_0
+               public void Ignore (string url)
+               {
+                       Ignore (url, null);
+               }
+
+               public void Ignore (string url, object constraints)
+               {
+                       if (url == null)
+                               throw new ArgumentNullException ("url");
+
+                       Add (new Route (url, null, new RouteValueDictionary (constraints), new StopRoutingHandler ()));
+               }
+               
+               public Route MapPageRoute (string routeName, string routeUrl, string physicalFile)
+               {
+                       return MapPageRoute (routeName, routeUrl, physicalFile, true, null, null, null);
+               }
 
+               public Route MapPageRoute (string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess)
+               {
+                       return MapPageRoute (routeName, routeUrl, physicalFile, checkPhysicalUrlAccess, null, null, null);
+               }
+
+               public Route MapPageRoute (string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess,
+                                          RouteValueDictionary defaults)
+               {
+                       return MapPageRoute (routeName, routeUrl, physicalFile, checkPhysicalUrlAccess, defaults, null, null);
+               }
+
+               public Route MapPageRoute (string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess,
+                                          RouteValueDictionary defaults, RouteValueDictionary constraints)
+               {
+                       return MapPageRoute (routeName, routeUrl, physicalFile, checkPhysicalUrlAccess, defaults, constraints, null);
+               }
+
+               public Route MapPageRoute (string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess,
+                                          RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens)
+               {
+                       if (routeUrl == null)
+                               throw new ArgumentNullException ("routeUrl");
+                       
+                       var route = new Route (routeUrl, defaults, constraints, dataTokens, new PageRouteHandler (physicalFile, checkPhysicalUrlAccess));
+                       Add (routeName, route);
+
+                       return route;
+               }
+#endif
                protected override void InsertItem (int index, RouteBase item)
                {
                        // FIXME: what happens wrt its name?
index 8fe583d7f989622f6c1da6932bfd823c33755cde..7bd0b01ca01f9298b0e7f2d0be48d9e2c4bf2d89 100644 (file)
@@ -80,10 +80,13 @@ namespace System.Web.Routing
                        if (values == null)
                                return;
 
-                       foreach (var fi in values.GetType ().GetFields ())
-                               Add (fi.Name, fi.GetValue (values));
-                       foreach (var pi in values.GetType ().GetProperties ())
-                               Add (pi.Name, pi.GetValue (values, null));
+                       foreach (var pi in values.GetType ().GetProperties ()) {
+                               try {
+                                       Add (pi.Name, pi.GetValue (values, null));
+                               } catch {
+                                       // ignore
+                               }
+                       }
                }
 
                public int Count {
index 4191b75bf85a6ca0783c16137b0a7b935fc56b02..dabfac1416ee5acc535e62dd0a283fd06c1c7e46 100644 (file)
@@ -4,7 +4,7 @@
 // Author:
 //     Atsushi Enomoto <atsushi@ximian.com>
 //
-// Copyright (C) 2008 Novell Inc. http://novell.com
+// Copyright (C) 2008-2010 Novell Inc. http://novell.com
 //
 
 //
index 5efc7e624c1bc46109a1c79aa661cd986d2385dd..43a05efd883840950e646484417ad287c890c07c 100644 (file)
@@ -2,6 +2,7 @@ System.Web.Routing/AssertExtensions.cs
 System.Web.Routing/FakeHttpWorkerRequest.cs
 System.Web.Routing/HttpMethodConstraintTest.cs
 System.Web.Routing/KnownResponseHeader.cs
+System.Web.Routing/RequestContext.cs
 System.Web.Routing/RouteCollectionTest.cs
 System.Web.Routing/RouteDataTest.cs
 System.Web.Routing/RouteTest.cs
index fc087ce5860e6634b9bd8a318dcf8555276c61c3..5d59be0c2fbecfa592a256e34c0f45343f678b66 100644 (file)
@@ -81,7 +81,11 @@ namespace MonoTests.Common
 
         public override string GetRawUrl ()
         {
+#if NET_4_0
+           return "/GetRawUrl";
+#else
             return "GetRawUrl";
+#endif
         }
 
         public override string GetHttpVerbName ()
diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RequestContext.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RequestContext.cs
new file mode 100644 (file)
index 0000000..7e890be
--- /dev/null
@@ -0,0 +1,103 @@
+//
+// RequestContext.cs
+//
+// Authors:
+//     Marek Habersack <mhabersack@novell.com>
+//
+// Copyright (C) 2010 Novell Inc. http://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;
+using System.IO;
+using System.Text;
+using System.Web;
+using System.Web.Routing;
+
+using NUnit.Framework;
+
+namespace MonoTests.System.Web.Routing
+{
+       [TestFixture]
+       public class RequestContextTest
+       {
+#if NET_4_0
+               [Test]
+               public void DefaultConstructor ()
+               {
+                       var rc = new RequestContext ();
+
+                       Assert.AreEqual (null, rc.HttpContext, "#A1");
+                       Assert.AreEqual (null, rc.RouteData, "#A2");
+               }
+#endif
+               [Test]
+               public void Constructor_HttpContextBase_RouteData ()
+               {
+                       RequestContext rc;
+
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               rc = new RequestContext (null, new RouteData ());
+                       }, "#A1");
+
+                       var ctx = new HttpContextWrapper (new HttpContext (new HttpRequest ("filename", "http://localhost/filename", String.Empty), new HttpResponse (new StringWriter ())));
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               rc = new RequestContext (ctx, null);
+                       }, "#A2");
+               }
+
+               [Test]
+               public void HttpContext ()
+               {
+                       var ctx = new HttpContextWrapper (new HttpContext (new HttpRequest ("filename", "http://localhost/filename", String.Empty), new HttpResponse (new StringWriter ())));
+                       var rc = new RequestContext (ctx, new RouteData ());
+
+                       Assert.AreSame (ctx, rc.HttpContext, "#A1");
+#if NET_4_0
+                       ctx = new HttpContextWrapper (new HttpContext (new HttpRequest ("filename", "http://localhost/filename", String.Empty), new HttpResponse (new StringWriter ())));
+                       rc.HttpContext = ctx;
+                       Assert.AreSame (ctx, rc.HttpContext, "#A2");
+
+                       rc.HttpContext = null;
+                       Assert.IsNull (rc.HttpContext, "#A3");
+#endif
+               }
+
+               [Test]
+               public void RouteData ()
+               {
+                       var ctx = new HttpContextWrapper (new HttpContext (new HttpRequest ("filename", "http://localhost/filename", String.Empty), new HttpResponse (new StringWriter ())));
+                       var rd = new RouteData ();
+                       var rc = new RequestContext (ctx, rd);
+
+                       Assert.AreSame (rd, rc.RouteData, "#A1");
+#if NET_4_0
+                       rd = new RouteData ();
+                       rc.RouteData = rd;
+                       Assert.AreSame (rd, rc.RouteData, "#A2");
+
+                       rc.RouteData = null;
+                       Assert.IsNull (rc.RouteData, "#A3");
+#endif
+               }
+       }
+}
index 7631d86d29b4413f5f9c9abfa962b07a76f7f831..5310aafbbf1067b2cd029be90a3f731538039ac6 100644 (file)
@@ -105,6 +105,13 @@ namespace MonoTests.System.Web.Routing
                        Assert.IsNull(c ["x"]);
                }
 
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void GetRouteDataNoRequest ()
+               {
+                       new RouteCollection ().GetRouteData (new HttpContextStub (true));
+               }
+
                [Test]
                [ExpectedException (typeof (ArgumentNullException))]
                public void GetRouteDataNullArg ()
@@ -123,13 +130,18 @@ namespace MonoTests.System.Web.Routing
                public void GetRouteDataForNonExistent2 ()
                {
                        var rd = new RouteCollection () { RouteExistingFiles = true }.GetRouteData (new HttpContextStub2 (null, null, null));
-                       Assert.IsNull (rd);
+                       Assert.IsNull (rd, "#A1");
+#if NET_4_0
+                       rd = new RouteCollection ().GetRouteData (new HttpContextStub2 (null, null, null));
+                       Assert.IsNull (rd, "#A2");
+#else
                        try {
                                new RouteCollection ().GetRouteData (new HttpContextStub2 (null, null, null));
-                               Assert.Fail ("#1");
+                               Assert.Fail ("#A3");
                        } catch (NotImplementedException) {
                                // it should fail due to the NIE on AppRelativeCurrentExecutionFilePath.
                        }
+#endif
                }
 
                [Test]
@@ -579,5 +591,284 @@ namespace MonoTests.System.Web.Routing
                        
                        Assert.IsNotNull (rd, "#A1");
                }
+#if NET_4_0
+               [Test]
+               public void Ignore_String ()
+               {
+                       var c = new RouteCollection ();
+
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               c.Ignore (null);
+                       }, "#A1");
+
+                       c.Ignore ("{resource}.axd/{*pathInfo}");
+                       var hc = new HttpContextStub2 ("~/something.axd/pathinfo", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (3));
+                       var rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A1-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A1-2");
+                       Assert.AreEqual (typeof (StopRoutingHandler), rd.RouteHandler.GetType (), "#A1-3");
+                       Assert.IsTrue (rd.Route is Route, "#A1-4");
+                       Assert.IsNotNull (((Route) rd.Route).Constraints, "#A1-5");
+                       Assert.AreEqual (0, ((Route) rd.Route).Constraints.Count, "#A1-6");
+               }
+
+               [Test]
+               public void Ignore_String_Object ()
+               {
+                       var c = new RouteCollection ();
+
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               c.Ignore (null, new { allaspx = @".*\.aspx(/.*)?" });
+                       }, "#A1");
+
+                       c.Ignore ("{*allaspx}", new { allaspx = @".*\.aspx(/.*)?" });
+                       var hc = new HttpContextStub2 ("~/page.aspx", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (3));
+                       var rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A1-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A1-2");
+                       Assert.AreEqual (typeof (StopRoutingHandler), rd.RouteHandler.GetType (), "#A1-3");
+                       Assert.IsTrue (rd.Route is Route, "#A1-4");
+                       Assert.IsNotNull (((Route) rd.Route).Constraints, "#A1-5");
+                       Assert.AreEqual (1, ((Route) rd.Route).Constraints.Count, "#A1-6");
+                       Assert.AreEqual (@".*\.aspx(/.*)?", ((Route) rd.Route).Constraints ["allaspx"], "#A1-7");
+
+                       c = new RouteCollection ();
+                       c.Ignore ("{*allaspx}", "something invalid");
+
+                       AssertExtensions.Throws<InvalidOperationException> (() => {
+                               rd = c.GetRouteData (hc);
+                       }, "#A2");
+               }
+
+               [Test]
+               public void MapPageRoute_String_String_String ()
+               {
+                       var c = new RouteCollection ();
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url");
+                       var hc = new HttpContextStub2 ("~/some-url", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (3));
+                       var rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A1-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A1-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A1-3");
+
+                       c = new RouteCollection ();
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               c.MapPageRoute ("RouteName", null, "~/some-url");
+                       }, "#A2");
+
+                       c = new RouteCollection ();
+                       c.MapPageRoute ("RouteName", String.Empty, "~/some-url");
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNull (rd, "#A2");
+
+                       c = new RouteCollection ();
+                       // thrown by PageRouteHandler's constructor
+                       AssertExtensions.Throws<ArgumentException> (() => {
+                               c.MapPageRoute ("RouteName", "~/some-url", null);
+                       }, "#A3");
+               }
+
+               [Test]
+               public void MapPageRoute_String_String_String_Bool ()
+               {
+                       var c = new RouteCollection ();
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", true);
+                       var hc = new HttpContextStub2 ("~/some-url", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (3));
+                       var rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A1-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A1-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A1-3");
+                       Assert.IsTrue (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A1-4");
+
+                       c = new RouteCollection ();
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               c.MapPageRoute ("RouteName", null, "~/some-url", true);
+                       }, "#A2");
+
+                       c = new RouteCollection ();
+                       c.MapPageRoute ("RouteName", String.Empty, "~/some-url", true);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNull (rd, "#A2");
+
+                       c = new RouteCollection ();
+                       // thrown by PageRouteHandler's constructor
+                       AssertExtensions.Throws<ArgumentException> (() => {
+                               c.MapPageRoute ("RouteName", "~/some-url", null, true);
+                       }, "#A3");
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", false);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A4-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A4-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A4-3");
+                       Assert.IsFalse (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A4-4");
+               }
+
+               [Test]
+               public void MapPageRoute_String_String_String_Bool_RVD ()
+               {
+                       var c = new RouteCollection ();
+                       var defaults = new RouteValueDictionary ();
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", true, defaults);
+                       var hc = new HttpContextStub2 ("~/some-url", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (3));
+                       var rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A1-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A1-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A1-3");
+                       Assert.IsTrue (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A1-4");
+
+                       c = new RouteCollection ();
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               c.MapPageRoute ("RouteName", null, "~/some-url", true, defaults);
+                       }, "#A2");
+
+                       c = new RouteCollection ();
+                       c.MapPageRoute ("RouteName", String.Empty, "~/some-url", true, defaults);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNull (rd, "#A2");
+
+                       c = new RouteCollection ();
+                       // thrown by PageRouteHandler's constructor
+                       AssertExtensions.Throws<ArgumentException> (() => {
+                               c.MapPageRoute ("RouteName", "~/some-url", null, true, defaults);
+                       }, "#A3");
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", false, defaults);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A4-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A4-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A4-3");
+                       Assert.IsFalse (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A4-4");
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", false, null);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A4-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A4-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A4-3");
+                       Assert.IsFalse (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A4-4"); 
+               }
+
+               [Test]
+               public void MapPageRoute_String_String_String_Bool_RVD_RVD ()
+               {
+                       var c = new RouteCollection ();
+                       var defaults = new RouteValueDictionary ();
+                       var constraints = new RouteValueDictionary ();
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", true, defaults, constraints);
+                       var hc = new HttpContextStub2 ("~/some-url", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (3));
+                       var rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A1-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A1-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A1-3");
+                       Assert.IsTrue (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A1-4");
+
+                       c = new RouteCollection ();
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               c.MapPageRoute ("RouteName", null, "~/some-url", true, defaults, constraints);
+                       }, "#A2");
+
+                       c = new RouteCollection ();
+                       c.MapPageRoute ("RouteName", String.Empty, "~/some-url", true, defaults, constraints);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNull (rd, "#A2");
+
+                       c = new RouteCollection ();
+                       // thrown by PageRouteHandler's constructor
+                       AssertExtensions.Throws<ArgumentException> (() => {
+                               c.MapPageRoute ("RouteName", "~/some-url", null, true, defaults, constraints);
+                       }, "#A3");
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", false, defaults, constraints);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A4-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A4-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A4-3");
+                       Assert.IsFalse (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A4-4");
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", false, null, constraints);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A4-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A4-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A4-3");
+                       Assert.IsFalse (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A4-4");
+               }
+
+               [Test]
+               public void MapPageRoute_String_String_String_Bool_RVD_RVD_RVD ()
+               {
+                       var c = new RouteCollection ();
+                       var defaults = new RouteValueDictionary ();
+                       var constraints = new RouteValueDictionary ();
+                       var dataTokens = new RouteValueDictionary ();
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", true, defaults, constraints, dataTokens);
+                       var hc = new HttpContextStub2 ("~/some-url", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (3));
+                       var rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A1-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A1-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A1-3");
+                       Assert.IsTrue (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A1-4");
+
+                       c = new RouteCollection ();
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               c.MapPageRoute ("RouteName", null, "~/some-url", true, defaults, constraints, dataTokens);
+                       }, "#A2");
+
+                       c = new RouteCollection ();
+                       c.MapPageRoute ("RouteName", String.Empty, "~/some-url", true, defaults, constraints, dataTokens);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNull (rd, "#A2");
+
+                       c = new RouteCollection ();
+                       // thrown by PageRouteHandler's constructor
+                       AssertExtensions.Throws<ArgumentException> (() => {
+                               c.MapPageRoute ("RouteName", "~/some-url", null, true, defaults, constraints, dataTokens);
+                       }, "#A3");
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", false, defaults, constraints, dataTokens);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A4-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A4-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A4-3");
+                       Assert.IsFalse (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A4-4");
+
+                       c.MapPageRoute (null, "{foo}-{bar}", "~/some-url", false, null, constraints, dataTokens);
+                       rd = c.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#A4-1");
+                       Assert.IsNotNull (rd.RouteHandler, "#A4-2");
+                       Assert.AreEqual (typeof (PageRouteHandler), rd.RouteHandler.GetType (), "#A4-3");
+                       Assert.IsFalse (((PageRouteHandler) rd.RouteHandler).CheckPhysicalUrlAccess, "#A4-4");
+               }
+#endif
        }
 }
index 2be319e6c06ead1bcbdcd382acf5a6cba07f236a..8889d23a8b25482f368be52ef0fb1091f5a00367 100644 (file)
@@ -341,7 +341,7 @@ namespace MonoTests.System.Web.Routing
                        Assert.AreEqual (3, rd.Values.Count, "#4");
                        Assert.AreEqual ("test", rd.Values["action"], "#4-1");
                        Assert.AreEqual ("xml", rd.Values["type"], "#4-2");
-                       Assert.AreEqual ("1", rd.Values["page"], "#4-2");
+                       Assert.AreEqual ("1", rd.Values["page"], "#4-3");
                }
 
                [Test]
@@ -626,7 +626,19 @@ namespace MonoTests.System.Web.Routing
                        var hc = new HttpContextStub ("~/xyzxyzxyzxyzblah", String.Empty);
                        var rd = r.GetRouteData (hc);
 
+#if NET_4_0 || !DOTNET
+                       // When running on Mono this test succeeds - it was a bug in .NET routing for 3.5 which
+                       // we don't reproduce anymore.
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (3, rd.Values.Count, "#4");
+                       Assert.AreEqual ("xyz", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("xyz", rd.Values ["bar"], "#4-2");
+                       Assert.AreEqual ("blah", rd.Values ["baz"], "#4-3");
+#else
                        Assert.IsNull (rd, "#1");
+#endif
                }
 
                [Test]
@@ -718,6 +730,183 @@ namespace MonoTests.System.Web.Routing
                        Assert.AreEqual (0, rd.Values.Count, "#4");
                }
 
+               [Test]
+               public void GetRouteData34 ()
+               {
+                       var r = new Route ("{foo}xyz{bar}xyz{baz}", null);
+                       var hc = new HttpContextStub ("~/xyzxyzxyzxyzxyzxyzblah", String.Empty);
+                       var rd = r.GetRouteData (hc);
+
+#if NET_4_0 || !DOTNET
+                       // When running on Mono this test succeeds - it was a bug in .NET routing for 3.5 which
+                       // we don't reproduce anymore.
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (3, rd.Values.Count, "#4");
+                       Assert.AreEqual ("xyzxyzxyz", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("xyz", rd.Values ["bar"], "#4-2");
+                       Assert.AreEqual ("blah", rd.Values ["baz"], "#4-3");
+#else
+                       Assert.IsNull (rd, "#1");
+#endif
+               }
+
+               [Test]
+               public void GetRouteData35 ()
+               {
+                       var r = new Route ("{foo}xyz{bar}xyz{baz}", null);
+                       var hc = new HttpContextStub ("~/xyzxyzxyzdabxyzblah", String.Empty);
+                       var rd = r.GetRouteData (hc);
+
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (3, rd.Values.Count, "#4");
+                       Assert.AreEqual ("xyzxyz", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("dab", rd.Values ["bar"], "#4-2");
+                       Assert.AreEqual ("blah", rd.Values ["baz"], "#4-3");
+               }
+
+               [Test]
+               public void GetRouteData36 ()
+               {
+                       var r = new Route ("xyz{foo}xyz{bar}xyz{baz}", null);
+                       var hc = new HttpContextStub ("~/xyzxyzxyzdabxyzblah", String.Empty);
+                       var rd = r.GetRouteData (hc);
+
+#if NET_4_0 || !DOTNET
+                       // When running on Mono this test succeeds - it was a bug in .NET routing for 3.5 which
+                       // we don't reproduce anymore.
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (3, rd.Values.Count, "#4");
+                       Assert.AreEqual ("xyz", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("dab", rd.Values ["bar"], "#4-2");
+                       Assert.AreEqual ("blah", rd.Values ["baz"], "#4-3");
+#else
+                       Assert.IsNull (rd, "#1");
+#endif
+               }
+
+               [Test]
+               public void GetRouteData37 ()
+               {
+                       var r = new Route ("{foo}xyz{bar}xyz{baz}", null);
+                       var hc = new HttpContextStub ("~/xyzxyzxyzxyzxyz", String.Empty);
+                       var rd = r.GetRouteData (hc);
+
+#if NET_4_0 || !DOTNET
+                       // When running on Mono this test succeeds - it was a bug in .NET routing for 3.5 which
+                       // we don't reproduce anymore.
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (3, rd.Values.Count, "#4");
+                       Assert.AreEqual ("xyz", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("xyz", rd.Values ["bar"], "#4-2");
+                       Assert.AreEqual ("xyz", rd.Values ["baz"], "#4-3");
+#else
+                       Assert.IsNull (rd, "#1");
+#endif
+               }
+
+               [Test]
+               public void GetRouteData38 ()
+               {
+                       // {} matches and substitutes even at partial state ...
+                       var r = new Route ("{foo}/bar{baz}", null);
+                       var hc = new HttpContextStub ("~/x/bartest", String.Empty);
+                       var rd = r.GetRouteData (hc);
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (2, rd.Values.Count, "#4");
+                       Assert.AreEqual ("x", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("test", rd.Values ["baz"], "#4-2");
+               }
+
+               [Test]
+               public void GetRouteData39 ()
+               {
+                       // {} matches and substitutes even at partial state ...
+                       var r = new Route ("{foo}/bar{baz}", null);
+                       var hc = new HttpContextStub ("~/x/barte", String.Empty);
+                       var rd = r.GetRouteData (hc);
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (2, rd.Values.Count, "#4");
+                       Assert.AreEqual ("x", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("te", rd.Values ["baz"], "#4-2");
+               }
+
+               [Test]
+               public void GetRouteData40 ()
+               {
+                       // {} matches and substitutes even at partial state ...
+                       var r = new Route ("{foo}/bar{baz}", null);
+                       var hc = new HttpContextStub ("~/x/bartes", String.Empty);
+                       var rd = r.GetRouteData (hc);
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (2, rd.Values.Count, "#4");
+                       Assert.AreEqual ("x", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("tes", rd.Values ["baz"], "#4-2");
+               }
+
+               [Test]
+               public void GetRouteData41 ()
+               {
+                       // {} matches and substitutes even at partial state ...
+                       var r = new Route ("{foo}/bartes{baz}", null);
+                       var hc = new HttpContextStub ("~/x/bartest", String.Empty);
+                       var rd = r.GetRouteData (hc);
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (2, rd.Values.Count, "#4");
+                       Assert.AreEqual ("x", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("t", rd.Values ["baz"], "#4-2");
+               }
+
+               [Test]
+               public void GetRouteData42 ()
+               {
+                       // {} matches and substitutes even at partial state ...
+                       var r = new Route ("{foo}/bartes{baz}", null);
+                       var hc = new HttpContextStub ("~/x/bartest1", String.Empty);
+                       var rd = r.GetRouteData (hc);
+                       Assert.IsNotNull (rd, "#1");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (2, rd.Values.Count, "#4");
+                       Assert.AreEqual ("x", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("t1", rd.Values ["baz"], "#4-2");
+               }
+
+               [Test]
+               public void GetRouteData43 ()
+               {
+                       // {} matches and substitutes even at partial state ...
+                       var r = new Route ("{foo}-{bar}-{baz}", null);
+                       var hc = new HttpContextStub ("~/--", String.Empty);
+                       var rd = r.GetRouteData (hc);
+                       Assert.IsNull (rd, "#1");
+
+                       hc = new HttpContextStub ("~/1-2-3", String.Empty);
+                       rd = r.GetRouteData (hc);
+                       Assert.IsNotNull (rd, "#2");
+                       Assert.AreEqual (r, rd.Route, "#2");
+                       Assert.AreEqual (0, rd.DataTokens.Count, "#3");
+                       Assert.AreEqual (3, rd.Values.Count, "#4");
+                       Assert.AreEqual ("1", rd.Values ["foo"], "#4-1");
+                       Assert.AreEqual ("2", rd.Values ["bar"], "#4-2");
+                       Assert.AreEqual ("3", rd.Values ["baz"], "#4-2");
+               }
+
                [Test]
                [ExpectedException (typeof (ArgumentNullException))]
                public void GetVirtualPathNullContext ()
index 0a2a8d5a3b395cdd1754cf089cc13785c61c316d..817ae81973e892c81add39b6b86cdbd11adbb3db 100644 (file)
@@ -38,12 +38,19 @@ namespace MonoTests.System.Web.Routing
        class HttpContextStub : HttpContextBase
        {
                HttpRequestStub req;
+               bool returnNullRequest;
 
                public HttpContextStub ()
                        : this (null)
                {
                }
 
+               public HttpContextStub (bool returnNullRequest)
+                       : this (null)
+               {
+                       this.returnNullRequest = returnNullRequest;
+               }
+
                public HttpContextStub (string dummyRequestPath)
                        : this (dummyRequestPath, null)
                {
@@ -63,7 +70,12 @@ namespace MonoTests.System.Web.Routing
                }
 
                public override HttpRequestBase Request {
-                       get { return req != null ? req : base.Request; }
+                       get {
+                               if (returnNullRequest)
+                                       return null;
+
+                               return req != null ? req : base.Request; 
+                       }
                }
        }
 
@@ -152,6 +164,11 @@ namespace MonoTests.System.Web.Routing
                {
                        this.response = response;
                }
+
+               public void SetRequest (HttpRequestStub request)
+               {
+                       this.request = request;
+               }
        }
 
        class HttpRequestStub2 : HttpRequestStub
@@ -231,7 +248,79 @@ namespace MonoTests.System.Web.Routing
 
                public string RewrittenPath { get; set; }
        }
+#if NET_4_0
+       class FakeHttpRequestWrapper : HttpRequestWrapper
+       {
+               string requestUrl;
+               string path;
+               string appPath;
+
+               public FakeHttpRequestWrapper (string requestUrl, string path, string appPath)
+                       : base (new HttpRequest (path, "http://localhost/", String.Empty))
+               {
+                       this.requestUrl = requestUrl;
+                       this.path = path;
+                       this.appPath = appPath;
+               }
+
+               public override string AppRelativeCurrentExecutionFilePath
+               {
+                       get
+                       {
+                               return appPath;
+                       }
+               }
+       }
+
+       class HttpContextStub4 : HttpContextStub3
+       {
+               HttpRequestWrapper wrapper;
 
+               public override HttpRequestBase Request
+               {
+                       get
+                       {
+                               return wrapper;
+                       }
+               }
+
+               public HttpContextStub4 (string requestUrl, string path, string appPath, bool supportHandler)
+                       : base (requestUrl, path, appPath, supportHandler)
+               {
+                       wrapper = new FakeHttpRequestWrapper (requestUrl, path, appPath);
+               }
+       }
+
+       class HttpContextStub5 : HttpContextStub2
+       {
+               HttpRequestWrapper wrapper;
+
+               public override HttpRequestBase Request
+               {
+                       get
+                       {
+                               return wrapper;
+                       }
+               }
+
+               public HttpContextStub5 ()
+                       : this (null, null)
+               {
+               }
+
+               public HttpContextStub5 (string requestUrl, string path)
+                       : this (requestUrl, path, null)
+               {
+                       
+               }
+
+               public HttpContextStub5 (string requestUrl, string path, string appPath)
+                       : base (requestUrl, path, appPath)
+               {
+                       wrapper = new FakeHttpRequestWrapper (requestUrl, path, appPath);
+               }
+       }
+#endif
        public class MyStopRoutingHandler : StopRoutingHandler
        {
                public IHttpHandler CallGetHttpHandler (RequestContext rc)
index 09dcc563e9028bdefdd590f032d765e3ca0bd41d..7357f1a8edac4958b8de05b59d45731fca7b1547 100644 (file)
@@ -85,15 +85,17 @@ namespace MonoTests.System.Web.Routing
                        m.PostResolveRequestCache (new HttpContextStub2 ("~/foo/bar", null));
                }
 
+#if !NET_4_0
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
                public void PostResolveRequestCacheNullHttpHandler ()
                {
                        var m = new UrlRoutingModule ();
                        RouteTable.Routes.Add (new MyRoute ("foo/bar", new NullRouteHandler ()));
+
                        m.PostResolveRequestCache (new HttpContextStub2 ("~/foo/bar", null));
                }
-
+#endif
                [Test]
                [ExpectedException (typeof (NotImplementedException))]
                public void PostResolveRequestCacheNoPath ()
@@ -104,6 +106,7 @@ namespace MonoTests.System.Web.Routing
                        m.PostResolveRequestCache (new HttpContextStub2 ("~/foo/bar", null));
                }
 
+#if !NET_4_0
                [Test]
                public void PostResolveRequestCacheCallRewritePath ()
                {
@@ -132,16 +135,24 @@ namespace MonoTests.System.Web.Routing
                                Assert.AreEqual ("~/UrlRouting.axd", ex.Message, "#2");
                        }
                }
-
+#endif
                [Test]
                public void PostResolveRequestCache ()
                {
                        var m = new UrlRoutingModule ();
                        RouteTable.Routes.Add (new MyRoute ("{foo}/{bar}", new MyRouteHandler ()));
+#if NET_4_0
+                       var hc = new HttpContextStub4 ("~/x/y", "z", "apppath", false);
+#else
                        var hc = new HttpContextStub3 ("~/x/y", "z", "apppath", false);
+#endif
                        hc.SetResponse (new HttpResponseStub (2));
                        m.PostResolveRequestCache (hc);
+#if NET_4_0
+                       Assert.AreEqual (null, hc.RewrittenPath, "#1");
+#else
                        Assert.AreEqual ("~/UrlRouting.axd", hc.RewrittenPath, "#1");
+#endif
                        // it internally stores the handler 
                }
 
@@ -181,23 +192,40 @@ namespace MonoTests.System.Web.Routing
                {
                        var m = new UrlRoutingModule ();
                        RouteTable.Routes.Add (new MyRoute ("{foo}/{bar}", new MyRouteHandler ()));
+#if NET_4_0
+                       var hc = new HttpContextStub4 ("~/x/y", "z", "apppath", true);
+#else
                        var hc = new HttpContextStub3 ("~/x/y", "z", "apppath", true);
+#endif
                        hc.HttpHandler = new MyHttpHandler ();
                        hc.SetResponse (new HttpResponseStub (2));
                        m.PostResolveRequestCache (hc);
+#if NET_4_0
+                       Assert.AreEqual (null, hc.RewrittenPath, "#1");
+#else
                        Assert.AreEqual ("~/UrlRouting.axd", hc.RewrittenPath, "#1");
+#endif
                        // It tries to set Handler and causes NIE
                        m.PostMapRequestHandler (hc);
                }
 
                [Test]
+#if !NET_4_0
                [ExpectedException (typeof (ApplicationException))]
+#endif
                public void Pipeline3 ()
                {
                        var m = new UrlRoutingModule ();
                        RouteTable.Routes.Add (new MyRoute ("{foo}/{bar}", new MyRouteHandler ()));
+#if NET_4_0
+                       var hc = new HttpContextStub5 ("~/x/y", String.Empty, "apppath");
+#else
                        var hc = new HttpContextStub2 ("~/x/y", String.Empty, "apppath");
+#endif
                        hc.SetResponse (new HttpResponseStub (2));
+#if NET_4_0
+                       Assert.IsNull (m.RouteCollection.GetRouteData (hc), "#0");
+#else
                        Assert.IsNotNull (m.RouteCollection.GetRouteData (hc), "#0");
                        m.PostResolveRequestCache (hc);
                        try {
@@ -206,6 +234,7 @@ namespace MonoTests.System.Web.Routing
                        } catch (ApplicationException ex) {
                                Assert.AreEqual ("~/UrlRouting.axd", ex.Message, "#2");
                        }
+#endif
                }
        }
 }
index 1dbb246f3b1bce3320426be0a85a7900d725dbf4..4beb9734880a09969d3cd13ffe42f07ac4741c0a 100644 (file)
@@ -52,6 +52,9 @@ namespace System.Web.Routing
 
                public PageRouteHandler (string virtualPath, bool checkPhysicalUrlAccess)
                {
+                       if (String.IsNullOrEmpty (virtualPath) || !virtualPath.StartsWith ("~/"))
+                               throw new ArgumentException ("VirtualPath must be a non empty string starting with ~/", "virtualPath");
+                       
                        VirtualPath = virtualPath;
                        CheckPhysicalUrlAccess = checkPhysicalUrlAccess;
                }