@@ -31,9 +31,10 @@ internal class HttpsConnectionMiddleware
3131 {
3232 private const string EnableWindows81Http2 = "Microsoft.AspNetCore.Server.Kestrel.EnableWindows81Http2" ;
3333
34- internal static readonly TimeSpan DefaultHandshakeTimeout = TimeSpan . FromSeconds ( 10 ) ;
34+ private static readonly bool _isWindowsVersionIncompatible = IsWindowsVersionIncompatible ( ) ;
3535
3636 private readonly ConnectionDelegate _next ;
37+ private readonly TimeSpan _handshakeTimeout ;
3738 private readonly ILogger _logger ;
3839 private readonly Func < Stream , SslStream > _sslStreamFactory ;
3940
@@ -43,7 +44,6 @@ internal class HttpsConnectionMiddleware
4344 private readonly Func < ConnectionContext , string , X509Certificate2 > _serverCertificateSelector ;
4445
4546 // The following fields are only set by ServerOptionsSelectionCallback ctor.
46- // If we ever expose this via a public API, we should really create a delegate type.
4747 private readonly HttpsOptionsCallback _httpsOptionsCallback ;
4848 private readonly object _httpsOptionsCallbackState ;
4949
@@ -59,12 +59,13 @@ public HttpsConnectionMiddleware(ConnectionDelegate next, HttpsConnectionAdapter
5959 throw new ArgumentNullException ( nameof ( options ) ) ;
6060 }
6161
62- _options = options ;
62+ _next = next ;
63+ _handshakeTimeout = options . HandshakeTimeout ;
6364 _logger = loggerFactory . CreateLogger < HttpsConnectionMiddleware > ( ) ;
6465
66+ _options = options ;
6567 _options . HttpProtocols = ValidateAndNormalizeHttpProtocols ( _options . HttpProtocols , _logger ) ;
6668
67- _next = next ;
6869 // capture the certificate now so it can't be switched after validation
6970 _serverCertificate = options . ServerCertificate ;
7071 _serverCertificateSelector = options . ServerCertificateSelector ;
@@ -94,10 +95,13 @@ internal HttpsConnectionMiddleware(
9495 ConnectionDelegate next ,
9596 HttpsOptionsCallback httpsOptionsCallback ,
9697 object httpsOptionsCallbackState ,
98+ TimeSpan handshakeTimeout ,
9799 ILoggerFactory loggerFactory )
98100 {
99101 _next = next ;
102+ _handshakeTimeout = handshakeTimeout ;
100103 _logger = loggerFactory . CreateLogger < HttpsConnectionMiddleware > ( ) ;
104+
101105 _httpsOptionsCallback = httpsOptionsCallback ;
102106 _httpsOptionsCallbackState = httpsOptionsCallbackState ;
103107 _sslStreamFactory = s => new SslStream ( s ) ;
@@ -122,7 +126,7 @@ public async Task OnConnectionAsync(ConnectionContext context)
122126
123127 try
124128 {
125- using var cancellationTokenSource = new CancellationTokenSource ( _options ? . HandshakeTimeout ?? DefaultHandshakeTimeout ) ;
129+ using var cancellationTokenSource = new CancellationTokenSource ( _handshakeTimeout ) ;
126130 if ( _httpsOptionsCallback is null )
127131 {
128132 await DoOptionsBasedHandshakeAsync ( context , sslStream , feature , cancellationTokenSource . Token ) ;
@@ -255,9 +259,6 @@ internal static void ConfigureAlpn(SslServerAuthenticationOptions serverOptions,
255259 }
256260 }
257261
258- private bool RemoteCertificateValidationCallback ( object sender , X509Certificate certificate , X509Chain chain , SslPolicyErrors sslPolicyErrors ) =>
259- RemoteCertificateValidationCallback ( _options . ClientCertificateMode , _options . ClientCertificateValidation , certificate , chain , sslPolicyErrors ) ;
260-
261262 internal static bool RemoteCertificateValidationCallback (
262263 ClientCertificateMode clientCertificateMode ,
263264 Func < X509Certificate2 , X509Chain , SslPolicyErrors , bool > clientCertificateValidation ,
@@ -295,6 +296,9 @@ internal static bool RemoteCertificateValidationCallback(
295296 return true ;
296297 }
297298
299+ private bool RemoteCertificateValidationCallback ( object sender , X509Certificate certificate , X509Chain chain , SslPolicyErrors sslPolicyErrors ) =>
300+ RemoteCertificateValidationCallback ( _options . ClientCertificateMode , _options . ClientCertificateValidation , certificate , chain , sslPolicyErrors ) ;
301+
298302 private SslDuplexPipe CreateSslDuplexPipe ( IDuplexPipe transport , MemoryPool < byte > memoryPool )
299303 {
300304 var inputPipeOptions = new StreamPipeReaderOptions
@@ -366,12 +370,12 @@ internal static HttpProtocols ValidateAndNormalizeHttpProtocols(HttpProtocols ht
366370 {
367371 throw new NotSupportedException ( CoreStrings . Http2NoTlsOsx ) ;
368372 }
369- else if ( IsWindowsVersionIncompatible ( ) )
373+ else if ( _isWindowsVersionIncompatible )
370374 {
371375 throw new NotSupportedException ( CoreStrings . Http2NoTlsWin81 ) ;
372376 }
373377 }
374- else if ( httpProtocols == HttpProtocols . Http1AndHttp2 && IsWindowsVersionIncompatible ( ) )
378+ else if ( httpProtocols == HttpProtocols . Http1AndHttp2 && _isWindowsVersionIncompatible )
375379 {
376380 logger . Http2DefaultCiphersInsufficient ( ) ;
377381 return HttpProtocols . Http1 ;
0 commit comments