From 73821983567625b2eef5cf239db034ef81dd5dc1 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 31 Mar 2018 07:29:35 -0700 Subject: [PATCH] Copy connection middleware when using ListenLocalHost (#2447) - Connection middleware got removed during Clone when using ListenLocalhost --- src/Kestrel.Core/ListenOptions.cs | 8 ++--- src/Kestrel.Core/LocalhostListenOptions.cs | 4 ++- test/Kestrel.Core.Tests/ListenOptionsTests.cs | 34 +++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/Kestrel.Core/ListenOptions.cs b/src/Kestrel.Core/ListenOptions.cs index bdef463d60..dfc15ad1ae 100644 --- a/src/Kestrel.Core/ListenOptions.cs +++ b/src/Kestrel.Core/ListenOptions.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core private FileHandleType _handleType; private HttpProtocols _protocols = HttpProtocols.Http1; internal bool _isHttp2Supported; - private readonly List> _components = new List>(); + internal readonly List> _middleware = new List>(); internal ListenOptions(IPEndPoint endPoint) { @@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core public IConnectionBuilder Use(Func middleware) { - _components.Add(middleware); + _middleware.Add(middleware); return this; } @@ -192,9 +192,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core return Task.CompletedTask; }; - for (int i = _components.Count - 1; i >= 0; i--) + for (int i = _middleware.Count - 1; i >= 0; i--) { - var component = _components[i]; + var component = _middleware[i]; app = component(app); } diff --git a/src/Kestrel.Core/LocalhostListenOptions.cs b/src/Kestrel.Core/LocalhostListenOptions.cs index 39c49abbfc..ee28dce63e 100644 --- a/src/Kestrel.Core/LocalhostListenOptions.cs +++ b/src/Kestrel.Core/LocalhostListenOptions.cs @@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core } // used for cloning to two IPEndpoints - private ListenOptions Clone(IPAddress address) + internal ListenOptions Clone(IPAddress address) { var options = new ListenOptions(new IPEndPoint(address, IPEndPoint.Port)) { @@ -81,6 +81,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core NoDelay = NoDelay, Protocols = Protocols, }; + + options._middleware.AddRange(_middleware); options.ConnectionAdapters.AddRange(ConnectionAdapters); return options; } diff --git a/test/Kestrel.Core.Tests/ListenOptionsTests.cs b/test/Kestrel.Core.Tests/ListenOptionsTests.cs index 808d4e6cdd..6b4f792f13 100644 --- a/test/Kestrel.Core.Tests/ListenOptionsTests.cs +++ b/test/Kestrel.Core.Tests/ListenOptionsTests.cs @@ -3,6 +3,10 @@ using System; using System.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal; +using Microsoft.AspNetCore.Testing; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests @@ -25,5 +29,35 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests ex = Assert.Throws(() => listenOptions.Protocols = HttpProtocols.Http2); Assert.Equal(CoreStrings.Http2NotSupported, ex.Message); } + + [Fact] + public void LocalHostListenOptionsClonesConnectionMiddleware() + { + var localhostListenOptions = new LocalhostListenOptions(1004); + localhostListenOptions.ConnectionAdapters.Add(new PassThroughConnectionAdapter()); + var serviceProvider = new ServiceCollection().BuildServiceProvider(); + localhostListenOptions.KestrelServerOptions = new KestrelServerOptions() + { + ApplicationServices = serviceProvider + }; + var middlewareRan = false; + localhostListenOptions.Use(next => + { + middlewareRan = true; + return context => Task.CompletedTask; + }); + + var clone = localhostListenOptions.Clone(IPAddress.IPv6Loopback); + var app = clone.Build(); + + // Execute the delegate + app(null); + + Assert.True(middlewareRan); + Assert.NotNull(clone.KestrelServerOptions); + Assert.NotNull(serviceProvider); + Assert.Same(serviceProvider, clone.ApplicationServices); + Assert.Single(clone.ConnectionAdapters); + } } }