From 0a876cece7b72b11e4e9bcedd9442ac29effdd22 Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Fri, 13 Apr 2018 15:55:42 -0700 Subject: [PATCH] Make https redirect no-op if no port is available #318 --- .../HttpsPolicySample.csproj | 3 +- .../Properties/launchSettings.json | 4 +- samples/HttpsPolicySample/Startup.cs | 6 + .../HttpsRedirectionMiddleware.cs | 65 +++++-- .../internal/HttpsLoggingExtensions.cs | 53 ++++++ .../HttpsPolicyTests.cs | 6 +- .../HttpsRedirectionMiddlewareTests.cs | 162 +++++++++++++++--- ...rosoft.AspNetCore.HttpsPolicy.Tests.csproj | 6 +- 8 files changed, 252 insertions(+), 53 deletions(-) create mode 100644 src/Microsoft.AspNetCore.HttpsPolicy/internal/HttpsLoggingExtensions.cs diff --git a/samples/HttpsPolicySample/HttpsPolicySample.csproj b/samples/HttpsPolicySample/HttpsPolicySample.csproj index 3ab7f8c7cb..fdfa716478 100644 --- a/samples/HttpsPolicySample/HttpsPolicySample.csproj +++ b/samples/HttpsPolicySample/HttpsPolicySample.csproj @@ -1,4 +1,4 @@ - + net461;netcoreapp2.0 @@ -8,6 +8,7 @@ + diff --git a/samples/HttpsPolicySample/Properties/launchSettings.json b/samples/HttpsPolicySample/Properties/launchSettings.json index fbffc1f457..a35390177b 100644 --- a/samples/HttpsPolicySample/Properties/launchSettings.json +++ b/samples/HttpsPolicySample/Properties/launchSettings.json @@ -21,7 +21,7 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "http://localhost:31895/" + "applicationUrl": "http://localhost:5000/" } } -} +} \ No newline at end of file diff --git a/samples/HttpsPolicySample/Startup.cs b/samples/HttpsPolicySample/Startup.cs index 1c9f11fcad..91888a01b4 100644 --- a/samples/HttpsPolicySample/Startup.cs +++ b/samples/HttpsPolicySample/Startup.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; namespace HttpsSample { @@ -62,6 +63,11 @@ namespace HttpsSample }); }) .UseContentRoot(Directory.GetCurrentDirectory()) // for the cert file + .ConfigureLogging(factory => + { + factory.SetMinimumLevel(LogLevel.Debug); + factory.AddConsole(); + }) .UseStartup() .Build(); diff --git a/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs b/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs index a4a9cc034d..192845f7db 100644 --- a/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs +++ b/src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs @@ -7,7 +7,9 @@ using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Http.Internal; +using Microsoft.AspNetCore.HttpsPolicy.Internal; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.Net.Http.Headers; @@ -16,11 +18,13 @@ namespace Microsoft.AspNetCore.HttpsPolicy public class HttpsRedirectionMiddleware { private readonly RequestDelegate _next; + private bool _portEvaluated = false; private int? _httpsPort; private readonly int _statusCode; private readonly IServerAddressesFeature _serverAddressesFeature; private readonly IConfiguration _config; + private readonly ILogger _logger; /// /// Initializes the HttpsRedirectionMiddleware @@ -28,7 +32,8 @@ namespace Microsoft.AspNetCore.HttpsPolicy /// /// /// - public HttpsRedirectionMiddleware(RequestDelegate next, IOptions options, IConfiguration config) + /// + public HttpsRedirectionMiddleware(RequestDelegate next, IOptions options, IConfiguration config, ILoggerFactory loggerFactory) { _next = next ?? throw new ArgumentNullException(nameof(next)); @@ -40,7 +45,9 @@ namespace Microsoft.AspNetCore.HttpsPolicy } var httpsRedirectionOptions = options.Value; _httpsPort = httpsRedirectionOptions.HttpsPort; + _portEvaluated = _httpsPort.HasValue; _statusCode = httpsRedirectionOptions.RedirectStatusCode; + _logger = loggerFactory.CreateLogger(); } /// @@ -49,9 +56,11 @@ namespace Microsoft.AspNetCore.HttpsPolicy /// /// /// + /// /// The - public HttpsRedirectionMiddleware(RequestDelegate next, IOptions options, IConfiguration config, IServerAddressesFeature serverAddressesFeature) - : this(next, options, config) + public HttpsRedirectionMiddleware(RequestDelegate next, IOptions options, IConfiguration config, ILoggerFactory loggerFactory, + IServerAddressesFeature serverAddressesFeature) + : this(next, options, config, loggerFactory) { _serverAddressesFeature = serverAddressesFeature ?? throw new ArgumentNullException(nameof(serverAddressesFeature)); } @@ -63,20 +72,15 @@ namespace Microsoft.AspNetCore.HttpsPolicy /// public Task Invoke(HttpContext context) { - if (context.Request.IsHttps) + if (context.Request.IsHttps || !TryGetHttpsPort(out var port)) { return _next(context); } - if (!_httpsPort.HasValue) - { - CheckForHttpsPorts(); - } - var host = context.Request.Host; - if (_httpsPort != 443) + if (port != 443) { - host = new HostString(host.Host, _httpsPort.Value); + host = new HostString(host.Host, port); } else { @@ -94,28 +98,41 @@ namespace Microsoft.AspNetCore.HttpsPolicy context.Response.StatusCode = _statusCode; context.Response.Headers[HeaderNames.Location] = redirectUrl; + _logger.RedirectingToHttps(redirectUrl); + return Task.CompletedTask; } - private void CheckForHttpsPorts() + private bool TryGetHttpsPort(out int port) { // The IServerAddressesFeature will not be ready until the middleware is Invoked, // Order for finding the HTTPS port: // 1. Set in the HttpsRedirectionOptions // 2. HTTPS_PORT environment variable // 3. IServerAddressesFeature - // 4. 443 (or not set) + // 4. Fail if not set + + port = -1; + + if (_portEvaluated) + { + port = _httpsPort ?? port; + return _httpsPort.HasValue; + } + _portEvaluated = true; _httpsPort = _config.GetValue("HTTPS_PORT"); if (_httpsPort.HasValue) { - return; + port = _httpsPort.Value; + _logger.PortLoadedFromConfig(port); + return true; } if (_serverAddressesFeature == null) { - _httpsPort = 443; - return; + _logger.FailedToDeterminePort(); + return false; } int? httpsPort = null; @@ -127,8 +144,8 @@ namespace Microsoft.AspNetCore.HttpsPolicy // If we find multiple different https ports specified, throw if (httpsPort.HasValue && httpsPort != bindingAddress.Port) { - throw new ArgumentException("Cannot determine the https port from IServerAddressesFeature, multiple values were found. " + - "Please set the desired port explicitly on HttpsRedirectionOptions.HttpsPort."); + _logger.FailedMultiplePorts(); + return false; } else { @@ -136,7 +153,17 @@ namespace Microsoft.AspNetCore.HttpsPolicy } } } - _httpsPort = httpsPort ?? 443; + + if (httpsPort.HasValue) + { + _httpsPort = httpsPort; + port = _httpsPort.Value; + _logger.PortFromServer(port); + return true; + } + + _logger.FailedToDeterminePort(); + return false; } } } diff --git a/src/Microsoft.AspNetCore.HttpsPolicy/internal/HttpsLoggingExtensions.cs b/src/Microsoft.AspNetCore.HttpsPolicy/internal/HttpsLoggingExtensions.cs new file mode 100644 index 0000000000..55e65dcbdd --- /dev/null +++ b/src/Microsoft.AspNetCore.HttpsPolicy/internal/HttpsLoggingExtensions.cs @@ -0,0 +1,53 @@ +// 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; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.HttpsPolicy.Internal +{ + internal static class HttpsLoggingExtensions + { + private static readonly Action _redirectingToHttps; + private static readonly Action _portLoadedFromConfig; + private static readonly Action _failedToDeterminePort; + private static readonly Action _failedMultiplePorts; + private static readonly Action _portFromServer; + + static HttpsLoggingExtensions() + { + _redirectingToHttps = LoggerMessage.Define(LogLevel.Debug, 1, "Redirecting to '{redirect}'."); + _portLoadedFromConfig = LoggerMessage.Define(LogLevel.Debug, 2, "Https port '{port}' loaded from configuration."); + _failedToDeterminePort = LoggerMessage.Define(LogLevel.Warning, 3, "Failed to determine the https port for redirect."); + _failedMultiplePorts = LoggerMessage.Define(LogLevel.Warning, 4, + "Cannot determine the https port from IServerAddressesFeature, multiple values were found. " + + "Please set the desired port explicitly on HttpsRedirectionOptions.HttpsPort."); + _portFromServer = LoggerMessage.Define(LogLevel.Debug, 5, "Https port '{httpsPort}' discovered from server endpoints."); + } + + public static void RedirectingToHttps(this ILogger logger, string redirect) + { + _redirectingToHttps(logger, redirect, null); + } + + public static void PortLoadedFromConfig(this ILogger logger, int port) + { + _portLoadedFromConfig(logger, port, null); + } + + public static void FailedToDeterminePort(this ILogger logger) + { + _failedToDeterminePort(logger, null); + } + + public static void FailedMultiplePorts(this ILogger logger) + { + _failedMultiplePorts(logger, null); + } + + public static void PortFromServer(this ILogger logger, int port) + { + _portFromServer(logger, port, null); + } + } +} diff --git a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsPolicyTests.cs b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsPolicyTests.cs index aa874fb8cd..2b9b3d3b49 100644 --- a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsPolicyTests.cs +++ b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsPolicyTests.cs @@ -21,12 +21,12 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests public class HttpsPolicyTests { [Theory] - [InlineData(302, null, 2592000, false, false, "max-age=2592000", "https://localhost/")] + [InlineData(302, 443, 2592000, false, false, "max-age=2592000", "https://localhost/")] [InlineData(301, 5050, 2592000, false, false, "max-age=2592000", "https://localhost:5050/")] [InlineData(301, 443, 2592000, false, false, "max-age=2592000", "https://localhost/")] [InlineData(301, 443, 2592000, true, false, "max-age=2592000; includeSubDomains", "https://localhost/")] [InlineData(301, 443, 2592000, false, true, "max-age=2592000; preload", "https://localhost/")] - [InlineData(301, null, 2592000, true, true, "max-age=2592000; includeSubDomains; preload", "https://localhost/")] + [InlineData(301, 443, 2592000, true, true, "max-age=2592000; includeSubDomains; preload", "https://localhost/")] [InlineData(302, 5050, 2592000, true, true, "max-age=2592000; includeSubDomains; preload", "https://localhost:5050/")] public async Task SetsBothHstsAndHttpsRedirection_RedirectOnFirstRequest_HstsOnSecondRequest(int statusCode, int? tlsPort, int maxAge, bool includeSubDomains, bool preload, string expectedHstsHeader, string expectedUrl) { @@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests client = server.CreateClient(); client.BaseAddress = new Uri(response.Headers.Location.ToString()); - request = new HttpRequestMessage(HttpMethod.Get, ""); + request = new HttpRequestMessage(HttpMethod.Get, expectedUrl); response = await client.SendAsync(request); Assert.Equal(expectedHstsHeader, response.Headers.GetValues(HeaderNames.StrictTransportSecurity).FirstOrDefault()); diff --git a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsRedirectionMiddlewareTests.cs b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsRedirectionMiddlewareTests.cs index b55c195272..ef0b0c3685 100644 --- a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsRedirectionMiddlewareTests.cs +++ b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/HttpsRedirectionMiddlewareTests.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; @@ -12,6 +13,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Xunit; namespace Microsoft.AspNetCore.HttpsPolicy.Tests @@ -19,9 +22,17 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests public class HttpsRedirectionMiddlewareTests { [Fact] - public async Task SetOptions_DefaultsSetCorrectly() + public async Task SetOptions_NotEnabledByDefault() { + var sink = new TestSink( + TestSink.EnableWithTypeName, + TestSink.EnableWithTypeName); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); var builder = new WebHostBuilder() + .ConfigureServices(services => + { + services.AddSingleton(loggerFactory); + }) .Configure(app => { app.UseHttpsRedirection(); @@ -38,23 +49,32 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests var response = await client.SendAsync(request); - Assert.Equal(HttpStatusCode.RedirectKeepVerb, response.StatusCode); - Assert.Equal("https://localhost/", response.Headers.Location.ToString()); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var logMessages = sink.Writes.ToList(); + + Assert.Single(logMessages); + var message = logMessages.Single(); + Assert.Equal(LogLevel.Warning, message.LogLevel); + Assert.Equal("Failed to determine the https port for redirect.", message.State.ToString()); } [Theory] - [InlineData(301, null, "https://localhost/")] - [InlineData(302, null, "https://localhost/")] - [InlineData(307, null, "https://localhost/")] - [InlineData(308, null, "https://localhost/")] + [InlineData(302, 5001, "https://localhost:5001/")] + [InlineData(307, 1, "https://localhost:1/")] + [InlineData(308, 3449, "https://localhost:3449/")] [InlineData(301, 5050, "https://localhost:5050/")] [InlineData(301, 443, "https://localhost/")] public async Task SetOptions_SetStatusCodeHttpsPort(int statusCode, int? httpsPort, string expected) { - + var sink = new TestSink( + TestSink.EnableWithTypeName, + TestSink.EnableWithTypeName); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); var builder = new WebHostBuilder() .ConfigureServices(services => { + services.AddSingleton(loggerFactory); services.Configure(options => { options.RedirectStatusCode = statusCode; @@ -79,20 +99,31 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests Assert.Equal(statusCode, (int)response.StatusCode); Assert.Equal(expected, response.Headers.Location.ToString()); + + var logMessages = sink.Writes.ToList(); + + Assert.Single(logMessages); + var message = logMessages.Single(); + Assert.Equal(LogLevel.Debug, message.LogLevel); + Assert.Equal($"Redirecting to '{expected}'.", message.State.ToString()); } [Theory] - [InlineData(301, null, "https://localhost/")] - [InlineData(302, null, "https://localhost/")] - [InlineData(307, null, "https://localhost/")] - [InlineData(308, null, "https://localhost/")] + [InlineData(302, 5001, "https://localhost:5001/")] + [InlineData(307, 1, "https://localhost:1/")] + [InlineData(308, 3449, "https://localhost:3449/")] [InlineData(301, 5050, "https://localhost:5050/")] [InlineData(301, 443, "https://localhost/")] public async Task SetOptionsThroughHelperMethod_SetStatusCodeAndHttpsPort(int statusCode, int? httpsPort, string expectedUrl) { + var sink = new TestSink( + TestSink.EnableWithTypeName, + TestSink.EnableWithTypeName); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); var builder = new WebHostBuilder() .ConfigureServices(services => { + services.AddSingleton(loggerFactory); services.AddHttpsRedirection(options => { options.RedirectStatusCode = statusCode; @@ -117,20 +148,26 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests Assert.Equal(statusCode, (int)response.StatusCode); Assert.Equal(expectedUrl, response.Headers.Location.ToString()); + + var logMessages = sink.Writes.ToList(); + + Assert.Single(logMessages); + var message = logMessages.Single(); + Assert.Equal(LogLevel.Debug, message.LogLevel); + Assert.Equal($"Redirecting to '{expectedUrl}'.", message.State.ToString()); } [Theory] - [InlineData(null, null, null, "https://localhost/")] [InlineData(null, null, "https://localhost:4444/", "https://localhost:4444/")] [InlineData(null, null, "https://localhost:443/", "https://localhost/")] - [InlineData(null, null, "http://localhost:5044/", "https://localhost/")] [InlineData(null, null, "https://localhost/", "https://localhost/")] [InlineData(null, "5000", "https://localhost:4444/", "https://localhost:5000/")] [InlineData(null, "443", "https://localhost:4444/", "https://localhost/")] [InlineData(443, "5000", "https://localhost:4444/", "https://localhost/")] [InlineData(4000, "5000", "https://localhost:4444/", "https://localhost:4000/")] [InlineData(5000, null, "https://localhost:4444/", "https://localhost:5000/")] - public async Task SetHttpsPortEnvironmentVariableAndServerFeature_ReturnsCorrectStatusCodeOnResponse(int? optionsHttpsPort, string configHttpsPort, string serverAddressFeatureUrl, string expectedUrl) + public async Task SetHttpsPortEnvironmentVariableAndServerFeature_ReturnsCorrectStatusCodeOnResponse( + int? optionsHttpsPort, string configHttpsPort, string serverAddressFeatureUrl, string expectedUrl) { var builder = new WebHostBuilder() .ConfigureServices(services => @@ -172,7 +209,15 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests [Fact] public async Task SetServerAddressesFeature_SingleHttpsAddress_Success() { + var sink = new TestSink( + TestSink.EnableWithTypeName, + TestSink.EnableWithTypeName); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); var builder = new WebHostBuilder() + .ConfigureServices(services => + { + services.AddSingleton(loggerFactory); + }) .Configure(app => { app.UseHttpsRedirection(); @@ -194,12 +239,31 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests var response = await client.SendAsync(request); Assert.Equal("https://localhost:5050/", response.Headers.Location.ToString()); + + var logMessages = sink.Writes.ToList(); + + Assert.Equal(2, logMessages.Count); + var message = logMessages.First(); + Assert.Equal(LogLevel.Debug, message.LogLevel); + Assert.Equal("Https port '5050' discovered from server endpoints.", message.State.ToString()); + + message = logMessages.Skip(1).First(); + Assert.Equal(LogLevel.Debug, message.LogLevel); + Assert.Equal("Redirecting to 'https://localhost:5050/'.", message.State.ToString()); } [Fact] - public async Task SetServerAddressesFeature_MultipleHttpsAddresses_ThrowInMiddleware() + public async Task SetServerAddressesFeature_MultipleHttpsAddresses_LogsAndFailsToRedirect() { + var sink = new TestSink( + TestSink.EnableWithTypeName, + TestSink.EnableWithTypeName); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); var builder = new WebHostBuilder() + .ConfigureServices(services => + { + services.AddSingleton(loggerFactory); + }) .Configure(app => { app.UseHttpsRedirection(); @@ -220,13 +284,30 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests var request = new HttpRequestMessage(HttpMethod.Get, ""); - await Assert.ThrowsAsync(async () => await client.SendAsync(request)); + var response = await client.SendAsync(request); + Assert.Equal(200, (int)response.StatusCode); + + var logMessages = sink.Writes.ToList(); + + Assert.Single(logMessages); + var message = logMessages.First(); + Assert.Equal(LogLevel.Warning, message.LogLevel); + Assert.Equal("Cannot determine the https port from IServerAddressesFeature, multiple values were found. " + + "Please set the desired port explicitly on HttpsRedirectionOptions.HttpsPort.", message.State.ToString()); } [Fact] public async Task SetServerAddressesFeature_MultipleHttpsAddressesWithSamePort_Success() { + var sink = new TestSink( + TestSink.EnableWithTypeName, + TestSink.EnableWithTypeName); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); var builder = new WebHostBuilder() + .ConfigureServices(services => + { + services.AddSingleton(loggerFactory); + }) .Configure(app => { app.UseHttpsRedirection(); @@ -241,7 +322,7 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests var server = new TestServer(builder, featureCollection); server.Features.Get().Addresses.Add("https://localhost:5050"); - server.Features.Get().Addresses.Add("https://localhost:5050"); + server.Features.Get().Addresses.Add("https://example.com:5050"); var client = server.CreateClient(); @@ -250,17 +331,30 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests var response = await client.SendAsync(request); Assert.Equal("https://localhost:5050/", response.Headers.Location.ToString()); + + var logMessages = sink.Writes.ToList(); + + Assert.Equal(2, logMessages.Count); + var message = logMessages.First(); + Assert.Equal(LogLevel.Debug, message.LogLevel); + Assert.Equal("Https port '5050' discovered from server endpoints.", message.State.ToString()); + + message = logMessages.Skip(1).First(); + Assert.Equal(LogLevel.Debug, message.LogLevel); + Assert.Equal("Redirecting to 'https://localhost:5050/'.", message.State.ToString()); } [Fact] - public async Task NoServerAddressFeature_DoesNotThrow_DefaultsTo443() + public async Task NoServerAddressFeature_DoesNotThrow_DoesNotRedirect() { + var sink = new TestSink( + TestSink.EnableWithTypeName, + TestSink.EnableWithTypeName); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); var builder = new WebHostBuilder() .ConfigureServices(services => { - services.AddHttpsRedirection(options => - { - }); + services.AddSingleton(loggerFactory); }) .Configure(app => { @@ -275,19 +369,27 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests var client = server.CreateClient(); var request = new HttpRequestMessage(HttpMethod.Get, ""); var response = await client.SendAsync(request); + Assert.Equal(200, (int)response.StatusCode); - Assert.Equal("https://localhost/", response.Headers.Location.ToString()); + var logMessages = sink.Writes.ToList(); + + Assert.Single(logMessages); + var message = logMessages.First(); + Assert.Equal(LogLevel.Warning, message.LogLevel); + Assert.Equal("Failed to determine the https port for redirect.", message.State.ToString()); } [Fact] public async Task SetNullAddressFeature_DoesNotThrow() { + var sink = new TestSink( + TestSink.EnableWithTypeName, + TestSink.EnableWithTypeName); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); var builder = new WebHostBuilder() .ConfigureServices(services => { - services.AddHttpsRedirection(options => - { - }); + services.AddSingleton(loggerFactory); }) .Configure(app => { @@ -305,8 +407,14 @@ namespace Microsoft.AspNetCore.HttpsPolicy.Tests var client = server.CreateClient(); var request = new HttpRequestMessage(HttpMethod.Get, ""); var response = await client.SendAsync(request); + Assert.Equal(200, (int)response.StatusCode); - Assert.Equal("https://localhost/", response.Headers.Location.ToString()); + var logMessages = sink.Writes.ToList(); + + Assert.Single(logMessages); + var message = logMessages.First(); + Assert.Equal(LogLevel.Warning, message.LogLevel); + Assert.Equal("Failed to determine the https port for redirect.", message.State.ToString()); } } } diff --git a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/Microsoft.AspNetCore.HttpsPolicy.Tests.csproj b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/Microsoft.AspNetCore.HttpsPolicy.Tests.csproj index af610a24a8..e51e3a6640 100644 --- a/test/Microsoft.AspNetCore.HttpsPolicy.Tests/Microsoft.AspNetCore.HttpsPolicy.Tests.csproj +++ b/test/Microsoft.AspNetCore.HttpsPolicy.Tests/Microsoft.AspNetCore.HttpsPolicy.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.1 @@ -8,4 +8,8 @@ + + + +