-
Notifications
You must be signed in to change notification settings - Fork 522
Add a Configuration package and tests. #1878
Conversation
/// <returns> | ||
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder. | ||
/// </returns> | ||
public static IWebHostBuilder UseKestrelWithConfiguration(this IWebHostBuilder hostBuilder) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this and why do we need it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there no way to takeover the default UseKestrel() which would make it match all of the other AddXyz()'s that also add default AddConfigureOptions?
Can we just add a reference to Microsoft.AspNetCore.Certificates.Configuration.Sources and ConfigurationBinder in Microsoft.AspNetCore.Server.Kestrel and do this inside of UseKestrel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not without pulling in the .Https dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets just make the .Kestrel package the uber one and nuke this package.
|
||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal | ||
{ | ||
internal class KestrelServerConfigureOptions : ConfigureDefaultOptions<KestrelServerOptions> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want all of these ConfigureDefaultOptions
public? Or just Kestrel's since its doing real work unlike the rest which are usually one liners that only call GetSection().Bind which are mostly private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be pubternal yea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I'll file an issue to make them all pubternal post preview2 if I don't end up touching them again this week. We need to standardize the naming then.
Xyz.Infrastructure/Internal.ConfigureDefaultXyzOptions
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.Internal
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
<PackageTags>aspnetcore;kestrel</PackageTags> | ||
<NoWarn>CS1591;$(NoWarn)</NoWarn> | ||
<EnableApiCheck>false</EnableApiCheck> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.Certificates.Configuration.Sources" Version="$(AspNetCoreVersion)" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PrivateAssets=All
@@ -28,6 +29,7 @@ public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder) | |||
return hostBuilder.ConfigureServices(services => | |||
{ | |||
services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>(); | |||
services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerConfigureOptions>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look right.
@@ -28,6 +29,7 @@ public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder) | |||
return hostBuilder.ConfigureServices(services => | |||
{ | |||
services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>(); | |||
services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerConfigureOptions>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing it this way temporarily to work around aspnet/DependencyInjection#500
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HaoK are all of the other sub systems doing this for preview2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works, the other alternative would be to register
services.AddTransient<IConfigureOptions<KestrelServerOptions>, ConfigureDefaults<KestrelServerConfigureOptions>()
Which would let us just remove this line once the DI is fixed.
For preview 2 I don't think it really matters which one we do. Its slightly easier to cleanup if we go with lining up all the defaults for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chatted a bit offline with @davidfowl lets use services.AddTransient<IConfigureOptions<KestrelServerOptions>, ConfigureDefaults<ConfigureDefaultKestrelServerOptions>()
so when the DI issues is fixed, we only have to remove this line, and won't have to update the ConfigureDefaultOptions class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's getting fixed: aspnet/DependencyInjection#530
That said, @halter73 says we can't rely on that because it doesn't guarantee the same ordering and KestrelServerConfigureOptions requires KestrelServerOptionsSetup to have run first.
|
||
if (!IPAddress.TryParse(configAddress, out var address)) | ||
{ | ||
throw new InvalidOperationException($"Invalid IP address in configuration: {configAddress}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User facing strings should go in the resx file.
} | ||
catch (KeyNotFoundException) when (certificateConfig.Value.Equals(DevelopmentSSLCertificateName, StringComparison.Ordinal) && _hostingEnvironment.IsDevelopment()) | ||
{ | ||
var storeLoader = new CertificateStoreLoader(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you're just moving the code, but it still bothers me that we're newing this up here. I think loading the default cert should be a method on CertificateLoader
. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really isn't the time to refactor it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah just file an issue for post preview 2 :)
if (certificate == null) | ||
{ | ||
var logger = _loggerFactory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel.KestrelServerConfigureOptions"); | ||
logger.LogError("No HTTPS certificate was found for development. For information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resx
|
||
if (certificate == null) | ||
{ | ||
throw new InvalidOperationException($"No certificate found for endpoint '{endPoint.Key}'."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resx
} | ||
catch (Exception ex) | ||
{ | ||
throw new InvalidOperationException("Unable to configure HTTPS endpoint. For information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.", ex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resx
@@ -4,19 +4,22 @@ | |||
|
|||
<PropertyGroup> | |||
<Description>ASP.NET Core Kestrel cross-platform web server.</Description> | |||
<TargetFramework>netstandard2.0</TargetFramework> | |||
<TargetFrameworks>netstandard2.0;netcoreapp2.0</TargetFrameworks> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cert loader sources package requires it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is the ifdef?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, what happens on .NET Framework?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It uses the netstandard version that doesn't have this new feature
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which does what?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just move this to the Core project. Currently only the "meta" project only contains WebHostBuilderKestrelExtensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm. I just realized this depends on both the Core and Https projects.
|
||
namespace Microsoft.AspNetCore.Server.Kestrel.Internal | ||
{ | ||
public class KestrelServerConfigureOptions : IConfigureOptions<KestrelServerOptions> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now the only class in the meta project other than WebHostBuilderKestrelExtensions. Why not just put this in Core/Internal alongside KestrelServerOptionsSetup? Or better yet, just combine this with KestrelServerOptionsSetup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, lets keep core clean. I don't want configuration leaking into the core APIs. The "meta package" is where all of the dependencies sit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't combine them as one is a true default that you always want to apply, while the config binding one is a 'squishy' default, that we only want to apply by default via WebHostBuilder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It requires .Https
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wouldn't work anyway since this calls UseHttps() 😢
private static int GetWebHostPort(IWebHost webHost) | ||
=> webHost.ServerFeatures.Get<IServerAddressesFeature>().Addresses | ||
.Select(serverAddress => new Uri(serverAddress).Port) | ||
.FirstOrDefault(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Single()
using Microsoft.Extensions.DependencyInjection; | ||
using Xunit; | ||
|
||
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any tests verifying the behavior when something goes wrong like being given an invalid address value or a bad/missing cert? Would the host fail to start even if there are other addresses that are successfully configured?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It throws. I added a test.
<ProjectReference Include="..\Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv\Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.csproj" /> | ||
<ProjectReference Include="..\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove?
That should be everything, Please review. |
rebased and merged. |
#1875, aspnet/Hosting#1095
This moves config code from Microsoft.AspNetCore.dll down to Kestrel's own config package. A reaction PR will follow for MetaPackages.
The cross targeting is due to the src package.