parent
71ecf5612f
commit
72cc0ffbd5
|
|
@ -32,22 +32,24 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
/// Initializes a new instance of the <see cref="DateHeaderValueManager"/> class.
|
/// Initializes a new instance of the <see cref="DateHeaderValueManager"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateHeaderValueManager()
|
public DateHeaderValueManager()
|
||||||
: this(
|
: this(systemClock: new SystemClock())
|
||||||
systemClock: new SystemClock(),
|
|
||||||
timeWithoutRequestsUntilIdle: TimeSpan.FromSeconds(10),
|
|
||||||
timerInterval: TimeSpan.FromSeconds(1))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal for testing
|
// Internal for testing
|
||||||
internal DateHeaderValueManager(
|
internal DateHeaderValueManager(
|
||||||
ISystemClock systemClock,
|
ISystemClock systemClock,
|
||||||
TimeSpan timeWithoutRequestsUntilIdle,
|
TimeSpan? timeWithoutRequestsUntilIdle = null,
|
||||||
TimeSpan timerInterval)
|
TimeSpan? timerInterval = null)
|
||||||
{
|
{
|
||||||
|
if (systemClock == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(systemClock));
|
||||||
|
}
|
||||||
|
|
||||||
_systemClock = systemClock;
|
_systemClock = systemClock;
|
||||||
_timeWithoutRequestsUntilIdle = timeWithoutRequestsUntilIdle;
|
_timeWithoutRequestsUntilIdle = timeWithoutRequestsUntilIdle ?? TimeSpan.FromSeconds(10);
|
||||||
_timerInterval = timerInterval;
|
_timerInterval = timerInterval ?? TimeSpan.FromSeconds(1);
|
||||||
_dateValueTimer = new Timer(TimerLoop, state: null, dueTime: Timeout.Infinite, period: Timeout.Infinite);
|
_dateValueTimer = new Timer(TimerLoop, state: null, dueTime: Timeout.Infinite, period: Timeout.Infinite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
private static readonly byte[] _bytesHttpVersion11 = Encoding.ASCII.GetBytes("HTTP/1.1 ");
|
private static readonly byte[] _bytesHttpVersion11 = Encoding.ASCII.GetBytes("HTTP/1.1 ");
|
||||||
private static readonly byte[] _bytesContentLengthZero = Encoding.ASCII.GetBytes("\r\nContent-Length: 0");
|
private static readonly byte[] _bytesContentLengthZero = Encoding.ASCII.GetBytes("\r\nContent-Length: 0");
|
||||||
private static readonly byte[] _bytesEndHeaders = Encoding.ASCII.GetBytes("\r\n\r\n");
|
private static readonly byte[] _bytesEndHeaders = Encoding.ASCII.GetBytes("\r\n\r\n");
|
||||||
|
private static readonly byte[] _bytesServer = Encoding.ASCII.GetBytes("\r\nServer: Kestrel");
|
||||||
|
|
||||||
private static Vector<byte> _vectorCRs = new Vector<byte>((byte)'\r');
|
private static Vector<byte> _vectorCRs = new Vector<byte>((byte)'\r');
|
||||||
private static Vector<byte> _vectorColons = new Vector<byte>((byte)':');
|
private static Vector<byte> _vectorColons = new Vector<byte>((byte)':');
|
||||||
|
|
@ -44,7 +45,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
private readonly object _onCompletedSync = new Object();
|
private readonly object _onCompletedSync = new Object();
|
||||||
|
|
||||||
private bool _requestRejected;
|
private bool _requestRejected;
|
||||||
private Headers _frameHeaders;
|
|
||||||
private Streams _frameStreams;
|
private Streams _frameStreams;
|
||||||
|
|
||||||
protected List<KeyValuePair<Func<object, Task>, object>> _onStarting;
|
protected List<KeyValuePair<Func<object, Task>, object>> _onStarting;
|
||||||
|
|
@ -210,21 +210,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
get { return _requestProcessingStatus == RequestProcessingStatus.ResponseStarted; }
|
get { return _requestProcessingStatus == RequestProcessingStatus.ResponseStarted; }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FrameRequestHeaders FrameRequestHeaders => _frameHeaders.RequestHeaders;
|
protected FrameRequestHeaders FrameRequestHeaders { get; private set; }
|
||||||
|
|
||||||
|
protected FrameResponseHeaders FrameResponseHeaders { get; private set; }
|
||||||
|
|
||||||
public void InitializeHeaders()
|
public void InitializeHeaders()
|
||||||
{
|
{
|
||||||
if (_frameHeaders == null)
|
if (FrameRequestHeaders == null)
|
||||||
{
|
{
|
||||||
_frameHeaders = new Headers(ServerOptions);
|
RequestHeaders = FrameRequestHeaders = new FrameRequestHeaders();
|
||||||
RequestHeaders = _frameHeaders.RequestHeaders;
|
|
||||||
ResponseHeaders = _frameHeaders.ResponseHeaders;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_frameHeaders.Initialize(DateHeaderValueManager);
|
if (FrameResponseHeaders == null)
|
||||||
|
{
|
||||||
|
ResponseHeaders = FrameResponseHeaders = new FrameResponseHeaders();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void InitializeStreams(MessageBody messageBody)
|
public void InitializeStreams(MessageBody messageBody)
|
||||||
{
|
{
|
||||||
if (_frameStreams == null)
|
if (_frameStreams == null)
|
||||||
|
|
@ -259,7 +261,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
_frameHeaders?.Reset();
|
FrameRequestHeaders?.Reset();
|
||||||
|
FrameResponseHeaders?.Reset();
|
||||||
|
|
||||||
_onStarting = null;
|
_onStarting = null;
|
||||||
_onCompleted = null;
|
_onCompleted = null;
|
||||||
|
|
@ -598,7 +601,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
if (_requestProcessingStatus == RequestProcessingStatus.RequestStarted && _requestRejected)
|
if (_requestProcessingStatus == RequestProcessingStatus.RequestStarted && _requestRejected)
|
||||||
{
|
{
|
||||||
if (_frameHeaders == null)
|
if (FrameRequestHeaders == null || FrameResponseHeaders == null)
|
||||||
{
|
{
|
||||||
InitializeHeaders();
|
InitializeHeaders();
|
||||||
}
|
}
|
||||||
|
|
@ -634,7 +637,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
ReasonPhrase = null;
|
ReasonPhrase = null;
|
||||||
|
|
||||||
var responseHeaders = _frameHeaders.ResponseHeaders;
|
var responseHeaders = FrameResponseHeaders;
|
||||||
responseHeaders.Reset();
|
responseHeaders.Reset();
|
||||||
var dateHeaderValues = DateHeaderValueManager.GetDateHeaderValues();
|
var dateHeaderValues = DateHeaderValueManager.GetDateHeaderValues();
|
||||||
|
|
||||||
|
|
@ -643,7 +646,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
if (ServerOptions.AddServerHeader)
|
if (ServerOptions.AddServerHeader)
|
||||||
{
|
{
|
||||||
responseHeaders.SetRawServer(Constants.ServerName, Headers.BytesServer);
|
responseHeaders.SetRawServer(Constants.ServerName, _bytesServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseHeaders = responseHeaders;
|
ResponseHeaders = responseHeaders;
|
||||||
|
|
@ -698,7 +701,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
byte[] statusBytes,
|
byte[] statusBytes,
|
||||||
bool appCompleted)
|
bool appCompleted)
|
||||||
{
|
{
|
||||||
var responseHeaders = _frameHeaders.ResponseHeaders;
|
var responseHeaders = FrameResponseHeaders;
|
||||||
responseHeaders.SetReadOnly();
|
responseHeaders.SetReadOnly();
|
||||||
|
|
||||||
var hasConnection = responseHeaders.HasConnection;
|
var hasConnection = responseHeaders.HasConnection;
|
||||||
|
|
@ -759,6 +762,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
responseHeaders.SetRawConnection("keep-alive", _bytesConnectionKeepAlive);
|
responseHeaders.SetRawConnection("keep-alive", _bytesConnectionKeepAlive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ServerOptions.AddServerHeader && !responseHeaders.HasServer)
|
||||||
|
{
|
||||||
|
responseHeaders.SetRawServer(Constants.ServerName, _bytesServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!responseHeaders.HasDate)
|
||||||
|
{
|
||||||
|
var dateHeaderValues = DateHeaderValueManager.GetDateHeaderValues();
|
||||||
|
responseHeaders.SetRawDate(dateHeaderValues.String, dateHeaderValues.Bytes);
|
||||||
|
}
|
||||||
|
|
||||||
end.CopyFrom(_bytesHttpVersion11);
|
end.CopyFrom(_bytesHttpVersion11);
|
||||||
end.CopyFrom(statusBytes);
|
end.CopyFrom(statusBytes);
|
||||||
responseHeaders.CopyTo(ref end);
|
responseHeaders.CopyTo(ref end);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Http
|
||||||
|
|
||||||
public bool HasContentLength => HeaderContentLength.Count != 0;
|
public bool HasContentLength => HeaderContentLength.Count != 0;
|
||||||
|
|
||||||
|
public bool HasServer => HeaderServer.Count != 0;
|
||||||
|
|
||||||
|
public bool HasDate => HeaderDate.Count != 0;
|
||||||
|
|
||||||
public Enumerator GetEnumerator()
|
public Enumerator GetEnumerator()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Http;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Infrastructure
|
|
||||||
{
|
|
||||||
class Headers
|
|
||||||
{
|
|
||||||
public static readonly byte[] BytesServer = Encoding.ASCII.GetBytes("\r\nServer: Kestrel");
|
|
||||||
|
|
||||||
private readonly KestrelServerOptions _options;
|
|
||||||
|
|
||||||
public Headers(KestrelServerOptions options)
|
|
||||||
{
|
|
||||||
_options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialize(DateHeaderValueManager dateValueManager)
|
|
||||||
{
|
|
||||||
var dateHeaderValues = dateValueManager.GetDateHeaderValues();
|
|
||||||
ResponseHeaders.SetRawDate(dateHeaderValues.String, dateHeaderValues.Bytes);
|
|
||||||
|
|
||||||
if (_options.AddServerHeader)
|
|
||||||
{
|
|
||||||
ResponseHeaders.SetRawServer("Kestrel", BytesServer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public FrameRequestHeaders RequestHeaders { get; } = new FrameRequestHeaders();
|
|
||||||
public FrameResponseHeaders ResponseHeaders { get; } = new FrameResponseHeaders();
|
|
||||||
|
|
||||||
public void Reset()
|
|
||||||
{
|
|
||||||
RequestHeaders.Reset();
|
|
||||||
ResponseHeaders.Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(context => { return Task.FromResult(0); }))
|
using (var server = new TestServer(context => { return Task.FromResult(0); }))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(request);
|
await connection.SendEnd(request);
|
||||||
await ReceiveBadRequestResponse(connection);
|
await ReceiveBadRequestResponse(connection);
|
||||||
|
|
@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(context => { return Task.FromResult(0); }))
|
using (var server = new TestServer(context => { return Task.FromResult(0); }))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(request);
|
await connection.Send(request);
|
||||||
await ReceiveBadRequestResponse(connection);
|
await ReceiveBadRequestResponse(connection);
|
||||||
|
|
@ -103,10 +103,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveStartsWith("Date: ");
|
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
$"Date: {connection.Server.Context.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
public class ChunkedRequestTests
|
public class ChunkedRequestTests
|
||||||
{
|
{
|
||||||
public static TheoryData<ServiceContext> ConnectionFilterData
|
public static TheoryData<TestServiceContext> ConnectionFilterData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new TheoryData<ServiceContext>
|
return new TheoryData<TestServiceContext>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
new TestServiceContext()
|
new TestServiceContext()
|
||||||
|
|
@ -34,7 +34,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
var request = httpContext.Request;
|
var request = httpContext.Request;
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var buffer = new byte[8192];
|
var buffer = new byte[8192];
|
||||||
|
|
@ -55,18 +54,17 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await request.Body.CopyToAsync(data);
|
await request.Body.CopyToAsync(data);
|
||||||
var bytes = data.ToArray();
|
var bytes = data.ToArray();
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = bytes.Length.ToString();
|
response.Headers["Content-Length"] = bytes.Length.ToString();
|
||||||
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10TransferEncoding(ServiceContext testContext)
|
public async Task Http10TransferEncoding(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App, testContext))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
|
@ -78,6 +76,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
}
|
}
|
||||||
|
|
@ -86,11 +85,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10KeepAliveTransferEncoding(ServiceContext testContext)
|
public async Task Http10KeepAliveTransferEncoding(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked, testContext))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
|
@ -107,11 +106,13 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
"Connection: keep-alive",
|
"Connection: keep-alive",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
|
|
@ -121,7 +122,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task RequestBodyIsConsumedAutomaticallyIfAppDoesntConsumeItFully(ServiceContext testContext)
|
public async Task RequestBodyIsConsumedAutomaticallyIfAppDoesntConsumeItFully(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
|
|
@ -130,13 +131,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
Assert.Equal("POST", request.Method);
|
Assert.Equal("POST", request.Method);
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
|
@ -154,12 +154,15 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello WorldHTTP/1.1 200 OK",
|
"Hello WorldHTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello WorldHTTP/1.1 200 OK",
|
"Hello WorldHTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
|
|
@ -169,7 +172,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task TrailingHeadersAreParsed(ServiceContext testContext)
|
public async Task TrailingHeadersAreParsed(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var requestCount = 10;
|
var requestCount = 10;
|
||||||
var requestsReceived = 0;
|
var requestsReceived = 0;
|
||||||
|
|
@ -199,7 +202,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
requestsReceived++;
|
requestsReceived++;
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
|
|
@ -207,6 +209,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
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",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World"});
|
"Hello World"});
|
||||||
|
|
@ -244,7 +247,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
var fullRequest = sendSequence.ToArray();
|
var fullRequest = sendSequence.ToArray();
|
||||||
|
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(fullRequest);
|
await connection.SendEnd(fullRequest);
|
||||||
|
|
||||||
|
|
@ -255,7 +258,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ExtensionsAreIgnored(ServiceContext testContext)
|
public async Task ExtensionsAreIgnored(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var requestCount = 10;
|
var requestCount = 10;
|
||||||
var requestsReceived = 0;
|
var requestsReceived = 0;
|
||||||
|
|
@ -285,7 +288,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
requestsReceived++;
|
requestsReceived++;
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
|
|
@ -293,6 +295,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
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",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World"});
|
"Hello World"});
|
||||||
|
|
@ -330,7 +333,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
var fullRequest = sendSequence.ToArray();
|
var fullRequest = sendSequence.ToArray();
|
||||||
|
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(fullRequest);
|
await connection.SendEnd(fullRequest);
|
||||||
|
|
||||||
|
|
@ -341,7 +344,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task InvalidLengthResultsIn400(ServiceContext testContext)
|
public async Task InvalidLengthResultsIn400(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
|
|
@ -355,13 +358,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
;// read to end
|
;// read to end
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
|
@ -373,10 +375,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"HTTP/1.1 400 Bad Request",
|
"HTTP/1.1 400 Bad Request",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveStartsWith("Date:");
|
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
@ -385,7 +386,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task InvalidSizedDataResultsIn400(ServiceContext testContext)
|
public async Task InvalidSizedDataResultsIn400(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
|
|
@ -399,13 +400,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
;// read to end
|
;// read to end
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
|
@ -418,10 +418,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"HTTP/1.1 400 Bad Request",
|
"HTTP/1.1 400 Bad Request",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveStartsWith("Date:");
|
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
public class ChunkedResponseTests
|
public class ChunkedResponseTests
|
||||||
{
|
{
|
||||||
public static TheoryData<ServiceContext> ConnectionFilterData
|
public static TheoryData<TestServiceContext> ConnectionFilterData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new TheoryData<ServiceContext>
|
return new TheoryData<TestServiceContext>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
new TestServiceContext()
|
new TestServiceContext()
|
||||||
|
|
@ -30,17 +30,16 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ResponsesAreChunkedAutomatically(ServiceContext testContext)
|
public async Task ResponsesAreChunkedAutomatically(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -48,6 +47,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"6",
|
"6",
|
||||||
|
|
@ -63,18 +63,17 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ZeroLengthWritesAreIgnored(ServiceContext testContext)
|
public async Task ZeroLengthWritesAreIgnored(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
||||||
await response.Body.WriteAsync(new byte[0], 0, 0);
|
await response.Body.WriteAsync(new byte[0], 0, 0);
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -82,6 +81,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"6",
|
"6",
|
||||||
|
|
@ -97,16 +97,15 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task EmptyResponseBodyHandledCorrectlyWithZeroLengthWrite(ServiceContext testContext)
|
public async Task EmptyResponseBodyHandledCorrectlyWithZeroLengthWrite(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
await response.Body.WriteAsync(new byte[0], 0, 0);
|
await response.Body.WriteAsync(new byte[0], 0, 0);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -114,6 +113,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"0",
|
"0",
|
||||||
|
|
@ -125,17 +125,16 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ConnectionClosedIfExeptionThrownAfterWrite(ServiceContext testContext)
|
public async Task ConnectionClosedIfExeptionThrownAfterWrite(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World!"), 0, 12);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World!"), 0, 12);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
// 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.
|
||||||
// client closing the connection.
|
// client closing the connection.
|
||||||
|
|
@ -145,6 +144,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"c",
|
"c",
|
||||||
|
|
@ -156,17 +156,16 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ConnectionClosedIfExeptionThrownAfterZeroLengthWrite(ServiceContext testContext)
|
public async Task ConnectionClosedIfExeptionThrownAfterZeroLengthWrite(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
await response.Body.WriteAsync(new byte[0], 0, 0);
|
await response.Body.WriteAsync(new byte[0], 0, 0);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
// 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(
|
||||||
|
|
@ -177,6 +176,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
// Headers are sent before connection is closed, but chunked body terminator isn't sent
|
// Headers are sent before connection is closed, but chunked body terminator isn't sent
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -186,14 +186,13 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task WritesAreFlushedPriorToResponseCompletion(ServiceContext testContext)
|
public async Task WritesAreFlushedPriorToResponseCompletion(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var flushWh = new ManualResetEventSlim();
|
var flushWh = new ManualResetEventSlim();
|
||||||
|
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
||||||
|
|
||||||
// Don't complete response until client has received the first chunk.
|
// Don't complete response until client has received the first chunk.
|
||||||
|
|
@ -202,7 +201,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -210,6 +209,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Transfer-Encoding: chunked",
|
"Transfer-Encoding: chunked",
|
||||||
"",
|
"",
|
||||||
"6",
|
"6",
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
var request = httpContext.Request;
|
var request = httpContext.Request;
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var buffer = new byte[8192];
|
var buffer = new byte[8192];
|
||||||
|
|
@ -39,12 +38,13 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
using (var server = new TestServer(App, serviceContext))
|
using (var server = new TestServer(App, serviceContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
// "?" changes to "!"
|
// "?" changes to "!"
|
||||||
await connection.SendEnd(sendString);
|
await connection.SendEnd(sendString);
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {serviceContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"Hello World!");
|
"Hello World!");
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
using (var server = new TestServer(App, serviceContext))
|
using (var server = new TestServer(App, serviceContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
|
@ -68,6 +68,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"Hello World?");
|
"Hello World?");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {serviceContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"Hello World!");
|
"Hello World!");
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +82,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
using (var server = new TestServer(App, serviceContext))
|
using (var server = new TestServer(App, serviceContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
{
|
||||||
|
public class DefaultHeaderTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task TestDefaultHeaders()
|
||||||
|
{
|
||||||
|
var testContext = new TestServiceContext()
|
||||||
|
{
|
||||||
|
ServerOptions = { AddServerHeader = true }
|
||||||
|
};
|
||||||
|
|
||||||
|
using (var server = new TestServer(ctx => TaskUtilities.CompletedTask, testContext))
|
||||||
|
{
|
||||||
|
using (var connection = server.CreateConnection())
|
||||||
|
{
|
||||||
|
await connection.SendEnd(
|
||||||
|
"GET / HTTP/1.0",
|
||||||
|
"",
|
||||||
|
"");
|
||||||
|
|
||||||
|
await connection.ReceiveEnd(
|
||||||
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
|
"Server: Kestrel",
|
||||||
|
"",
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,11 +20,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EngineTests
|
public class EngineTests
|
||||||
{
|
{
|
||||||
public static TheoryData<ServiceContext> ConnectionFilterData
|
public static TheoryData<TestServiceContext> ConnectionFilterData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new TheoryData<ServiceContext>
|
return new TheoryData<TestServiceContext>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
new TestServiceContext()
|
new TestServiceContext()
|
||||||
|
|
@ -40,7 +40,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
var request = httpContext.Request;
|
var request = httpContext.Request;
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var buffer = new byte[8192];
|
var buffer = new byte[8192];
|
||||||
|
|
@ -61,20 +60,18 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await request.Body.CopyToAsync(data);
|
await request.Body.CopyToAsync(data);
|
||||||
var bytes = data.ToArray();
|
var bytes = data.ToArray();
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = bytes.Length.ToString();
|
response.Headers["Content-Length"] = bytes.Length.ToString();
|
||||||
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task EmptyApp(HttpContext httpContext)
|
private Task EmptyApp(HttpContext httpContext)
|
||||||
{
|
{
|
||||||
httpContext.Response.Headers.Clear();
|
|
||||||
return Task.FromResult<object>(null);
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public void EngineCanStartAndStop(ServiceContext testContext)
|
public void EngineCanStartAndStop(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine(testContext);
|
var engine = new KestrelEngine(testContext);
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
|
|
@ -121,11 +118,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10RequestReceivesHttp11Response(ServiceContext testContext)
|
public async Task Http10RequestReceivesHttp11Response(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App, testContext))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
|
@ -133,6 +130,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"Hello World");
|
"Hello World");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
}
|
}
|
||||||
|
|
@ -142,11 +140,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http11(ServiceContext testContext)
|
public async Task Http11(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked, testContext))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -157,10 +155,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
|
|
@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task HeadersAndStreamsAreReused(ServiceContext testContext)
|
public async Task HeadersAndStreamsAreReused(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var streamCount = 0;
|
var streamCount = 0;
|
||||||
var requestHeadersCount = 0;
|
var requestHeadersCount = 0;
|
||||||
|
|
@ -198,21 +198,35 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
lastResponseHeaders = context.Response.Headers;
|
lastResponseHeaders = context.Response.Headers;
|
||||||
responseHeadersCount++;
|
responseHeadersCount++;
|
||||||
}
|
}
|
||||||
context.Response.Headers.Clear();
|
|
||||||
return context.Request.Body.CopyToAsync(context.Response.Body);
|
return context.Request.Body.CopyToAsync(context.Response.Body);
|
||||||
},
|
},
|
||||||
testContext))
|
testContext))
|
||||||
{
|
{
|
||||||
|
|
||||||
using (var connection = new TestConnection(server.Port))
|
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\n", loopCount)
|
||||||
.Concat(new[] { "GET / HTTP/1.1\r\nConnection: close\r\n\r\nGoodbye" });
|
.Concat(new[] { "GET / HTTP/1.1\r\nConnection: close\r\n\r\nGoodbye" });
|
||||||
|
|
||||||
|
var response = string.Join("\r\n", new string[] {
|
||||||
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
|
"Content-Length: 0",
|
||||||
|
""});
|
||||||
|
|
||||||
|
var lastResponse = string.Join("\r\n", new string[]
|
||||||
|
{
|
||||||
|
"HTTP/1.1 200 OK",
|
||||||
|
"Connection: close",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
|
"",
|
||||||
|
"Goodbye"
|
||||||
|
});
|
||||||
|
|
||||||
var responseData =
|
var responseData =
|
||||||
Enumerable.Repeat("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n", loopCount)
|
Enumerable.Repeat(response, loopCount)
|
||||||
.Concat(new[] { "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\nGoodbye" });
|
.Concat(new[] { lastResponse });
|
||||||
|
|
||||||
await connection.SendEnd(requestData.ToArray());
|
await connection.SendEnd(requestData.ToArray());
|
||||||
|
|
||||||
|
|
@ -227,11 +241,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10ContentLength(ServiceContext testContext)
|
public async Task Http10ContentLength(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App, testContext))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
|
@ -240,6 +254,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"Hello World");
|
"Hello World");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
}
|
}
|
||||||
|
|
@ -248,11 +263,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10KeepAlive(ServiceContext testContext)
|
public async Task Http10KeepAlive(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked, testContext))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.0",
|
"GET / HTTP/1.0",
|
||||||
|
|
@ -264,10 +279,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
"Connection: keep-alive",
|
"Connection: keep-alive",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"\r\n");
|
"\r\n");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
|
|
@ -277,11 +294,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10KeepAliveNotUsedIfResponseContentLengthNotSet(ServiceContext testContext)
|
public async Task Http10KeepAliveNotUsedIfResponseContentLengthNotSet(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App, testContext))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.0",
|
"GET / HTTP/1.0",
|
||||||
|
|
@ -295,10 +312,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
"Connection: keep-alive",
|
"Connection: keep-alive",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"\r\n");
|
"\r\n");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
}
|
}
|
||||||
|
|
@ -307,11 +326,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Http10KeepAliveContentLength(ServiceContext testContext)
|
public async Task Http10KeepAliveContentLength(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked, testContext))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
|
@ -324,11 +343,13 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
"Connection: keep-alive",
|
"Connection: keep-alive",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
|
|
@ -338,11 +359,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task Expect100ContinueForBody(ServiceContext testContext)
|
public async Task Expect100ContinueForBody(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked, testContext))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
|
@ -355,6 +376,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
|
|
@ -364,7 +386,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task DisconnectingClient(ServiceContext testContext)
|
public async Task DisconnectingClient(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(App, testContext))
|
using (var server = new TestServer(App, testContext))
|
||||||
{
|
{
|
||||||
|
|
@ -373,13 +395,14 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
socket.Dispose();
|
socket.Dispose();
|
||||||
|
|
||||||
await Task.Delay(200);
|
await Task.Delay(200);
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.0",
|
"GET / HTTP/1.0",
|
||||||
"\r\n");
|
"\r\n");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"\r\n");
|
"\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -387,11 +410,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ZeroContentLengthSetAutomaticallyAfterNoWrites(ServiceContext testContext)
|
public async Task ZeroContentLengthSetAutomaticallyAfterNoWrites(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(EmptyApp, testContext))
|
using (var server = new TestServer(EmptyApp, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -402,10 +425,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
"Connection: keep-alive",
|
"Connection: keep-alive",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -415,11 +440,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ZeroContentLengthNotSetAutomaticallyForNonKeepAliveRequests(ServiceContext testContext)
|
public async Task ZeroContentLengthNotSetAutomaticallyForNonKeepAliveRequests(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(EmptyApp, testContext))
|
using (var server = new TestServer(EmptyApp, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -429,11 +454,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.0",
|
"GET / HTTP/1.0",
|
||||||
|
|
@ -441,6 +467,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
@ -449,11 +476,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ZeroContentLengthNotSetAutomaticallyForHeadRequests(ServiceContext testContext)
|
public async Task ZeroContentLengthNotSetAutomaticallyForHeadRequests(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(EmptyApp, testContext))
|
using (var server = new TestServer(EmptyApp, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"HEAD / HTTP/1.1",
|
"HEAD / HTTP/1.1",
|
||||||
|
|
@ -461,6 +488,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
@ -469,13 +497,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes(ServiceContext testContext)
|
public async Task ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var request = httpContext.Request;
|
var request = httpContext.Request;
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
|
|
||||||
using (var reader = new StreamReader(request.Body, Encoding.ASCII))
|
using (var reader = new StreamReader(request.Body, Encoding.ASCII))
|
||||||
{
|
{
|
||||||
|
|
@ -484,7 +511,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
|
@ -505,14 +532,19 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"200");
|
"200");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 101 Switching Protocols",
|
"HTTP/1.1 101 Switching Protocols",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 204 No Content",
|
"HTTP/1.1 204 No Content",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 205 Reset Content",
|
"HTTP/1.1 205 Reset Content",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 304 Not Modified",
|
"HTTP/1.1 304 Not Modified",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
@ -522,7 +554,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ThrowingResultsIn500Response(ServiceContext testContext)
|
public async Task ThrowingResultsIn500Response(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
bool onStartingCalled = false;
|
bool onStartingCalled = false;
|
||||||
|
|
||||||
|
|
@ -539,12 +571,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
// Anything added to the ResponseHeaders dictionary is ignored
|
// Anything added to the ResponseHeaders dictionary is ignored
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = "11";
|
response.Headers["Content-Length"] = "11";
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -556,19 +587,17 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"HTTP/1.1 500 Internal Server Error",
|
"HTTP/1.1 500 Internal Server Error",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveStartsWith("Date:");
|
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 500 Internal Server Error",
|
"HTTP/1.1 500 Internal Server Error",
|
||||||
"");
|
"");
|
||||||
await connection.Receive("Connection: close",
|
await connection.Receive("Connection: close",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveStartsWith("Date:");
|
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
|
@ -580,7 +609,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ThrowingAfterWritingKillsConnection(ServiceContext testContext)
|
public async Task ThrowingAfterWritingKillsConnection(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
bool onStartingCalled = false;
|
bool onStartingCalled = false;
|
||||||
|
|
||||||
|
|
@ -596,13 +625,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
return Task.FromResult<object>(null);
|
return Task.FromResult<object>(null);
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -610,6 +638,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
|
|
@ -622,7 +651,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ThrowingAfterPartialWriteKillsConnection(ServiceContext testContext)
|
public async Task ThrowingAfterPartialWriteKillsConnection(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
bool onStartingCalled = false;
|
bool onStartingCalled = false;
|
||||||
|
|
||||||
|
|
@ -638,13 +667,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
return Task.FromResult<object>(null);
|
return Task.FromResult<object>(null);
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello"), 0, 5);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello"), 0, 5);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -652,6 +680,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello");
|
"Hello");
|
||||||
|
|
@ -664,11 +693,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ConnectionClosesWhenFinReceived(ServiceContext testContext)
|
public async Task ConnectionClosesWhenFinReceived(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked, testContext))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -679,9 +708,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 7",
|
"Content-Length: 7",
|
||||||
"",
|
"",
|
||||||
"Goodbye");
|
"Goodbye");
|
||||||
|
|
@ -691,49 +722,45 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ConnectionClosesWhenFinReceivedBeforeRequestCompletes(ServiceContext testContext)
|
public async Task ConnectionClosesWhenFinReceivedBeforeRequestCompletes(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
using (var server = new TestServer(AppChunked, testContext))
|
using (var server = new TestServer(AppChunked, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
"",
|
"",
|
||||||
"POST / HTTP/1.1");
|
"POST / HTTP/1.1");
|
||||||
await connection.Receive(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 400 Bad Request",
|
"HTTP/1.1 400 Bad Request",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"");
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
await connection.ReceiveStartsWith("Date:");
|
|
||||||
await connection.ReceiveForcedEnd(
|
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
"",
|
"",
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
"Content-Length: 7");
|
"Content-Length: 7");
|
||||||
await connection.Receive(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 400 Bad Request",
|
"HTTP/1.1 400 Bad Request",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"");
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
await connection.ReceiveStartsWith("Date:");
|
|
||||||
await connection.ReceiveForcedEnd(
|
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
@ -742,7 +769,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ThrowingInOnStartingResultsInFailedWritesAnd500Response(ServiceContext testContext)
|
public async Task ThrowingInOnStartingResultsInFailedWritesAnd500Response(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var onStartingCallCount1 = 0;
|
var onStartingCallCount1 = 0;
|
||||||
var onStartingCallCount2 = 0;
|
var onStartingCallCount2 = 0;
|
||||||
|
|
@ -767,7 +794,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
throw onStartingException;
|
throw onStartingException;
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
|
|
||||||
var writeException = await Assert.ThrowsAsync<ObjectDisposedException>(async () =>
|
var writeException = await Assert.ThrowsAsync<ObjectDisposedException>(async () =>
|
||||||
|
|
@ -778,7 +804,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
failedWriteCount++;
|
failedWriteCount++;
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.SendEnd(
|
await connection.SendEnd(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -790,18 +816,16 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
"HTTP/1.1 500 Internal Server Error",
|
"HTTP/1.1 500 Internal Server Error",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveStartsWith("Date:");
|
|
||||||
await connection.Receive(
|
await connection.Receive(
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"HTTP/1.1 500 Internal Server Error",
|
"HTTP/1.1 500 Internal Server Error",
|
||||||
"Connection: close",
|
"Connection: close",
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveStartsWith("Date:");
|
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 0",
|
"Content-Length: 0",
|
||||||
"Server: Kestrel",
|
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
|
@ -815,7 +839,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ThrowingInOnCompletedIsLoggedAndClosesConnection(ServiceContext testContext)
|
public async Task ThrowingInOnCompletedIsLoggedAndClosesConnection(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var onCompletedCalled1 = false;
|
var onCompletedCalled1 = false;
|
||||||
var onCompletedCalled2 = false;
|
var onCompletedCalled2 = false;
|
||||||
|
|
@ -837,13 +861,12 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
|
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.1",
|
"GET / HTTP/1.1",
|
||||||
|
|
@ -851,6 +874,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
|
|
@ -865,7 +889,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task RequestsCanBeAbortedMidRead(ServiceContext testContext)
|
public async Task RequestsCanBeAbortedMidRead(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var readTcs = new TaskCompletionSource<object>();
|
var readTcs = new TaskCompletionSource<object>();
|
||||||
var registrationTcs = new TaskCompletionSource<int>();
|
var registrationTcs = new TaskCompletionSource<int>();
|
||||||
|
|
@ -883,7 +907,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
if (requestId == 1)
|
if (requestId == 1)
|
||||||
{
|
{
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "5" };
|
response.Headers["Content-Length"] = new[] { "5" };
|
||||||
|
|
||||||
await response.WriteAsync("World");
|
await response.WriteAsync("World");
|
||||||
|
|
@ -908,7 +931,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
// Never send the body so CopyToAsync always fails.
|
// Never send the body so CopyToAsync always fails.
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
|
|
@ -922,6 +945,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 5",
|
"Content-Length: 5",
|
||||||
"",
|
"",
|
||||||
"World");
|
"World");
|
||||||
|
|
@ -937,7 +961,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task FailedWritesResultInAbortedRequest(ServiceContext testContext)
|
public async Task FailedWritesResultInAbortedRequest(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
// This should match _maxBytesPreCompleted in SocketOutput
|
// This should match _maxBytesPreCompleted in SocketOutput
|
||||||
var maxBytesPreCompleted = 65536;
|
var maxBytesPreCompleted = 65536;
|
||||||
|
|
@ -959,8 +983,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
await request.Body.CopyToAsync(Stream.Null);
|
await request.Body.CopyToAsync(Stream.Null);
|
||||||
connectionCloseWh.Wait();
|
connectionCloseWh.Wait();
|
||||||
|
|
||||||
response.Headers.Clear();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Ensure write is long enough to disable write-behind buffering
|
// Ensure write is long enough to disable write-behind buffering
|
||||||
|
|
@ -979,7 +1001,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
writeTcs.SetException(new Exception("This shouldn't be reached."));
|
writeTcs.SetException(new Exception("This shouldn't be reached."));
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.1",
|
"POST / HTTP/1.1",
|
||||||
|
|
@ -1000,7 +1022,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task NoErrorsLoggedWhenServerEndsConnectionBeforeClient(ServiceContext testContext)
|
public async Task NoErrorsLoggedWhenServerEndsConnectionBeforeClient(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var testLogger = new TestApplicationErrorLogger();
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
testContext.Log = new KestrelTrace(testLogger);
|
testContext.Log = new KestrelTrace(testLogger);
|
||||||
|
|
@ -1008,12 +1030,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
using (var server = new TestServer(async httpContext =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
response.Headers["Content-Length"] = new[] { "11" };
|
response.Headers["Content-Length"] = new[] { "11" };
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"GET / HTTP/1.0",
|
"GET / HTTP/1.0",
|
||||||
|
|
@ -1021,6 +1042,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
"");
|
"");
|
||||||
await connection.ReceiveForcedEnd(
|
await connection.ReceiveForcedEnd(
|
||||||
"HTTP/1.1 200 OK",
|
"HTTP/1.1 200 OK",
|
||||||
|
$"Date: {testContext.DateHeaderValue}",
|
||||||
"Content-Length: 11",
|
"Content-Length: 11",
|
||||||
"",
|
"",
|
||||||
"Hello World");
|
"Hello World");
|
||||||
|
|
@ -1032,7 +1054,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task NoResponseSentWhenConnectionIsClosedByServerBeforeClientFinishesSendingRequest(ServiceContext testContext)
|
public async Task NoResponseSentWhenConnectionIsClosedByServerBeforeClientFinishesSendingRequest(TestServiceContext testContext)
|
||||||
{
|
{
|
||||||
var testLogger = new TestApplicationErrorLogger();
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
testContext.Log = new KestrelTrace(testLogger);
|
testContext.Log = new KestrelTrace(testLogger);
|
||||||
|
|
@ -1043,7 +1065,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}, testContext))
|
}, testContext))
|
||||||
{
|
{
|
||||||
using (var connection = new TestConnection(server.Port))
|
using (var connection = server.CreateConnection())
|
||||||
{
|
{
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"POST / HTTP/1.0",
|
"POST / HTTP/1.0",
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,10 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
public class FrameResponseHeadersTests
|
public class FrameResponseHeadersTests
|
||||||
{
|
{
|
||||||
[Theory]
|
[Fact]
|
||||||
[InlineData(true)]
|
public void InitialDictionaryIsEmpty()
|
||||||
[InlineData(false)]
|
|
||||||
public void InitialDictionaryContainsServerAndDate(bool addServerHeader)
|
|
||||||
{
|
{
|
||||||
var serverOptions = new KestrelServerOptions { AddServerHeader = addServerHeader };
|
var serverOptions = new KestrelServerOptions();
|
||||||
|
|
||||||
var connectionContext = new ConnectionContext
|
var connectionContext = new ConnectionContext
|
||||||
{
|
{
|
||||||
|
|
@ -26,60 +24,17 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
ServerAddress = ServerAddress.FromUrl("http://localhost:5000"),
|
ServerAddress = ServerAddress.FromUrl("http://localhost:5000"),
|
||||||
ServerOptions = serverOptions,
|
ServerOptions = serverOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
var frame = new Frame<object>(application: null, context: connectionContext);
|
var frame = new Frame<object>(application: null, context: connectionContext);
|
||||||
|
|
||||||
frame.InitializeHeaders();
|
frame.InitializeHeaders();
|
||||||
|
|
||||||
IDictionary<string, StringValues> headers = frame.ResponseHeaders;
|
IDictionary<string, StringValues> headers = frame.ResponseHeaders;
|
||||||
|
|
||||||
if (addServerHeader)
|
Assert.Equal(0, headers.Count);
|
||||||
{
|
|
||||||
Assert.Equal(2, headers.Count);
|
|
||||||
|
|
||||||
StringValues serverHeader;
|
|
||||||
Assert.True(headers.TryGetValue("Server", out serverHeader));
|
|
||||||
Assert.Equal(1, serverHeader.Count);
|
|
||||||
Assert.Equal("Kestrel", serverHeader[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert.Equal(1, headers.Count);
|
|
||||||
|
|
||||||
StringValues serverHeader;
|
|
||||||
Assert.False(headers.TryGetValue("Server", out serverHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
StringValues dateHeader;
|
|
||||||
DateTime date;
|
|
||||||
Assert.True(headers.TryGetValue("Date", out dateHeader));
|
|
||||||
Assert.Equal(1, dateHeader.Count);
|
|
||||||
Assert.True(DateTime.TryParse(dateHeader[0], out date));
|
|
||||||
Assert.True(DateTime.Now - date <= TimeSpan.FromMinutes(1));
|
|
||||||
|
|
||||||
Assert.False(headers.IsReadOnly);
|
Assert.False(headers.IsReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void InitialEntriesCanBeCleared()
|
|
||||||
{
|
|
||||||
var serverOptions = new KestrelServerOptions();
|
|
||||||
var connectionContext = new ConnectionContext
|
|
||||||
{
|
|
||||||
DateHeaderValueManager = new DateHeaderValueManager(),
|
|
||||||
ServerAddress = ServerAddress.FromUrl("http://localhost:5000"),
|
|
||||||
ServerOptions = serverOptions,
|
|
||||||
};
|
|
||||||
var frame = new Frame<object>(application: null, context: connectionContext);
|
|
||||||
frame.InitializeHeaders();
|
|
||||||
|
|
||||||
Assert.True(frame.ResponseHeaders.Count > 0);
|
|
||||||
|
|
||||||
frame.ResponseHeaders.Clear();
|
|
||||||
|
|
||||||
Assert.Equal(0, frame.ResponseHeaders.Count);
|
|
||||||
Assert.False(frame.ResponseHeaders.ContainsKey("Server"));
|
|
||||||
Assert.False(frame.ResponseHeaders.ContainsKey("Date"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("Server", "\r\nData")]
|
[InlineData("Server", "\r\nData")]
|
||||||
[InlineData("Server", "\0Data")]
|
[InlineData("Server", "\0Data")]
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
var request = httpContext.Request;
|
var request = httpContext.Request;
|
||||||
var response = httpContext.Response;
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var buffer = new byte[8192];
|
var buffer = new byte[8192];
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,14 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
private NetworkStream _stream;
|
private NetworkStream _stream;
|
||||||
private StreamReader _reader;
|
private StreamReader _reader;
|
||||||
|
|
||||||
public TestConnection(int port)
|
public TestConnection(TestServer server)
|
||||||
{
|
{
|
||||||
Create(port);
|
Server = server;
|
||||||
|
Create(server.Port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TestServer Server { get; }
|
||||||
|
|
||||||
public void Create(int port)
|
public void Create(int port)
|
||||||
{
|
{
|
||||||
_socket = CreateConnectedLoopbackSocket(port);
|
_socket = CreateConnectedLoopbackSocket(port);
|
||||||
|
|
@ -85,38 +88,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
Assert.Equal(expected, new String(actual, 0, offset));
|
Assert.Equal(expected, new String(actual, 0, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ReceiveStartsWith(string prefix, int maxLineLength = 1024)
|
|
||||||
{
|
|
||||||
var actual = new char[maxLineLength];
|
|
||||||
var offset = 0;
|
|
||||||
|
|
||||||
while (offset < maxLineLength)
|
|
||||||
{
|
|
||||||
// Read one char at a time so we don't read past the end of the line.
|
|
||||||
var task = _reader.ReadAsync(actual, offset, 1);
|
|
||||||
if (!Debugger.IsAttached)
|
|
||||||
{
|
|
||||||
Assert.True(task.Wait(4000), "timeout");
|
|
||||||
}
|
|
||||||
var count = await task;
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.True(count == 1);
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
if (actual[offset - 1] == '\n')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var actualLine = new string(actual, 0, offset);
|
|
||||||
Assert.StartsWith(prefix, actualLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ReceiveEnd(params string[] lines)
|
public async Task ReceiveEnd(params string[] lines)
|
||||||
{
|
{
|
||||||
await Receive(lines);
|
await Receive(lines);
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,15 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestServer(RequestDelegate app, ServiceContext context)
|
public TestServer(RequestDelegate app, TestServiceContext context)
|
||||||
: this(app, context, "http://127.0.0.1:0/")
|
: this(app, context, "http://127.0.0.1:0/")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Port => _address.Port;
|
public TestServer(RequestDelegate app, TestServiceContext context, string serverAddress)
|
||||||
|
|
||||||
public TestServer(RequestDelegate app, ServiceContext context, string serverAddress)
|
|
||||||
{
|
{
|
||||||
|
Context = context;
|
||||||
|
|
||||||
context.FrameFactory = connectionContext =>
|
context.FrameFactory = connectionContext =>
|
||||||
{
|
{
|
||||||
return new Frame<HttpContext>(new DummyApplication(app), connectionContext);
|
return new Frame<HttpContext>(new DummyApplication(app), connectionContext);
|
||||||
|
|
@ -51,6 +51,15 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int Port => _address.Port;
|
||||||
|
|
||||||
|
public TestServiceContext Context { get; }
|
||||||
|
|
||||||
|
public TestConnection CreateConnection()
|
||||||
|
{
|
||||||
|
return new TestConnection(this);
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_server.Dispose();
|
_server.Dispose();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Server.Kestrel;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Filter;
|
using Microsoft.AspNetCore.Server.Kestrel.Filter;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Server.KestrelTests.TestHelpers;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.KestrelTests
|
namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
|
|
@ -19,9 +20,9 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
AppLifetime = new LifetimeNotImplemented();
|
AppLifetime = new LifetimeNotImplemented();
|
||||||
Log = new TestKestrelTrace();
|
Log = new TestKestrelTrace();
|
||||||
ThreadPool = new LoggingThreadPool(Log);
|
ThreadPool = new LoggingThreadPool(Log);
|
||||||
DateHeaderValueManager = new DateHeaderValueManager();
|
DateHeaderValueManager = new DateHeaderValueManager(systemClock: new MockSystemClock());
|
||||||
|
DateHeaderValue = DateHeaderValueManager.GetDateHeaderValues().String;
|
||||||
ServerOptions = new KestrelServerOptions();
|
ServerOptions = new KestrelServerOptions { AddServerHeader = false };
|
||||||
ServerOptions.ShutdownTimeout = TimeSpan.FromSeconds(5);
|
ServerOptions.ShutdownTimeout = TimeSpan.FromSeconds(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,6 +32,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
ServerOptions.ConnectionFilter = filter;
|
ServerOptions.ConnectionFilter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string DateHeaderValue { get; }
|
||||||
|
|
||||||
public RequestDelegate App
|
public RequestDelegate App
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue