From b6b0c7121f541856ec3fc697ac905fe14f529327 Mon Sep 17 00:00:00 2001 From: Chris R Date: Mon, 26 Sep 2022 15:56:57 -0700 Subject: [PATCH 1/3] Read HTTP_PORTS and HTTPS_PORTS into IServerAddresses #43135 --- .../Abstractions/src/PublicAPI.Unshipped.txt | 2 + .../Abstractions/src/WebHostDefaults.cs | 10 +++++ .../src/GenericHost/GenericWebHostService.cs | 12 ++++++ .../test/GenericWebHostBuilderTests.cs | 41 +++++++++++++++++++ 4 files changed, 65 insertions(+) diff --git a/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt b/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt index 7dc5c58110bf..18dff1b65628 100644 --- a/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt +++ b/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ #nullable enable +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.HttpPortKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.HttpsPortKey -> string! diff --git a/src/Hosting/Abstractions/src/WebHostDefaults.cs b/src/Hosting/Abstractions/src/WebHostDefaults.cs index 4bc80699019d..31b04be4c194 100644 --- a/src/Hosting/Abstractions/src/WebHostDefaults.cs +++ b/src/Hosting/Abstractions/src/WebHostDefaults.cs @@ -53,6 +53,16 @@ public static class WebHostDefaults /// public static readonly string ServerUrlsKey = "urls"; + /// + /// The configuration key associated with the "http_port" configuration. + /// + public static readonly string HttpPortKey = "http_port"; + + /// + /// The configuration key associated with the "https_port" configuration. + /// + public static readonly string HttpsPortKey = "https_port"; + /// /// The configuration key associated with the "ContentRoot" configuration. /// diff --git a/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs b/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs index f70e65f388b7..ade707729791 100644 --- a/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs +++ b/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs @@ -73,6 +73,18 @@ public async Task StartAsync(CancellationToken cancellationToken) urls = Options.WebHostOptions.ServerUrls; } + if (string.IsNullOrEmpty(urls)) + { + // HTTP_PORTS and HTTPS_PORTS, these are lower priority than Urls. + var httpPorts = Configuration[WebHostDefaults.HttpPortKey]; + var httpUrls = httpPorts?.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Select(port => $"http://*:{port}").Aggregate((s1, s2) => string.Concat(s1, ";", s2)); + var httpsPorts = Configuration[WebHostDefaults.HttpsPortKey]; + var httpsUrls = httpsPorts?.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Select(port => $"https://*:{port}").Aggregate((s1, s2) => string.Concat(s1, ";", s2)); + urls = string.Join(';', httpUrls, httpsUrls); + } + if (!string.IsNullOrEmpty(urls)) { // We support reading "preferHostingUrls" from app configuration diff --git a/src/Hosting/Hosting/test/GenericWebHostBuilderTests.cs b/src/Hosting/Hosting/test/GenericWebHostBuilderTests.cs index 36cc21e2deff..da04f20313fa 100644 --- a/src/Hosting/Hosting/test/GenericWebHostBuilderTests.cs +++ b/src/Hosting/Hosting/test/GenericWebHostBuilderTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Linq; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Http.Features; @@ -87,6 +88,46 @@ public void UseUrlsWorksAfterHostConfigurationSourcesAreCleared() Assert.Equal("TEST_URL", server.Addresses.Single()); } + [Theory] + [InlineData(null, null, null, "")] + [InlineData("", "", "", "")] + [InlineData("http://urls", "", "", "http://urls")] + [InlineData("http://urls", "5000", "", "http://urls")] + [InlineData("http://urls", "", "5001", "http://urls")] + [InlineData("http://urls", "5000", "5001", "http://urls")] + [InlineData("", "5000", "", "http://*:5000")] + [InlineData("", "5000;5002;5004", "", "http://*:5000;http://*:5002;http://*:5004")] + [InlineData("", "", "5001", "https://*:5001")] + [InlineData("", "", "5001;5003;5005", "https://*:5001;https://*:5003;https://*:5005")] + [InlineData("", "5000", "5001", "http://*:5000;https://*:5001")] + [InlineData("", "5000;5002", "5001;5003", "http://*:5000;http://*:5002;https://*:5001;https://*:5003")] + public void ReadsUrlsOrPorts(string urls, string httpPort, string httpsPort, string expected) + { + var server = new TestServer(); + + using var host = new HostBuilder() + .ConfigureHostConfiguration(config => + { + config.AddInMemoryCollection(new[] + { + new KeyValuePair("urls", urls), + new KeyValuePair("http_port", httpPort), + new KeyValuePair("https_port", httpsPort), + }); + }) + .ConfigureWebHost(webHostBuilder => + { + webHostBuilder + .UseServer(server) + .Configure(_ => { }); + }) + .Build(); + + host.Start(); + + Assert.Equal(expected, string.Join(';', server.Addresses)); + } + private class TestServer : IServer, IServerAddressesFeature { public TestServer() From 59b0f01fc8ab629a9289497e6f5e3fb878967dd4 Mon Sep 17 00:00:00 2001 From: Chris R Date: Tue, 27 Sep 2022 10:22:25 -0700 Subject: [PATCH 2/3] Plurel, consolidated --- .../Abstractions/src/PublicAPI.Unshipped.txt | 4 ++-- src/Hosting/Abstractions/src/WebHostDefaults.cs | 8 ++++---- .../src/GenericHost/GenericWebHostService.cs | 17 ++++++++++------- .../Hosting/test/GenericWebHostBuilderTests.cs | 6 +++--- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt b/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt index 18dff1b65628..1e94a8b9b73a 100644 --- a/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt +++ b/src/Hosting/Abstractions/src/PublicAPI.Unshipped.txt @@ -1,3 +1,3 @@ #nullable enable -static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.HttpPortKey -> string! -static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.HttpsPortKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.HttpPortsKey -> string! +static readonly Microsoft.AspNetCore.Hosting.WebHostDefaults.HttpsPortsKey -> string! diff --git a/src/Hosting/Abstractions/src/WebHostDefaults.cs b/src/Hosting/Abstractions/src/WebHostDefaults.cs index 31b04be4c194..1024c7f1e23e 100644 --- a/src/Hosting/Abstractions/src/WebHostDefaults.cs +++ b/src/Hosting/Abstractions/src/WebHostDefaults.cs @@ -54,14 +54,14 @@ public static class WebHostDefaults public static readonly string ServerUrlsKey = "urls"; /// - /// The configuration key associated with the "http_port" configuration. + /// The configuration key associated with the "http_ports" configuration. /// - public static readonly string HttpPortKey = "http_port"; + public static readonly string HttpPortsKey = "http_ports"; /// - /// The configuration key associated with the "https_port" configuration. + /// The configuration key associated with the "https_ports" configuration. /// - public static readonly string HttpsPortKey = "https_port"; + public static readonly string HttpsPortsKey = "https_ports"; /// /// The configuration key associated with the "ContentRoot" configuration. diff --git a/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs b/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs index ade707729791..c1764156742c 100644 --- a/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs +++ b/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs @@ -76,13 +76,16 @@ public async Task StartAsync(CancellationToken cancellationToken) if (string.IsNullOrEmpty(urls)) { // HTTP_PORTS and HTTPS_PORTS, these are lower priority than Urls. - var httpPorts = Configuration[WebHostDefaults.HttpPortKey]; - var httpUrls = httpPorts?.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) - .Select(port => $"http://*:{port}").Aggregate((s1, s2) => string.Concat(s1, ";", s2)); - var httpsPorts = Configuration[WebHostDefaults.HttpsPortKey]; - var httpsUrls = httpsPorts?.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) - .Select(port => $"https://*:{port}").Aggregate((s1, s2) => string.Concat(s1, ";", s2)); - urls = string.Join(';', httpUrls, httpsUrls); + static string ExpandPorts(string ports, string scheme) + { + return string.Join(';', + ports.Split(';', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Select(port => $"{scheme}://*:{port}")); + } + + var httpUrls = ExpandPorts(Configuration[WebHostDefaults.HttpPortsKey] ?? string.Empty, Uri.UriSchemeHttp); + var httpsUrls = ExpandPorts(Configuration[WebHostDefaults.HttpsPortsKey] ?? string.Empty, Uri.UriSchemeHttps); + urls = $"{httpUrls};{httpsUrls}"; } if (!string.IsNullOrEmpty(urls)) diff --git a/src/Hosting/Hosting/test/GenericWebHostBuilderTests.cs b/src/Hosting/Hosting/test/GenericWebHostBuilderTests.cs index da04f20313fa..d517e6e0fe6b 100644 --- a/src/Hosting/Hosting/test/GenericWebHostBuilderTests.cs +++ b/src/Hosting/Hosting/test/GenericWebHostBuilderTests.cs @@ -101,7 +101,7 @@ public void UseUrlsWorksAfterHostConfigurationSourcesAreCleared() [InlineData("", "", "5001;5003;5005", "https://*:5001;https://*:5003;https://*:5005")] [InlineData("", "5000", "5001", "http://*:5000;https://*:5001")] [InlineData("", "5000;5002", "5001;5003", "http://*:5000;http://*:5002;https://*:5001;https://*:5003")] - public void ReadsUrlsOrPorts(string urls, string httpPort, string httpsPort, string expected) + public void ReadsUrlsOrPorts(string urls, string httpPorts, string httpsPorts, string expected) { var server = new TestServer(); @@ -111,8 +111,8 @@ public void ReadsUrlsOrPorts(string urls, string httpPort, string httpsPort, str config.AddInMemoryCollection(new[] { new KeyValuePair("urls", urls), - new KeyValuePair("http_port", httpPort), - new KeyValuePair("https_port", httpsPort), + new KeyValuePair("http_ports", httpPorts), + new KeyValuePair("https_ports", httpsPorts), }); }) .ConfigureWebHost(webHostBuilder => From eda6124199c432961787b612ca8b6e8d5b889512 Mon Sep 17 00:00:00 2001 From: Chris R Date: Wed, 28 Sep 2022 13:17:52 -0700 Subject: [PATCH 3/3] Log if overriden --- .../Hosting/src/GenericHost/GenericWebHostService.cs | 10 ++++++++-- .../Hosting/src/Internal/HostingLoggerExtensions.cs | 7 +++++++ src/Hosting/Hosting/src/Internal/LoggerEventIds.cs | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs b/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs index c1764156742c..d281484cc048 100644 --- a/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs +++ b/src/Hosting/Hosting/src/GenericHost/GenericWebHostService.cs @@ -73,6 +73,8 @@ public async Task StartAsync(CancellationToken cancellationToken) urls = Options.WebHostOptions.ServerUrls; } + var httpPorts = Configuration[WebHostDefaults.HttpPortsKey] ?? string.Empty; + var httpsPorts = Configuration[WebHostDefaults.HttpsPortsKey] ?? string.Empty; if (string.IsNullOrEmpty(urls)) { // HTTP_PORTS and HTTPS_PORTS, these are lower priority than Urls. @@ -83,10 +85,14 @@ static string ExpandPorts(string ports, string scheme) .Select(port => $"{scheme}://*:{port}")); } - var httpUrls = ExpandPorts(Configuration[WebHostDefaults.HttpPortsKey] ?? string.Empty, Uri.UriSchemeHttp); - var httpsUrls = ExpandPorts(Configuration[WebHostDefaults.HttpsPortsKey] ?? string.Empty, Uri.UriSchemeHttps); + var httpUrls = ExpandPorts(httpPorts, Uri.UriSchemeHttp); + var httpsUrls = ExpandPorts(httpsPorts, Uri.UriSchemeHttps); urls = $"{httpUrls};{httpsUrls}"; } + else if (!string.IsNullOrEmpty(httpPorts) || !string.IsNullOrEmpty(httpsPorts)) + { + Logger.PortsOverridenByUrls(httpPorts, httpsPorts, urls); + } if (!string.IsNullOrEmpty(urls)) { diff --git a/src/Hosting/Hosting/src/Internal/HostingLoggerExtensions.cs b/src/Hosting/Hosting/src/Internal/HostingLoggerExtensions.cs index c5550af76c6b..2c9d46b6c1d1 100644 --- a/src/Hosting/Hosting/src/Internal/HostingLoggerExtensions.cs +++ b/src/Hosting/Hosting/src/Internal/HostingLoggerExtensions.cs @@ -42,5 +42,12 @@ public static void ApplicationError(this ILogger logger, EventId eventId, string message: message, exception: exception); } + + public static void PortsOverridenByUrls(this ILogger logger, string httpPorts, string httpsPorts, string urls) + { + logger.LogWarning(eventId: LoggerEventIds.PortsOverridenByUrls, + message: "Overriding HTTP_PORTS '{http}' and HTTPS_PORTS '{https}'. Binding to values defined by URLS instead '{urls}'.", + httpPorts, httpsPorts, urls); + } } diff --git a/src/Hosting/Hosting/src/Internal/LoggerEventIds.cs b/src/Hosting/Hosting/src/Internal/LoggerEventIds.cs index beb534aa406c..6b644347c863 100644 --- a/src/Hosting/Hosting/src/Internal/LoggerEventIds.cs +++ b/src/Hosting/Hosting/src/Internal/LoggerEventIds.cs @@ -19,4 +19,5 @@ internal static class LoggerEventIds public const int ServerShutdownException = 12; public const int HostingStartupAssemblyLoaded = 13; public const int ServerListeningOnAddresses = 14; + public const int PortsOverridenByUrls = 15; }