Revert "Add MaxRequestBodySize limit (#478)."

This reverts commit e53a87be9c.
This commit is contained in:
Cesar Blum Silveira 2016-12-08 11:06:47 -08:00
parent 859816bb53
commit defcbdb907
10 changed files with 5 additions and 250 deletions

View File

@ -78,9 +78,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel
case RequestRejectionReason.RequestTimeout:
ex = new BadHttpRequestException("Request timed out.", 408);
break;
case RequestRejectionReason.PayloadTooLarge:
ex = new BadHttpRequestException("Payload too large.", 413);
break;
default:
ex = new BadHttpRequestException("Bad request.", 400);
break;

View File

@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
private DateHeaderValueManager DateHeaderValueManager => ConnectionContext.ListenerContext.ServiceContext.DateHeaderValueManager;
private ServerAddress ServerAddress => ConnectionContext.ListenerContext.ServerAddress;
// Hold direct reference to ServerOptions since this is used very often in the request processing path
public KestrelServerOptions ServerOptions { get; }
private KestrelServerOptions ServerOptions { get; }
private IPEndPoint LocalEndPoint => ConnectionContext.LocalEndPoint;
private IPEndPoint RemoteEndPoint => ConnectionContext.RemoteEndPoint;
protected string ConnectionId => ConnectionContext.ConnectionId;

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
{
@ -271,12 +272,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
try
{
var contentLength = FrameHeaders.ParseContentLength(unparsedContentLength);
if (contentLength > context.ServerOptions.Limits.MaxRequestBodySize)
{
context.RejectRequest(RequestRejectionReason.PayloadTooLarge);
}
return new ForContentLength(keepAlive, contentLength, context);
}
catch (InvalidOperationException)
@ -286,7 +281,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
}
// Avoid slowing down most common case
if (!ReferenceEquals(context.Method, HttpMethods.Get))
if (!object.ReferenceEquals(context.Method, HttpMethods.Get))
{
// If we got here, request contains no Content-Length or Transfer-Encoding header.
// Reject with 411 Length Required.
@ -399,7 +394,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
private readonly SocketInput _input;
private readonly FrameRequestHeaders _requestHeaders;
private long _inputBytesRead;
private int _inputLength;
private Mode _mode = Mode.Prefix;
@ -420,12 +414,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
protected override void OnConsumedBytes(int count)
{
_inputLength -= count;
_inputBytesRead += count;
if (_inputBytesRead > _context.ServerOptions.Limits.MaxRequestBodySize)
{
_context.RejectRequest(RequestRejectionReason.PayloadTooLarge);
}
}
private async Task<ArraySegment<byte>> PeekStateMachineAsync()

View File

@ -30,6 +30,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
FinalTransferCodingNotChunked,
LengthRequired,
LengthRequiredHttp10,
PayloadTooLarge
}
}

View File

@ -23,10 +23,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel
// Matches the default LimitRequestFields in Apache httpd.
private int _maxRequestHeaderCount = 100;
// Matches default HttpRuntimeSection.MaxRequestLength.
// https://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.maxrequestlength%28v=vs.100%29.aspx
private long _maxRequestBodySize = 4 * 1024 * 1024;
// Matches the default http.sys connectionTimeout.
private TimeSpan _keepAliveTimeout = TimeSpan.FromMinutes(2);
@ -148,28 +144,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel
}
}
/// <summary>
/// Gets or sets the maximum request body size, in bytes.
/// </summary>
/// <remarks>
/// Defaults to 4MB.
/// </remarks>
public long MaxRequestBodySize
{
get
{
return _maxRequestBodySize;
}
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "Value must a positive integer.");
}
_maxRequestBodySize = value;
}
}
/// <summary>
/// Gets or sets the keep-alive timeout.
/// </summary>

View File

@ -178,10 +178,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
AddServerHeader = false,
Limits =
{
KeepAliveTimeout = KeepAliveTimeout,
// Prevent request rejection if ConnectionNotTimedOutWhileRequestBeingSent
// sends more bytes than the default body size limit.
MaxRequestBodySize = long.MaxValue
KeepAliveTimeout = KeepAliveTimeout
}
}
});

View File

@ -1,168 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Testing;
using Xunit;
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{
public class MaxRequestBodySizeTests
{
private const int MaxRequestBodySize = 128;
[Theory]
[InlineData(MaxRequestBodySize - 1, 0)]
[InlineData(MaxRequestBodySize, 0)]
[InlineData(MaxRequestBodySize - 1, 1)]
[InlineData(MaxRequestBodySize, 1)]
[InlineData(MaxRequestBodySize - 1, 2)]
[InlineData(MaxRequestBodySize, 2)]
public async Task ServerAcceptsRequestBodyWithinLimit(int requestBodySize, int chunks)
{
using (var server = CreateServer(MaxRequestBodySize, async httpContext => await httpContext.Response.WriteAsync("hello, world")))
{
using (var connection = new TestConnection(server.Port))
{
await connection.SendAll(BuildRequest(connection, requestBodySize, chunks));
await connection.Receive(
"HTTP/1.1 200 OK",
$"Date: {server.Context.DateHeaderValue}",
"Transfer-Encoding: chunked",
"",
"c",
"hello, world",
"0",
"",
"");
}
}
}
[Theory]
[InlineData(MaxRequestBodySize + 1, 0)]
[InlineData(MaxRequestBodySize + 1, 1)]
[InlineData(MaxRequestBodySize + 1, 2)]
public async Task ServerRejectsRequestBodyExceedingLimit(int requestBodySize, int chunks)
{
using (var server = CreateServer(MaxRequestBodySize, async httpContext =>
{
var received = 0;
while (received < requestBodySize)
{
received += await httpContext.Request.Body.ReadAsync(new byte[1024], 0, 1024);
}
// Should never get here
await httpContext.Response.WriteAsync("hello, world");
}))
{
using (var connection = new TestConnection(server.Port))
{
await connection.SendAll(BuildRequest(connection, requestBodySize, chunks));
await connection.ReceiveForcedEnd(
"HTTP/1.1 413 Payload Too Large",
"Connection: close",
$"Date: {server.Context.DateHeaderValue}",
"Content-Length: 0",
"",
"");
}
}
}
[Fact]
public async Task MaxRequestBodySizeNotEnforcedOnUpgradedConnection()
{
var sendBytes = MaxRequestBodySize + 1;
using (var server = CreateServer(MaxRequestBodySize, async httpContext =>
{
var stream = await httpContext.Features.Get<IHttpUpgradeFeature>().UpgradeAsync();
var received = 0;
while (received < sendBytes)
{
received += await stream.ReadAsync(new byte[1024], 0, 1024);
}
var response = Encoding.ASCII.GetBytes($"{received}");
await stream.WriteAsync(response, 0, response.Length);
}))
{
using (var connection = new TestConnection(server.Port))
{
await connection.Send(
"GET / HTTP/1.1",
"Connection: upgrade",
"",
new string('a', sendBytes));
await connection.Receive(
"HTTP/1.1 101 Switching Protocols",
"Connection: Upgrade",
$"Date: {server.Context.DateHeaderValue}",
"",
$"{sendBytes}");
}
}
}
private string BuildRequest(TestConnection connection, int requestBodySize, int chunks)
{
var request = new StringBuilder();
request.Append("POST / HTTP/1.1\r\n");
if (chunks == 0)
{
request.Append($"Content-Length: {requestBodySize}\r\n\r\n");
request.Append(new string('a', requestBodySize));
}
else
{
request.Append("Transfer-Encoding: chunked\r\n\r\n");
var bytesSent = 0;
while (bytesSent < requestBodySize)
{
var chunkSize = Math.Min(requestBodySize / chunks, requestBodySize - bytesSent);
request.Append($"{chunkSize:X}\r\n");
request.Append(new string('a', chunkSize));
request.Append("\r\n");
bytesSent += chunkSize;
}
// Make sure we sent the right amount of data
Assert.Equal(requestBodySize, bytesSent);
request.Append("0\r\n\r\n");
}
return request.ToString();
}
private TestServer CreateServer(int maxRequestBodySize, RequestDelegate app)
{
return new TestServer(app, new TestServiceContext
{
ServerOptions = new KestrelServerOptions
{
AddServerHeader = false,
Limits =
{
MaxRequestBodySize = maxRequestBodySize
}
}
});
}
}
}

View File

@ -169,7 +169,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
.UseKestrel(options =>
{
options.Limits.MaxRequestBufferSize = maxRequestBufferSize;
options.Limits.MaxRequestBodySize = _dataLength;
options.UseHttps(@"TestResources/testCert.pfx", "testPassword");
if (maxRequestBufferSize.HasValue &&

View File

@ -43,10 +43,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
Assert.True(bufferLength % 256 == 0, $"{nameof(bufferLength)} must be evenly divisible by 256");
var builder = new WebHostBuilder()
.UseKestrel(options =>
{
options.Limits.MaxRequestBodySize = contentLength;
})
.UseKestrel()
.UseUrls("http://127.0.0.1:0/")
.Configure(app =>
{

View File

@ -149,34 +149,6 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
Assert.Equal(value, o.MaxRequestHeaderCount);
}
[Fact]
public void MaxRequestBodySizeDefault()
{
Assert.Equal(4 * 1024 * 1024, (new KestrelServerLimits()).MaxRequestBodySize);
}
[Theory]
[InlineData(long.MinValue)]
[InlineData(-1)]
[InlineData(0)]
public void MaxRequestBodySizeInvalid(long value)
{
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
(new KestrelServerLimits()).MaxRequestBodySize = value;
});
}
[Theory]
[InlineData(1)]
[InlineData(long.MaxValue)]
public void MaxRequestBodySizeValid(long value)
{
var o = new KestrelServerLimits();
o.MaxRequestBodySize = value;
Assert.Equal(value, o.MaxRequestBodySize);
}
[Fact]
public void KeepAliveTimeoutDefault()
{