private void LoadDefaultCert() { if (ConfigurationReader.Certificates.TryGetValue("Default", out var defaultCertConfig)) { var defaultCert = CertificateConfigLoader.LoadCertificate(defaultCertConfig, "Default"); if (defaultCert != null) { DefaultCertificateConfig = defaultCertConfig; Options.DefaultCertificate = defaultCert; } } else { var(certificate, certificateConfig) = FindDeveloperCertificateFile(); if (certificate != null) { Logger.LocatedDevelopmentCertificate(certificate); DefaultCertificateConfig = certificateConfig; Options.DefaultCertificate = certificate; } } }
// Adds endpoints from config to KestrelServerOptions.ConfigurationBackedListenOptions and configures some other options. // Any endpoints that were removed from the last time endpoints were loaded are returned. internal (List <ListenOptions>, List <ListenOptions>) Reload() { var endpointsToStop = Options.ConfigurationBackedListenOptions.ToList(); var endpointsToStart = new List <ListenOptions>(); Options.ConfigurationBackedListenOptions.Clear(); DefaultCertificateConfig = null; ConfigurationReader = new ConfigurationReader(Configuration); LoadDefaultCert(); foreach (var endpoint in ConfigurationReader.Endpoints) { var listenOptions = AddressBinder.ParseAddress(endpoint.Url, out var https); if (!https) { ConfigurationReader.ThrowIfContainsHttpsOnlyConfiguration(endpoint); } Options.ApplyEndpointDefaults(listenOptions); if (endpoint.Protocols.HasValue) { listenOptions.Protocols = endpoint.Protocols.Value; } else { // Ensure endpoint is reloaded if it used the default protocol and the protocol changed. // listenOptions.Protocols should already be set to this by ApplyEndpointDefaults. endpoint.Protocols = ConfigurationReader.EndpointDefaults.Protocols; } // Compare to UseHttps(httpsOptions => { }) var httpsOptions = new HttpsConnectionAdapterOptions(); if (https) { // Defaults Options.ApplyHttpsDefaults(httpsOptions); if (endpoint.SslProtocols.HasValue) { httpsOptions.SslProtocols = endpoint.SslProtocols.Value; } else { // Ensure endpoint is reloaded if it used the default protocol and the SslProtocols changed. endpoint.SslProtocols = ConfigurationReader.EndpointDefaults.SslProtocols; } if (endpoint.ClientCertificateMode.HasValue) { httpsOptions.ClientCertificateMode = endpoint.ClientCertificateMode.Value; } else { // Ensure endpoint is reloaded if it used the default mode and the ClientCertificateMode changed. endpoint.ClientCertificateMode = ConfigurationReader.EndpointDefaults.ClientCertificateMode; } // A cert specified directly on the endpoint overrides any defaults. httpsOptions.ServerCertificate = CertificateConfigLoader.LoadCertificate(endpoint.Certificate, endpoint.Name) ?? httpsOptions.ServerCertificate; if (httpsOptions.ServerCertificate == null && httpsOptions.ServerCertificateSelector == null) { // Fallback Options.ApplyDefaultCert(httpsOptions); // Ensure endpoint is reloaded if it used the default certificate and the certificate changed. endpoint.Certificate = DefaultCertificateConfig; } } // Now that defaults have been loaded, we can compare to the currently bound endpoints to see if the config changed. // There's no reason to rerun an EndpointConfigurations callback if nothing changed. var matchingBoundEndpoints = endpointsToStop.Where(o => o.EndpointConfig == endpoint).ToList(); if (matchingBoundEndpoints.Count > 0) { endpointsToStop.RemoveAll(o => o.EndpointConfig == endpoint); Options.ConfigurationBackedListenOptions.AddRange(matchingBoundEndpoints); continue; } if (EndpointConfigurations.TryGetValue(endpoint.Name, out var configureEndpoint)) { var endpointConfig = new EndpointConfiguration(https, listenOptions, httpsOptions, endpoint.ConfigSection); configureEndpoint(endpointConfig); } // EndpointDefaults or configureEndpoint may have added an https adapter. if (https && !listenOptions.IsTls) { if (endpoint.Sni.Count == 0) { if (httpsOptions.ServerCertificate == null && httpsOptions.ServerCertificateSelector == null) { throw new InvalidOperationException(CoreStrings.NoCertSpecifiedNoDevelopmentCertificateFound); } listenOptions.UseHttps(httpsOptions); } else { var sniOptionsSelector = new SniOptionsSelector(endpoint.Name, endpoint.Sni, CertificateConfigLoader, httpsOptions, listenOptions.Protocols, HttpsLogger); var tlsCallbackOptions = new TlsHandshakeCallbackOptions() { OnConnection = SniOptionsSelector.OptionsCallback, HandshakeTimeout = httpsOptions.HandshakeTimeout, OnConnectionState = sniOptionsSelector, }; listenOptions.UseHttps(tlsCallbackOptions); } } listenOptions.EndpointConfig = endpoint; endpointsToStart.Add(listenOptions); Options.ConfigurationBackedListenOptions.Add(listenOptions); } return(endpointsToStop, endpointsToStart); }