Include address in error message when address already in use (#1086).
This commit is contained in:
parent
f1f66448f4
commit
2c94884da9
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
|
@ -109,8 +110,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
|
||||
if (!parsedAddress.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_disposables.Push(engine.CreateServer(
|
||||
parsedAddress));
|
||||
try
|
||||
{
|
||||
_disposables.Push(engine.CreateServer(parsedAddress));
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
if ((ex.InnerException as UvException)?.StatusCode == Constants.EADDRINUSE)
|
||||
{
|
||||
throw new IOException($"Failed to bind to address {parsedAddress}: address already in use.", ex);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -120,24 +132,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
}
|
||||
|
||||
var ipv4Address = parsedAddress.WithHost("127.0.0.1");
|
||||
var exceptions = new List<UvException>();
|
||||
var exceptions = new List<Exception>();
|
||||
|
||||
try
|
||||
{
|
||||
_disposables.Push(engine.CreateServer(ipv4Address));
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
catch (AggregateException ex) when (ex.InnerException is UvException)
|
||||
{
|
||||
var uvException = ex.InnerException as UvException;
|
||||
|
||||
if (uvException != null && uvException.StatusCode != Constants.EADDRINUSE)
|
||||
if ((ex.InnerException as UvException).StatusCode == Constants.EADDRINUSE)
|
||||
{
|
||||
_logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv4 loopback interface.");
|
||||
exceptions.Add(uvException);
|
||||
throw new IOException($"Failed to bind to address {parsedAddress.ToString()} on the IPv4 loopback interface: port already in use.", ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
_logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv4 loopback interface.");
|
||||
exceptions.Add(ex.InnerException);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,26 +157,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
{
|
||||
_disposables.Push(engine.CreateServer(ipv6Address));
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
catch (AggregateException ex) when (ex.InnerException is UvException)
|
||||
{
|
||||
var uvException = ex.InnerException as UvException;
|
||||
|
||||
if (uvException != null && uvException.StatusCode != Constants.EADDRINUSE)
|
||||
if ((ex.InnerException as UvException).StatusCode == Constants.EADDRINUSE)
|
||||
{
|
||||
_logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv6 loopback interface.");
|
||||
exceptions.Add(uvException);
|
||||
throw new IOException($"Failed to bind to address {parsedAddress.ToString()} on the IPv6 loopback interface: port already in use.", ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
_logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv6 loopback interface.");
|
||||
exceptions.Add(ex.InnerException);
|
||||
}
|
||||
}
|
||||
|
||||
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 new IOException($"Failed to bind to address {parsedAddress.ToString()}.", new AggregateException(exceptions));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
|
|
@ -97,6 +98,49 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsWhenBindingToIPv4AddressInUse()
|
||||
{
|
||||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||
{
|
||||
var port = GetNextPort();
|
||||
socket.Bind(new IPEndPoint(IPAddress.Loopback, port));
|
||||
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseUrls($"http://127.0.0.1:{port}")
|
||||
.Configure(ConfigureEchoAddress);
|
||||
|
||||
using (var host = hostBuilder.Build())
|
||||
{
|
||||
var exception = Assert.Throws<IOException>(() => host.Start());
|
||||
Assert.Equal($"Failed to bind to address http://127.0.0.1:{port}: address already in use.", exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[IPv6SupportedCondition]
|
||||
public void ThrowsWhenBindingToIPv6AddressInUse()
|
||||
{
|
||||
using (var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
|
||||
{
|
||||
var port = GetNextPort();
|
||||
socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, port));
|
||||
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseUrls($"http://[::1]:{port}")
|
||||
.Configure(ConfigureEchoAddress);
|
||||
|
||||
using (var host = hostBuilder.Build())
|
||||
{
|
||||
var exception = Assert.Throws<IOException>(() => host.Start());
|
||||
Assert.Equal($"Failed to bind to address http://[::1]:{port}: address already in use.", exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsWhenBindingLocalhostToIPv4AddressInUse()
|
||||
{
|
||||
|
|
@ -138,8 +182,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
using (var host = hostBuilder.Build())
|
||||
{
|
||||
var exception = Assert.Throws<AggregateException>(() => host.Start());
|
||||
Assert.Contains(exception.InnerExceptions, ex => ex is UvException);
|
||||
var exception = Assert.Throws<IOException>(() => host.Start());
|
||||
Assert.Equal(
|
||||
$"Failed to bind to address http://localhost:{port} on the {(addressFamily == AddressFamily.InterNetwork ? "IPv4" : "IPv6")} loopback interface: port already in use.",
|
||||
exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue