Esempio n. 1
0
    internal KestrelConfigurationLoader(
        KestrelServerOptions options,
        IConfiguration configuration,
        IHostEnvironment hostEnvironment,
        bool reloadOnChange,
        ILogger <KestrelServer> logger,
        ILogger <HttpsConnectionMiddleware> httpsLogger)
    {
        Options         = options ?? throw new ArgumentNullException(nameof(options));
        Configuration   = configuration ?? throw new ArgumentNullException(nameof(configuration));
        HostEnvironment = hostEnvironment ?? throw new ArgumentNullException(nameof(hostEnvironment));
        Logger          = logger ?? throw new ArgumentNullException(nameof(logger));
        HttpsLogger     = httpsLogger ?? throw new ArgumentNullException(nameof(logger));

        ReloadOnChange = reloadOnChange;

        ConfigurationReader     = new ConfigurationReader(configuration);
        CertificateConfigLoader = new CertificateConfigLoader(hostEnvironment, logger);
    }
Esempio n. 2
0
 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;
         }
     }
 }
Esempio n. 3
0
    // 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);
    }