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",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "Compile: solution",
|
||||
"program": "${workspaceRoot}/samples/SampleApp/bin/Debug/netcoreapp1.1/SampleApp.dll",
|
||||
"args": [],
|
||||
"program": "${workspaceRoot}/samples/SampleApp/bin/Debug/netcoreapp2.0/SampleApp.dll",
|
||||
"cwd": "${workspaceRoot}/samples/SampleApp",
|
||||
"console": "internalConsole",
|
||||
"stopAtEntry": false,
|
||||
|
|
@ -38,8 +37,7 @@
|
|||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "Compile: solution",
|
||||
"program": "${workspaceRoot}/samples/LargeResponseApp/bin/Debug/netcoreapp1.1/LargeResponseApp.dll",
|
||||
"args": [],
|
||||
"program": "${workspaceRoot}/samples/LargeResponseApp/bin/Debug/netcoreapp2.0/LargeResponseApp.dll",
|
||||
"cwd": "${workspaceRoot}/samples/LargeResponseApp",
|
||||
"console": "internalConsole",
|
||||
"stopAtEntry": false,
|
||||
|
|
|
|||
|
|
@ -5,10 +5,20 @@
|
|||
"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": [
|
||||
{
|
||||
"taskName": "Restore: solution",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"restore"
|
||||
]
|
||||
|
|
@ -16,7 +26,6 @@
|
|||
{
|
||||
"taskName": "Compile: solution",
|
||||
"isBuildCommand": true,
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceRoot}/KestrelHttpServer.sln"
|
||||
|
|
@ -40,9 +49,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"taskName": "Test",
|
||||
"args": [
|
||||
"test"
|
||||
],
|
||||
"problemMatcher": "$msCompile",
|
||||
"isTestCommand": true
|
||||
},
|
||||
{
|
||||
"taskName": "Compile: CodeGenerator",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
|
|
@ -53,7 +69,6 @@
|
|||
},
|
||||
{
|
||||
"taskName": "Run: CodeGenerator",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"run"
|
||||
],
|
||||
|
|
@ -63,7 +78,6 @@
|
|||
},
|
||||
{
|
||||
"taskName": "Run: Benchmarks",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"run",
|
||||
"-c",
|
||||
|
|
@ -72,33 +86,6 @@
|
|||
"options": {
|
||||
"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:
|
||||
ex = new BadHttpRequestException("Method not allowed.", StatusCodes.Status405MethodNotAllowed, HttpMethod.Connect);
|
||||
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:
|
||||
ex = new BadHttpRequestException("Bad request.", StatusCodes.Status400BadRequest);
|
||||
break;
|
||||
|
|
@ -116,6 +125,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
case RequestRejectionReason.LengthRequiredHttp10:
|
||||
ex = new BadHttpRequestException($"{detail} request contains no Content-Length header", StatusCodes.Status400BadRequest);
|
||||
break;
|
||||
case RequestRejectionReason.InvalidHostHeader:
|
||||
ex = new BadHttpRequestException($"Invalid Host header: '{detail}'", StatusCodes.Status400BadRequest);
|
||||
break;
|
||||
default:
|
||||
ex = new BadHttpRequestException("Bad request.", StatusCodes.Status400BadRequest);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
private readonly FrameContext _frameContext;
|
||||
private readonly IHttpParser<FrameAdapter> _parser;
|
||||
|
||||
private HttpRequestTarget _requestTargetForm = HttpRequestTarget.Unknown;
|
||||
private Uri _absoluteRequestTarget;
|
||||
|
||||
public Frame(FrameContext frameContext)
|
||||
{
|
||||
_frameContext = frameContext;
|
||||
|
|
@ -141,6 +144,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
public string Path { get; set; }
|
||||
public string QueryString { get; set; }
|
||||
public string RawTarget { get; set; }
|
||||
|
||||
public string HttpVersion
|
||||
{
|
||||
get
|
||||
|
|
@ -365,6 +369,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
Method = null;
|
||||
PathBase = null;
|
||||
Path = null;
|
||||
RawTarget = null;
|
||||
_requestTargetForm = HttpRequestTarget.Unknown;
|
||||
_absoluteRequestTarget = null;
|
||||
QueryString = null;
|
||||
_httpVersion = Http.HttpVersion.Unknown;
|
||||
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 /");
|
||||
|
||||
_requestTargetForm = HttpRequestTarget.OriginForm;
|
||||
|
||||
// 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;
|
||||
// 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)
|
||||
{
|
||||
// TODO Validate that target is a correct host[:port] string.
|
||||
// Reject as 400 if not. This is just a quick scan for invalid characters
|
||||
_requestTargetForm = HttpRequestTarget.AuthorityForm;
|
||||
|
||||
// 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.
|
||||
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)
|
||||
{
|
||||
_requestTargetForm = HttpRequestTarget.AsteriskForm;
|
||||
|
||||
// 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).
|
||||
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)
|
||||
{
|
||||
_requestTargetForm = HttpRequestTarget.AbsoluteForm;
|
||||
|
||||
// absolute-form
|
||||
// https://tools.ietf.org/html/rfc7230#section-5.3.2
|
||||
|
||||
|
|
@ -1394,6 +1408,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
RejectRequestTarget(target);
|
||||
}
|
||||
|
||||
_absoluteRequestTarget = uri;
|
||||
Path = uri.LocalPath;
|
||||
// don't use uri.Query because we need the unescaped version
|
||||
QueryString = query.GetAsciiStringNonNullCharacters();
|
||||
|
|
@ -1420,5 +1435,62 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
|
||||
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)
|
||||
{
|
||||
EnsureHostHeaderExists();
|
||||
|
||||
var messageBody = MessageBody.For(_httpVersion, FrameRequestHeaders, this);
|
||||
_keepAlive = messageBody.RequestKeepAlive;
|
||||
_upgrade = messageBody.RequestUpgrade;
|
||||
|
|
|
|||
|
|
@ -27,5 +27,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
LengthRequiredHttp10,
|
||||
OptionsMethodRequired,
|
||||
ConnectMethodRequired,
|
||||
MissingHostHeader,
|
||||
MultipleHostHeaders,
|
||||
InvalidHostHeader,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -533,7 +533,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
{
|
||||
_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);
|
||||
|
||||
var requestProcessingTask = _frame.StopAsync();
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
public Task BadRequestIfMethodRequiresLengthButNoContentLengthOrTransferEncodingInRequest(string method)
|
||||
{
|
||||
return TestBadRequest(
|
||||
$"{method} / HTTP/1.1\r\n\r\n",
|
||||
$"{method} / HTTP/1.1\r\nHost:\r\n\r\n",
|
||||
"411 Length Required",
|
||||
$"{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)
|
||||
{
|
||||
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",
|
||||
$"Invalid content length: {contentLength}");
|
||||
}
|
||||
|
|
@ -106,6 +106,33 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
$"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]
|
||||
public async Task BadRequestLogsAreNotHigherThanInformation()
|
||||
{
|
||||
|
|
@ -211,5 +238,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
public static TheoryData<string> UnrecognizedHttpVersionData => HttpParsingData.UnrecognizedHttpVersionData;
|
||||
|
||||
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(
|
||||
"POST / HTTP/1.0",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"5", "Hello",
|
||||
|
|
@ -95,6 +96,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.0",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"Connection: keep-alive",
|
||||
"",
|
||||
|
|
@ -146,15 +148,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 5",
|
||||
"",
|
||||
"HelloPOST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"C", "HelloChunked",
|
||||
"0",
|
||||
"",
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 7",
|
||||
"",
|
||||
"Goodbye");
|
||||
|
|
@ -225,6 +230,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
IEnumerable<string> sendSequence = new string[] {
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"C",
|
||||
|
|
@ -236,6 +242,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
sendSequence = sendSequence.Concat(new string[] {
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"C",
|
||||
|
|
@ -247,6 +254,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
sendSequence = sendSequence.Concat(new string[] {
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 7",
|
||||
"",
|
||||
"Goodbye"
|
||||
|
|
@ -286,6 +294,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.SendAll(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
$"{transferEncodingHeaderLine}",
|
||||
$"{headerLine}",
|
||||
"",
|
||||
|
|
@ -327,6 +336,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.SendAll(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
$"{transferEncodingHeaderLine}",
|
||||
$"{headerLine}",
|
||||
"",
|
||||
|
|
@ -396,6 +406,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
IEnumerable<string> sendSequence = new string[] {
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"C;hello there",
|
||||
|
|
@ -407,6 +418,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
sendSequence = sendSequence.Concat(new string[] {
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"C;hello there",
|
||||
|
|
@ -418,6 +430,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
sendSequence = sendSequence.Concat(new string[] {
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 7",
|
||||
"",
|
||||
"Goodbye"
|
||||
|
|
@ -459,6 +472,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.SendAll(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"Cii");
|
||||
|
|
@ -502,6 +516,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.SendAll(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"C",
|
||||
|
|
@ -535,6 +550,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.SendAll(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: not-chunked",
|
||||
"",
|
||||
"C",
|
||||
|
|
@ -557,6 +573,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.SendAll(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: not-chunked",
|
||||
"Content-Length: 22",
|
||||
"",
|
||||
|
|
@ -579,6 +596,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.SendAll(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked, not-chunked",
|
||||
"",
|
||||
"C",
|
||||
|
|
@ -601,6 +619,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.SendAll(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked, not-chunked",
|
||||
"Content-Length: 22",
|
||||
"",
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -104,6 +105,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -141,6 +143,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -178,6 +181,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -218,6 +222,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"",
|
||||
"");
|
||||
|
||||
|
|
@ -256,6 +261,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -289,6 +295,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
// client closing the connection.
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"",
|
||||
"");
|
||||
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.
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"",
|
||||
"");
|
||||
|
||||
|
|
@ -358,6 +366,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -401,6 +410,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: ",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"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())
|
||||
{
|
||||
await connection.SendAll("GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"")
|
||||
.TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||
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.ReadAsync(new byte[32], 0, 32);
|
||||
}
|
||||
|
|
@ -187,7 +187,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
enabledSslProtocols: SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||
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.ReadAsync(new byte[32], 0, 32);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await ReceiveResponse(connection);
|
||||
|
|
@ -72,6 +73,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await Task.Delay(ShortDelay);
|
||||
|
|
@ -93,6 +95,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -120,6 +123,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET /longrunning HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
cts.CancelAfter(LongDelay);
|
||||
|
|
@ -133,6 +137,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await ReceiveResponse(connection);
|
||||
|
|
@ -154,6 +159,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET /upgrade HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
// Initialize data with random bytes
|
||||
(new Random()).NextBytes(data);
|
||||
|
||||
var startReadingRequestBody = new ManualResetEvent(false);
|
||||
var clientFinishedSendingRequestBody = new ManualResetEvent(false);
|
||||
var startReadingRequestBody = new TaskCompletionSource<object>();
|
||||
var clientFinishedSendingRequestBody = new TaskCompletionSource<object>();
|
||||
var lastBytesWritten = DateTime.MaxValue;
|
||||
|
||||
using (var host = StartWebHost(maxRequestBufferSize, data, connectionAdapter, startReadingRequestBody, clientFinishedSendingRequestBody))
|
||||
|
|
@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
}
|
||||
|
||||
Assert.Equal(data.Length, bytesWritten);
|
||||
clientFinishedSendingRequestBody.Set();
|
||||
clientFinishedSendingRequestBody.TrySetResult(null);
|
||||
};
|
||||
|
||||
var sendTask = sendFunc();
|
||||
|
|
@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
Assert.InRange(bytesWritten, minimumExpectedBytesWritten, maximumExpectedBytesWritten);
|
||||
|
||||
// Tell server to start reading request body
|
||||
startReadingRequestBody.Set();
|
||||
startReadingRequestBody.TrySetResult(null);
|
||||
|
||||
// Wait for sendTask to finish sending the remaining bytes
|
||||
await sendTask;
|
||||
|
|
@ -160,7 +160,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
await sendTask;
|
||||
|
||||
// Tell server to start reading request body
|
||||
startReadingRequestBody.Set();
|
||||
startReadingRequestBody.TrySetResult(null);
|
||||
}
|
||||
|
||||
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 maxSendSize = 4096;
|
||||
|
||||
var startReadingRequestBody = new ManualResetEvent(false);
|
||||
var clientFinishedSendingRequestBody = new ManualResetEvent(false);
|
||||
var startReadingRequestBody = new TaskCompletionSource<object>();
|
||||
var clientFinishedSendingRequestBody = new TaskCompletionSource<object>();
|
||||
var lastBytesWritten = DateTime.MaxValue;
|
||||
|
||||
using (var host = StartWebHost(16 * 1024, data, false, startReadingRequestBody, clientFinishedSendingRequestBody))
|
||||
|
|
@ -205,7 +205,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
lastBytesWritten = DateTime.Now;
|
||||
}
|
||||
|
||||
clientFinishedSendingRequestBody.Set();
|
||||
clientFinishedSendingRequestBody.TrySetResult(null);
|
||||
};
|
||||
|
||||
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,
|
||||
ManualResetEvent clientFinishedSendingRequestBody)
|
||||
private static IWebHost StartWebHost(long? maxRequestBufferSize,
|
||||
byte[] expectedBody,
|
||||
bool useConnectionAdapter,
|
||||
TaskCompletionSource<object> startReadingRequestBody,
|
||||
TaskCompletionSource<object> clientFinishedSendingRequestBody)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseKestrel(options =>
|
||||
|
|
@ -275,7 +278,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.Configure(app => app.Run(async context =>
|
||||
{
|
||||
startReadingRequestBody.WaitOne();
|
||||
await startReadingRequestBody.Task.TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||
|
||||
var buffer = new byte[expectedBody.Length];
|
||||
var bytesRead = 0;
|
||||
|
|
@ -284,7 +287,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
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
|
||||
if (context.Request.Body.ReadByte() != -1)
|
||||
|
|
|
|||
|
|
@ -12,18 +12,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
public class MaxRequestLineSizeTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("GET / HTTP/1.1\r\n\r\n", 16)]
|
||||
[InlineData("GET / HTTP/1.1\r\n\r\n", 17)]
|
||||
[InlineData("GET / HTTP/1.1\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\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("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\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("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\n\r\n", 41)]
|
||||
[InlineData("DELETE /a%20b%20c/d%20e?f=ghi HTTP/1.1\r\n\r\n", 1027)]
|
||||
[InlineData("GET / HTTP/1.1\r\nHost:\r\n\r\n", 16)]
|
||||
[InlineData("GET / HTTP/1.1\r\nHost:\r\n\r\n", 17)]
|
||||
[InlineData("GET / HTTP/1.1\r\nHost:\r\n\r\n", 137)]
|
||||
[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\nHost:\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", 287)]
|
||||
[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\nHost:\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", 589)]
|
||||
[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\nHost:\r\n\r\n", 41)]
|
||||
[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)
|
||||
{
|
||||
using (var server = CreateServer(limit))
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
<PlatformTarget Condition="'$(TargetFramework)' == 'net46'">x64</PlatformTarget>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
|
||||
<!--
|
||||
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)
|
||||
{
|
||||
return string.Join("", Enumerable
|
||||
.Range(0, count)
|
||||
.Select(i => $"Header-{i}: value{i}\r\n"));
|
||||
const string host = "Host:\r\n";
|
||||
if (count <= 1) return host;
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
var tasks = new[]
|
||||
{
|
||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, ""),
|
||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Content-Length: 1\r\n"),
|
||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Content-Length: 1\r\n\r"),
|
||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Host:\r\n"),
|
||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Host:\r\nContent-Length: 1\r\n"),
|
||||
ConnectionAbortedWhenRequestHeadersNotReceivedInTime(server, "Host:\r\nContent-Length: 1\r\n\r"),
|
||||
RequestHeadersTimeoutCanceledAfterHeadersReceived(server),
|
||||
ConnectionAbortedWhenRequestLineNotReceivedInTime(server, "P"),
|
||||
ConnectionAbortedWhenRequestLineNotReceivedInTime(server, "POST / HTTP/1.1\r"),
|
||||
|
|
@ -55,6 +55,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 1",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -80,7 +81,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
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 Task.Delay(ShortDelay);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET /%41%CC%8A/A/../B/%41%CC%8A HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -77,6 +78,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
$"GET {requestTarget} HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -109,8 +111,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
var host = method == HttpMethod.Connect
|
||||
? requestTarget
|
||||
: string.Empty;
|
||||
|
||||
await connection.Send(
|
||||
$"{HttpUtilities.MethodToString(method)} {requestTarget} HTTP/1.1",
|
||||
$"Host: {host}",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||
{
|
||||
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"));
|
||||
|
||||
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))
|
||||
{
|
||||
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
|
||||
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))
|
||||
{
|
||||
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
|
||||
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.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));
|
||||
}
|
||||
|
||||
|
|
@ -505,7 +505,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||
{
|
||||
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();
|
||||
socket.Shutdown(SocketShutdown.Send);
|
||||
await requestAborted.WaitAsync().TimeoutAfter(TimeSpan.FromSeconds(10));
|
||||
|
|
@ -534,13 +534,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
var pathTcs = new TaskCompletionSource<PathString>();
|
||||
var rawTargetTcs = new TaskCompletionSource<string>();
|
||||
var hostTcs = new TaskCompletionSource<HostString>();
|
||||
var queryTcs = new TaskCompletionSource<IQueryCollection>();
|
||||
|
||||
using (var server = new TestServer(async context =>
|
||||
{
|
||||
pathTcs.TrySetResult(context.Request.Path);
|
||||
hostTcs.TrySetResult(context.Request.Host);
|
||||
queryTcs.TrySetResult(context.Request.Query);
|
||||
rawTargetTcs.TrySetResult(context.Features.Get<IHttpRequestFeature>().RawTarget);
|
||||
await context.Response.WriteAsync("Done");
|
||||
|
|
@ -548,10 +546,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
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(
|
||||
$"GET {requestUrl} HTTP/1.1",
|
||||
"Content-Length: 0",
|
||||
"Host: localhost",
|
||||
$"Host: {host}",
|
||||
"",
|
||||
"");
|
||||
|
||||
|
|
@ -563,10 +568,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
"Done")
|
||||
.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(requestUrl, rawTargetTcs.Task.Result);
|
||||
Assert.Equal("localhost", hostTcs.Task.Result.ToString());
|
||||
if (queryValue == null)
|
||||
{
|
||||
Assert.False(queryTcs.Task.Result.ContainsKey("q"));
|
||||
|
|
@ -626,6 +630,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
for (var i = 0; i < iterations; i++)
|
||||
{
|
||||
await connection.Send("GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
|
||||
|
|
@ -657,8 +662,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"Connection: close",
|
||||
"Content-Length: 7",
|
||||
"",
|
||||
|
|
@ -862,6 +869,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Expect: 100-continue",
|
||||
"Connection: close",
|
||||
"Content-Length: 11",
|
||||
|
|
@ -901,6 +909,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
// https://github.com/aspnet/KestrelHttpServer/issues/1104 is not regressing.
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -917,6 +926,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.0",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -950,6 +960,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 7");
|
||||
connection.Shutdown(SocketShutdown.Send);
|
||||
await connection.ReceiveForcedEnd();
|
||||
|
|
@ -1008,9 +1019,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
// Never send the body so CopyToAsync always fails.
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 5",
|
||||
"",
|
||||
"HelloPOST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 5",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -1062,8 +1075,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -1107,6 +1122,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"Connection: Upgrade",
|
||||
"",
|
||||
message);
|
||||
|
|
@ -1163,8 +1179,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
var requestData =
|
||||
Enumerable.Repeat("GET / HTTP/1.1\r\n", loopCount)
|
||||
.Concat(new[] { "GET / HTTP/1.1\r\nContent-Length: 7\r\nConnection: close\r\n\r\nGoodbye" });
|
||||
Enumerable.Repeat("GET / HTTP/1.1\r\nHost:\r\n", loopCount)
|
||||
.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[] {
|
||||
"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)
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
|
|
@ -1233,5 +1267,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
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(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"gg");
|
||||
|
|
@ -360,6 +361,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"gg");
|
||||
|
|
@ -389,6 +391,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -423,6 +426,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -446,6 +450,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"HEAD / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -478,6 +483,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"HEAD / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -515,6 +521,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -524,7 +531,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
"",
|
||||
"hello,");
|
||||
|
||||
await connection.WaitForConnectionClose();
|
||||
await connection.WaitForConnectionClose().TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -554,6 +561,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -589,6 +597,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -624,6 +633,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -664,6 +674,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
|
||||
|
|
@ -718,6 +729,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -757,8 +769,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -801,6 +815,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -836,6 +851,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -872,6 +888,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -900,6 +917,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"HEAD / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -928,6 +946,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"HEAD / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -959,6 +978,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"HEAD / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -990,6 +1010,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -1033,17 +1054,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
|
||||
requestStarted.Wait();
|
||||
connection.Shutdown(SocketShutdown.Send);
|
||||
await connection.WaitForConnectionClose();
|
||||
await connection.WaitForConnectionClose().TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||
}
|
||||
|
||||
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(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"gg");
|
||||
await responseWritten.WaitAsync();
|
||||
await responseWritten.WaitAsync().TimeoutAfter(TimeSpan.FromSeconds(30));
|
||||
await connection.ReceiveEnd(
|
||||
"HTTP/1.1 400 Bad Request",
|
||||
$"Date: {server.Context.DateHeaderValue}",
|
||||
|
|
@ -1104,6 +1127,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -1151,6 +1175,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -1197,6 +1222,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -1209,6 +1235,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
// Make sure connection was kept open
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -1245,6 +1272,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -1286,6 +1314,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -1327,6 +1356,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -1367,6 +1397,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.Receive(
|
||||
|
|
@ -1397,6 +1428,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 1",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -1430,6 +1462,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"gg");
|
||||
|
|
@ -1460,6 +1493,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Transfer-Encoding: chunked",
|
||||
"Expect: 100-continue",
|
||||
"",
|
||||
|
|
@ -1508,6 +1542,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 2",
|
||||
"Expect: 100-continue",
|
||||
"",
|
||||
|
|
@ -1578,6 +1613,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"GET / HTTP/1.0",
|
||||
"Connection: keep-alive",
|
||||
|
|
@ -1613,6 +1649,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -1654,6 +1691,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"HEAD / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -1687,15 +1725,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 3",
|
||||
"",
|
||||
"204POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 3",
|
||||
"",
|
||||
"205POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 3",
|
||||
"",
|
||||
"304POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 3",
|
||||
"",
|
||||
"200");
|
||||
|
|
@ -1736,6 +1778,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -1792,8 +1835,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
|
|
@ -1850,8 +1895,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -1909,6 +1956,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -1955,6 +2003,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -1999,6 +2048,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveForcedEnd(
|
||||
|
|
@ -2061,6 +2111,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"POST / HTTP/1.1",
|
||||
"Host:",
|
||||
"Content-Length: 5",
|
||||
"",
|
||||
"Hello");
|
||||
|
|
@ -2166,8 +2217,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -2217,6 +2270,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
@ -2268,6 +2322,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await connection.Send(
|
||||
"GET / HTTP/1.1",
|
||||
"Host:",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
|
|||
|
|
@ -57,9 +57,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
}
|
||||
catch
|
||||
{
|
||||
_transport.UnbindAsync().Wait();
|
||||
_transport.StopAsync().Wait();
|
||||
_transport = null;
|
||||
if (_transport != null)
|
||||
{
|
||||
_transport.UnbindAsync().Wait();
|
||||
_transport.StopAsync().Wait();
|
||||
_transport = null;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
<PlatformTarget Condition="'$(TargetFramework)' == 'net46'">x64</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
|
||||
<!--
|
||||
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 \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