diff --git a/src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs b/src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs index e3d411e087..d664fa5ee0 100644 --- a/src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs +++ b/src/Servers/Kestrel/Core/src/ListenOptionsHttpsExtensions.cs @@ -216,15 +216,15 @@ namespace Microsoft.AspNetCore.Hosting { var loggerFactory = listenOptions.KestrelServerOptions?.ApplicationServices.GetRequiredService() ?? NullLoggerFactory.Instance; - // Set the list of protocols from listen options - httpsOptions.HttpProtocols = listenOptions.Protocols; listenOptions.IsTls = true; - listenOptions.Use(next => { + // Set the list of protocols from listen options + httpsOptions.HttpProtocols = listenOptions.Protocols; var middleware = new HttpsConnectionMiddleware(next, httpsOptions, loggerFactory); return middleware.OnConnectionAsync; }); + return listenOptions; } } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs index 70ee2b30ad..45e21934be 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs @@ -589,6 +589,41 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests Assert.Equal(CoreStrings.FormatInvalidServerCertificateEku(cert.Thumbprint), ex.Message); } + [ConditionalTheory] + [InlineData(HttpProtocols.Http1)] + [InlineData(HttpProtocols.Http2)] + [InlineData(HttpProtocols.Http1AndHttp2)] + [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "Missing SslStream ALPN support: https://github.com/dotnet/corefx/issues/30492")] + [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win81)] + public async Task ListenOptionsProtolsCanBeSetAfterUseHttps(HttpProtocols httpProtocols) + { + void ConfigureListenOptions(ListenOptions listenOptions) + { + listenOptions.UseHttps(_x509Certificate2); + listenOptions.Protocols = httpProtocols; + } + + await using var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions); + using var connection = server.CreateConnection(); + + var sslOptions = new SslClientAuthenticationOptions + { + TargetHost = "localhost", + EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11, + ApplicationProtocols = new List { SslApplicationProtocol.Http11, SslApplicationProtocol.Http2 }, + }; + + using var stream = OpenSslStream(connection.Stream); + await stream.AuthenticateAsClientAsync(sslOptions); + + Assert.Equal( + httpProtocols.HasFlag(HttpProtocols.Http2) ? + SslApplicationProtocol.Http2 : + SslApplicationProtocol.Http11, + stream.NegotiatedApplicationProtocol); + } + private static async Task App(HttpContext httpContext) { var request = httpContext.Request;