diff --git a/KestrelHttpServer.sln b/KestrelHttpServer.sln index d907c16aee..b5b6dc71f3 100644 --- a/KestrelHttpServer.sln +++ b/KestrelHttpServer.sln @@ -71,15 +71,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel.Tests", "test\Microsoft.AspNetCore.Server.Kestrel.Tests\Microsoft.AspNetCore.Server.Kestrel.Tests.csproj", "{4F1C30F8-CCAA-48D7-9DF6-2A84021F5BCC}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{FD3692F8-F5C7-49A5-8D69-29F8A87A9DB7}" - ProjectSection(SolutionItems) = preProject - build\common.props = build\common.props - build\dependencies.props = build\dependencies.props - build\Key.snk = build\Key.snk - build\repo.props = build\repo.props - build\repo.targets = build\repo.targets - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -279,6 +270,5 @@ Global {2E9CB89D-EC8F-4DD9-A72B-08D5BABF752D} = {2D5D5227-4DBD-499A-96B1-76A36B03B750} {D95A7EC3-48AC-4D03-B2E2-0DA3E13BD3A4} = {D3273454-EA07-41D2-BF0B-FCC3675C2483} {4F1C30F8-CCAA-48D7-9DF6-2A84021F5BCC} = {D3273454-EA07-41D2-BF0B-FCC3675C2483} - {FD3692F8-F5C7-49A5-8D69-29F8A87A9DB7} = {7972A5D6-3385-4127-9277-428506DD44FF} EndGlobalSection EndGlobal diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/ConfigureDefaultKestrelServerOptions.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Internal/ConfigureDefaultKestrelServerOptions.cs deleted file mode 100644 index 02e1f0d561..0000000000 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Internal/ConfigureDefaultKestrelServerOptions.cs +++ /dev/null @@ -1,116 +0,0 @@ -// 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 System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Security.Cryptography.X509Certificates; -using Microsoft.AspNetCore.Certificates.Configuration; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.Options.Infrastructure; - -namespace Microsoft.AspNetCore.Server.Kestrel.Internal -{ - public class ConfigureDefaultKestrelServerOptions : ConfigureDefaultOptions - { - private const string DefaultCertificateSubjectName = "CN=localhost"; - private const string DevelopmentSSLCertificateName = "localhost"; - - private readonly IServiceProvider _services; - private readonly IHostingEnvironment _hostingEnvironment; - private readonly IConfiguration _configurationRoot; - private readonly ILoggerFactory _loggerFactory; - - public ConfigureDefaultKestrelServerOptions( - IServiceProvider services, - IHostingEnvironment hostingEnvironment, - IConfiguration configurationRoot, - ILoggerFactory loggerFactory) - { - _services = services; - _hostingEnvironment = hostingEnvironment; - _configurationRoot = configurationRoot; - _loggerFactory = loggerFactory; - } - - public override void Configure(string name, KestrelServerOptions options) - { - // Don't assume KestrelServerOptionsSetup has already set the services. Needed for UseHttps. - options.ApplicationServices = _services; - BindConfiguration(options); - } - - private void BindConfiguration(KestrelServerOptions options) - { - var certificateLoader = new CertificateLoader(_configurationRoot.GetSection("Certificates"), _loggerFactory, _hostingEnvironment.EnvironmentName); - - foreach (var endPoint in _configurationRoot.GetSection("Microsoft:AspNetCore:Server:Kestrel:EndPoints").GetChildren()) - { - BindEndPoint(options, endPoint, certificateLoader); - } - } - - private void BindEndPoint( - KestrelServerOptions options, - IConfigurationSection endPoint, - CertificateLoader certificateLoader) - { - var configAddress = endPoint.GetValue("Address"); - var configPort = endPoint.GetValue("Port"); - - if (!IPAddress.TryParse(configAddress, out var address)) - { - throw new InvalidOperationException(KestrelStrings.FormatInvalidIp(configAddress)); - } - - if (!int.TryParse(configPort, out var port)) - { - throw new InvalidOperationException(KestrelStrings.FormatInvalidPort(configPort)); - } - - options.Listen(address, port, listenOptions => - { - var certificateConfig = endPoint.GetSection("Certificate"); - X509Certificate2 certificate = null; - if (certificateConfig.Exists()) - { - try - { - try - { - certificate = certificateLoader.Load(certificateConfig).FirstOrDefault(); - } - catch (KeyNotFoundException) when (certificateConfig.Value.Equals(DevelopmentSSLCertificateName, StringComparison.Ordinal) && _hostingEnvironment.IsDevelopment()) - { - var storeLoader = new CertificateStoreLoader(); - certificate = storeLoader.Load(DefaultCertificateSubjectName, "My", StoreLocation.CurrentUser, validOnly: false) ?? - storeLoader.Load(DefaultCertificateSubjectName, "My", StoreLocation.LocalMachine, validOnly: false); - - if (certificate == null) - { - var logger = _loggerFactory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel.KestrelServerConfigureOptions"); - logger.LogError(KestrelStrings.NoCertFoundLog); - } - } - - if (certificate == null) - { - throw new InvalidOperationException(KestrelStrings.FormatNoCertForEndpoint(endPoint.Key)); - } - } - catch (Exception ex) - { - throw new InvalidOperationException(KestrelStrings.UnableToConfigureHttps, ex); - } - - listenOptions.UseHttps(certificate); - } - }); - } - } -} diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/KestrelStrings.resx b/src/Microsoft.AspNetCore.Server.Kestrel/KestrelStrings.resx deleted file mode 100644 index bf5c93410c..0000000000 --- a/src/Microsoft.AspNetCore.Server.Kestrel/KestrelStrings.resx +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Invalid IP address in configuration: {configAddress}. - - - Invalid port in configuration: {configPort}. - - - No certificate found for endpoint {endPoint}. - - - Unable to configure HTTPS endpoint. For information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054. - - - No HTTPS certificate was found for development. For information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054. - - \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Microsoft.AspNetCore.Server.Kestrel.csproj b/src/Microsoft.AspNetCore.Server.Kestrel/Microsoft.AspNetCore.Server.Kestrel.csproj index fbaa34e0b7..616830814d 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Microsoft.AspNetCore.Server.Kestrel.csproj +++ b/src/Microsoft.AspNetCore.Server.Kestrel/Microsoft.AspNetCore.Server.Kestrel.csproj @@ -4,7 +4,7 @@ ASP.NET Core Kestrel cross-platform web server. - netstandard2.0;netcoreapp2.0 + netstandard2.0 true aspnetcore;kestrel CS1591;$(NoWarn) @@ -12,14 +12,11 @@ - - - diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/Properties/KestrelStrings.Designer.cs b/src/Microsoft.AspNetCore.Server.Kestrel/Properties/KestrelStrings.Designer.cs deleted file mode 100644 index ee0b31857d..0000000000 --- a/src/Microsoft.AspNetCore.Server.Kestrel/Properties/KestrelStrings.Designer.cs +++ /dev/null @@ -1,100 +0,0 @@ -// -namespace Microsoft.AspNetCore.Server.Kestrel -{ - using System.Globalization; - using System.Reflection; - using System.Resources; - - internal static class KestrelStrings - { - private static readonly ResourceManager _resourceManager - = new ResourceManager("Microsoft.AspNetCore.Server.Kestrel.KestrelStrings", typeof(KestrelStrings).GetTypeInfo().Assembly); - - /// - /// Invalid IP address in configuration: {configAddress}. - /// - internal static string InvalidIp - { - get => GetString("InvalidIp"); - } - - /// - /// Invalid IP address in configuration: {configAddress}. - /// - internal static string FormatInvalidIp(object configAddress) - => string.Format(CultureInfo.CurrentCulture, GetString("InvalidIp", "configAddress"), configAddress); - - /// - /// Invalid port in configuration: {configPort}. - /// - internal static string InvalidPort - { - get => GetString("InvalidPort"); - } - - /// - /// Invalid port in configuration: {configPort}. - /// - internal static string FormatInvalidPort(object configPort) - => string.Format(CultureInfo.CurrentCulture, GetString("InvalidPort", "configPort"), configPort); - - /// - /// No certificate found for endpoint {endPoint}. - /// - internal static string NoCertForEndpoint - { - get => GetString("NoCertForEndpoint"); - } - - /// - /// No certificate found for endpoint {endPoint}. - /// - internal static string FormatNoCertForEndpoint(object endPoint) - => string.Format(CultureInfo.CurrentCulture, GetString("NoCertForEndpoint", "endPoint"), endPoint); - - /// - /// Unable to configure HTTPS endpoint. For information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054. - /// - internal static string UnableToConfigureHttps - { - get => GetString("UnableToConfigureHttps"); - } - - /// - /// Unable to configure HTTPS endpoint. For information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054. - /// - internal static string FormatUnableToConfigureHttps() - => GetString("UnableToConfigureHttps"); - - /// - /// No HTTPS certificate was found for development. For information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054. - /// - internal static string NoCertFoundLog - { - get => GetString("NoCertFoundLog"); - } - - /// - /// No HTTPS certificate was found for development. For information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054. - /// - internal static string FormatNoCertFoundLog() - => GetString("NoCertFoundLog"); - - private static string GetString(string name, params string[] formatterNames) - { - var value = _resourceManager.GetString(name); - - System.Diagnostics.Debug.Assert(value != null); - - if (formatterNames != null) - { - for (var i = 0; i < formatterNames.Length; i++) - { - value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); - } - } - - return value; - } - } -} diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/WebHostBuilderKestrelExtensions.cs b/src/Microsoft.AspNetCore.Server.Kestrel/WebHostBuilderKestrelExtensions.cs index 0823e62db1..3d3dad73cb 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/WebHostBuilderKestrelExtensions.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/WebHostBuilderKestrelExtensions.cs @@ -3,12 +3,10 @@ using System; using Microsoft.AspNetCore.Hosting.Server; -using Microsoft.AspNetCore.Server.Kestrel.Internal; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using Microsoft.Extensions.Options.Infrastructure; namespace Microsoft.AspNetCore.Hosting { @@ -30,9 +28,6 @@ namespace Microsoft.AspNetCore.Hosting return hostBuilder.ConfigureServices(services => { services.AddTransient, KestrelServerOptionsSetup>(); - // https://github.com/aspnet/DependencyInjection/issues/500 - services.AddTransient, ConfigureDefaults>(); - services.AddTransient, ConfigureDefaultKestrelServerOptions>(); services.AddSingleton(); }); } diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/ConfigurationTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/ConfigurationTests.cs deleted file mode 100644 index c7581dfd15..0000000000 --- a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/ConfigurationTests.cs +++ /dev/null @@ -1,153 +0,0 @@ -// 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 System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Hosting.Server.Features; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; -using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.AspNetCore.Testing; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Microsoft.Extensions.Options.Infrastructure; -using Xunit; - -namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests -{ - public class ConfigurationTests - { - private void ConfigureEchoAddress(IApplicationBuilder app) - { - app.Run(context => - { - return context.Response.WriteAsync(context.Request.GetDisplayUrl()); - }); - } - - [Fact] - public void BindsKestrelToInvalidIp_FailsToStart() - { - var hostBuilder = new WebHostBuilder() - .UseKestrel() - .UseConfiguration(new ConfigurationBuilder().AddInMemoryCollection(new Dictionary() - { - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Address", "ABCDEFGH" }, - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Port", "0" } - }).Build()) - .ConfigureServices(services => - { - // Microsoft.AspNetCore.dll does this - services.AddTransient(typeof(IConfigureOptions<>), typeof(ConfigureDefaults<>)); - }) - .Configure(ConfigureEchoAddress); - - Assert.Throws(() => hostBuilder.Build()); - } - - [Theory] - [InlineData("127.0.0.1", "127.0.0.1")] - [InlineData("::1", "[::1]")] - public async Task BindsKestrelHttpEndPointFromConfiguration(string endPointAddress, string requestAddress) - { - var hostBuilder = new WebHostBuilder() - .UseKestrel() - .UseConfiguration(new ConfigurationBuilder().AddInMemoryCollection(new Dictionary() - { - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Address", $"{endPointAddress}" }, - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Port", "0" } - }).Build()) - .ConfigureServices(services => - { - // Microsoft.AspNetCore.dll does this - services.AddTransient(typeof(IConfigureOptions<>), typeof(ConfigureDefaults<>)); - }) - .Configure(ConfigureEchoAddress); - - using (var webHost = hostBuilder.Start()) - { - var port = GetWebHostPort(webHost); - - Assert.NotEqual(5000, port); // Default port - - Assert.NotEqual(0, port); - - using (var client = new HttpClient()) - { - var response = await client.GetStringAsync($"http://{requestAddress}:{port}"); - Assert.Equal($"http://{requestAddress}:{port}/", response); - } - } - } - - [Fact] - public async Task BindsKestrelHttpsEndPointFromConfiguration_ReferencedCertificateFile() - { - var hostBuilder = new WebHostBuilder() - .UseKestrel() - .UseConfiguration(new ConfigurationBuilder().AddInMemoryCollection(new Dictionary() - { - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Address", "127.0.0.1" }, - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Port", "0" }, - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Certificate", "TestCert" }, - { "Certificates:TestCert:Source", "File" }, - { "Certificates:TestCert:Path", "testCert.pfx" }, - { "Certificates:TestCert:Password", "testPassword" } - }).Build()) - .ConfigureServices(services => - { - // Microsoft.AspNetCore.dll does this - services.AddTransient(typeof(IConfigureOptions<>), typeof(ConfigureDefaults<>)); - }) - .Configure(ConfigureEchoAddress); - - using (var webHost = hostBuilder.Start()) - { - var port = GetWebHostPort(webHost); - - var response = await HttpClientSlim.GetStringAsync($"https://127.0.0.1:{port}", validateCertificate: false); - Assert.Equal($"https://127.0.0.1:{port}/", response); - } - } - - [Fact] - public async Task BindsKestrelHttpsEndPointFromConfiguration_InlineCertificateFile() - { - var hostBuilder = new WebHostBuilder() - .UseKestrel() - .UseConfiguration(new ConfigurationBuilder().AddInMemoryCollection(new Dictionary() - { - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Address", "127.0.0.1" }, - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Port", "0" }, - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Certificate:Source", "File" }, - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Certificate:Path", "testCert.pfx" }, - { "Microsoft:AspNetCore:Server:Kestrel:Endpoints:0:Certificate:Password", "testPassword" } - }).Build()) - .ConfigureServices(services => - { - // Microsoft.AspNetCore.dll does this - services.AddTransient(typeof(IConfigureOptions<>), typeof(ConfigureDefaults<>)); - }) - .Configure(ConfigureEchoAddress); - - using (var webHost = hostBuilder.Start()) - { - var port = GetWebHostPort(webHost); - - var response = await HttpClientSlim.GetStringAsync($"https://127.0.0.1:{port}", validateCertificate: false); - Assert.Equal($"https://127.0.0.1:{port}/", response); - } - } - - private static int GetWebHostPort(IWebHost webHost) - => webHost.ServerFeatures.Get().Addresses - .Select(serverAddress => new Uri(serverAddress).Port) - .Single(); - } -}