Bind to both IPv4 and IPv6 when localhost is specified (#231).
This commit is contained in:
parent
3f4e2323f4
commit
a3d0bd0ec4
|
|
@ -11,6 +11,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
||||||
|
|
||||||
public const int EOF = -4095;
|
public const int EOF = -4095;
|
||||||
public static readonly int? ECONNRESET = GetECONNRESET();
|
public static readonly int? ECONNRESET = GetECONNRESET();
|
||||||
|
public static readonly int? EADDRINUSE = GetEADDRINUSE();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prefix of host name used to specify Unix sockets in the configuration.
|
/// Prefix of host name used to specify Unix sockets in the configuration.
|
||||||
|
|
@ -39,5 +40,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int? GetEADDRINUSE()
|
||||||
|
{
|
||||||
|
switch (PlatformServices.Default.Runtime.OperatingSystemPlatform)
|
||||||
|
{
|
||||||
|
case Platform.Windows:
|
||||||
|
return -4091;
|
||||||
|
case Platform.Linux:
|
||||||
|
return -98;
|
||||||
|
case Platform.Darwin:
|
||||||
|
return -48;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
|
|
@ -11,6 +12,7 @@ using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Networking;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
|
|
@ -94,6 +96,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Unable to determine ECONNRESET value on this platform.");
|
_logger.LogWarning("Unable to determine ECONNRESET value on this platform.");
|
||||||
}
|
}
|
||||||
|
if (!Constants.EADDRINUSE.HasValue)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Unable to determine EADDRINUSE value on this platform.");
|
||||||
|
}
|
||||||
|
|
||||||
engine.Start(threadCount);
|
engine.Start(threadCount);
|
||||||
var atLeastOneListener = false;
|
var atLeastOneListener = false;
|
||||||
|
|
@ -108,8 +114,69 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
atLeastOneListener = true;
|
atLeastOneListener = true;
|
||||||
_disposables.Push(engine.CreateServer(
|
|
||||||
parsedAddress));
|
if (!parsedAddress.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
_disposables.Push(engine.CreateServer(
|
||||||
|
parsedAddress));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (parsedAddress.Port == 0)
|
||||||
|
{
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var ipv4Address = parsedAddress.WithHost("127.0.0.1");
|
||||||
|
var exceptions = new List<UvException>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If requested port was "0", replace with assigned dynamic port.
|
// If requested port was "0", replace with assigned dynamic port.
|
||||||
_serverAddresses.Addresses.Remove(address);
|
_serverAddresses.Addresses.Remove(address);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Networking
|
||||||
{
|
{
|
||||||
var errorName = err_name(statusCode);
|
var errorName = err_name(statusCode);
|
||||||
var errorDescription = strerror(statusCode);
|
var errorDescription = strerror(statusCode);
|
||||||
error = new UvException("Error " + statusCode + " " + errorName + " " + errorDescription);
|
error = new UvException("Error " + statusCode + " " + errorName + " " + errorDescription, statusCode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Networking
|
||||||
{
|
{
|
||||||
public class UvException : Exception
|
public class UvException : Exception
|
||||||
{
|
{
|
||||||
public UvException(string message) : base(message) { }
|
public UvException(string message, int statusCode) : base(message)
|
||||||
|
{
|
||||||
|
StatusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int StatusCode { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,5 +155,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
||||||
|
|
||||||
return serverAddress;
|
return serverAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal ServerAddress WithHost(string host)
|
||||||
|
{
|
||||||
|
return new ServerAddress
|
||||||
|
{
|
||||||
|
Scheme = Scheme,
|
||||||
|
Host = host,
|
||||||
|
Port = Port,
|
||||||
|
PathBase = PathBase
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
|
@ -13,8 +12,8 @@ using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Extensions;
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Networking;
|
||||||
using Microsoft.AspNetCore.Testing.xunit;
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
@ -42,7 +41,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
await RegisterAddresses_Success(addressInput, testUrls);
|
await RegisterAddresses_Success(addressInput, testUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory, MemberData(nameof(AddressRegistrationDataIPv6Port80))]
|
||||||
|
[IPv6SupportedCondition]
|
||||||
|
[Port80SupportedCondition]
|
||||||
|
public async Task RegisterAddresses_IPv6Port80_Success(string addressInput, Func<IServerAddressesFeature, string[]> testUrls)
|
||||||
|
{
|
||||||
|
await RegisterAddresses_Success(addressInput, testUrls);
|
||||||
|
}
|
||||||
|
|
||||||
[ConditionalTheory, MemberData(nameof(AddressRegistrationDataIPv6ScopeId))]
|
[ConditionalTheory, MemberData(nameof(AddressRegistrationDataIPv6ScopeId))]
|
||||||
|
[IPv6SupportedCondition]
|
||||||
[OSSkipCondition(OperatingSystems.Linux, SkipReason = "HttpClient does not support IPv6 with scope ID on Linux (https://github.com/dotnet/corefx/issues/8235).")]
|
[OSSkipCondition(OperatingSystems.Linux, SkipReason = "HttpClient does not support IPv6 with scope ID on Linux (https://github.com/dotnet/corefx/issues/8235).")]
|
||||||
[OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "HttpClient does not support IPv6 with scope ID on Mac (https://github.com/dotnet/corefx/issues/8235).")]
|
[OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "HttpClient does not support IPv6 with scope ID on Mac (https://github.com/dotnet/corefx/issues/8235).")]
|
||||||
public async Task RegisterAddresses_IPv6ScopeId_Success(string addressInput, Func<IServerAddressesFeature, string[]> testUrls)
|
public async Task RegisterAddresses_IPv6ScopeId_Success(string addressInput, Func<IServerAddressesFeature, string[]> testUrls)
|
||||||
|
|
@ -50,18 +58,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
await RegisterAddresses_Success(addressInput, testUrls);
|
await RegisterAddresses_Success(addressInput, testUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RegisterAddresses_Success(string addressInput, Func<IServerAddressesFeature, string[]> testUrls)
|
private async Task RegisterAddresses_Success(string addressInput, Func<IServerAddressesFeature, string[]> testUrls)
|
||||||
{
|
{
|
||||||
var config = new ConfigurationBuilder()
|
|
||||||
.AddInMemoryCollection(new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "server.urls", addressInput }
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder()
|
var hostBuilder = new WebHostBuilder()
|
||||||
.UseConfiguration(config)
|
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
|
.UseUrls(addressInput)
|
||||||
.Configure(ConfigureEchoAddress);
|
.Configure(ConfigureEchoAddress);
|
||||||
|
|
||||||
using (var host = hostBuilder.Build())
|
using (var host = hostBuilder.Build())
|
||||||
|
|
@ -84,6 +85,53 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ThrowsWhenBindingLocalhostToIPv4AddressInUse()
|
||||||
|
{
|
||||||
|
ThrowsWhenBindingLocalhostToAddressInUse(AddressFamily.InterNetwork, IPAddress.Loopback);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[IPv6SupportedCondition]
|
||||||
|
public void ThrowsWhenBindingLocalhostToIPv6AddressInUse()
|
||||||
|
{
|
||||||
|
ThrowsWhenBindingLocalhostToAddressInUse(AddressFamily.InterNetworkV6, IPAddress.IPv6Loopback);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ThrowsWhenBindingLocalhostToDynamicPort()
|
||||||
|
{
|
||||||
|
var hostBuilder = new WebHostBuilder()
|
||||||
|
.UseKestrel()
|
||||||
|
.UseUrls("http://localhost:0")
|
||||||
|
.Configure(ConfigureEchoAddress);
|
||||||
|
|
||||||
|
using (var host = hostBuilder.Build())
|
||||||
|
{
|
||||||
|
Assert.Throws<InvalidOperationException>(() => host.Start());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThrowsWhenBindingLocalhostToAddressInUse(AddressFamily addressFamily, IPAddress address)
|
||||||
|
{
|
||||||
|
using (var socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp))
|
||||||
|
{
|
||||||
|
var port = GetNextPort();
|
||||||
|
socket.Bind(new IPEndPoint(address, port));
|
||||||
|
|
||||||
|
var hostBuilder = new WebHostBuilder()
|
||||||
|
.UseKestrel()
|
||||||
|
.UseUrls($"http://localhost:{port}")
|
||||||
|
.Configure(ConfigureEchoAddress);
|
||||||
|
|
||||||
|
using (var host = hostBuilder.Build())
|
||||||
|
{
|
||||||
|
var exception = Assert.Throws<AggregateException>(() => host.Start());
|
||||||
|
Assert.Contains(exception.InnerExceptions, ex => ex is UvException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static TheoryData<string, Func<IServerAddressesFeature, string[]>> AddressRegistrationDataIPv4
|
public static TheoryData<string, Func<IServerAddressesFeature, string[]>> AddressRegistrationDataIPv4
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -91,26 +139,31 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
var dataset = new TheoryData<string, Func<IServerAddressesFeature, string[]>>();
|
var dataset = new TheoryData<string, Func<IServerAddressesFeature, string[]>>();
|
||||||
|
|
||||||
// Default host and port
|
// Default host and port
|
||||||
dataset.Add(null, _ => new[] { "http://localhost:5000/" });
|
dataset.Add(null, _ => new[] { "http://127.0.0.1:5000/" });
|
||||||
dataset.Add(string.Empty, _ => new[] { "http://localhost:5000/" });
|
dataset.Add(string.Empty, _ => new[] { "http://127.0.0.1:5000/" });
|
||||||
|
|
||||||
// Static port
|
// Static ports
|
||||||
var port1 = GetNextPort();
|
var port1 = GetNextPort();
|
||||||
var port2 = GetNextPort();
|
var port2 = GetNextPort();
|
||||||
|
|
||||||
// Ensure multiple addresses can be separated by semicolon
|
// Loopback
|
||||||
dataset.Add($"http://localhost:{port1};http://localhost:{port2}",
|
dataset.Add($"http://127.0.0.1:{port1}", _ => new[] { $"http://127.0.0.1:{port1}/" });
|
||||||
_ => new[] { $"http://localhost:{port1}/", $"http://localhost:{port2}/" });
|
|
||||||
|
|
||||||
// Ensure "localhost" and "127.0.0.1" are equivalent
|
// Localhost
|
||||||
dataset.Add($"http://localhost:{port1}", _ => new[] { $"http://localhost:{port1}/", $"http://127.0.0.1:{port1}/" });
|
dataset.Add($"http://localhost:{port1}", _ => new[] { $"http://localhost:{port1}/", $"http://127.0.0.1:{port1}/" });
|
||||||
dataset.Add($"http://127.0.0.1:{port1}", _ => new[] { $"http://localhost:{port1}/", $"http://127.0.0.1:{port1}/" });
|
|
||||||
|
// Any
|
||||||
|
dataset.Add($"http://*:{port1}/", _ => new[] { $"http://127.0.0.1:{port1}/" });
|
||||||
|
dataset.Add($"http://+:{port1}/", _ => new[] { $"http://127.0.0.1:{port1}/" });
|
||||||
|
|
||||||
|
// Multiple addresses
|
||||||
|
dataset.Add($"http://127.0.0.1:{port1};http://127.0.0.1:{port2}", _ => new[] { $"http://127.0.0.1:{port1}/", $"http://127.0.0.1:{port2}/" });
|
||||||
|
|
||||||
// Path after port
|
// Path after port
|
||||||
dataset.Add($"http://localhost:{port1}/base/path", _ => new[] { $"http://localhost:{port1}/base/path" });
|
dataset.Add($"http://127.0.0.1:{port1}/base/path", _ => new[] { $"http://127.0.0.1:{port1}/base/path" });
|
||||||
|
|
||||||
// Dynamic port
|
// Dynamic port and non-loopback addresses
|
||||||
dataset.Add("http://localhost:0/", GetTestUrls);
|
dataset.Add("http://127.0.0.1:0/", GetTestUrls);
|
||||||
dataset.Add($"http://{Dns.GetHostName()}:0/", GetTestUrls);
|
dataset.Add($"http://{Dns.GetHostName()}:0/", GetTestUrls);
|
||||||
|
|
||||||
var ipv4Addresses = Dns.GetHostAddressesAsync(Dns.GetHostName()).Result
|
var ipv4Addresses = Dns.GetHostAddressesAsync(Dns.GetHostName()).Result
|
||||||
|
|
@ -131,8 +184,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
var dataset = new TheoryData<string, Func<IServerAddressesFeature, string[]>>();
|
var dataset = new TheoryData<string, Func<IServerAddressesFeature, string[]>>();
|
||||||
|
|
||||||
// Default port for HTTP (80)
|
// Default port for HTTP (80)
|
||||||
dataset.Add("http://*", _ => new[] { "http://localhost/" });
|
dataset.Add("http://127.0.0.1", _ => new[] { "http://127.0.0.1/" });
|
||||||
dataset.Add("http://localhost", _ => new[] { "http://localhost/" });
|
dataset.Add("http://localhost", _ => new[] { "http://127.0.0.1/" });
|
||||||
|
dataset.Add("http://*", _ => new[] { "http://127.0.0.1/" });
|
||||||
|
|
||||||
return dataset;
|
return dataset;
|
||||||
}
|
}
|
||||||
|
|
@ -144,17 +198,32 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
var dataset = new TheoryData<string, Func<IServerAddressesFeature, string[]>>();
|
var dataset = new TheoryData<string, Func<IServerAddressesFeature, string[]>>();
|
||||||
|
|
||||||
// Static port
|
// Default host and port
|
||||||
var port = GetNextPort();
|
dataset.Add(null, _ => new[] { "http://127.0.0.1:5000/", "http://[::1]:5000/" });
|
||||||
dataset.Add($"http://*:{port}/", _ => new[] { $"http://localhost:{port}/", $"http://127.0.0.1:{port}/", $"http://[::1]:{port}/" });
|
dataset.Add(string.Empty, _ => new[] { "http://127.0.0.1:5000/", "http://[::1]:5000/" });
|
||||||
dataset.Add($"http://localhost:{port}/", _ => new[] { $"http://localhost:{port}/", $"http://127.0.0.1:{port}/",
|
|
||||||
/* // https://github.com/aspnet/KestrelHttpServer/issues/231
|
|
||||||
$"http://[::1]:{port}/"
|
|
||||||
*/ });
|
|
||||||
dataset.Add($"http://[::1]:{port}/", _ => new[] { $"http://[::1]:{port}/", });
|
|
||||||
dataset.Add($"http://127.0.0.1:{port}/;http://[::1]:{port}/", _ => new[] { $"http://127.0.0.1:{port}/", $"http://[::1]:{port}/" });
|
|
||||||
|
|
||||||
// Dynamic port
|
// Static ports
|
||||||
|
var port1 = GetNextPort();
|
||||||
|
var port2 = GetNextPort();
|
||||||
|
|
||||||
|
// Loopback
|
||||||
|
dataset.Add($"http://[::1]:{port1}/", _ => new[] { $"http://[::1]:{port1}/" });
|
||||||
|
|
||||||
|
// Localhost
|
||||||
|
dataset.Add($"http://localhost:{port1}", _ => new[] { $"http://localhost:{port1}/", $"http://127.0.0.1:{port1}/", $"http://[::1]:{port1}/" });
|
||||||
|
|
||||||
|
// Any
|
||||||
|
dataset.Add($"http://*:{port1}/", _ => new[] { $"http://127.0.0.1:{port1}/", $"http://[::1]:{port1}/" });
|
||||||
|
dataset.Add($"http://+:{port1}/", _ => new[] { $"http://127.0.0.1:{port1}/", $"http://[::1]:{port1}/" });
|
||||||
|
|
||||||
|
// Multiple addresses
|
||||||
|
dataset.Add($"http://127.0.0.1:{port1}/;http://[::1]:{port1}/", _ => new[] { $"http://127.0.0.1:{port1}/", $"http://[::1]:{port1}/" });
|
||||||
|
dataset.Add($"http://[::1]:{port1};http://[::1]:{port2}", _ => new[] { $"http://[::1]:{port1}/", $"http://[::1]:{port2}/" });
|
||||||
|
|
||||||
|
// Path after port
|
||||||
|
dataset.Add($"http://[::1]:{port1}/base/path", _ => new[] { $"http://[::1]:{port1}/base/path" });
|
||||||
|
|
||||||
|
// Dynamic port and non-loopback addresses
|
||||||
var ipv6Addresses = Dns.GetHostAddressesAsync(Dns.GetHostName()).Result
|
var ipv6Addresses = Dns.GetHostAddressesAsync(Dns.GetHostName()).Result
|
||||||
.Where(ip => ip.AddressFamily == AddressFamily.InterNetworkV6)
|
.Where(ip => ip.AddressFamily == AddressFamily.InterNetworkV6)
|
||||||
.Where(ip => ip.ScopeId == 0);
|
.Where(ip => ip.ScopeId == 0);
|
||||||
|
|
@ -167,6 +236,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TheoryData<string, Func<IServerAddressesFeature, string[]>> AddressRegistrationDataIPv6Port80
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var dataset = new TheoryData<string, Func<IServerAddressesFeature, string[]>>();
|
||||||
|
|
||||||
|
// Default port for HTTP (80)
|
||||||
|
dataset.Add("http://[::1]", _ => new[] { "http://[::1]/" });
|
||||||
|
dataset.Add("http://localhost", _ => new[] { "http://127.0.0.1/", "http://[::1]/" });
|
||||||
|
dataset.Add("http://*", _ => new[] { "http://[::1]/" });
|
||||||
|
|
||||||
|
return dataset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static TheoryData<string, Func<IServerAddressesFeature, string[]>> AddressRegistrationDataIPv6ScopeId
|
public static TheoryData<string, Func<IServerAddressesFeature, string[]>> AddressRegistrationDataIPv6ScopeId
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
using (var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
|
using (var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
|
||||||
{
|
{
|
||||||
socket.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 8787));
|
socket.Bind(new IPEndPoint(IPAddress.IPv6Any, 0));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -68,14 +66,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
private async Task TestPathBase(string registerPathBase, string requestPath, string expectedPathBase, string expectedPath)
|
private async Task TestPathBase(string registerPathBase, string requestPath, string expectedPathBase, string expectedPath)
|
||||||
{
|
{
|
||||||
var config = new ConfigurationBuilder().AddInMemoryCollection(
|
|
||||||
new Dictionary<string, string> {
|
|
||||||
{ "server.urls", $"http://localhost:0{registerPathBase}" }
|
|
||||||
}).Build();
|
|
||||||
|
|
||||||
var builder = new WebHostBuilder()
|
var builder = new WebHostBuilder()
|
||||||
.UseConfiguration(config)
|
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
|
.UseUrls($"http://127.0.0.1:0{registerPathBase}")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
var builder = new WebHostBuilder()
|
var builder = new WebHostBuilder()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseUrls($"http://localhost:0/")
|
.UseUrls("http://127.0.0.1:0/")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
var builder = new WebHostBuilder()
|
var builder = new WebHostBuilder()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseUrls($"http://localhost:0/")
|
.UseUrls("http://127.0.0.1:0/")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
@ -117,12 +117,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Fact]
|
||||||
[InlineData("127.0.0.1", "127.0.0.1")]
|
public Task RemoteIPv4Address()
|
||||||
[InlineData("localhost", "127.0.0.1")]
|
|
||||||
public Task RemoteIPv4Address(string requestAddress, string expectAddress)
|
|
||||||
{
|
{
|
||||||
return TestRemoteIPAddress("localhost", requestAddress, expectAddress);
|
return TestRemoteIPAddress("127.0.0.1", "127.0.0.1", "127.0.0.1");
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalFact]
|
[ConditionalFact]
|
||||||
|
|
@ -137,7 +135,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
var builder = new WebHostBuilder()
|
var builder = new WebHostBuilder()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseUrls($"http://localhost:0")
|
.UseUrls($"http://127.0.0.1:0")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
@ -165,7 +163,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
var builder = new WebHostBuilder()
|
var builder = new WebHostBuilder()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseUrls($"http://localhost:0/\u0041\u030A")
|
.UseUrls($"http://127.0.0.1:0/\u0041\u030A")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
|
@ -10,7 +9,6 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -21,16 +19,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task LargeDownload()
|
public async Task LargeDownload()
|
||||||
{
|
{
|
||||||
var config = new ConfigurationBuilder()
|
|
||||||
.AddInMemoryCollection(new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "server.urls", $"http://localhost:0/" }
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder()
|
var hostBuilder = new WebHostBuilder()
|
||||||
.UseConfiguration(config)
|
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
|
.UseUrls("http://127.0.0.1:0/")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
@ -80,16 +71,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
[Theory, MemberData(nameof(NullHeaderData))]
|
[Theory, MemberData(nameof(NullHeaderData))]
|
||||||
public async Task IgnoreNullHeaderValues(string headerName, StringValues headerValue, string expectedValue)
|
public async Task IgnoreNullHeaderValues(string headerName, StringValues headerValue, string expectedValue)
|
||||||
{
|
{
|
||||||
var config = new ConfigurationBuilder()
|
|
||||||
.AddInMemoryCollection(new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "server.urls", $"http://localhost:0/" }
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder()
|
var hostBuilder = new WebHostBuilder()
|
||||||
.UseConfiguration(config)
|
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
|
.UseUrls("http://127.0.0.1:0/")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
@ -127,19 +111,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task OnCompleteCalledEvenWhenOnStartingNotCalled()
|
public async Task OnCompleteCalledEvenWhenOnStartingNotCalled()
|
||||||
{
|
{
|
||||||
var config = new ConfigurationBuilder()
|
|
||||||
.AddInMemoryCollection(new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "server.urls", $"http://localhost:0/" }
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var onStartingCalled = false;
|
var onStartingCalled = false;
|
||||||
var onCompletedCalled = false;
|
var onCompletedCalled = false;
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder()
|
var hostBuilder = new WebHostBuilder()
|
||||||
.UseConfiguration(config)
|
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
|
.UseUrls("http://127.0.0.1:0/")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(context =>
|
app.Run(context =>
|
||||||
|
|
|
||||||
|
|
@ -7,28 +7,22 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
public class ThreadCountTests
|
public class ThreadCountTests
|
||||||
{
|
{
|
||||||
public async Task ZeroToTenThreads(int threadCount)
|
[Theory]
|
||||||
|
[MemberData(nameof(OneToTen))]
|
||||||
|
public async Task OneToTenThreads(int threadCount)
|
||||||
{
|
{
|
||||||
var config = new ConfigurationBuilder()
|
|
||||||
.AddInMemoryCollection(new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "server.urls", $"http://localhost:0/" }
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder()
|
var hostBuilder = new WebHostBuilder()
|
||||||
.UseConfiguration(config)
|
|
||||||
.UseKestrel(options =>
|
.UseKestrel(options =>
|
||||||
{
|
{
|
||||||
options.ThreadCount = threadCount;
|
options.ThreadCount = threadCount;
|
||||||
})
|
})
|
||||||
|
.UseUrls("http://127.0.0.1:0/")
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.Run(context =>
|
app.Run(context =>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
FrameFactory = connectionContext => new Frame<HttpContext>(
|
FrameFactory = connectionContext => new Frame<HttpContext>(
|
||||||
new DummyApplication(httpContext => TaskUtilities.CompletedTask), connectionContext),
|
new DummyApplication(httpContext => TaskUtilities.CompletedTask), connectionContext),
|
||||||
Memory = memory,
|
Memory = memory,
|
||||||
ServerAddress = ServerAddress.FromUrl($"http://localhost:0"),
|
ServerAddress = ServerAddress.FromUrl("http://127.0.0.1:0"),
|
||||||
Thread = engine.Threads[0]
|
Thread = engine.Threads[0]
|
||||||
};
|
};
|
||||||
var socket = new MockSocket(mockLibuv, Thread.CurrentThread.ManagedThreadId, trace);
|
var socket = new MockSocket(mockLibuv, Thread.CurrentThread.ManagedThreadId, trace);
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
testContext.App = App;
|
testContext.App = App;
|
||||||
var engine = new KestrelEngine(testContext);
|
var engine = new KestrelEngine(testContext);
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
var address = ServerAddress.FromUrl($"http://localhost:0/");
|
var address = ServerAddress.FromUrl("http://127.0.0.1:0/");
|
||||||
var started = engine.CreateServer(address);
|
var started = engine.CreateServer(address);
|
||||||
started.Dispose();
|
started.Dispose();
|
||||||
engine.Dispose();
|
engine.Dispose();
|
||||||
|
|
@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
testContext.App = App;
|
testContext.App = App;
|
||||||
var engine = new KestrelEngine(testContext);
|
var engine = new KestrelEngine(testContext);
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
var address = ServerAddress.FromUrl($"http://localhost:0/");
|
var address = ServerAddress.FromUrl("http://127.0.0.1:0/");
|
||||||
var started = engine.CreateServer(address);
|
var started = engine.CreateServer(address);
|
||||||
|
|
||||||
var socket = TestConnection.CreateConnectedLoopbackSocket(address.Port);
|
var socket = TestConnection.CreateConnectedLoopbackSocket(address.Port);
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
new NoOpConnectionFilter())
|
new NoOpConnectionFilter())
|
||||||
);
|
);
|
||||||
|
|
||||||
using (var server = new TestServer(App, serviceContext, "https://localhost:0/"))
|
using (var server = new TestServer(App, serviceContext, "https://127.0.0.1:0/"))
|
||||||
{
|
{
|
||||||
using (var client = new HttpClient(handler))
|
using (var client = new HttpClient(handler))
|
||||||
{
|
{
|
||||||
|
|
@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
new NoOpConnectionFilter())
|
new NoOpConnectionFilter())
|
||||||
);
|
);
|
||||||
|
|
||||||
using (var server = new TestServer(App, serviceContext, "https://localhost:0/"))
|
using (var server = new TestServer(App, serviceContext, "https://127.0.0.1:0/"))
|
||||||
{
|
{
|
||||||
using (var client = new HttpClient(handler))
|
using (var client = new HttpClient(handler))
|
||||||
{
|
{
|
||||||
|
|
@ -172,7 +172,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
return context.Response.WriteAsync("hello world");
|
return context.Response.WriteAsync("hello world");
|
||||||
};
|
};
|
||||||
|
|
||||||
using (var server = new TestServer(app, serviceContext, "https://localhost:0/"))
|
using (var server = new TestServer(app, serviceContext, "https://127.0.0.1:0/"))
|
||||||
{
|
{
|
||||||
using (var client = new HttpClient(handler))
|
using (var client = new HttpClient(handler))
|
||||||
{
|
{
|
||||||
|
|
@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
return context.Response.WriteAsync("hello world");
|
return context.Response.WriteAsync("hello world");
|
||||||
};
|
};
|
||||||
|
|
||||||
using (var server = new TestServer(app, serviceContext, "https://localhost:0/"))
|
using (var server = new TestServer(app, serviceContext, "https://127.0.0.1:0/"))
|
||||||
{
|
{
|
||||||
// SslStream is used to ensure the certificate is actually passed to the server
|
// SslStream is used to ensure the certificate is actually passed to the server
|
||||||
// HttpClient might not send the certificate because it is invalid or it doesn't match any
|
// HttpClient might not send the certificate because it is invalid or it doesn't match any
|
||||||
|
|
@ -281,7 +281,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
RequestDelegate app = context => context.Response.WriteAsync(context.Request.Scheme);
|
RequestDelegate app = context => context.Response.WriteAsync(context.Request.Scheme);
|
||||||
|
|
||||||
using (var server = new TestServer(app, serviceContext, "https://localhost:0/"))
|
using (var server = new TestServer(app, serviceContext, "https://127.0.0.1:0/"))
|
||||||
{
|
{
|
||||||
using (var client = new HttpClient(handler))
|
using (var client = new HttpClient(handler))
|
||||||
{
|
{
|
||||||
|
|
@ -327,7 +327,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
return context.Response.WriteAsync("hello world");
|
return context.Response.WriteAsync("hello world");
|
||||||
};
|
};
|
||||||
|
|
||||||
using (var server = new TestServer(app, serviceContext, "https://localhost:0/"))
|
using (var server = new TestServer(app, serviceContext, "https://127.0.0.1:0/"))
|
||||||
{
|
{
|
||||||
// SslStream is used to ensure the certificate is actually passed to the server
|
// SslStream is used to ensure the certificate is actually passed to the server
|
||||||
// HttpClient might not send the certificate because it is invalid or it doesn't match any
|
// HttpClient might not send the certificate because it is invalid or it doesn't match any
|
||||||
|
|
@ -384,7 +384,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
return context.Response.WriteAsync("hello world");
|
return context.Response.WriteAsync("hello world");
|
||||||
};
|
};
|
||||||
|
|
||||||
using (var server = new TestServer(app, serviceContext, "https://localhost:0/"))
|
using (var server = new TestServer(app, serviceContext, "https://127.0.0.1:0/"))
|
||||||
{
|
{
|
||||||
// SslStream is used to ensure the certificate is actually passed to the server
|
// SslStream is used to ensure the certificate is actually passed to the server
|
||||||
// HttpClient might not send the certificate because it is invalid or it doesn't match any
|
// HttpClient might not send the certificate because it is invalid or it doesn't match any
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
var serverListenTcp = new UvTcpHandle(_logger);
|
var serverListenTcp = new UvTcpHandle(_logger);
|
||||||
serverListenTcp.Init(loop, (a, b) => { });
|
serverListenTcp.Init(loop, (a, b) => { });
|
||||||
var address = ServerAddress.FromUrl($"http://localhost:0/");
|
var address = ServerAddress.FromUrl($"http://127.0.0.1:0/");
|
||||||
serverListenTcp.Bind(address);
|
serverListenTcp.Bind(address);
|
||||||
var port = serverListenTcp.GetSockIPEndPoint().Port;
|
var port = serverListenTcp.GetSockIPEndPoint().Port;
|
||||||
serverListenTcp.Listen(128, (_1, status, error, _2) =>
|
serverListenTcp.Listen(128, (_1, status, error, _2) =>
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
loop.Init(_uv);
|
loop.Init(_uv);
|
||||||
var tcp = new UvTcpHandle(_logger);
|
var tcp = new UvTcpHandle(_logger);
|
||||||
tcp.Init(loop, (a, b) => { });
|
tcp.Init(loop, (a, b) => { });
|
||||||
var address = ServerAddress.FromUrl("http://localhost:0/");
|
var address = ServerAddress.FromUrl("http://127.0.0.1:0/");
|
||||||
tcp.Bind(address);
|
tcp.Bind(address);
|
||||||
tcp.Dispose();
|
tcp.Dispose();
|
||||||
loop.Run();
|
loop.Run();
|
||||||
|
|
@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
loop.Init(_uv);
|
loop.Init(_uv);
|
||||||
var tcp = new UvTcpHandle(_logger);
|
var tcp = new UvTcpHandle(_logger);
|
||||||
tcp.Init(loop, (a, b) => { });
|
tcp.Init(loop, (a, b) => { });
|
||||||
var address = ServerAddress.FromUrl($"http://localhost:0/");
|
var address = ServerAddress.FromUrl($"http://127.0.0.1:0/");
|
||||||
tcp.Bind(address);
|
tcp.Bind(address);
|
||||||
var port = tcp.GetSockIPEndPoint().Port;
|
var port = tcp.GetSockIPEndPoint().Port;
|
||||||
tcp.Listen(10, (stream, status, error, state) =>
|
tcp.Listen(10, (stream, status, error, state) =>
|
||||||
|
|
@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
loop.Init(_uv);
|
loop.Init(_uv);
|
||||||
var tcp = new UvTcpHandle(_logger);
|
var tcp = new UvTcpHandle(_logger);
|
||||||
tcp.Init(loop, (a, b) => { });
|
tcp.Init(loop, (a, b) => { });
|
||||||
var address = ServerAddress.FromUrl($"http://localhost:0/");
|
var address = ServerAddress.FromUrl($"http://127.0.0.1:0/");
|
||||||
tcp.Bind(address);
|
tcp.Bind(address);
|
||||||
var port = tcp.GetSockIPEndPoint().Port;
|
var port = tcp.GetSockIPEndPoint().Port;
|
||||||
tcp.Listen(10, (_, status, error, state) =>
|
tcp.Listen(10, (_, status, error, state) =>
|
||||||
|
|
@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
loop.Init(_uv);
|
loop.Init(_uv);
|
||||||
var tcp = new UvTcpHandle(_logger);
|
var tcp = new UvTcpHandle(_logger);
|
||||||
tcp.Init(loop, (a, b) => { });
|
tcp.Init(loop, (a, b) => { });
|
||||||
var address = ServerAddress.FromUrl($"http://localhost:0/");
|
var address = ServerAddress.FromUrl($"http://127.0.0.1:0/");
|
||||||
tcp.Bind(address);
|
tcp.Bind(address);
|
||||||
var port = tcp.GetSockIPEndPoint().Port;
|
var port = tcp.GetSockIPEndPoint().Port;
|
||||||
tcp.Listen(10, (_, status, error, state) =>
|
tcp.Listen(10, (_, status, error, state) =>
|
||||||
|
|
|
||||||
|
|
@ -60,5 +60,15 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
Assert.True(serverAddres.PathBase.IsNormalized(NormalizationForm.FormC));
|
Assert.True(serverAddres.PathBase.IsNormalized(NormalizationForm.FormC));
|
||||||
Assert.Equal("/p\u00C5thbase", serverAddres.PathBase);
|
Assert.Equal("/p\u00C5thbase", serverAddres.PathBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WithHostReturnsNewInstanceWithDifferentHost()
|
||||||
|
{
|
||||||
|
var serverAddress = ServerAddress.FromUrl("http://localhost:8080");
|
||||||
|
var newAddress = serverAddress.WithHost("otherhost");
|
||||||
|
Assert.NotSame(serverAddress, newAddress);
|
||||||
|
Assert.Equal("otherhost", newAddress.Host);
|
||||||
|
Assert.Equal("localhost", serverAddress.Host);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel;
|
using Microsoft.AspNetCore.Server.Kestrel;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Http;
|
||||||
|
|
@ -16,7 +15,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
private KestrelEngine _engine;
|
private KestrelEngine _engine;
|
||||||
private IDisposable _server;
|
private IDisposable _server;
|
||||||
ServerAddress _address;
|
private ServerAddress _address;
|
||||||
|
|
||||||
public TestServer(RequestDelegate app)
|
public TestServer(RequestDelegate app)
|
||||||
: this(app, new TestServiceContext())
|
: this(app, new TestServiceContext())
|
||||||
|
|
@ -24,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestServer(RequestDelegate app, ServiceContext context)
|
public TestServer(RequestDelegate app, ServiceContext context)
|
||||||
: this(app, context, "http://localhost:0/")
|
: this(app, context, "http://127.0.0.1:0/")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue