From 78b46768d7eab55dc90361b42fa4372ce2256134 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 7 Aug 2019 09:49:27 -0700 Subject: [PATCH] Lazyily initialize Https port in HttpsRedirectionMiddleware --- .../src/HttpsRedirectionMiddleware.cs | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs b/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs index 1e860a0e87..021a030e17 100644 --- a/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs +++ b/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// 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; @@ -15,9 +15,10 @@ namespace Microsoft.AspNetCore.HttpsPolicy { public class HttpsRedirectionMiddleware { + private const int PortNotFound = -1; + private readonly RequestDelegate _next; - private bool _portEvaluated = false; - private int? _httpsPort; + private readonly Lazy _httpsPort; private readonly int _statusCode; private readonly IServerAddressesFeature _serverAddressesFeature; @@ -42,8 +43,14 @@ namespace Microsoft.AspNetCore.HttpsPolicy throw new ArgumentNullException(nameof(options)); } var httpsRedirectionOptions = options.Value; - _httpsPort = httpsRedirectionOptions.HttpsPort; - _portEvaluated = _httpsPort.HasValue; + if (httpsRedirectionOptions.HttpsPort.HasValue) + { + _httpsPort = new Lazy(() => httpsRedirectionOptions.HttpsPort.Value); + } + else + { + _httpsPort = new Lazy(TryGetHttpsPort); + } _statusCode = httpsRedirectionOptions.RedirectStatusCode; _logger = loggerFactory.CreateLogger(); } @@ -70,7 +77,13 @@ namespace Microsoft.AspNetCore.HttpsPolicy /// public Task Invoke(HttpContext context) { - if (context.Request.IsHttps || !TryGetHttpsPort(out var port)) + if (context.Request.IsHttps) + { + return _next(context); + } + + var port = _httpsPort.Value; + if (port == PortNotFound) { return _next(context); } @@ -101,7 +114,8 @@ namespace Microsoft.AspNetCore.HttpsPolicy return Task.CompletedTask; } - private bool TryGetHttpsPort(out int port) + // Returns PortNotFound (-1) if we were unable to determine the port. + private int TryGetHttpsPort() { // The IServerAddressesFeature will not be ready until the middleware is Invoked, // Order for finding the HTTPS port: @@ -109,59 +123,47 @@ namespace Microsoft.AspNetCore.HttpsPolicy // 2. HTTPS_PORT environment variable // 3. IServerAddressesFeature // 4. Fail if not set - - port = -1; - - if (_portEvaluated) + var nullablePort = _config.GetValue("HTTPS_PORT"); + if (nullablePort.HasValue) { - port = _httpsPort ?? port; - return _httpsPort.HasValue; - } - _portEvaluated = true; - - _httpsPort = _config.GetValue("HTTPS_PORT"); - if (_httpsPort.HasValue) - { - port = _httpsPort.Value; + var port = nullablePort.Value; _logger.PortLoadedFromConfig(port); - return true; + return port; } if (_serverAddressesFeature == null) { _logger.FailedToDeterminePort(); - return false; + return PortNotFound; } - int? httpsPort = null; foreach (var address in _serverAddressesFeature.Addresses) { var bindingAddress = BindingAddress.Parse(address); if (bindingAddress.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)) { // If we find multiple different https ports specified, throw - if (httpsPort.HasValue && httpsPort != bindingAddress.Port) + if (nullablePort.HasValue && nullablePort != bindingAddress.Port) { _logger.FailedMultiplePorts(); - return false; + return PortNotFound; } else { - httpsPort = bindingAddress.Port; + nullablePort = bindingAddress.Port; } } } - if (httpsPort.HasValue) + if (nullablePort.HasValue) { - _httpsPort = httpsPort; - port = _httpsPort.Value; + var port = nullablePort.Value; _logger.PortFromServer(port); - return true; + return port; } _logger.FailedToDeterminePort(); - return false; + return PortNotFound; } } }