Reject HTTP/1.1 requests that do not have a correct Host header
Improves Kestrel to reject requests that don't conform to HTTP spec. RFC 7230 section 5.4: "A server MUST respond with a 400 (Bad Request) status code to any HTTP/1.1 request message that lacks a Host header field and to any request message that contains more than one Host header field or a Host header field with an invalid field-value." See https://tools.ietf.org/html/rfc7230#section-5.4. Other changes: - update VS code settings to work better with CLI 2.0 - update tests that were subject to infinite hangs
This commit is contained in:
parent
9e37272f06
commit
c08c57f764
|
|
@ -12,8 +12,7 @@
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "Compile: solution",
|
"preLaunchTask": "Compile: solution",
|
||||||
"program": "${workspaceRoot}/samples/SampleApp/bin/Debug/netcoreapp1.1/SampleApp.dll",
|
"program": "${workspaceRoot}/samples/SampleApp/bin/Debug/netcoreapp2.0/SampleApp.dll",
|
||||||
"args": [],
|
|
||||||
"cwd": "${workspaceRoot}/samples/SampleApp",
|
"cwd": "${workspaceRoot}/samples/SampleApp",
|
||||||
"console": "internalConsole",
|
"console": "internalConsole",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
|
@ -38,8 +37,7 @@
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "Compile: solution",
|
"preLaunchTask": "Compile: solution",
|
||||||
"program": "${workspaceRoot}/samples/LargeResponseApp/bin/Debug/netcoreapp1.1/LargeResponseApp.dll",
|
"program": "${workspaceRoot}/samples/LargeResponseApp/bin/Debug/netcoreapp2.0/LargeResponseApp.dll",
|
||||||
"args": [],
|
|
||||||
"cwd": "${workspaceRoot}/samples/LargeResponseApp",
|
"cwd": "${workspaceRoot}/samples/LargeResponseApp",
|
||||||
"console": "internalConsole",
|
"console": "internalConsole",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,20 @@
|
||||||
"DOTNET_SKIP_FIRST_TIME_EXPERIENCE": "true"
|
"DOTNET_SKIP_FIRST_TIME_EXPERIENCE": "true"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// requires that you first run build.cmd or build.sh to install local builds of dotnet
|
||||||
|
"windows": {
|
||||||
|
"command": "${env.LOCALAPPDATA}/Microsoft/dotnet/dotnet.exe"
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"command": "${env.HOME}/.dotnet/dotnet"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"command": "${env.HOME}/.dotnet/dotnet"
|
||||||
|
},
|
||||||
|
"suppressTaskName": true,
|
||||||
"tasks": [
|
"tasks": [
|
||||||
{
|
{
|
||||||
"taskName": "Restore: solution",
|
"taskName": "Restore: solution",
|
||||||
"command": "dotnet",
|
|
||||||
"args": [
|
"args": [
|
||||||
"restore"
|
"restore"
|
||||||
]
|
]
|
||||||
|
|
@ -16,7 +26,6 @@
|
||||||
{
|
{
|
||||||
"taskName": "Compile: solution",
|
"taskName": "Compile: solution",
|
||||||
"isBuildCommand": true,
|
"isBuildCommand": true,
|
||||||
"command": "dotnet",
|
|
||||||
"args": [
|
"args": [
|
||||||
"build",
|
"build",
|
||||||
"${workspaceRoot}/KestrelHttpServer.sln"
|
"${workspaceRoot}/KestrelHttpServer.sln"
|
||||||
|
|
@ -40,9 +49,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"taskName": "Test",
|
||||||
|
"args": [
|
||||||
|
"test"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile",
|
||||||
|
"isTestCommand": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"taskName": "Compile: CodeGenerator",
|
"taskName": "Compile: CodeGenerator",
|
||||||
"command": "dotnet",
|
|
||||||
"args": [
|
"args": [
|
||||||
"build"
|
"build"
|
||||||
],
|
],
|
||||||
|
|
@ -53,7 +69,6 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"taskName": "Run: CodeGenerator",
|
"taskName": "Run: CodeGenerator",
|
||||||
"command": "dotnet",
|
|
||||||
"args": [
|
"args": [
|
||||||
"run"
|
"run"
|
||||||
],
|
],
|
||||||
|
|
@ -63,7 +78,6 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"taskName": "Run: Benchmarks",
|
"taskName": "Run: Benchmarks",
|
||||||
"command": "dotnet",
|
|
||||||
"args": [
|
"args": [
|
||||||
"run",
|
"run",
|
||||||
"-c",
|
"-c",
|
||||||
|
|
@ -72,33 +86,6 @@
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceRoot}/test/Microsoft.AspNetCore.Server.Kestrel.Performance/"
|
"cwd": "${workspaceRoot}/test/Microsoft.AspNetCore.Server.Kestrel.Performance/"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"taskName": "Test: KestrelTests",
|
|
||||||
"isTestCommand": true,
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": [
|
|
||||||
"test",
|
|
||||||
"-f",
|
|
||||||
"netcoreapp1.1"
|
|
||||||
],
|
|
||||||
"options": {
|
|
||||||
"cwd": "${workspaceRoot}/test/Microsoft.AspNetCore.Server.KestrelTests"
|
|
||||||
},
|
|
||||||
"problemMatcher": "$msCompile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"taskName": "Test: FunctionalTests",
|
|
||||||
"command": "dotnet",
|
|
||||||
"args": [
|
|
||||||
"test",
|
|
||||||
"-f",
|
|
||||||
"netcoreapp1.1"
|
|
||||||
],
|
|
||||||
"options": {
|
|
||||||
"cwd": "${workspaceRoot}/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests"
|
|
||||||
},
|
|
||||||
"problemMatcher": "$msCompile"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
||||||
case RequestRejectionReason.ConnectMethodRequired:
|
case RequestRejectionReason.ConnectMethodRequired:
|
||||||
ex = new BadHttpRequestException("Method not allowed.", StatusCodes.Status405MethodNotAllowed, HttpMethod.Connect);
|
ex = new BadHttpRequestException("Method not allowed.", StatusCodes.Status405MethodNotAllowed, HttpMethod.Connect);
|
||||||
break;
|
break;
|
||||||
|
case RequestRejectionReason.MissingHostHeader:
|
||||||
|
ex = new BadHttpRequestException("Request is missing Host header.", StatusCodes.Status400BadRequest);
|
||||||
|
break;
|
||||||
|
case RequestRejectionReason.MultipleHostHeaders:
|
||||||
|
ex = new BadHttpRequestException("Multiple Host headers.", StatusCodes.Status400BadRequest);
|
||||||
|
break;
|
||||||
|
case RequestRejectionReason.InvalidHostHeader:
|
||||||
|
ex = new BadHttpRequestException("Invalid Host header.", StatusCodes.Status400BadRequest);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ex = new BadHttpRequestException("Bad request.", StatusCodes.Status400BadRequest);
|
ex = new BadHttpRequestException("Bad request.", StatusCodes.Status400BadRequest);
|
||||||
break;
|
break;
|
||||||
|
|
@ -116,6 +125,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
||||||
case RequestRejectionReason.LengthRequiredHttp10:
|
case RequestRejectionReason.LengthRequiredHttp10:
|
||||||
ex = new BadHttpRequestException($"{detail} request contains no Content-Length header", StatusCodes.Status400BadRequest);
|
ex = new BadHttpRequestException($"{detail} request contains no Content-Length header", StatusCodes.Status400BadRequest);
|
||||||
break;
|
break;
|
||||||
|
case RequestRejectionReason.InvalidHostHeader:
|
||||||
|
ex = new BadHttpRequestException($"Invalid Host header: '{detail}'", StatusCodes.Status400BadRequest);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ex = new BadHttpRequestException("Bad request.", StatusCodes.Status400BadRequest);
|
ex = new BadHttpRequestException("Bad request.", StatusCodes.Status400BadRequest);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
private readonly FrameContext _frameContext;
|
private readonly FrameContext _frameContext;
|
||||||
private readonly IHttpParser<FrameAdapter> _parser;
|
private readonly IHttpParser<FrameAdapter> _parser;
|
||||||
|
|
||||||
|
private HttpRequestTarget _requestTargetForm = HttpRequestTarget.Unknown;
|
||||||
|
private Uri _absoluteRequestTarget;
|
||||||
|
|
||||||
public Frame(FrameContext frameContext)
|
public Frame(FrameContext frameContext)
|
||||||
{
|
{
|
||||||
_frameContext = frameContext;
|
_frameContext = frameContext;
|
||||||
|
|
@ -141,6 +144,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public string QueryString { get; set; }
|
public string QueryString { get; set; }
|
||||||
public string RawTarget { get; set; }
|
public string RawTarget { get; set; }
|
||||||
|
|
||||||
public string HttpVersion
|
public string HttpVersion
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -365,6 +369,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
Method = null;
|
Method = null;
|
||||||
PathBase = null;
|
PathBase = null;
|
||||||
Path = null;
|
Path = null;
|
||||||
|
RawTarget = null;
|
||||||
|
_requestTargetForm = HttpRequestTarget.Unknown;
|
||||||
|
_absoluteRequestTarget = null;
|
||||||
QueryString = null;
|
QueryString = null;
|
||||||
_httpVersion = Http.HttpVersion.Unknown;
|
_httpVersion = Http.HttpVersion.Unknown;
|
||||||
StatusCode = StatusCodes.Status200OK;
|
StatusCode = StatusCodes.Status200OK;
|
||||||
|
|
@ -1266,6 +1273,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
{
|
{
|
||||||
Debug.Assert(target[0] == ByteForwardSlash, "Should only be called when path starts with /");
|
Debug.Assert(target[0] == ByteForwardSlash, "Should only be called when path starts with /");
|
||||||
|
|
||||||
|
_requestTargetForm = HttpRequestTarget.OriginForm;
|
||||||
|
|
||||||
// URIs are always encoded/escaped to ASCII https://tools.ietf.org/html/rfc3986#page-11
|
// URIs are always encoded/escaped to ASCII https://tools.ietf.org/html/rfc3986#page-11
|
||||||
// Multibyte Internationalized Resource Identifiers (IRIs) are first converted to utf8;
|
// Multibyte Internationalized Resource Identifiers (IRIs) are first converted to utf8;
|
||||||
// then encoded/escaped to ASCII https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs"
|
// then encoded/escaped to ASCII https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs"
|
||||||
|
|
@ -1325,8 +1334,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
private void OnAuthorityFormTarget(HttpMethod method, Span<byte> target)
|
private void OnAuthorityFormTarget(HttpMethod method, Span<byte> target)
|
||||||
{
|
{
|
||||||
// TODO Validate that target is a correct host[:port] string.
|
_requestTargetForm = HttpRequestTarget.AuthorityForm;
|
||||||
// Reject as 400 if not. This is just a quick scan for invalid characters
|
|
||||||
|
// This is not complete validation. It is just a quick scan for invalid characters
|
||||||
// but doesn't check that the target fully matches the URI spec.
|
// but doesn't check that the target fully matches the URI spec.
|
||||||
for (var i = 0; i < target.Length; i++)
|
for (var i = 0; i < target.Length; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -1360,6 +1370,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
private void OnAsteriskFormTarget(HttpMethod method)
|
private void OnAsteriskFormTarget(HttpMethod method)
|
||||||
{
|
{
|
||||||
|
_requestTargetForm = HttpRequestTarget.AsteriskForm;
|
||||||
|
|
||||||
// The asterisk-form of request-target is only used for a server-wide
|
// The asterisk-form of request-target is only used for a server-wide
|
||||||
// OPTIONS request (https://tools.ietf.org/html/rfc7231#section-4.3.7).
|
// OPTIONS request (https://tools.ietf.org/html/rfc7231#section-4.3.7).
|
||||||
if (method != HttpMethod.Options)
|
if (method != HttpMethod.Options)
|
||||||
|
|
@ -1374,6 +1386,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
private void OnAbsoluteFormTarget(Span<byte> target, Span<byte> query)
|
private void OnAbsoluteFormTarget(Span<byte> target, Span<byte> query)
|
||||||
{
|
{
|
||||||
|
_requestTargetForm = HttpRequestTarget.AbsoluteForm;
|
||||||
|
|
||||||
// absolute-form
|
// absolute-form
|
||||||
// https://tools.ietf.org/html/rfc7230#section-5.3.2
|
// https://tools.ietf.org/html/rfc7230#section-5.3.2
|
||||||
|
|
||||||
|
|
@ -1394,6 +1408,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
RejectRequestTarget(target);
|
RejectRequestTarget(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_absoluteRequestTarget = uri;
|
||||||
Path = uri.LocalPath;
|
Path = uri.LocalPath;
|
||||||
// don't use uri.Query because we need the unescaped version
|
// don't use uri.Query because we need the unescaped version
|
||||||
QueryString = query.GetAsciiStringNonNullCharacters();
|
QueryString = query.GetAsciiStringNonNullCharacters();
|
||||||
|
|
@ -1420,5 +1435,62 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
FrameRequestHeaders.Append(name, valueString);
|
FrameRequestHeaders.Append(name, valueString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void EnsureHostHeaderExists()
|
||||||
|
{
|
||||||
|
if (_httpVersion == Http.HttpVersion.Http10)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://tools.ietf.org/html/rfc7230#section-5.4
|
||||||
|
// A server MUST respond with a 400 (Bad Request) status code to any
|
||||||
|
// HTTP/1.1 request message that lacks a Host header field and to any
|
||||||
|
// request message that contains more than one Host header field or a
|
||||||
|
// Host header field with an invalid field-value.
|
||||||
|
|
||||||
|
var host = FrameRequestHeaders.HeaderHost;
|
||||||
|
if (host.Count <= 0)
|
||||||
|
{
|
||||||
|
RejectRequest(RequestRejectionReason.MissingHostHeader);
|
||||||
|
}
|
||||||
|
else if (host.Count > 1)
|
||||||
|
{
|
||||||
|
RejectRequest(RequestRejectionReason.MultipleHostHeaders);
|
||||||
|
}
|
||||||
|
else if (_requestTargetForm == HttpRequestTarget.AuthorityForm)
|
||||||
|
{
|
||||||
|
if (!host.Equals(RawTarget))
|
||||||
|
{
|
||||||
|
RejectRequest(RequestRejectionReason.InvalidHostHeader, host.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_requestTargetForm == HttpRequestTarget.AbsoluteForm)
|
||||||
|
{
|
||||||
|
// If the target URI includes an authority component, then a
|
||||||
|
// client MUST send a field - value for Host that is identical to that
|
||||||
|
// authority component, excluding any userinfo subcomponent and its "@"
|
||||||
|
// delimiter.
|
||||||
|
|
||||||
|
// System.Uri doesn't not tell us if the port was in the original string or not.
|
||||||
|
// When IsDefaultPort = true, we will allow Host: with or without the default port
|
||||||
|
var authorityAndPort = _absoluteRequestTarget.Authority + ":" + _absoluteRequestTarget.Port;
|
||||||
|
if ((host != _absoluteRequestTarget.Authority || !_absoluteRequestTarget.IsDefaultPort)
|
||||||
|
&& host != authorityAndPort)
|
||||||
|
{
|
||||||
|
RejectRequest(RequestRejectionReason.InvalidHostHeader, host.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum HttpRequestTarget
|
||||||
|
{
|
||||||
|
Unknown = -1,
|
||||||
|
// origin-form is the most common
|
||||||
|
OriginForm,
|
||||||
|
AbsoluteForm,
|
||||||
|
AuthorityForm,
|
||||||
|
AsteriskForm
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
if (!_requestProcessingStopping)
|
if (!_requestProcessingStopping)
|
||||||
{
|
{
|
||||||
|
EnsureHostHeaderExists();
|
||||||
|
|
||||||
var messageBody = MessageBody.For(_httpVersion, FrameRequestHeaders, this);
|
var messageBody = MessageBody.For(_httpVersion, FrameRequestHeaders, this);
|
||||||
_keepAlive = messageBody.RequestKeepAlive;
|
_keepAlive = messageBody.RequestKeepAlive;
|
||||||
_upgrade = messageBody.RequestUpgrade;
|
_upgrade = messageBody.RequestUpgrade;
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
LengthRequiredHttp10,
|
LengthRequiredHttp10,
|
||||||
OptionsMethodRequired,
|
OptionsMethodRequired,
|
||||||
ConnectMethodRequired,
|
ConnectMethodRequired,
|
||||||
|
MissingHostHeader,
|
||||||
|
MultipleHostHeaders,
|
||||||
|
InvalidHostHeader,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -533,7 +533,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
{
|
{
|
||||||
_frame.Start();
|
_frame.Start();
|
||||||
|
|
||||||
var data = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n\r\n");
|
var data = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n");
|
||||||
await _input.Writer.WriteAsync(data);
|
await _input.Writer.WriteAsync(data);
|
||||||
|
|
||||||
var requestProcessingTask = _frame.StopAsync();
|
var requestProcessingTask = _frame.StopAsync();
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
public Task BadRequestIfMethodRequiresLengthButNoContentLengthOrTransferEncodingInRequest(string method)
|
public Task BadRequestIfMethodRequiresLengthButNoContentLengthOrTransferEncodingInRequest(string method)
|
||||||
{
|
{
|
||||||
return TestBadRequest(
|
return TestBadRequest(
|
||||||
$"{method} / HTTP/1.1\r\n\r\n",
|
$"{method} / HTTP/1.1\r\nHost:\r\n\r\n",
|
||||||
"411 Length Required",
|
"411 Length Required",
|
||||||
$"{method} request contains no Content-Length or Transfer-Encoding header");
|
$"{method} request contains no Content-Length or Transfer-Encoding header");
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
public Task BadRequestIfContentLengthInvalid(string contentLength)
|
public Task BadRequestIfContentLengthInvalid(string contentLength)
|
||||||
{
|
{
|
||||||
return TestBadRequest(
|
return TestBadRequest(
|
||||||
$"POST / HTTP/1.1\r\nContent-Length: {contentLength}\r\n\r\n",
|
$"POST / HTTP/1.1\r\nHost:\r\nContent-Length: {contentLength}\r\n\r\n",
|
||||||
"400 Bad Request",
|
"400 Bad Request",
|
||||||
$"Invalid content length: {contentLength}");
|
$"Invalid content length: {contentLength}");
|
||||||
}
|
}
|
||||||
|
|
@ -106,6 +106,33 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
$"Allow: {allowedMethod}");
|
$"Allow: {allowedMethod}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public Task BadRequestIfHostHeaderMissing()
|
||||||
|
{
|
||||||
|
return TestBadRequest(
|
||||||
|
"GET / HTTP/1.1\r\n\r\n",
|
||||||
|
"400 Bad Request",
|
||||||
|
"Request is missing Host header.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public Task BadRequestIfMultipleHostHeaders()
|
||||||
|
{
|
||||||
|
return TestBadRequest("GET / HTTP/1.1\r\nHost: localhost\r\nHost: localhost\r\n\r\n",
|
||||||
|
"400 Bad Request",
|
||||||
|
"Multiple Host headers.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(InvalidHostHeaderData))]
|
||||||
|
public Task BadRequestIfHostHeaderDoesNotMatchRequestTarget(string requestTarget, string host)
|
||||||
|
{
|
||||||
|
return TestBadRequest(
|
||||||
|
$"{requestTarget} HTTP/1.1\r\nHost: {host}\r\n\r\n",
|
||||||
|
"400 Bad Request",
|
||||||
|
$"Invalid Host header: '{host.Trim()}'");
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task BadRequestLogsAreNotHigherThanInformation()
|
public async Task BadRequestLogsAreNotHigherThanInformation()
|
||||||
{
|
{
|
||||||
|
|
@ -211,5 +238,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
public static TheoryData<string> UnrecognizedHttpVersionData => HttpParsingData.UnrecognizedHttpVersionData;
|
public static TheoryData<string> UnrecognizedHttpVersionData => HttpParsingData.UnrecognizedHttpVersionData;
|
||||||
|
|
||||||
public static IEnumerable<object[]> InvalidRequestHeaderData => HttpParsingData.RequestHeaderInvalidData;
|
public static IEnumerable<object[]> InvalidRequestHeaderData => HttpParsingData.RequestHeaderInvalidData;
|
||||||
|
|
||||||
|
public static TheoryData<string,string> InvalidHostHeaderData => HttpParsingData.HostHeaderInvalidData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"5", "Hello",
|
"5", "Hello",
|
||||||
|
|
@ -95,6 +96,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"Connection: keep-alive",
|
"Connection: keep-alive",
|
||||||
"",
|
"",
|
||||||
|
|
@ -146,15 +148,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 5",
|
"Content-Length: 5",
|
||||||
"",
|
"",
|
||||||
"HelloPOST / HTTP/1.1",
|
"HelloPOST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"C", "HelloChunked",
|
"C", "HelloChunked",
|
||||||
"0",
|
"0",
|
||||||
"",
|
"",
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
|
|
@ -225,6 +230,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
IEnumerable<string> sendSequence = new string[] {
|
IEnumerable<string> sendSequence = new string[] {
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"C",
|
"C",
|
||||||
|
|
@ -236,6 +242,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
sendSequence = sendSequence.Concat(new string[] {
|
sendSequence = sendSequence.Concat(new string[] {
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"C",
|
"C",
|
||||||
|
|
@ -247,6 +254,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
sendSequence = sendSequence.Concat(new string[] {
|
sendSequence = sendSequence.Concat(new string[] {
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
"Goodbye"
|
"Goodbye"
|
||||||
|
|
@ -286,6 +294,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.SendAll(
|
await connection.SendAll(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
$"{transferEncodingHeaderLine}",
|
$"{transferEncodingHeaderLine}",
|
||||||
$"{headerLine}",
|
$"{headerLine}",
|
||||||
"",
|
"",
|
||||||
|
|
@ -327,6 +336,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.SendAll(
|
await connection.SendAll(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
$"{transferEncodingHeaderLine}",
|
$"{transferEncodingHeaderLine}",
|
||||||
$"{headerLine}",
|
$"{headerLine}",
|
||||||
"",
|
"",
|
||||||
|
|
@ -396,6 +406,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
IEnumerable<string> sendSequence = new string[] {
|
IEnumerable<string> sendSequence = new string[] {
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"C;hello there",
|
"C;hello there",
|
||||||
|
|
@ -407,6 +418,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
sendSequence = sendSequence.Concat(new string[] {
|
sendSequence = sendSequence.Concat(new string[] {
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"C;hello there",
|
"C;hello there",
|
||||||
|
|
@ -418,6 +430,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
sendSequence = sendSequence.Concat(new string[] {
|
sendSequence = sendSequence.Concat(new string[] {
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
"Goodbye"
|
"Goodbye"
|
||||||
|
|
@ -459,6 +472,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.SendAll(
|
await connection.SendAll(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"Cii");
|
"Cii");
|
||||||
|
|
@ -502,6 +516,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.SendAll(
|
await connection.SendAll(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"C",
|
"C",
|
||||||
|
|
@ -535,6 +550,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.SendAll(
|
await connection.SendAll(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: not-chunked",
|
"Transfer-Encoding: not-chunked",
|
||||||
"",
|
"",
|
||||||
"C",
|
"C",
|
||||||
|
|
@ -557,6 +573,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.SendAll(
|
await connection.SendAll(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: not-chunked",
|
"Transfer-Encoding: not-chunked",
|
||||||
"Content-Length: 22",
|
"Content-Length: 22",
|
||||||
"",
|
"",
|
||||||
|
|
@ -579,6 +596,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.SendAll(
|
await connection.SendAll(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked, not-chunked",
|
"Transfer-Encoding: chunked, not-chunked",
|
||||||
"",
|
"",
|
||||||
"C",
|
"C",
|
||||||
|
|
@ -601,6 +619,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.SendAll(
|
await connection.SendAll(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked, not-chunked",
|
"Transfer-Encoding: chunked, not-chunked",
|
||||||
"Content-Length: 22",
|
"Content-Length: 22",
|
||||||
"",
|
"",
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -104,6 +105,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -141,6 +143,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -178,6 +181,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -218,6 +222,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
|
@ -256,6 +261,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -289,6 +295,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
// client closing the connection.
|
// client closing the connection.
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -321,6 +328,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
// SendEnd is not called, so it isn't the client closing the connection.
|
// SendEnd is not called, so it isn't the client closing the connection.
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
|
@ -358,6 +366,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -401,6 +410,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host: ",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"GET / HTTP/1.0",
|
"GET / HTTP/1.0",
|
||||||
"",
|
"",
|
||||||
|
|
@ -46,4 +47,4 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
using (var connection = server.CreateConnection())
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendAll("GET / HTTP/1.1",
|
await connection.SendAll("GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"")
|
"")
|
||||||
.TimeoutAfter(TimeSpan.FromSeconds(10));
|
.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12,
|
enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||||
checkCertificateRevocation: false);
|
checkCertificateRevocation: false);
|
||||||
|
|
||||||
var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n\r\n");
|
var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n");
|
||||||
await sslStream.WriteAsync(request, 0, request.Length);
|
await sslStream.WriteAsync(request, 0, request.Length);
|
||||||
await sslStream.ReadAsync(new byte[32], 0, 32);
|
await sslStream.ReadAsync(new byte[32], 0, 32);
|
||||||
}
|
}
|
||||||
|
|
@ -187,7 +187,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12,
|
enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||||
checkCertificateRevocation: false);
|
checkCertificateRevocation: false);
|
||||||
|
|
||||||
var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n\r\n");
|
var request = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n");
|
||||||
await sslStream.WriteAsync(request, 0, request.Length);
|
await sslStream.WriteAsync(request, 0, request.Length);
|
||||||
await sslStream.ReadAsync(new byte[32], 0, 32);
|
await sslStream.ReadAsync(new byte[32], 0, 32);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await ReceiveResponse(connection);
|
await ReceiveResponse(connection);
|
||||||
|
|
@ -72,6 +73,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await Task.Delay(ShortDelay);
|
await Task.Delay(ShortDelay);
|
||||||
|
|
@ -93,6 +95,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -120,6 +123,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET /longrunning HTTP/1.1",
|
"GET /longrunning HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
cts.CancelAfter(LongDelay);
|
cts.CancelAfter(LongDelay);
|
||||||
|
|
@ -133,6 +137,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await ReceiveResponse(connection);
|
await ReceiveResponse(connection);
|
||||||
|
|
@ -154,6 +159,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET /upgrade HTTP/1.1",
|
"GET /upgrade HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
|
||||||
|
|
@ -89,8 +89,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
// Initialize data with random bytes
|
// Initialize data with random bytes
|
||||||
(new Random()).NextBytes(data);
|
(new Random()).NextBytes(data);
|
||||||
|
|
||||||
var startReadingRequestBody = new ManualResetEvent(false);
|
var startReadingRequestBody = new TaskCompletionSource<object>();
|
||||||
var clientFinishedSendingRequestBody = new ManualResetEvent(false);
|
var clientFinishedSendingRequestBody = new TaskCompletionSource<object>();
|
||||||
var lastBytesWritten = DateTime.MaxValue;
|
var lastBytesWritten = DateTime.MaxValue;
|
||||||
|
|
||||||
using (var host = StartWebHost(maxRequestBufferSize, data, connectionAdapter, startReadingRequestBody, clientFinishedSendingRequestBody))
|
using (var host = StartWebHost(maxRequestBufferSize, data, connectionAdapter, startReadingRequestBody, clientFinishedSendingRequestBody))
|
||||||
|
|
@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.Equal(data.Length, bytesWritten);
|
Assert.Equal(data.Length, bytesWritten);
|
||||||
clientFinishedSendingRequestBody.Set();
|
clientFinishedSendingRequestBody.TrySetResult(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
var sendTask = sendFunc();
|
var sendTask = sendFunc();
|
||||||
|
|
@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
Assert.InRange(bytesWritten, minimumExpectedBytesWritten, maximumExpectedBytesWritten);
|
Assert.InRange(bytesWritten, minimumExpectedBytesWritten, maximumExpectedBytesWritten);
|
||||||
|
|
||||||
// Tell server to start reading request body
|
// Tell server to start reading request body
|
||||||
startReadingRequestBody.Set();
|
startReadingRequestBody.TrySetResult(null);
|
||||||
|
|
||||||
// Wait for sendTask to finish sending the remaining bytes
|
// Wait for sendTask to finish sending the remaining bytes
|
||||||
await sendTask;
|
await sendTask;
|
||||||
|
|
@ -160,7 +160,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
await sendTask;
|
await sendTask;
|
||||||
|
|
||||||
// Tell server to start reading request body
|
// Tell server to start reading request body
|
||||||
startReadingRequestBody.Set();
|
startReadingRequestBody.TrySetResult(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var reader = new StreamReader(stream, Encoding.ASCII))
|
using (var reader = new StreamReader(stream, Encoding.ASCII))
|
||||||
|
|
@ -181,8 +181,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
var bytesWrittenPollingInterval = TimeSpan.FromMilliseconds(bytesWrittenTimeout.TotalMilliseconds / 10);
|
var bytesWrittenPollingInterval = TimeSpan.FromMilliseconds(bytesWrittenTimeout.TotalMilliseconds / 10);
|
||||||
var maxSendSize = 4096;
|
var maxSendSize = 4096;
|
||||||
|
|
||||||
var startReadingRequestBody = new ManualResetEvent(false);
|
var startReadingRequestBody = new TaskCompletionSource<object>();
|
||||||
var clientFinishedSendingRequestBody = new ManualResetEvent(false);
|
var clientFinishedSendingRequestBody = new TaskCompletionSource<object>();
|
||||||
var lastBytesWritten = DateTime.MaxValue;
|
var lastBytesWritten = DateTime.MaxValue;
|
||||||
|
|
||||||
using (var host = StartWebHost(16 * 1024, data, false, startReadingRequestBody, clientFinishedSendingRequestBody))
|
using (var host = StartWebHost(16 * 1024, data, false, startReadingRequestBody, clientFinishedSendingRequestBody))
|
||||||
|
|
@ -205,7 +205,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
lastBytesWritten = DateTime.Now;
|
lastBytesWritten = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
clientFinishedSendingRequestBody.Set();
|
clientFinishedSendingRequestBody.TrySetResult(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
var ignore = sendFunc();
|
var ignore = sendFunc();
|
||||||
|
|
@ -244,8 +244,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IWebHost StartWebHost(long? maxRequestBufferSize, byte[] expectedBody, bool useConnectionAdapter, ManualResetEvent startReadingRequestBody,
|
private static IWebHost StartWebHost(long? maxRequestBufferSize,
|
||||||
ManualResetEvent clientFinishedSendingRequestBody)
|
byte[] expectedBody,
|
||||||
|
bool useConnectionAdapter,
|
||||||
|
TaskCompletionSource<object> startReadingRequestBody,
|
||||||
|
TaskCompletionSource<object> clientFinishedSendingRequestBody)
|
||||||
{
|
{
|
||||||
var host = new WebHostBuilder()
|
var host = new WebHostBuilder()
|
||||||
.UseKestrel(options =>
|
.UseKestrel(options =>
|
||||||
|
|
@ -275,7 +278,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.Configure(app => app.Run(async context =>
|
.Configure(app => app.Run(async context =>
|
||||||
{
|
{
|
||||||
startReadingRequestBody.WaitOne();
|
await startReadingRequestBody.Task.TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
var buffer = new byte[expectedBody.Length];
|
var buffer = new byte[expectedBody.Length];
|
||||||
var bytesRead = 0;
|
var bytesRead = 0;
|
||||||
|
|
@ -284,7 +287,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
bytesRead += await context.Request.Body.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead);
|
bytesRead += await context.Request.Body.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
clientFinishedSendingRequestBody.WaitOne();
|
await clientFinishedSendingRequestBody.Task.TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
// Verify client didn't send extra bytes
|
// Verify client didn't send extra bytes
|
||||||
if (context.Request.Body.ReadByte() != -1)
|
if (context.Request.Body.ReadByte() != -1)
|
||||||
|
|
|
||||||
|
|
@ -12,18 +12,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
public class MaxRequestLineSizeTests
|
public class MaxRequestLineSizeTests
|
||||||
{
|
{
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("GET / HTTP/1.1\r\n\r\n", 16)]
|
[InlineData("GET / HTTP/1.1\r\nHost:\r\n\r\n", 16)]
|
||||||
[InlineData("GET / HTTP/1.1\r\n\r\n", 17)]
|
[InlineData("GET / HTTP/1.1\r\nHost:\r\n\r\n", 17)]
|
||||||
[InlineData("GET / HTTP/1.1\r\n\r\n", 137)]
|
[InlineData("GET / HTTP/1.1\r\nHost:\r\n\r\n", 137)]
|
||||||
[InlineData("POST /abc/de HTTP/1.1\r\nContent-Length: 0\r\n\r\n", 23)]
|
[InlineData("POST /abc/de HTTP/1.1\r\nHost:\r\nContent-Length: 0\r\n\r\n", 23)]
|
||||||
[InlineData("POST /abc/de HTTP/1.1\r\nContent-Length: 0\r\n\r\n", 24)]
|
[InlineData("POST /abc/de HTTP/1.1\r\nHost:\r\nContent-Length: 0\r\n\r\n", 24)]
|
||||||
[InlineData("POST /abc/de HTTP/1.1\r\nContent-Length: 0\r\n\r\n", 287)]
|
[InlineData("POST /abc/de HTTP/1.1\r\nHost:\r\nContent-Length: 0\r\n\r\n", 287)]
|
||||||
[InlineData("PUT /abc/de?f=ghi HTTP/1.1\r\nContent-Length: 0\r\n\r\n", 28)]
|
[InlineData("PUT /abc/de?f=ghi HTTP/1.1\r\nHost:\r\nContent-Length: 0\r\n\r\n", 28)]
|
||||||
[InlineData("PUT /abc/de?f=ghi HTTP/1.1\r\nContent-Length: 0\r\n\r\n", 29)]
|
[InlineData("PUT /abc/de?f=ghi HTTP/1.1\r\nHost:\r\nContent-Length: 0\r\n\r\n", 29)]
|
||||||
[InlineData("PUT /abc/de?f=ghi HTTP/1.1\r\nContent-Length: 0\r\n\r\n", 589)]
|
[InlineData("PUT /abc/de?f=ghi HTTP/1.1\r\nHost:\r\nContent-Length: 0\r\n\r\n", 589)]
|
||||||
[InlineData("DELETE /a%20b%20c/d%20e?f=ghi HTTP/1.1\r\n\r\n", 40)]
|
[InlineData("DELETE /a%20b%20c/d%20e?f=ghi HTTP/1.1\r\nHost:\r\n\r\n", 40)]
|
||||||
[InlineData("DELETE /a%20b%20c/d%20e?f=ghi HTTP/1.1\r\n\r\n", 41)]
|
[InlineData("DELETE /a%20b%20c/d%20e?f=ghi HTTP/1.1\r\nHost:\r\n\r\n", 41)]
|
||||||
[InlineData("DELETE /a%20b%20c/d%20e?f=ghi HTTP/1.1\r\n\r\n", 1027)]
|
[InlineData("DELETE /a%20b%20c/d%20e?f=ghi HTTP/1.1\r\nHost:\r\n\r\n", 1027)]
|
||||||
public async Task ServerAcceptsRequestLineWithinLimit(string request, int limit)
|
public async Task ServerAcceptsRequestLineWithinLimit(string request, int limit)
|
||||||
{
|
{
|
||||||
using (var server = CreateServer(limit))
|
using (var server = CreateServer(limit))
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
<PlatformTarget Condition="'$(TargetFramework)' == 'net46'">x64</PlatformTarget>
|
<PlatformTarget Condition="'$(TargetFramework)' == 'net46'">x64</PlatformTarget>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||||
|
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Workaround for "Explicit RID still required for .NET Framework test projects" (https://github.com/dotnet/sdk/issues/909).
|
Workaround for "Explicit RID still required for .NET Framework test projects" (https://github.com/dotnet/sdk/issues/909).
|
||||||
|
|
|
||||||
|
|
@ -125,9 +125,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
|
|
||||||
private static string MakeHeaders(int count)
|
private static string MakeHeaders(int count)
|
||||||
{
|
{
|
||||||
return string.Join("", Enumerable
|
const string host = "Host:\r\n";
|
||||||
.Range(0, count)
|
if (count <= 1) return host;
|
||||||
.Select(i => $"Header-{i}: value{i}\r\n"));
|
|
||||||
|
return string.Join("", new[] { host }
|
||||||
|
.Concat(Enumerable
|
||||||
|
.Range(0, count -1)
|
||||||
|
.Select(i => $"Header-{i}: value{i}\r\n")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestServer CreateServer(int? maxRequestHeaderCount = null, int? maxRequestHeadersTotalSize = null)
|
private TestServer CreateServer(int? maxRequestHeaderCount = null, int? maxRequestHeadersTotalSize = null)
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
var tasks = new[]
|
var tasks = new[]
|
||||||
{
|
{
|
||||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, ""),
|
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Host:\r\n"),
|
||||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Content-Length: 1\r\n"),
|
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Host:\r\nContent-Length: 1\r\n"),
|
||||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Content-Length: 1\r\n\r"),
|
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Host:\r\nContent-Length: 1\r\n\r"),
|
||||||
RequestHeadersTimeoutCanceledAfterHeadersReceived(server),
|
RequestHeadersTimeoutCanceledAfterHeadersReceived(server),
|
||||||
ConnectionAbortedWhenRequestLineNotReceivedInTime(server, "P"),
|
ConnectionAbortedWhenRequestLineNotReceivedInTime(server, "P"),
|
||||||
ConnectionAbortedWhenRequestLineNotReceivedInTime(server, "POST / HTTP/1.1\r"),
|
ConnectionAbortedWhenRequestLineNotReceivedInTime(server, "POST / HTTP/1.1\r"),
|
||||||
|
|
@ -55,6 +55,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 1",
|
"Content-Length: 1",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -80,7 +81,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await Assert.ThrowsAsync<IOException>(async () =>
|
await Assert.ThrowsAsync<IOException>(async () =>
|
||||||
{
|
{
|
||||||
foreach (var ch in "POST / HTTP/1.1\r\n\r\n")
|
foreach (var ch in "POST / HTTP/1.1\r\nHost:\r\n\r\n")
|
||||||
{
|
{
|
||||||
await connection.Send(ch.ToString());
|
await connection.Send(ch.ToString());
|
||||||
await Task.Delay(ShortDelay);
|
await Task.Delay(ShortDelay);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET /%41%CC%8A/A/../B/%41%CC%8A HTTP/1.1",
|
"GET /%41%CC%8A/A/../B/%41%CC%8A HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -77,6 +78,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
$"GET {requestTarget} HTTP/1.1",
|
$"GET {requestTarget} HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -109,8 +111,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
using (var connection = server.CreateConnection())
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
|
var host = method == HttpMethod.Connect
|
||||||
|
? requestTarget
|
||||||
|
: string.Empty;
|
||||||
|
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
$"{HttpUtilities.MethodToString(method)} {requestTarget} HTTP/1.1",
|
$"{HttpUtilities.MethodToString(method)} {requestTarget} HTTP/1.1",
|
||||||
|
$"Host: {host}",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||||
{
|
{
|
||||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
||||||
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nConnection: keep-alive, upgrade\r\n\r\n"));
|
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\nConnection: keep-alive, upgrade\r\n\r\n"));
|
||||||
socket.Send(Encoding.ASCII.GetBytes("abc"));
|
socket.Send(Encoding.ASCII.GetBytes("abc"));
|
||||||
|
|
||||||
while (socket.Receive(new byte[1024]) > 0) ;
|
while (socket.Receive(new byte[1024]) > 0) ;
|
||||||
|
|
@ -357,7 +357,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||||
{
|
{
|
||||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
||||||
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n\r\n"));
|
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n"));
|
||||||
|
|
||||||
// Wait until request is done being processed
|
// Wait until request is done being processed
|
||||||
await requestDone.WaitAsync(TimeSpan.FromSeconds(10));
|
await requestDone.WaitAsync(TimeSpan.FromSeconds(10));
|
||||||
|
|
@ -417,7 +417,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||||
{
|
{
|
||||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
||||||
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n\r\n"));
|
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n"));
|
||||||
|
|
||||||
// Wait until connection is established
|
// Wait until connection is established
|
||||||
await requestStarted.WaitAsync(TimeSpan.FromSeconds(10));
|
await requestStarted.WaitAsync(TimeSpan.FromSeconds(10));
|
||||||
|
|
@ -470,7 +470,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
||||||
socket.LingerState = new LingerOption(true, 0);
|
socket.LingerState = new LingerOption(true, 0);
|
||||||
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nContent-Length: 1\r\n\r\n"));
|
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\nContent-Length: 1\r\n\r\n"));
|
||||||
Assert.True(await requestStarted.WaitAsync(_semaphoreWaitTimeout));
|
Assert.True(await requestStarted.WaitAsync(_semaphoreWaitTimeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -505,7 +505,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||||
{
|
{
|
||||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
|
||||||
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n\r\n"));
|
socket.Send(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\n\r\n"));
|
||||||
await appStarted.WaitAsync();
|
await appStarted.WaitAsync();
|
||||||
socket.Shutdown(SocketShutdown.Send);
|
socket.Shutdown(SocketShutdown.Send);
|
||||||
await requestAborted.WaitAsync().TimeoutAfter(TimeSpan.FromSeconds(10));
|
await requestAborted.WaitAsync().TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||||
|
|
@ -534,13 +534,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
var pathTcs = new TaskCompletionSource<PathString>();
|
var pathTcs = new TaskCompletionSource<PathString>();
|
||||||
var rawTargetTcs = new TaskCompletionSource<string>();
|
var rawTargetTcs = new TaskCompletionSource<string>();
|
||||||
var hostTcs = new TaskCompletionSource<HostString>();
|
|
||||||
var queryTcs = new TaskCompletionSource<IQueryCollection>();
|
var queryTcs = new TaskCompletionSource<IQueryCollection>();
|
||||||
|
|
||||||
using (var server = new TestServer(async context =>
|
using (var server = new TestServer(async context =>
|
||||||
{
|
{
|
||||||
pathTcs.TrySetResult(context.Request.Path);
|
pathTcs.TrySetResult(context.Request.Path);
|
||||||
hostTcs.TrySetResult(context.Request.Host);
|
|
||||||
queryTcs.TrySetResult(context.Request.Query);
|
queryTcs.TrySetResult(context.Request.Query);
|
||||||
rawTargetTcs.TrySetResult(context.Features.Get<IHttpRequestFeature>().RawTarget);
|
rawTargetTcs.TrySetResult(context.Features.Get<IHttpRequestFeature>().RawTarget);
|
||||||
await context.Response.WriteAsync("Done");
|
await context.Response.WriteAsync("Done");
|
||||||
|
|
@ -548,10 +546,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
using (var connection = server.CreateConnection())
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
|
var requestTarget = new Uri(requestUrl, UriKind.Absolute);
|
||||||
|
var host = requestTarget.Authority;
|
||||||
|
if (!requestTarget.IsDefaultPort)
|
||||||
|
{
|
||||||
|
host += ":" + requestTarget.Port;
|
||||||
|
}
|
||||||
|
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
$"GET {requestUrl} HTTP/1.1",
|
$"GET {requestUrl} HTTP/1.1",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Host: localhost",
|
$"Host: {host}",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
|
@ -563,10 +568,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
"Done")
|
"Done")
|
||||||
.TimeoutAfter(TimeSpan.FromSeconds(10));
|
.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||||
|
|
||||||
await Task.WhenAll(pathTcs.Task, rawTargetTcs.Task, hostTcs.Task, queryTcs.Task).TimeoutAfter(TimeSpan.FromSeconds(30));
|
await Task.WhenAll(pathTcs.Task, rawTargetTcs.Task, queryTcs.Task).TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||||
Assert.Equal(new PathString(expectedPath), pathTcs.Task.Result);
|
Assert.Equal(new PathString(expectedPath), pathTcs.Task.Result);
|
||||||
Assert.Equal(requestUrl, rawTargetTcs.Task.Result);
|
Assert.Equal(requestUrl, rawTargetTcs.Task.Result);
|
||||||
Assert.Equal("localhost", hostTcs.Task.Result.ToString());
|
|
||||||
if (queryValue == null)
|
if (queryValue == null)
|
||||||
{
|
{
|
||||||
Assert.False(queryTcs.Task.Result.ContainsKey("q"));
|
Assert.False(queryTcs.Task.Result.ContainsKey("q"));
|
||||||
|
|
@ -626,6 +630,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
for (var i = 0; i < iterations; i++)
|
for (var i = 0; i < iterations; i++)
|
||||||
{
|
{
|
||||||
await connection.Send("GET / HTTP/1.1",
|
await connection.Send("GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
|
@ -657,8 +662,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
|
|
@ -862,6 +869,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Expect: 100-continue",
|
"Expect: 100-continue",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
|
|
@ -901,6 +909,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
// https://github.com/aspnet/KestrelHttpServer/issues/1104 is not regressing.
|
// https://github.com/aspnet/KestrelHttpServer/issues/1104 is not regressing.
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -917,6 +926,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.0",
|
"GET / HTTP/1.0",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -950,6 +960,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 7");
|
"Content-Length: 7");
|
||||||
connection.Shutdown(SocketShutdown.Send);
|
connection.Shutdown(SocketShutdown.Send);
|
||||||
await connection.ReceiveForcedEnd();
|
await connection.ReceiveForcedEnd();
|
||||||
|
|
@ -1008,9 +1019,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
// Never send the body so CopyToAsync always fails.
|
// Never send the body so CopyToAsync always fails.
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 5",
|
"Content-Length: 5",
|
||||||
"",
|
"",
|
||||||
"HelloPOST / HTTP/1.1",
|
"HelloPOST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 5",
|
"Content-Length: 5",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -1062,8 +1075,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -1107,6 +1122,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Connection: Upgrade",
|
"Connection: Upgrade",
|
||||||
"",
|
"",
|
||||||
message);
|
message);
|
||||||
|
|
@ -1163,8 +1179,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
using (var connection = server.CreateConnection())
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
var requestData =
|
var requestData =
|
||||||
Enumerable.Repeat("GET / HTTP/1.1\r\n", loopCount)
|
Enumerable.Repeat("GET / HTTP/1.1\r\nHost:\r\n", loopCount)
|
||||||
.Concat(new[] { "GET / HTTP/1.1\r\nContent-Length: 7\r\nConnection: close\r\n\r\nGoodbye" });
|
.Concat(new[] { "GET / HTTP/1.1\r\nHost:\r\nContent-Length: 7\r\nConnection: close\r\n\r\nGoodbye" });
|
||||||
|
|
||||||
var response = string.Join("\r\n", new string[] {
|
var response = string.Join("\r\n", new string[] {
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
|
@ -1197,6 +1213,24 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(HostHeaderData))]
|
||||||
|
public async Task MatchesValidRequestTargetAndHostHeader(string request, string hostHeader)
|
||||||
|
{
|
||||||
|
using (var server = new TestServer(context => Task.CompletedTask))
|
||||||
|
{
|
||||||
|
using (var connection = server.CreateConnection())
|
||||||
|
{
|
||||||
|
await connection.Send($"{request} HTTP/1.1",
|
||||||
|
$"Host: {hostHeader}",
|
||||||
|
"",
|
||||||
|
"");
|
||||||
|
|
||||||
|
await connection.Receive("HTTP/1.1 200 OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task TestRemoteIPAddress(string registerAddress, string requestAddress, string expectAddress)
|
private async Task TestRemoteIPAddress(string registerAddress, string requestAddress, string expectAddress)
|
||||||
{
|
{
|
||||||
var builder = new WebHostBuilder()
|
var builder = new WebHostBuilder()
|
||||||
|
|
@ -1233,5 +1267,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
Assert.NotEmpty(facts["RemotePort"].Value<string>());
|
Assert.NotEmpty(facts["RemotePort"].Value<string>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TheoryData<string, string> HostHeaderData => HttpParsingData.HostHeaderData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -326,6 +326,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"gg");
|
"gg");
|
||||||
|
|
@ -360,6 +361,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"gg");
|
"gg");
|
||||||
|
|
@ -389,6 +391,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -423,6 +426,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -446,6 +450,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"HEAD / HTTP/1.1",
|
"HEAD / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -478,6 +483,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"HEAD / HTTP/1.1",
|
"HEAD / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -515,6 +521,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -524,7 +531,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
"",
|
"",
|
||||||
"hello,");
|
"hello,");
|
||||||
|
|
||||||
await connection.WaitForConnectionClose();
|
await connection.WaitForConnectionClose().TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -554,6 +561,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -589,6 +597,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -624,6 +633,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -664,6 +674,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
|
@ -718,6 +729,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -757,8 +769,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -801,6 +815,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -836,6 +851,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -872,6 +888,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -900,6 +917,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"HEAD / HTTP/1.1",
|
"HEAD / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -928,6 +946,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"HEAD / HTTP/1.1",
|
"HEAD / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -959,6 +978,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"HEAD / HTTP/1.1",
|
"HEAD / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -990,6 +1010,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -1033,17 +1054,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
||||||
requestStarted.Wait();
|
requestStarted.Wait();
|
||||||
connection.Shutdown(SocketShutdown.Send);
|
connection.Shutdown(SocketShutdown.Send);
|
||||||
await connection.WaitForConnectionClose();
|
await connection.WaitForConnectionClose().TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionClosed.Set();
|
connectionClosed.Set();
|
||||||
|
|
||||||
await tcs.Task;
|
await tcs.Task.TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1073,10 +1095,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"gg");
|
"gg");
|
||||||
await responseWritten.WaitAsync();
|
await responseWritten.WaitAsync().TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 400 Bad Request",
|
"HTTP/1.1 400 Bad Request",
|
||||||
$"Date: {server.Context.DateHeaderValue}",
|
$"Date: {server.Context.DateHeaderValue}",
|
||||||
|
|
@ -1104,6 +1127,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -1151,6 +1175,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -1197,6 +1222,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -1209,6 +1235,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
// Make sure connection was kept open
|
// Make sure connection was kept open
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -1245,6 +1272,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -1286,6 +1314,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -1327,6 +1356,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -1367,6 +1397,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
|
@ -1397,6 +1428,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 1",
|
"Content-Length: 1",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -1430,6 +1462,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"gg");
|
"gg");
|
||||||
|
|
@ -1460,6 +1493,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"Expect: 100-continue",
|
"Expect: 100-continue",
|
||||||
"",
|
"",
|
||||||
|
|
@ -1508,6 +1542,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 2",
|
"Content-Length: 2",
|
||||||
"Expect: 100-continue",
|
"Expect: 100-continue",
|
||||||
"",
|
"",
|
||||||
|
|
@ -1578,6 +1613,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"GET / HTTP/1.0",
|
"GET / HTTP/1.0",
|
||||||
"Connection: keep-alive",
|
"Connection: keep-alive",
|
||||||
|
|
@ -1613,6 +1649,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -1654,6 +1691,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"HEAD / HTTP/1.1",
|
"HEAD / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -1687,15 +1725,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 3",
|
"Content-Length: 3",
|
||||||
"",
|
"",
|
||||||
"204POST / HTTP/1.1",
|
"204POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 3",
|
"Content-Length: 3",
|
||||||
"",
|
"",
|
||||||
"205POST / HTTP/1.1",
|
"205POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 3",
|
"Content-Length: 3",
|
||||||
"",
|
"",
|
||||||
"304POST / HTTP/1.1",
|
"304POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 3",
|
"Content-Length: 3",
|
||||||
"",
|
"",
|
||||||
"200");
|
"200");
|
||||||
|
|
@ -1736,6 +1778,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -1792,8 +1835,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -1850,8 +1895,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -1909,6 +1956,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -1955,6 +2003,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -1999,6 +2048,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
|
@ -2061,6 +2111,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"Content-Length: 5",
|
"Content-Length: 5",
|
||||||
"",
|
"",
|
||||||
"Hello");
|
"Hello");
|
||||||
|
|
@ -2166,8 +2217,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -2217,6 +2270,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
@ -2268,6 +2322,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
"Host:",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
_transport.UnbindAsync().Wait();
|
if (_transport != null)
|
||||||
_transport.StopAsync().Wait();
|
{
|
||||||
_transport = null;
|
_transport.UnbindAsync().Wait();
|
||||||
|
_transport.StopAsync().Wait();
|
||||||
|
_transport = null;
|
||||||
|
}
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||||
<PlatformTarget Condition="'$(TargetFramework)' == 'net46'">x64</PlatformTarget>
|
<PlatformTarget Condition="'$(TargetFramework)' == 'net46'">x64</PlatformTarget>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Workaround for "Explicit RID still required for .NET Framework test projects" (https://github.com/dotnet/sdk/issues/909).
|
Workaround for "Explicit RID still required for .NET Framework test projects" (https://github.com/dotnet/sdk/issues/909).
|
||||||
|
|
|
||||||
|
|
@ -427,5 +427,58 @@ namespace Microsoft.AspNetCore.Testing
|
||||||
new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r ", @"Invalid request headers: missing final CRLF in header fields." },
|
new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r ", @"Invalid request headers: missing final CRLF in header fields." },
|
||||||
new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r \n", @"Invalid request headers: missing final CRLF in header fields." },
|
new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r \n", @"Invalid request headers: missing final CRLF in header fields." },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static TheoryData<string, string> HostHeaderData
|
||||||
|
=> new TheoryData<string, string>
|
||||||
|
{
|
||||||
|
{ "OPTIONS *", "" },
|
||||||
|
{ "GET /pub/WWW/", "" },
|
||||||
|
{ "GET /pub/WWW/", " " },
|
||||||
|
{ "GET /pub/WWW/", "www.example.org" },
|
||||||
|
{ "GET http://localhost/", "localhost" },
|
||||||
|
{ "GET http://localhost:80/", "localhost:80" },
|
||||||
|
{ "GET https://localhost/", "localhost" },
|
||||||
|
{ "GET https://localhost:443/", "localhost:443" },
|
||||||
|
{ "CONNECT asp.net:80", "asp.net:80" },
|
||||||
|
{ "CONNECT asp.net:443", "asp.net:443" },
|
||||||
|
};
|
||||||
|
|
||||||
|
public static TheoryData<string, string> HostHeaderInvalidData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// see https://tools.ietf.org/html/rfc7230#section-5.4
|
||||||
|
var invalidHostValues = new[] {
|
||||||
|
"",
|
||||||
|
" ",
|
||||||
|
"contoso.com:4000",
|
||||||
|
"contoso.com/",
|
||||||
|
"not-contoso.com",
|
||||||
|
"user@password:contoso.com",
|
||||||
|
"user@contoso.com",
|
||||||
|
"http://contoso.com/",
|
||||||
|
"http://contoso.com"
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = new TheoryData<string, string>();
|
||||||
|
|
||||||
|
foreach (var host in invalidHostValues)
|
||||||
|
{
|
||||||
|
// absolute form
|
||||||
|
// expected: GET http://contoso.com/ => Host: contoso.com
|
||||||
|
data.Add("GET http://contoso.com/", host);
|
||||||
|
|
||||||
|
// authority-form
|
||||||
|
// expected: CONNECT contoso.com => Host: contoso.com
|
||||||
|
data.Add("CONNECT contoso.com", host);
|
||||||
|
}
|
||||||
|
|
||||||
|
// port mismatch when target contains port
|
||||||
|
data.Add("GET https://contoso.com:443/", "contoso.com:5000");
|
||||||
|
data.Add("CONNECT contoso.com:443", "contoso.com:5000");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue