Fix NRE in KestrelServerOptions.Listen*() (#21467)

* Fix NRE in KestrelServerOptions.Listen*()

* Fix tests
This commit is contained in:
Stephen Halter 2020-05-04 20:04:28 -07:00 committed by GitHub
parent c9ce0664ea
commit 4ebf695a98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 10 deletions

View File

@ -19,19 +19,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private IDictionary<string, CertificateConfig> _certificates;
private EndpointDefaults _endpointDefaults;
private IEnumerable<EndpointConfig> _endpoints;
private bool? _latin1RequestHeaders;
public ConfigurationReader(IConfiguration configuration) public ConfigurationReader(IConfiguration configuration)
{ {
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
Certificates = ReadCertificates();
EndpointDefaults = ReadEndpointDefaults();
Endpoints = ReadEndpoints();
Latin1RequestHeaders = _configuration.GetValue<bool>(Latin1RequestHeadersKey);
} }
public IDictionary<string, CertificateConfig> Certificates { get; } public IDictionary<string, CertificateConfig> Certificates => _certificates ??= ReadCertificates();
public EndpointDefaults EndpointDefaults { get; } public EndpointDefaults EndpointDefaults => _endpointDefaults ??= ReadEndpointDefaults();
public IEnumerable<EndpointConfig> Endpoints { get; } public IEnumerable<EndpointConfig> Endpoints => _endpoints ??= ReadEndpoints();
public bool Latin1RequestHeaders { get; } public bool Latin1RequestHeaders => _latin1RequestHeaders ??= _configuration.GetValue<bool>(Latin1RequestHeadersKey);
private IDictionary<string, CertificateConfig> ReadCertificates() private IDictionary<string, CertificateConfig> ReadCertificates()
{ {

View File

@ -29,6 +29,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel
Options = options ?? throw new ArgumentNullException(nameof(options)); Options = options ?? throw new ArgumentNullException(nameof(options));
Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
ReloadOnChange = reloadOnChange; ReloadOnChange = reloadOnChange;
ConfigurationReader = new ConfigurationReader(configuration);
} }
public KestrelServerOptions Options { get; } public KestrelServerOptions Options { get; }

View File

@ -49,5 +49,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
}); });
Assert.Equal(HttpProtocols.Http2, options.CodeBackedListenOptions[3].Protocols); Assert.Equal(HttpProtocols.Http2, options.CodeBackedListenOptions[3].Protocols);
} }
[Fact]
public void CanCallListenAfterConfigure()
{
var options = new KestrelServerOptions();
options.Configure();
// This is a regression test to verify the Listen* methods don't throw a NullReferenceException if called after Configure().
// https://github.com/dotnet/aspnetcore/issues/21423
options.ListenLocalhost(5000);
}
} }
} }

View File

@ -97,7 +97,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests
{ {
new KeyValuePair<string, string>("Endpoints:End1", ""), new KeyValuePair<string, string>("Endpoints:End1", ""),
}).Build(); }).Build();
Assert.Throws<InvalidOperationException>(() => new ConfigurationReader(config)); var reader = new ConfigurationReader(config);
Assert.Throws<InvalidOperationException>(() => reader.Endpoints);
} }
[Fact] [Fact]
@ -107,7 +108,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests
{ {
new KeyValuePair<string, string>("Endpoints:End1:Url", ""), new KeyValuePair<string, string>("Endpoints:End1:Url", ""),
}).Build(); }).Build();
Assert.Throws<InvalidOperationException>(() => new ConfigurationReader(config)); var reader = new ConfigurationReader(config);
Assert.Throws<InvalidOperationException>(() => reader.Endpoints);
} }
[Fact] [Fact]