Remove splitting of path and path base (#1050).
This commit is contained in:
parent
d4c0d4b81e
commit
632780dd16
|
|
@ -68,8 +68,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
|
||||
protected HttpVersion _httpVersion;
|
||||
|
||||
private readonly string _pathBase;
|
||||
|
||||
private int _remainingRequestHeadersBytesAllowed;
|
||||
private int _requestHeadersParsed;
|
||||
|
||||
|
|
@ -88,7 +86,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
|
||||
ServerOptions = context.ListenerContext.ServiceContext.ServerOptions;
|
||||
|
||||
_pathBase = context.ListenerContext.ListenOptions.PathBase;
|
||||
_parser = context.ListenerContext.ServiceContext.HttpParserFactory(this);
|
||||
|
||||
FrameControl = this;
|
||||
|
|
@ -1041,38 +1038,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
return result;
|
||||
}
|
||||
|
||||
private bool RequestUrlStartsWithPathBase(string requestUrl, out bool caseMatches)
|
||||
{
|
||||
caseMatches = true;
|
||||
|
||||
if (string.IsNullOrEmpty(_pathBase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (requestUrl.Length < _pathBase.Length || (requestUrl.Length > _pathBase.Length && requestUrl[_pathBase.Length] != '/'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _pathBase.Length; i++)
|
||||
{
|
||||
if (requestUrl[i] != _pathBase[i])
|
||||
{
|
||||
if (char.ToLowerInvariant(requestUrl[i]) == char.ToLowerInvariant(_pathBase[i]))
|
||||
{
|
||||
caseMatches = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TakeMessageHeaders(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
{
|
||||
// Make sure the buffer is limited
|
||||
|
|
@ -1321,7 +1286,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
|
||||
QueryString = query.GetAsciiStringNonNullCharacters();
|
||||
RawTarget = rawTarget;
|
||||
SetNormalizedPath(requestUrlPath);
|
||||
Path = PathNormalizer.RemoveDotSegments(requestUrlPath);
|
||||
}
|
||||
|
||||
private void OnAuthorityFormTarget(HttpMethod method, Span<byte> target)
|
||||
|
|
@ -1356,7 +1321,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
// See https://tools.ietf.org/html/rfc3986#section-3.2
|
||||
RawTarget = target.GetAsciiStringNonNullCharacters();
|
||||
Path = string.Empty;
|
||||
PathBase = string.Empty;
|
||||
QueryString = string.Empty;
|
||||
}
|
||||
|
||||
|
|
@ -1371,7 +1335,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
|
||||
RawTarget = Asterisk;
|
||||
Path = string.Empty;
|
||||
PathBase = string.Empty;
|
||||
QueryString = string.Empty;
|
||||
}
|
||||
|
||||
|
|
@ -1397,25 +1360,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
RejectRequestTarget(target);
|
||||
}
|
||||
|
||||
SetNormalizedPath(uri.LocalPath);
|
||||
Path = PathNormalizer.RemoveDotSegments(uri.LocalPath);
|
||||
// don't use uri.Query because we need the unescaped version
|
||||
QueryString = query.GetAsciiStringNonNullCharacters();
|
||||
}
|
||||
|
||||
private void SetNormalizedPath(string requestPath)
|
||||
{
|
||||
var normalizedTarget = PathNormalizer.RemoveDotSegments(requestPath);
|
||||
if (RequestUrlStartsWithPathBase(normalizedTarget, out bool caseMatches))
|
||||
{
|
||||
PathBase = caseMatches ? _pathBase : normalizedTarget.Substring(0, _pathBase.Length);
|
||||
Path = normalizedTarget.Substring(_pathBase.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
Path = normalizedTarget;
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe static string GetUtf8String(Span<byte> path)
|
||||
{
|
||||
// .NET 451 doesn't have pointer overloads for Encoding.GetString so we
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
|
|
@ -163,12 +164,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
{
|
||||
var parsedAddress = ServerAddress.FromUrl(address);
|
||||
|
||||
if (!string.IsNullOrEmpty(parsedAddress.PathBase))
|
||||
{
|
||||
_logger.LogWarning($"Path base in address {address} is not supported and will be ignored. To specify a path base, use {nameof(IApplicationBuilder)}.UsePathBase().");
|
||||
}
|
||||
|
||||
if (parsedAddress.IsUnixPipe)
|
||||
{
|
||||
listenOptions.Add(new ListenOptions(parsedAddress.UnixPipePath)
|
||||
{
|
||||
Scheme = parsedAddress.Scheme,
|
||||
PathBase = parsedAddress.PathBase
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
@ -188,7 +193,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
listenOptions.Add(new ListenOptions(CreateIPEndPoint(parsedAddress))
|
||||
{
|
||||
Scheme = parsedAddress.Scheme,
|
||||
PathBase = parsedAddress.PathBase
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -259,7 +263,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
var ipv4ListenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, parsedAddress.Port))
|
||||
{
|
||||
Scheme = parsedAddress.Scheme,
|
||||
PathBase = parsedAddress.PathBase
|
||||
};
|
||||
|
||||
_disposables.Push(engine.CreateServer(ipv4ListenOptions));
|
||||
|
|
@ -283,7 +286,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
var ipv6ListenOptions = new ListenOptions(new IPEndPoint(IPAddress.IPv6Loopback, parsedAddress.Port))
|
||||
{
|
||||
Scheme = parsedAddress.Scheme,
|
||||
PathBase = parsedAddress.PathBase
|
||||
};
|
||||
|
||||
_disposables.Push(engine.CreateServer(ipv6ListenOptions));
|
||||
|
|
|
|||
|
|
@ -81,9 +81,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
/// </remarks>
|
||||
public List<IConnectionAdapter> ConnectionAdapters { get; } = new List<IConnectionAdapter>();
|
||||
|
||||
// PathBase and Scheme are hopefully only a temporary measure for back compat with IServerAddressesFeature.
|
||||
// This allows a ListenOptions to describe all the information encoded in IWebHostBuilder.UseUrls.
|
||||
internal string PathBase { get; set; }
|
||||
// Scheme is hopefully only a temporary measure for back compat with IServerAddressesFeature.
|
||||
internal string Scheme { get; set; } = "http";
|
||||
|
||||
public override string ToString()
|
||||
|
|
@ -93,12 +91,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
switch (Type)
|
||||
{
|
||||
case ListenType.IPEndPoint:
|
||||
return $"{Scheme}://{IPEndPoint}{PathBase}";
|
||||
return $"{Scheme}://{IPEndPoint}";
|
||||
case ListenType.SocketPath:
|
||||
// ":" is used by ServerAddress to separate the socket path from PathBase.
|
||||
return $"{Scheme}://unix:{SocketPath}:{PathBase}";
|
||||
return $"{Scheme}://unix:{SocketPath}";
|
||||
case ListenType.FileHandle:
|
||||
// This was never supported via --server.urls, so no need to include Scheme or PathBase.
|
||||
// This was never supported via --server.urls, so no need to include Scheme.
|
||||
return "http://<file handle>";
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
|
|
|
|||
|
|
@ -37,18 +37,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
{
|
||||
if (IsUnixPipe)
|
||||
{
|
||||
if (string.IsNullOrEmpty(PathBase))
|
||||
{
|
||||
return Scheme.ToLowerInvariant() + "://" + Host.ToLowerInvariant();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Scheme.ToLowerInvariant() + "://" + Host.ToLowerInvariant() + ":" + PathBase.ToLowerInvariant();
|
||||
}
|
||||
return Scheme.ToLowerInvariant() + "://" + Host.ToLowerInvariant();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Scheme.ToLowerInvariant() + "://" + Host.ToLowerInvariant() + ":" + Port.ToString(CultureInfo.InvariantCulture) + PathBase.ToLowerInvariant();
|
||||
return Scheme.ToLowerInvariant() + "://" + Host.ToLowerInvariant() + ":" + Port.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -66,8 +59,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
}
|
||||
return string.Equals(Scheme, other.Scheme, StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(Host, other.Host, StringComparison.OrdinalIgnoreCase)
|
||||
&& Port == other.Port
|
||||
&& string.Equals(PathBase, other.PathBase, StringComparison.OrdinalIgnoreCase);
|
||||
&& Port == other.Port;
|
||||
}
|
||||
|
||||
public static ServerAddress FromUrl(string url)
|
||||
|
|
@ -145,7 +137,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
throw new FormatException($"Invalid URL: {url}");
|
||||
}
|
||||
|
||||
// Path should not end with a / since it will be used as PathBase later
|
||||
if (url[url.Length - 1] == '/')
|
||||
{
|
||||
serverAddress.PathBase = url.Substring(pathDelimiterEnd, url.Length - pathDelimiterEnd - 1);
|
||||
|
|
@ -157,16 +148,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
|
||||
return serverAddress;
|
||||
}
|
||||
|
||||
internal ServerAddress WithHost(string host)
|
||||
{
|
||||
return new ServerAddress
|
||||
{
|
||||
Scheme = Scheme,
|
||||
Host = host,
|
||||
Port = Port,
|
||||
PathBase = PathBase
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||
{
|
||||
public class PathBaseTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("/base", "/base", "/base", "")]
|
||||
[InlineData("/base", "/base/", "/base", "/")]
|
||||
[InlineData("/base", "/base/something", "/base", "/something")]
|
||||
[InlineData("/base", "/base/something/", "/base", "/something/")]
|
||||
[InlineData("/base/more", "/base/more", "/base/more", "")]
|
||||
[InlineData("/base/more", "/base/more/something", "/base/more", "/something")]
|
||||
[InlineData("/base/more", "/base/more/something/", "/base/more", "/something/")]
|
||||
public Task RequestPathBaseIsServerPathBase(string registerPathBase, string requestPath, string expectedPathBase, string expectedPath)
|
||||
{
|
||||
return TestPathBase(registerPathBase, requestPath, expectedPathBase, expectedPath);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", "/", "", "/")]
|
||||
[InlineData("", "/something", "", "/something")]
|
||||
[InlineData("/", "/", "", "/")]
|
||||
[InlineData("/base", "/", "", "/")]
|
||||
[InlineData("/base", "/something", "", "/something")]
|
||||
[InlineData("/base", "/baseandsomething", "", "/baseandsomething")]
|
||||
[InlineData("/base", "/ba", "", "/ba")]
|
||||
[InlineData("/base", "/ba/se", "", "/ba/se")]
|
||||
public Task DefaultPathBaseIsEmpty(string registerPathBase, string requestPath, string expectedPathBase, string expectedPath)
|
||||
{
|
||||
return TestPathBase(registerPathBase, requestPath, expectedPathBase, expectedPath);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", "/", "", "/")]
|
||||
[InlineData("/", "/", "", "/")]
|
||||
[InlineData("/base", "/base/", "/base", "/")]
|
||||
[InlineData("/base/", "/base", "/base", "")]
|
||||
[InlineData("/base/", "/base/", "/base", "/")]
|
||||
public Task PathBaseNeverEndsWithSlash(string registerPathBase, string requestPath, string expectedPathBase, string expectedPath)
|
||||
{
|
||||
return TestPathBase(registerPathBase, requestPath, expectedPathBase, expectedPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task PathBaseAndPathPreserveRequestCasing()
|
||||
{
|
||||
return TestPathBase("/base", "/Base/Something", "/Base", "/Something");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task PathBaseCanHaveUTF8Characters()
|
||||
{
|
||||
return TestPathBase("/b♫se", "/b♫se/something", "/b♫se", "/something");
|
||||
}
|
||||
|
||||
private async Task TestPathBase(string registerPathBase, string requestPath, string expectedPathBase, string expectedPath)
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseUrls($"http://127.0.0.1:0{registerPathBase}")
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Run(async context =>
|
||||
{
|
||||
await context.Response.WriteAsync(JsonConvert.SerializeObject(new
|
||||
{
|
||||
PathBase = context.Request.PathBase.Value,
|
||||
Path = context.Request.Path.Value
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
using (var host = builder.Build())
|
||||
{
|
||||
host.Start();
|
||||
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
var response = await client.GetAsync($"http://127.0.0.1:{host.GetPort()}{requestPath}");
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var responseText = await response.Content.ReadAsStringAsync();
|
||||
Assert.NotEmpty(responseText);
|
||||
|
||||
var pathFacts = JsonConvert.DeserializeObject<JObject>(responseText);
|
||||
Assert.Equal(expectedPathBase, pathFacts["PathBase"].Value<string>());
|
||||
Assert.Equal(expectedPath, pathFacts["Path"].Value<string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ using System.IO;
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -18,8 +19,11 @@ using Microsoft.AspNetCore.Http.Features;
|
|||
using Microsoft.AspNetCore.Server.Kestrel.Internal.Networking;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.Testing.xunit;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xunit;
|
||||
|
|
@ -520,6 +524,64 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("/base", "/base")]
|
||||
[InlineData("/base", "/base/")]
|
||||
[InlineData("/base", "/base/something")]
|
||||
[InlineData("/base", "/base/something/")]
|
||||
[InlineData("/base/something", "/base/something")]
|
||||
[InlineData("/base/something", "/base/something/")]
|
||||
[InlineData("/base/something", "/base/something/more")]
|
||||
[InlineData("/base/something", "/base/something/more/")]
|
||||
public async Task DoesNotSplitPathBase(string registerPathBase, string requestPath)
|
||||
{
|
||||
var testLogger = new TestApplicationErrorLogger();
|
||||
|
||||
string contextPathBase = null;
|
||||
string contextPath = null;
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseUrls($"http://127.0.0.1:0{registerPathBase}")
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddSingleton<ILoggerFactory>(new KestrelTestLoggerFactory(testLogger));
|
||||
})
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Run(context =>
|
||||
{
|
||||
contextPathBase = context.Request.PathBase;
|
||||
contextPath = context.Request.Path;
|
||||
|
||||
return TaskCache.CompletedTask;
|
||||
});
|
||||
});
|
||||
|
||||
using (var host = builder.Build())
|
||||
{
|
||||
host.Start();
|
||||
|
||||
using (var connection = new TestConnection(host.GetPort()))
|
||||
{
|
||||
await connection.Send($"GET {requestPath} HTTP/1.1\r\n\r\n");
|
||||
await connection.Receive("HTTP/1.1 200 OK");
|
||||
}
|
||||
|
||||
Assert.Single(testLogger.Messages, log =>
|
||||
log.LogLevel == LogLevel.Warning &&
|
||||
string.Equals(
|
||||
$"Path base in address http://127.0.0.1:0{registerPathBase} is not supported and will be ignored. To specify a path base, use {nameof(IApplicationBuilder)}.UsePathBase().",
|
||||
log.Message,
|
||||
StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
Assert.Equal("", contextPathBase);
|
||||
Assert.Equal(requestPath, contextPath);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private async Task TestRemoteIPAddress(string registerAddress, string requestAddress, string expectAddress)
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
|
|
|
|||
|
|
@ -19,18 +19,13 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
public async Task RequestPathIsNotNormalized()
|
||||
{
|
||||
var testContext = new TestServiceContext();
|
||||
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
{
|
||||
PathBase = "/\u0041\u030A"
|
||||
};
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
|
||||
|
||||
using (var server = new TestServer(async context =>
|
||||
{
|
||||
Assert.Equal("/\u0041\u030A", context.Request.PathBase.Value);
|
||||
Assert.Equal("/B/\u0041\u030A", context.Request.Path.Value);
|
||||
Assert.Equal("/\u0041\u030A/B/\u0041\u030A", context.Request.Path.Value);
|
||||
|
||||
context.Response.Headers["Content-Length"] = new[] { "11" };
|
||||
context.Response.Headers.ContentLength = 11;
|
||||
await context.Response.WriteAsync("Hello World");
|
||||
}, testContext, listenOptions))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Server.Kestrel;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -41,21 +40,21 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
[InlineData("http://www.example.com", "http", "www.example.com", 80, "", "http://www.example.com:80")]
|
||||
[InlineData("https://www.example.com", "https", "www.example.com", 443, "", "https://www.example.com:443")]
|
||||
[InlineData("http://www.example.com/", "http", "www.example.com", 80, "", "http://www.example.com:80")]
|
||||
[InlineData("http://www.example.com/foo?bar=baz", "http", "www.example.com", 80, "/foo?bar=baz", "http://www.example.com:80/foo?bar=baz")]
|
||||
[InlineData("http://www.example.com/foo?bar=baz", "http", "www.example.com", 80, "/foo?bar=baz", "http://www.example.com:80")]
|
||||
[InlineData("http://www.example.com:5000", "http", "www.example.com", 5000, "", null)]
|
||||
[InlineData("https://www.example.com:5000", "https", "www.example.com", 5000, "", null)]
|
||||
[InlineData("http://www.example.com:5000/", "http", "www.example.com", 5000, "", "http://www.example.com:5000")]
|
||||
[InlineData("http://www.example.com:NOTAPORT", "http", "www.example.com:NOTAPORT", 80, "", "http://www.example.com:notaport:80")]
|
||||
[InlineData("https://www.example.com:NOTAPORT", "https", "www.example.com:NOTAPORT", 443, "", "https://www.example.com:notaport:443")]
|
||||
[InlineData("http://www.example.com:NOTAPORT/", "http", "www.example.com:NOTAPORT", 80, "", "http://www.example.com:notaport:80")]
|
||||
[InlineData("http://foo:/tmp/kestrel-test.sock:5000/doesn't/matter", "http", "foo:", 80, "/tmp/kestrel-test.sock:5000/doesn't/matter", "http://foo::80/tmp/kestrel-test.sock:5000/doesn't/matter")]
|
||||
[InlineData("http://unix:foo/tmp/kestrel-test.sock", "http", "unix:foo", 80, "/tmp/kestrel-test.sock", "http://unix:foo:80/tmp/kestrel-test.sock")]
|
||||
[InlineData("http://unix:5000/tmp/kestrel-test.sock", "http", "unix", 5000, "/tmp/kestrel-test.sock", null)]
|
||||
[InlineData("http://foo:/tmp/kestrel-test.sock:5000/doesn't/matter", "http", "foo:", 80, "/tmp/kestrel-test.sock:5000/doesn't/matter", "http://foo::80")]
|
||||
[InlineData("http://unix:foo/tmp/kestrel-test.sock", "http", "unix:foo", 80, "/tmp/kestrel-test.sock", "http://unix:foo:80")]
|
||||
[InlineData("http://unix:5000/tmp/kestrel-test.sock", "http", "unix", 5000, "/tmp/kestrel-test.sock", "http://unix:5000")]
|
||||
[InlineData("http://unix:/tmp/kestrel-test.sock", "http", "unix:/tmp/kestrel-test.sock", 0, "", null)]
|
||||
[InlineData("https://unix:/tmp/kestrel-test.sock", "https", "unix:/tmp/kestrel-test.sock", 0, "", null)]
|
||||
[InlineData("http://unix:/tmp/kestrel-test.sock:", "http", "unix:/tmp/kestrel-test.sock", 0, "", "http://unix:/tmp/kestrel-test.sock")]
|
||||
[InlineData("http://unix:/tmp/kestrel-test.sock:/", "http", "unix:/tmp/kestrel-test.sock", 0, "", "http://unix:/tmp/kestrel-test.sock")]
|
||||
[InlineData("http://unix:/tmp/kestrel-test.sock:5000/doesn't/matter", "http", "unix:/tmp/kestrel-test.sock", 0, "5000/doesn't/matter", null)]
|
||||
[InlineData("http://unix:/tmp/kestrel-test.sock:5000/doesn't/matter", "http", "unix:/tmp/kestrel-test.sock", 0, "5000/doesn't/matter", "http://unix:/tmp/kestrel-test.sock")]
|
||||
public void UrlsAreParsedCorrectly(string url, string scheme, string host, int port, string pathBase, string toString)
|
||||
{
|
||||
var serverAddress = ServerAddress.FromUrl(url);
|
||||
|
|
@ -67,24 +66,5 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
|
||||
Assert.Equal(toString ?? url, serverAddress.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PathBaseIsNotNormalized()
|
||||
{
|
||||
var serverAddres = ServerAddress.FromUrl("http://localhost:8080/p\u0041\u030Athbase");
|
||||
|
||||
Assert.False(serverAddres.PathBase.IsNormalized(NormalizationForm.FormC));
|
||||
Assert.Equal("/p\u0041\u030Athbase", 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue