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:
parent
457cd92bca
commit
0c3f6497db
|
|
@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
{
|
{
|
||||||
if (current.ConstrainedCatchAlls == null)
|
if (current.ConstrainedCatchAlls == null)
|
||||||
{
|
{
|
||||||
current.ConstrainedCatchAlls = new UrlMatchingNode(length: i + 1);
|
current.ConstrainedCatchAlls = new UrlMatchingNode(length: i + 1) { IsCatchAll = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
current = current.ConstrainedCatchAlls;
|
current = current.ConstrainedCatchAlls;
|
||||||
|
|
@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
{
|
{
|
||||||
if (current.CatchAlls == null)
|
if (current.CatchAlls == null)
|
||||||
{
|
{
|
||||||
current.CatchAlls = new UrlMatchingNode(length: i + 1);
|
current.CatchAlls = new UrlMatchingNode(length: i + 1) { IsCatchAll = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
current = current.CatchAlls;
|
current = current.CatchAlls;
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,17 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
while (_stack.Count > 0)
|
while (_stack.Count > 0)
|
||||||
{
|
{
|
||||||
var next = _stack.Pop();
|
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--;
|
_segmentIndex--;
|
||||||
if (next.Matches.Count > 0)
|
if (next.Matches.Count > 0)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
|
|
||||||
public int Length { get; }
|
public int Length { get; }
|
||||||
|
|
||||||
|
public bool IsCatchAll { get; set; }
|
||||||
|
|
||||||
// These entries are sorted by precedence then template
|
// These entries are sorted by precedence then template
|
||||||
public List<TreeRouteMatchingEntry> Matches { get; }
|
public List<TreeRouteMatchingEntry> Matches { get; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,39 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
Assert.Equal(expectedRouteGroup, context.RouteData.Values["test_route_group"]);
|
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]
|
[Theory]
|
||||||
[InlineData("template/5")]
|
[InlineData("template/5")]
|
||||||
[InlineData("template/{parameter:int}")]
|
[InlineData("template/{parameter:int}")]
|
||||||
|
|
@ -761,7 +794,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
IEnumerable<TreeRouteLinkGenerationEntry> namedEntries)
|
IEnumerable<TreeRouteLinkGenerationEntry> namedEntries)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var expectedLink =
|
var expectedLink =
|
||||||
namedEntries.First().Template.Parameters.Any() ? "/template/5" : "/template";
|
namedEntries.First().Template.Parameters.Any() ? "/template/5" : "/template";
|
||||||
|
|
||||||
var matchingEntries = Enumerable.Empty<TreeRouteMatchingEntry>();
|
var matchingEntries = Enumerable.Empty<TreeRouteMatchingEntry>();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue