From bcf40c740d2311e28da489d3e61913ac060a728d Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Tue, 6 Nov 2018 11:23:59 +1300 Subject: [PATCH 1/4] Implicitly execute matched endpoint at the end of middleware pipeline --- .../Internal/ApplicationBuilder.cs | 7 ++ .../Internal/ApplicationBuilderTests.cs | 66 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs b/src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs index d0b6b6f6..0d56e731 100644 --- a/src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs +++ b/src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs @@ -81,6 +81,13 @@ public RequestDelegate Build() { RequestDelegate app = context => { + // Implicitly execute matched endpoint at the end of the pipeline instead of returning 404 + var endpointRequestDelegate = context.Features.Get()?.Endpoint?.RequestDelegate; + if (endpointRequestDelegate != null) + { + return endpointRequestDelegate(context); + } + context.Response.StatusCode = 404; return Task.CompletedTask; }; diff --git a/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs b/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs index e1336c82..537f8133 100644 --- a/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs +++ b/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs @@ -1,7 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; using Xunit; namespace Microsoft.AspNetCore.Builder.Internal @@ -20,6 +22,65 @@ public void BuildReturnsCallableDelegate() Assert.Equal(404, httpContext.Response.StatusCode); } + [Fact] + public void BuildImplicitlyCallsMatchedEndpointAsLastStep() + { + var builder = new ApplicationBuilder(null); + var app = builder.Build(); + + var endpointCalled = false; + var endpoint = new Endpoint( + context => + { + endpointCalled = true; + return Task.CompletedTask; + }, + EndpointMetadataCollection.Empty, + "Test endpoint"); + + var httpContext = new DefaultHttpContext(); + httpContext.Features.Set(new EndpointFeature + { + Endpoint = endpoint + }); + + app.Invoke(httpContext); + + Assert.True(endpointCalled); + } + + [Fact] + public void BuildDoesNotCallMatchedEndpointWhenTerminated() + { + var builder = new ApplicationBuilder(null); + builder.Use((context, next) => + { + // Do not call next + return Task.CompletedTask; + }); + var app = builder.Build(); + + var endpointCalled = false; + var endpoint = new Endpoint( + context => + { + endpointCalled = true; + return Task.CompletedTask; + }, + EndpointMetadataCollection.Empty, + "Test endpoint"); + + var httpContext = new DefaultHttpContext(); + httpContext.Features.Set(new EndpointFeature + { + Endpoint = endpoint + }); + + app.Invoke(httpContext); + + Assert.False(endpointCalled); + } + [Fact] public void PropertiesDictionaryIsDistinctAfterNew() { @@ -31,5 +92,10 @@ public void PropertiesDictionaryIsDistinctAfterNew() Assert.Equal("value1", builder1.Properties["test"]); } + + private class EndpointFeature : IEndpointFeature + { + public Endpoint Endpoint { get; set; } + } } } \ No newline at end of file From 3bc1fc8d2d5660d876fb12f0cd89276787568cf2 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Wed, 7 Nov 2018 12:28:10 +1300 Subject: [PATCH 2/4] Use extension method --- src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs b/src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs index 0d56e731..291ccc38 100644 --- a/src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs +++ b/src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs @@ -82,7 +82,7 @@ public RequestDelegate Build() RequestDelegate app = context => { // Implicitly execute matched endpoint at the end of the pipeline instead of returning 404 - var endpointRequestDelegate = context.Features.Get()?.Endpoint?.RequestDelegate; + var endpointRequestDelegate = context.GetEndpoint()?.RequestDelegate; if (endpointRequestDelegate != null) { return endpointRequestDelegate(context); From 7a5238c5cd2ceccc3670032eec20379d0b642dae Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Wed, 7 Nov 2018 12:30:37 +1300 Subject: [PATCH 3/4] Update tests --- .../Internal/ApplicationBuilderTests.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs b/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs index 537f8133..be1e2b7d 100644 --- a/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs +++ b/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs @@ -39,10 +39,7 @@ public void BuildImplicitlyCallsMatchedEndpointAsLastStep() "Test endpoint"); var httpContext = new DefaultHttpContext(); - httpContext.Features.Set(new EndpointFeature - { - Endpoint = endpoint - }); + httpContext.SetEndpoint(endpoint); app.Invoke(httpContext); @@ -71,10 +68,7 @@ public void BuildDoesNotCallMatchedEndpointWhenTerminated() "Test endpoint"); var httpContext = new DefaultHttpContext(); - httpContext.Features.Set(new EndpointFeature - { - Endpoint = endpoint - }); + httpContext.SetEndpoint(endpoint); app.Invoke(httpContext); From acc83c007ef067586bd855cf0a125c20f565fc6d Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Wed, 7 Nov 2018 12:31:34 +1300 Subject: [PATCH 4/4] Remove unused feature --- .../Internal/ApplicationBuilderTests.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs b/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs index be1e2b7d..cee2042a 100644 --- a/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs +++ b/test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs @@ -86,10 +86,5 @@ public void PropertiesDictionaryIsDistinctAfterNew() Assert.Equal("value1", builder1.Properties["test"]); } - - private class EndpointFeature : IEndpointFeature - { - public Endpoint Endpoint { get; set; } - } } } \ No newline at end of file