Wait until after UseHttps() to read HttpProtocols (#13202)

- This makes it so ListenOptions.HttpProtocols can be set after
  ListenOptions.UseHttps() is called and still function.
This commit is contained in:
Stephen Halter 2019-08-19 10:58:49 -07:00 committed by GitHub
parent e55f47c05a
commit ff5c200345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 3 deletions

View File

@ -216,15 +216,15 @@ namespace Microsoft.AspNetCore.Hosting
{ {
var loggerFactory = listenOptions.KestrelServerOptions?.ApplicationServices.GetRequiredService<ILoggerFactory>() ?? NullLoggerFactory.Instance; var loggerFactory = listenOptions.KestrelServerOptions?.ApplicationServices.GetRequiredService<ILoggerFactory>() ?? NullLoggerFactory.Instance;
// Set the list of protocols from listen options
httpsOptions.HttpProtocols = listenOptions.Protocols;
listenOptions.IsTls = true; listenOptions.IsTls = true;
listenOptions.Use(next => listenOptions.Use(next =>
{ {
// Set the list of protocols from listen options
httpsOptions.HttpProtocols = listenOptions.Protocols;
var middleware = new HttpsConnectionMiddleware(next, httpsOptions, loggerFactory); var middleware = new HttpsConnectionMiddleware(next, httpsOptions, loggerFactory);
return middleware.OnConnectionAsync; return middleware.OnConnectionAsync;
}); });
return listenOptions; return listenOptions;
} }
} }

View File

@ -589,6 +589,41 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
Assert.Equal(CoreStrings.FormatInvalidServerCertificateEku(cert.Thumbprint), ex.Message); 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> { 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) private static async Task App(HttpContext httpContext)
{ {
var request = httpContext.Request; var request = httpContext.Request;