11// Copyright (c) .NET Foundation. All rights reserved.
22// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33
4+ #nullable enable
5+
46using System ;
57using System . Collections . Generic ;
68using System . IO ;
79using System . Linq ;
810using System . Net ;
911using System . Security . Cryptography . X509Certificates ;
12+ using System . Text ;
1013using Microsoft . AspNetCore . Certificates . Generation ;
1114using Microsoft . AspNetCore . Http ;
1215using Microsoft . AspNetCore . Server . Kestrel . Core . Internal ;
16+ using Microsoft . AspNetCore . Server . Kestrel . Core . Internal . Infrastructure ;
1317using Microsoft . AspNetCore . Server . Kestrel . Https ;
1418using Microsoft . Extensions . Configuration ;
1519using Microsoft . Extensions . DependencyInjection ;
@@ -22,6 +26,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
2226 /// </summary>
2327 public class KestrelServerOptions
2428 {
29+ // Internal to fast-path header decoding when RequestHeaderEncodingSelector is unchanged.
30+ internal static readonly UTF8EncodingSealed DefaultRequestHeaderEncoding = new UTF8EncodingSealed ( ) ;
31+ internal static readonly Func < string , Encoding > DefaultRequestHeaderEncodingSelector = _ => DefaultRequestHeaderEncoding ;
32+ internal static readonly Func < string , Encoding > DefaultLatin1RequestHeaderEncodingSelector = _ => Encoding . Latin1 ;
33+
2534 // The following two lists configure the endpoints that Kestrel should listen to. If both lists are empty, the "urls" config setting (e.g. UseUrls) is used.
2635 internal List < ListenOptions > CodeBackedListenOptions { get ; } = new List < ListenOptions > ( ) ;
2736 internal List < ListenOptions > ConfigurationBackedListenOptions { get ; } = new List < ListenOptions > ( ) ;
@@ -65,11 +74,27 @@ public class KestrelServerOptions
6574 /// </remarks>
6675 public bool DisableStringReuse { get ; set ; } = false ;
6776
77+ /// <summary>
78+ /// Controls whether to return the AltSvcHeader from on an HTTP/2 or lower response for HTTP/3
79+ /// </summary>
80+ /// <remarks>
81+ /// Defaults to false.
82+ /// </remarks>
83+ public bool EnableAltSvc { get ; set ; } = false ;
84+
85+ /// <summary>
86+ /// Gets or sets a callback that returns the <see cref="Encoding"/> to decode the value for the specified request header name.
87+ /// </summary>
88+ /// <remarks>
89+ /// Defaults to returning a <see cref="UTF8Encoding"/> for all headers.
90+ /// </remarks>
91+ public Func < string , Encoding ? > RequestHeaderEncodingSelector { get ; set ; } = DefaultRequestHeaderEncodingSelector ;
92+
6893 /// <summary>
6994 /// Enables the Listen options callback to resolve and use services registered by the application during startup.
7095 /// Typically initialized by UseKestrel()"/>.
7196 /// </summary>
72- public IServiceProvider ApplicationServices { get ; set ; }
97+ public IServiceProvider ? ApplicationServices { get ; set ; }
7398
7499 /// <summary>
75100 /// Provides access to request limit options.
@@ -80,12 +105,7 @@ public class KestrelServerOptions
80105 /// Provides a configuration source where endpoints will be loaded from on server start.
81106 /// The default is null.
82107 /// </summary>
83- public KestrelConfigurationLoader ConfigurationLoader { get ; set ; }
84-
85- /// <summary>
86- /// Controls whether to return the AltSvcHeader from on an HTTP/2 or lower response for HTTP/3
87- /// </summary>
88- public bool EnableAltSvc { get ; set ; } = false ;
108+ public KestrelConfigurationLoader ? ConfigurationLoader { get ; set ; }
89109
90110 /// <summary>
91111 /// A default configuration action for all endpoints. Use for Listen, configuration, the default url, and URLs.
@@ -100,7 +120,7 @@ public class KestrelServerOptions
100120 /// <summary>
101121 /// The default server certificate for https endpoints. This is applied lazily after HttpsDefaults and user options.
102122 /// </summary>
103- internal X509Certificate2 DefaultCertificate { get ; set ; }
123+ internal X509Certificate2 ? DefaultCertificate { get ; set ; }
104124
105125 /// <summary>
106126 /// Has the default dev certificate load been attempted?
@@ -121,9 +141,19 @@ public void ConfigureEndpointDefaults(Action<ListenOptions> configureOptions)
121141 EndpointDefaults = configureOptions ?? throw new ArgumentNullException ( nameof ( configureOptions ) ) ;
122142 }
123143
144+ internal Func < string , Encoding ? > GetRequestHeaderEncodingSelector ( )
145+ {
146+ if ( ReferenceEquals ( RequestHeaderEncodingSelector , DefaultRequestHeaderEncodingSelector ) && Latin1RequestHeaders )
147+ {
148+ return DefaultLatin1RequestHeaderEncodingSelector ;
149+ }
150+
151+ return RequestHeaderEncodingSelector ;
152+ }
153+
124154 internal void ApplyEndpointDefaults ( ListenOptions listenOptions )
125155 {
126- listenOptions . KestrelServerOptions = this ;
156+ listenOptions . KestrelServerOptions = this ;
127157 ConfigurationLoader ? . ApplyConfigurationDefaults ( listenOptions ) ;
128158 EndpointDefaults ( listenOptions ) ;
129159 }
@@ -159,7 +189,7 @@ private void EnsureDefaultCert()
159189 if ( DefaultCertificate == null && ! IsDevCertLoaded )
160190 {
161191 IsDevCertLoaded = true ; // Only try once
162- var logger = ApplicationServices . GetRequiredService < ILogger < KestrelServer > > ( ) ;
192+ var logger = ApplicationServices ! . GetRequiredService < ILogger < KestrelServer > > ( ) ;
163193 try
164194 {
165195 DefaultCertificate = CertificateManager . Instance . ListCertificates ( StoreName . My , StoreLocation . CurrentUser , isValid : true )
@@ -220,10 +250,11 @@ private void EnsureDefaultCert()
220250 /// </summary>
221251 /// <param name="config">The configuration section for Kestrel.</param>
222252 /// <param name="reloadOnChange">
223- /// If <see langword="true" />, Kestrel will dynamically update endpoint bindings when configuration changes.
253+ /// If <see langword="true"/>, Kestrel will dynamically update endpoint bindings when configuration changes.
224254 /// This will only reload endpoints defined in the "Endpoints" section of your <paramref name="config"/>. Endpoints defined in code will not be reloaded.
225255 /// </param>
226256 /// <returns>A <see cref="KestrelConfigurationLoader"/> for further endpoint configuration.</returns>
257+
227258 public KestrelConfigurationLoader Configure ( IConfiguration config , bool reloadOnChange )
228259 {
229260 var loader = new KestrelConfigurationLoader ( this , config , reloadOnChange ) ;
0 commit comments