Fixes issue of request path segment length greater than the wildcard template route

Fixes https://github.com/aspnet/Mvc/issues/4256
This commit is contained in:
Kiran Challa 2016-03-22 17:00:24 -07:00
parent 457cd92bca
commit 0c3f6497db
4 changed files with 49 additions and 4 deletions

View File

@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
{
if (current.ConstrainedCatchAlls == null)
{
current.ConstrainedCatchAlls = new UrlMatchingNode(length: i + 1);
current.ConstrainedCatchAlls = new UrlMatchingNode(length: i + 1) { IsCatchAll = true };
}
current = current.ConstrainedCatchAlls;
@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
{
if (current.CatchAlls == null)
{
current.CatchAlls = new UrlMatchingNode(length: i + 1);
current.CatchAlls = new UrlMatchingNode(length: i + 1) { IsCatchAll = true };
}
current = current.CatchAlls;

View File

@ -249,7 +249,17 @@ namespace Microsoft.AspNetCore.Routing.Tree
while (_stack.Count > 0)
{
var next = _stack.Pop();
if (++_segmentIndex >= _tokenizer.Count)
// In case of wild card segment, the request path segment length can be greater
// Example:
// Template: a/{*path}
// Request Url: a/b/c/d
if (next.IsCatchAll && next.Matches.Count > 0)
{
Current = next;
return true;
}
else if (++_segmentIndex >= _tokenizer.Count)
{
_segmentIndex--;
if (next.Matches.Count > 0)

View File

@ -18,6 +18,8 @@ namespace Microsoft.AspNetCore.Routing.Tree
public int Length { get; }
public bool IsCatchAll { get; set; }
// These entries are sorted by precedence then template
public List<TreeRouteMatchingEntry> Matches { get; }

View File

@ -119,6 +119,39 @@ namespace Microsoft.AspNetCore.Routing.Tree
Assert.Equal(expectedRouteGroup, context.RouteData.Values["test_route_group"]);
}
[Theory]
[InlineData("{*path}", "/a", "a")]
[InlineData("{*path}", "/a/b/c", "a/b/c")]
[InlineData("a/{*path}", "/a/b", "b")]
[InlineData("a/{*path}", "/a/b/c/d", "b/c/d")]
[InlineData("a/{*path:regex(10/20/30)}", "/a/10/20/30", "10/20/30")]
public async Task TreeRouter_RouteAsync_MatchesWildCard_ForLargerPathSegments(
string template,
string requestPath,
string expectedResult)
{
// Arrange
var next = new Mock<IRouter>();
next
.Setup(r => r.RouteAsync(It.IsAny<RouteContext>()))
.Callback<RouteContext>(c => c.Handler = NullHandler)
.Returns(Task.FromResult(true))
.Verifiable();
var firstRoute = CreateMatchingEntry(next.Object, template, order: 0);
var matchingRoutes = new[] { firstRoute };
var linkGenerationEntries = Enumerable.Empty<TreeRouteLinkGenerationEntry>();
var attributeRoute = CreateAttributeRoute(next.Object, matchingRoutes, linkGenerationEntries);
var context = CreateRouteContext(requestPath);
// Act
await attributeRoute.RouteAsync(context);
// Assert
Assert.NotNull(context.Handler);
Assert.Equal(expectedResult, context.RouteData.Values["path"]);
}
[Theory]
[InlineData("template/5")]
[InlineData("template/{parameter:int}")]
@ -761,7 +794,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
IEnumerable<TreeRouteLinkGenerationEntry> namedEntries)
{
// Arrange
var expectedLink =
var expectedLink =
namedEntries.First().Template.Parameters.Any() ? "/template/5" : "/template";
var matchingEntries = Enumerable.Empty<TreeRouteMatchingEntry>();