diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServer.cs b/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServer.cs index 50b873c265..1770678b29 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServer.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServer.cs @@ -107,81 +107,74 @@ namespace Microsoft.AspNetCore.Server.Kestrel foreach (var address in _serverAddresses.Addresses.ToArray()) { var parsedAddress = ServerAddress.FromUrl(address); - if (parsedAddress == null) + atLeastOneListener = true; + + if (!parsedAddress.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase)) { - throw new FormatException("Unrecognized listening address: " + address); + _disposables.Push(engine.CreateServer( + parsedAddress)); } else { - atLeastOneListener = true; - - if (!parsedAddress.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase)) + if (parsedAddress.Port == 0) { - _disposables.Push(engine.CreateServer( - parsedAddress)); + throw new InvalidOperationException("Dynamic port binding is not supported when binding to localhost. You must either bind to 127.0.0.1:0 or [::1]:0, or both."); } - else + + var ipv4Address = parsedAddress.WithHost("127.0.0.1"); + var exceptions = new List(); + + try { - if (parsedAddress.Port == 0) + _disposables.Push(engine.CreateServer(ipv4Address)); + } + catch (AggregateException ex) + { + var uvException = ex.InnerException as UvException; + + if (uvException != null && uvException.StatusCode != Constants.EADDRINUSE) { - throw new InvalidOperationException("Dynamic port binding is not supported when binding to localhost. You must either bind to 127.0.0.1:0 or [::1]:0, or both."); + _logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv4 loopback interface."); + exceptions.Add(uvException); } - - var ipv4Address = parsedAddress.WithHost("127.0.0.1"); - var exceptions = new List(); - - try + else { - _disposables.Push(engine.CreateServer(ipv4Address)); - } - catch (AggregateException ex) - { - var uvException = ex.InnerException as UvException; - - if (uvException != null && uvException.StatusCode != Constants.EADDRINUSE) - { - _logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv4 loopback interface."); - exceptions.Add(uvException); - } - else - { - throw; - } - } - - var ipv6Address = parsedAddress.WithHost("[::1]"); - - try - { - _disposables.Push(engine.CreateServer(ipv6Address)); - } - catch (AggregateException ex) - { - var uvException = ex.InnerException as UvException; - - if (uvException != null && uvException.StatusCode != Constants.EADDRINUSE) - { - _logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv6 loopback interface."); - exceptions.Add(uvException); - } - else - { - throw; - } - } - - if (exceptions.Count == 2) - { - var ex = new AggregateException(exceptions); - _logger.LogError(0, ex, $"Unable to bind to {parsedAddress.ToString()} on any loopback interface."); - throw ex; + throw; } } - // If requested port was "0", replace with assigned dynamic port. - _serverAddresses.Addresses.Remove(address); - _serverAddresses.Addresses.Add(parsedAddress.ToString()); + var ipv6Address = parsedAddress.WithHost("[::1]"); + + try + { + _disposables.Push(engine.CreateServer(ipv6Address)); + } + catch (AggregateException ex) + { + var uvException = ex.InnerException as UvException; + + if (uvException != null && uvException.StatusCode != Constants.EADDRINUSE) + { + _logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv6 loopback interface."); + exceptions.Add(uvException); + } + else + { + throw; + } + } + + if (exceptions.Count == 2) + { + var ex = new AggregateException(exceptions); + _logger.LogError(0, ex, $"Unable to bind to {parsedAddress.ToString()} on any loopback interface."); + throw ex; + } } + + // If requested port was "0", replace with assigned dynamic port. + _serverAddresses.Addresses.Remove(address); + _serverAddresses.Addresses.Add(parsedAddress.ToString()); } if (!atLeastOneListener) diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/ServerAddress.cs b/src/Microsoft.AspNetCore.Server.Kestrel/ServerAddress.cs index 528a39edb8..8f7b19c634 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/ServerAddress.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/ServerAddress.cs @@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel int schemeDelimiterStart = url.IndexOf("://", StringComparison.Ordinal); if (schemeDelimiterStart < 0) { - return null; + throw new FormatException($"Invalid URL: {url}"); } int schemeDelimiterEnd = schemeDelimiterStart + "://".Length; diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/KestrelServerTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/KestrelServerTests.cs index 7db58f52a6..f83e6bcc0a 100644 --- a/test/Microsoft.AspNetCore.Server.KestrelTests/KestrelServerTests.cs +++ b/test/Microsoft.AspNetCore.Server.KestrelTests/KestrelServerTests.cs @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests var exception = Assert.Throws(() => StartDummyApplication(server)); - Assert.Contains("Unrecognized listening address", exception.Message); + Assert.Contains("Invalid URL", exception.Message); } [Fact] diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/ServerAddressTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/ServerAddressTests.cs index 50c96cc9c4..9e113d7978 100644 --- a/test/Microsoft.AspNetCore.Server.KestrelTests/ServerAddressTests.cs +++ b/test/Microsoft.AspNetCore.Server.KestrelTests/ServerAddressTests.cs @@ -14,9 +14,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests [InlineData("")] [InlineData("5000")] [InlineData("//noscheme")] - public void FromUriReturnsNullForSchemelessUrls(string url) + public void FromUriThrowsForSchemelessUrls(string url) { - Assert.Null(ServerAddress.FromUrl(url)); + Assert.Throws(() => ServerAddress.FromUrl(url)); } [Theory]