Disable automatic chunking for all non keep-alive requests
- Fixes a bug where Upgrade requests (e.g. WebSockets) would be chunked - Allows chunking to be disabled by setting "Connection: close" on the response
This commit is contained in:
parent
16fbb94c44
commit
972be6e8c1
|
|
@ -723,14 +723,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
var end = SocketOutput.ProducingStart();
|
||||
if (_keepAlive && hasConnection)
|
||||
{
|
||||
foreach (var connectionValue in responseHeaders.HeaderConnection)
|
||||
{
|
||||
if (connectionValue.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
_keepAlive = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var connectionValue = responseHeaders.HeaderConnection.ToString();
|
||||
_keepAlive = connectionValue.Equals("keep-alive", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
if (!responseHeaders.HasTransferEncoding && !responseHeaders.HasContentLength)
|
||||
|
|
@ -746,7 +740,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
|
|||
responseHeaders.SetRawContentLength("0", _bytesContentLengthZero);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(_keepAlive)
|
||||
{
|
||||
// Note for future reference: never change this to set _autoChunk to true on HTTP/1.0
|
||||
// connections, even if we were to infer the client supports it because an HTTP/1.0 request
|
||||
|
|
|
|||
|
|
@ -63,42 +63,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
|
||||
[Theory]
|
||||
[MemberData(nameof(ConnectionFilterData))]
|
||||
public async Task ResponsesAreChunkedAutomaticallyForHttp11NonKeepAliveRequests(TestServiceContext testContext)
|
||||
{
|
||||
using (var server = new TestServer(async httpContext =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
||||
}, testContext))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
await connection.SendEnd(
|
||||
"GET / HTTP/1.1",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
"HTTP/1.1 200 OK",
|
||||
"Connection: close",
|
||||
$"Date: {testContext.DateHeaderValue}",
|
||||
"Transfer-Encoding: chunked",
|
||||
"",
|
||||
"6",
|
||||
"Hello ",
|
||||
"6",
|
||||
"World!",
|
||||
"0",
|
||||
"",
|
||||
"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ConnectionFilterData))]
|
||||
public async Task ResponsesAreNotChunkedAutomaticallyForHttp10Requests(TestServiceContext testContext)
|
||||
public async Task ResponsesAreNotChunkedAutomaticallyForHttp10RequestsAndHttp11NonKeepAliveRequests(TestServiceContext testContext)
|
||||
{
|
||||
using (var server = new TestServer(async httpContext =>
|
||||
{
|
||||
|
|
@ -111,6 +76,51 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
{
|
||||
await connection.SendEnd(
|
||||
"GET / HTTP/1.0",
|
||||
"Connection: keep-alive",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
"HTTP/1.1 200 OK",
|
||||
"Connection: close",
|
||||
$"Date: {testContext.DateHeaderValue}",
|
||||
"",
|
||||
"Hello World!");
|
||||
}
|
||||
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
await connection.SendEnd(
|
||||
"GET / HTTP/1.1",
|
||||
"Connection: close",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
"HTTP/1.1 200 OK",
|
||||
"Connection: close",
|
||||
$"Date: {testContext.DateHeaderValue}",
|
||||
"",
|
||||
"Hello World!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ConnectionFilterData))]
|
||||
public async Task SettingConnectionCloseHeaderInAppDisablesChunking(TestServiceContext testContext)
|
||||
{
|
||||
using (var server = new TestServer(async httpContext =>
|
||||
{
|
||||
var response = httpContext.Response;
|
||||
response.Headers["Connection"] = "close";
|
||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
||||
}, testContext))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
await connection.SendEnd(
|
||||
"GET / HTTP/1.1",
|
||||
"",
|
||||
"");
|
||||
await connection.ReceiveEnd(
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
engine.Dispose();
|
||||
}
|
||||
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ConnectionFilterData))]
|
||||
public async Task Http10RequestReceivesHttp11Response(TestServiceContext testContext)
|
||||
|
|
@ -143,7 +142,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ConnectionFilterData))]
|
||||
public async Task Http11(TestServiceContext testContext)
|
||||
|
|
@ -1310,5 +1308,43 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ConnectionFilterData))]
|
||||
public async Task UpgradeRequestIsNotKeptAliveOrChunked(TestServiceContext testContext)
|
||||
{
|
||||
using (var server = new TestServer(async context =>
|
||||
{
|
||||
var upgradeFeature = context.Features.Get<IHttpUpgradeFeature>();
|
||||
var duplexStream = await upgradeFeature.UpgradeAsync();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var buffer = new byte[8192];
|
||||
var count = await duplexStream.ReadAsync(buffer, 0, buffer.Length);
|
||||
if (count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
await duplexStream.WriteAsync(buffer, 0, count);
|
||||
}
|
||||
}, testContext))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
await connection.SendEnd(
|
||||
"GET / HTTP/1.1",
|
||||
"Connection: Upgrade",
|
||||
"",
|
||||
"Hello World");
|
||||
await connection.ReceiveEnd(
|
||||
"HTTP/1.1 101 Switching Protocols",
|
||||
"Connection: Upgrade",
|
||||
$"Date: {testContext.DateHeaderValue}",
|
||||
"",
|
||||
"Hello World");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue