-
Notifications
You must be signed in to change notification settings - Fork 523
Conversation
src/Kestrel/Internal/ConfigReader.cs
Outdated
var url = endpointConfig["Url"]; | ||
if (string.IsNullOrEmpty(url)) | ||
{ | ||
// TODO: Log? |
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.
Why not throw in this case? I would log at a minimum though.
src/Kestrel/KestrelConfigBuilder.cs
Outdated
{ | ||
if (Options.ConfigurationBuilder == null) | ||
{ | ||
// The builder has already been built. |
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.
When does Build get called twice?
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 don't expect a given builder to be called twice, but it is a public API. If it was allowed to run twice you'd get duplicate endpoints and port conflicts.
{ | ||
public static KestrelConfigBuilder Configure(this KestrelServerOptions options, IConfiguration config) | ||
{ | ||
return new KestrelConfigBuilder(options, config); // Assigns itself to options.ConfigurationBuilder |
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.
Why not just create a local variable and assign it to options.ConfigurationBuilder in this method instead? It feels slightly better than assigning a partially constructed object even if it's functionally the same.
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 did it this way because Build then un-assigns itself, this way you can see the whole lifecycle in one class. I can change it.
src/Kestrel/Internal/ConfigReader.cs
Outdated
"Path": "testCert.pfx", | ||
"Password": "testPassword" | ||
} | ||
} |
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: I don't mind the comment, but use single line comments instead.
src/Kestrel/KestrelConfigBuilder.cs
Outdated
Options.GetHttpsDefaults()(httpsOptions); | ||
|
||
var certInfo = new CertificateConfig(endpoint.CertConfig); | ||
if (certInfo.IsFileCert) |
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.
Are any errors thrown if a file path and a store location are both specified for the same endpoint?
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, I don't want to second guess extraneous data. If we have what we need then there's no reason to fail. Nor do I expect people to mix those two up.
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 no reason not to fail if both a file path and a store location is provided.
What's the logic behind choosing file path over the store location when both are specified? If you don't expect people to mix the two, what's wrong with throwing?
/// <summary> | ||
/// Used to flow settings for connection adapters and other extensions. | ||
/// </summary> | ||
public IDictionary<string, object> AdapterData { get; } = new Dictionary<string, object>(0); |
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.
Yuck. IFeatureCollection?
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.
A dictionary in sheep's clothing... You prefer the typed keys?
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 pretty gross. How is it used?
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.
@davidfowl It's there to allow extension methods defined by connection adapters in separate assemblies to store data between calls to extension methods.
In this case it is used by KestrelServerOptions.ConfigureHttpsDefaults() to store away a default HttpsConnectionAdapterOptions for later use by ListenOptions.UseHttps() and KestrelConfigBuilder.Build().
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.
@davidfowl You're OK with merging this right, I don't exactly have a better alternative right 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.
This looks pretty weird, I'm still catching up with this PR and I'll see if I have any better alternatives for what you guys are trying to do
{ | ||
public static class KestrelServerOptionsHttpsExtensions | ||
{ | ||
public static void ConfigureHttpsDefaults(this KestrelServerOptions serverOptions, Action<HttpsConnectionAdapterOptions> configureOptions) |
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 would add doc comments to this and ConfigureEndpointDefaults
need to be called prior to the Configure/Listen calls it is providing default values for.
samples/SampleApp/SampleApp.csproj
Outdated
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="../../test/shared/TestCertificates/testCert.pfx" CopyToOutputDirectory="PreserveNewest" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Content Update="appsettings.Development.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
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: Make these properties
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'd rather not hand customizes VS generated settings.
samples/SampleApp/Startup.cs
Outdated
}); | ||
|
||
options.ListenAnyIP(basePort + 3); | ||
|
||
options.ListenAnyIP(basePort + 4, listenOptions => | ||
{ | ||
listenOptions.UseHttps(StoreName.My, "aspnet.test", StoreLocation.CurrentUser); |
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.
Will this explode?
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.
If the cert is missing? Yes
/// Provides a configuration source where endpoints will be loaded from on server start. | ||
/// The default is null. | ||
/// </summary> | ||
public IKestrelConfigBuilder ConfigurationBuilder { get; set; } |
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: IKestrelConfigurationBuilder
37b20c2
to
c599d2a
Compare
dc7515b
to
2b21b63
Compare
@halter73 Updated with tests and ready to review. Let me know if you want me to trim down the new sample content. |
Filed https://github.com/aspnet/KestrelHttpServer/issues/2216 to consider what other settings would make sense to read from config. These would all be easy to add on top of the existing design. |
Poke please review this today. |
@@ -104,6 +104,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Protocols.Abstractions", "s | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{C2910A13-B2C2-46D8-81D8-7E166F4F5981}" | |||
ProjectSection(SolutionItems) = preProject | |||
build\dependencies.props = build\dependencies.props |
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.
👍
/// <returns></returns> | ||
public static KestrelConfigurationBuilder Configure(this KestrelServerOptions options) | ||
{ | ||
var builder = new KestrelConfigurationBuilder(options, new ConfigurationBuilder().Build()); |
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's no Configuration.Empty
or similar?
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 that I see. @HaoK ?
I'm not concerned about it, this Configure method is only called once or twice at startup.
/// Creates a configuration builder for setting up Kestrel. | ||
/// </summary> | ||
/// <param name="options"></param> | ||
/// <returns></returns> |
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: remove empty doc comment sections.
{ | ||
var env = hostingContext.HostingEnvironment; | ||
config.AddJsonFile("appsettings.json", optional: true) | ||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); |
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.
At least one of these appsettings files is required now, right?
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, they're optional in the sample. The config is additive on top of the endpoints defined in code.
options.KestrelServerOptions = context.ServerOptions; | ||
context.ServerOptions.EndpointDefaults(options); | ||
|
||
if (!options.ConnectionAdapters.Any(f => f.IsHttps)) |
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.
So if you don't configure a specific endpoint and the DefaultAddressStrategy is used, you bind to "http://localhost:5000" and "https://localhost:5001". So far so good.
But if you also configure an HTTPS adapter using ConfigureEndpointDefaults
you now listen on "https://localhost:5000" and don't listen on port 5001 at all? Seems weird.
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.
If you add HTTPS in ConfigureEndpointDefaults then you end up listening on both "https://localhost:5000" and "https://localhost:5001". This if only skips adding the https adapter twice, it doesn't skip binding to this endpoint.
/// <summary> | ||
/// Returns the default certificate, if available, otherwise null. | ||
/// </summary> | ||
X509Certificate2 Certificate { get; } |
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.
When does this need to be set?
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 found it over at https://github.com/aspnet/KestrelHttpServer/pull/2186/files#diff-590565eed2ca0d80acae41edb7fde1a7R230. Continuing the discussion there.
/// <param name="configureOptions"></param> | ||
public void ConfigureEndpointDefaults(Action<ListenOptions> configureOptions) | ||
{ | ||
EndpointDefaults = configureOptions ?? throw new ArgumentNullException(nameof(configureOptions)); |
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.
Should we allow this to stack? Either way the doc comments should mention whether this overrides previous calls to ConfigureEndpointDefaults.
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 don't think more that one default action is required. Comments updated.
} | ||
|
||
DisposeCertificates(storeCertificates); | ||
DisposeCertificates(foundCertificates); |
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.
After you're done with a X509Store, you seriously have to enumerate X509Store.Certificates and dispose all the ones you didn't use? That's ridiculous if true.
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.
Also isn't everything in foundCertificates also in storeCertificates, so the second call is just double disposing?
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.
@javiercn? You've played with the cert store a lot lately.
Note this was copied from Hosting with an added EKU check.
https://github.com/aspnet/Hosting/blob/a2962d54f18dece7ec57ee42f3e565f3727168e1/shared/Microsoft.AspNetCore.Certificates.Configuration.Sources/CertificateStoreLoader.cs#L50
I think you're right about the double dispose, unless Find is making a deep copy for some reason.
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.
@halter73 I think you need to dispose the ones that you don't use. I would have to ask, but I believe that when you open the store and enumerate the certificates you get some unmanaged references to the actual underlying keys (when present) so I believe you need to dispose those.
I believe that the dotnet crypto folks gave us explicit feedback on Cesar's original PR about this. We can probably dig up that PR
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.
Native resources would all have finalizers, but it's a good habit to explicitly dispose them when you're done.
src/Kestrel/EndpointConfiguration.cs
Outdated
} | ||
|
||
public bool IsHttps { get; } | ||
public ListenOptions Listener { get; } |
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: name it ListenOptions.
|
||
/// <summary> | ||
/// Bind to given IP address and port. | ||
/// The callback configures endpoint-specific settings. |
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: If we're going to include the sentence about the configure callback, we should do so for all applicable overloads.
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.
Removed
samples/SampleApp/Startup.cs
Outdated
.Configure() | ||
.Endpoint(IPAddress.Loopback, basePort + 5) | ||
.LocalhostEndpoint(basePort + 6) | ||
.Build(); |
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.
So, this I'm guessing Build() is required because that's what triggers the endpoint to actually get added to the options?
Related question, there is no Build() on the Kestrel config section binding one below, so would that just basically be a no-op giving you an unused builder?
I think it might make things simpler if you just add a separate dedicated options for the defaults, i.e. KestralServerDefaultOptions and configure it via options normally. Thent he ConfigureXyzDefault methods would just be configuring this other option instead of manipulating the builder.
You'd still need the existing builder logic to be able to create endpoints from config, but its no longer part of the KestralServerOptions. The server can just get new default options along with the normal options and continue doing the same thing that Build() does. The only change that might be required is all of the defaults configuration would need to be done earlier, as they would need to be in the service container.
I definitely don't have a ton of context in this code or how everything fits together, but using a dedicated options class for the defaults seems to be an potential alternative path to consider
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.
Kestrel calls Build on the last builder at Start. The idea is that the metapackage will assign a default configuration but it won't call Build so that that default can be replaced by user code. If you want to add two configurations you need to call Build on at least the first one.
instead of manipulating the builder.
? The ConfigureXDefault methods don't manipulate the builder.
We didn't want to go the route of KestralServerDefaultOptions as that would require duplicating every setting. With the callbacks all settings added to ListenOptions are automatically available as defaults. There are also some things like the connection adapters that are better to create per endpoint.
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.
Requiring them to call build sometimes seems a bit awkward, can't you just expose a list that they can control and remove/add as needed instead... options.Builders.Add instead of options.Configure
RE duplication, you should be able to reuse whatever sub options you want in the defaults, why wouldn't you be able to use the ListenOptions/Adapters for the default options as well. But even if you wanted to have a complete identical surface area, you could just use named options
// Store defaults via "default" name
var defaults = IOptionsMonitor<KestrelServerOptions>.Get("defaults");
// ConfigureXDefault methods just pass extra name parameter
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.
In practice I expect them to almost never call build, they either use the config defined in the metapackage or they use the one from their own code. Keeping a list does not seem necessary. We'll see what the preview1 feedback is like.
From your examples I'm not sure you understand what defaults we're talking about configuring. It's not that there are multiple KestrelServerOptions with a set of defaults, it's that a given KestrelServerOptions has multiple endpoints / ListenOptions / httpsOptions and you can define defaults for the options on those. The connection adapters are the most tricky here, you'd need to create a fresh one for each endpoint so you can't create one as a default without implementing some kind of cloning logic. With the current model you can re-use all of the extensions off of ListenOptions for creating connection adapters.
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.
So let me try to get on the same page...
So the KestrelServer eventually wants to produce a bunch of endpoints which has options in a ListenOptions instance, (Endpoints are created from these 1:1?)
Https is doing weird stuff which I guess relates to the fact that its configuring listen option instances and doing its own options like stuff. The EndpointDefaults action is basically equivalent to doing a ConfigureAll on ListenOptions if you were using IOptions.
Part of the confusion here I think is that KestrelServerOptions are using IOptions/Configure, while there are a few options types that are used more like EndpointSettings/AdapterSettings and not configured like normal options.
With named endpoints, that matches exactly named options, you can just use IOptions<EndpointOptions>.Get(name)
and just bind against config.GetSection("Kestrel:Endpoints")
. Your defaults could then just be sugar for services.ConfigureAll(o => o.Protocols = HttpProtocols.Http1)
Assuming you can just hang all Endpoint operations off of .Endpoints
, maybe something like? But I'm sure I don't grok what's going on around the adapter/https yet.
UseKestrel(context, o => {
// Default wireup (but showing what the sugar methods call)
o.ConfigureAll<EndpointOptions>(opt => opt.Protocols = HttpProtocols.Http1);
o.ConfigureAll<HttpsDefaultOptions>(o => o.SslProtocols = SslProtocols.Tls12);
// just binds all the endpoint options to their names using Configure (and defaults?)
o.Endpoints.Configure(context.Configuration.GetSection("Kestrel:Endpoints"));
o.Endpoints.Add(IPAddress.Loopback, basePort + 5);
o.Endpoints.AddLocalhost(basePort + 6);
o.Endpoints.AddNamed("NamedEndpoint", opt =>
{
opt.Listener.Protocols = HttpProtocols.Http1;
})
o.Endpoints.AddNamed("NamedHttpsEndpoint", opt =>
{
opt.Https.SslProtocols = SslProtocols.Tls12;
});
}
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're still missing quite a bit of context. Stop by if you want to walk through it.
The question I'd originally sent you was if configuration has a static helper for the scenario where I only want an empty placeholder instance like new ConfigurationBuilder().Build()
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 because there's always config, its pretty strange to pass in empty configuration to a configuration loader class though... Hence why I think the naming is a bit weird.
Like this doesn't use config at all right?
options
.Configure()
.Endpoint(IPAddress.Loopback, basePort + 5)
.LocalhostEndpoint(basePort + 6)
.Load();
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.
Damian wanted to mirror the Listen APIs so you could still configure everything in one place. Yes it makes for a slightly odd fraken type.
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's fine, my main point is that this seems more than just a configuration loader, this is public endpoint management API basically, where the ctor takes an optional config and Load() is basically committing the set of endpoints.
I think building that dedicated API where configuration is just one way to import a chunk of endpoint settings is maybe a simpler way to expose this...
I still think this would be easier to understand if the API just exposed the endpoints on the options. Having to call configure/endpoint/load and then another configure/endpoint block just seems strange.
Seems like it'd be better to let them express it more concisely, without any weird loads.
options
.LoadConfig(context.Configuration.GetSection("Kestrel") // Order for this shouldn't matter when its called, it just adds bindings using the config section for named endpoints
.AddEndpoint(IPAddress.Loopback, basePort + 5) // uses defaults
.AddLocalhostEndpoint(basePort + 6) // uses defaults
.AddEndpoint("NamedEndpoint", opt => // uses defaults and config section bindings via name
{
opt.ListenOptions.Protocols = HttpProtocols.Http1;
})
.AddEndpoint("NamedHttpsEndpoint", opt => // uses defaults and config section bindings via name
{
opt.HttpsOptions.SslProtocols = SslProtocols.Tls12;
}
And you can always just let them Remove/Update existing endpoints.
|
||
public IConfigurationSection ConfigSection { get; } | ||
|
||
public bool Exists => ConfigSection.GetChildren().Any(); |
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: you could consider using the Exists extension method which is similar.
https://github.com/aspnet/Configuration/blob/dev/src/Config.Abstractions/ConfigurationExtensions.cs#L76
You can consider using section.Bind(this) if you wanted to avoid all the ConfigSection property lookups where the name is the property name.
|
||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal | ||
{ | ||
internal class ConfigurationReader |
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: you could consider just making this into two internal static extension methods on IConfiguration
IConfiguration.ReadCertificates(this IConfiguration)
IConfiguration.ReadEndpoints(this IConfiguration)
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 need when this is only for internal usage.
Note many of the strange design decisions here are due to the assembly separation between K.Core and K.Https. We've opted to merge the https libraries into core and then revisit this PR. |
0a1be15
to
e1de1d5
Compare
Rebased on the new merged assemblies and code consolidated. Ready for a final pass @halter73 |
/// <summary> | ||
/// Open a socket file descriptor. | ||
/// </summary> | ||
public KestrelConfigurationLoader HandleEndpoint(ulong handle) => HandleEndpoint(handle, _ => { }); |
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 curious - did we expose ulong
s in the public API before?
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.
Yes these are all mirrors of the existing Listen APIs.
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.
Yes. KestrelServerOptions.ListenHandle(ulong)
.
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 would like a test for force upgrading an HTTP endpoint passed in via the IServerAddressesFeature to HTTPS though.
9b86b3c
to
dfaf37c
Compare
In the initial post above {
"Kestrel": {
"Certificates": {
"Default": {
"Path": "...",
"Password": ""
}
}
}
} ... but in the blog post, it's not ... https://blogs.msdn.microsoft.com/webdev/2018/02/02/asp-net-core-2-1-roadmap#security {
"Kestrel": {
},
"Certificates": {
"Default": {
"Path": "<file>",
"Password": "<password>"
},
"Default": {
"Subject": "",
"Store": "",
"Location": "",
"AllowInvalid": ""
}
}
} ... no love from schema store ... http://json.schemastore.org/appsettings I assume the blog post is incorrect. cc/ @danroth27 |
@guardrex you're correct. We've already fixed that in another blog post, but it looks like we should update this one too. I left him a comment directly on the that post. |
This includes the updated design. If you like it then I'll start working on the tests.
Related issues:
#2016 - Config support
#2167 - Default settings
#2166 - UseHttps()
#1290 - Config and code parity
#2188 - Listen on https by default
Major features:
Supported configurations:
UseUrls
IWebHostBuilder extension. These can be http or https (if a default cert is available). This may be a semicolon separated list. E.g."Urls": "http://localhost:5000;http://localhost:5001"
.serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
to specify the configuration section (this will be added to the metapackage). Then add the following config:Certificates can also be loaded from the machine store by specifying the following parameters instead of Path and Password:
Schema details:
serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
returns a KestrelConfigurationLoader with an.Endpoint(string name, options => { })
method that can be used to supplement configured endpoint's settings.serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
again with another section. Only the last configuration will be used unless Load is explicitly called on prior instances. The metapackage will not call Load so that it's default configuration section may be replaced.