Check that MaxRequestBufferSize is greater than or equal to MaxRequestHeadersTotalSize (#1491).
This commit is contained in:
parent
6c131ea240
commit
72587baac3
|
|
@ -247,6 +247,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
$"Maximum request buffer size ({Options.Limits.MaxRequestBufferSize.Value}) must be greater than or equal to maximum request line size ({Options.Limits.MaxRequestLineSize}).");
|
$"Maximum request buffer size ({Options.Limits.MaxRequestBufferSize.Value}) must be greater than or equal to maximum request line size ({Options.Limits.MaxRequestLineSize}).");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Options.Limits.MaxRequestBufferSize.HasValue &&
|
||||||
|
Options.Limits.MaxRequestBufferSize < Options.Limits.MaxRequestHeadersTotalSize)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
$"Maximum request buffer size ({Options.Limits.MaxRequestBufferSize.Value}) must be greater than or equal to maximum request headers size ({Options.Limits.MaxRequestHeadersTotalSize}).");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartLocalhost(KestrelEngine engine, ServerAddress parsedAddress)
|
private void StartLocalhost(KestrelEngine engine, ServerAddress parsedAddress)
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Security;
|
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Security.Authentication;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -24,13 +22,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
private const int _dataLength = 20 * 1024 * 1024;
|
private const int _dataLength = 20 * 1024 * 1024;
|
||||||
|
|
||||||
|
private static readonly string[] _requestLines = new[]
|
||||||
|
{
|
||||||
|
"POST / HTTP/1.0\r\n",
|
||||||
|
$"Content-Length: {_dataLength}\r\n",
|
||||||
|
"\r\n"
|
||||||
|
};
|
||||||
|
|
||||||
public static IEnumerable<object[]> LargeUploadData
|
public static IEnumerable<object[]> LargeUploadData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var maxRequestBufferSizeValues = new Tuple<long?, bool>[] {
|
var maxRequestBufferSizeValues = new Tuple<long?, bool>[] {
|
||||||
// Smallest buffer that can hold a POST request line to the root.
|
// Smallest buffer that can hold a test request line without causing
|
||||||
Tuple.Create((long?)"POST / HTTP/1.1\r\n".Length, true),
|
// the server to hang waiting for the end of the request line or
|
||||||
|
// a header line.
|
||||||
|
Tuple.Create((long?)(_requestLines.Max(line => line.Length)), true),
|
||||||
|
|
||||||
// Small buffer, but large enough to hold all request headers.
|
// Small buffer, but large enough to hold all request headers.
|
||||||
Tuple.Create((long?)16 * 1024, true),
|
Tuple.Create((long?)16 * 1024, true),
|
||||||
|
|
@ -186,6 +193,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
options.Limits.MaxRequestLineSize = (int)maxRequestBufferSize;
|
options.Limits.MaxRequestLineSize = (int)maxRequestBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (maxRequestBufferSize.HasValue &&
|
||||||
|
maxRequestBufferSize.Value < options.Limits.MaxRequestHeadersTotalSize)
|
||||||
|
{
|
||||||
|
options.Limits.MaxRequestHeadersTotalSize = (int)maxRequestBufferSize;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
.Configure(app => app.Run(async context =>
|
.Configure(app => app.Run(async context =>
|
||||||
|
|
@ -246,9 +259,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
{
|
{
|
||||||
using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize: 1024, leaveOpen: true))
|
using (var writer = new StreamWriter(stream, Encoding.ASCII, bufferSize: 1024, leaveOpen: true))
|
||||||
{
|
{
|
||||||
await writer.WriteAsync("POST / HTTP/1.0\r\n");
|
foreach (var line in _requestLines)
|
||||||
await writer.WriteAsync($"Content-Length: {contentLength}\r\n");
|
{
|
||||||
await writer.WriteAsync("\r\n");
|
await writer.WriteAsync(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,25 +24,30 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
public void StartWithNonPositiveThreadCountThrows(int threadCount)
|
public void StartWithNonPositiveThreadCountThrows(int threadCount)
|
||||||
{
|
{
|
||||||
var testLogger = new TestApplicationErrorLogger { ThrowOnCriticalErrors = false };
|
var testLogger = new TestApplicationErrorLogger { ThrowOnCriticalErrors = false };
|
||||||
var server = CreateServer(new KestrelServerOptions() { ThreadCount = threadCount }, testLogger);
|
|
||||||
|
|
||||||
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => StartDummyApplication(server));
|
using (var server = CreateServer(new KestrelServerOptions() { ThreadCount = threadCount }, testLogger))
|
||||||
|
{
|
||||||
|
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => StartDummyApplication(server));
|
||||||
|
|
||||||
Assert.Equal("threadCount", exception.ParamName);
|
Assert.Equal("threadCount", exception.ParamName);
|
||||||
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void StartWithInvalidAddressThrows()
|
public void StartWithInvalidAddressThrows()
|
||||||
{
|
{
|
||||||
var testLogger = new TestApplicationErrorLogger { ThrowOnCriticalErrors = false };
|
var testLogger = new TestApplicationErrorLogger { ThrowOnCriticalErrors = false };
|
||||||
var server = CreateServer(new KestrelServerOptions(), testLogger);
|
|
||||||
server.Features.Get<IServerAddressesFeature>().Addresses.Add("http:/asdf");
|
|
||||||
|
|
||||||
var exception = Assert.Throws<FormatException>(() => StartDummyApplication(server));
|
using (var server = CreateServer(new KestrelServerOptions(), testLogger))
|
||||||
|
{
|
||||||
|
server.Features.Get<IServerAddressesFeature>().Addresses.Add("http:/asdf");
|
||||||
|
|
||||||
Assert.Contains("Invalid URL", exception.Message);
|
var exception = Assert.Throws<FormatException>(() => StartDummyApplication(server));
|
||||||
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
|
||||||
|
Assert.Contains("Invalid URL", exception.Message);
|
||||||
|
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -77,14 +82,37 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
options.Limits.MaxRequestBufferSize = maxRequestBufferSize;
|
options.Limits.MaxRequestBufferSize = maxRequestBufferSize;
|
||||||
options.Limits.MaxRequestLineSize = maxRequestLineSize;
|
options.Limits.MaxRequestLineSize = maxRequestLineSize;
|
||||||
|
|
||||||
var server = CreateServer(options, testLogger);
|
using (var server = CreateServer(options, testLogger))
|
||||||
|
{
|
||||||
|
var exception = Assert.Throws<InvalidOperationException>(() => StartDummyApplication(server));
|
||||||
|
|
||||||
var exception = Assert.Throws<InvalidOperationException>(() => StartDummyApplication(server));
|
Assert.Equal(
|
||||||
|
$"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request line size ({maxRequestLineSize}).",
|
||||||
|
exception.Message);
|
||||||
|
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Assert.Equal(
|
[Theory]
|
||||||
$"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request line size ({maxRequestLineSize}).",
|
[InlineData(1, 2)]
|
||||||
exception.Message);
|
[InlineData(int.MaxValue - 1, int.MaxValue)]
|
||||||
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
public void StartWithMaxRequestBufferSizeLessThanMaxRequestHeadersTotalSizeThrows(long maxRequestBufferSize, int maxRequestHeadersTotalSize)
|
||||||
|
{
|
||||||
|
var testLogger = new TestApplicationErrorLogger { ThrowOnCriticalErrors = false };
|
||||||
|
var options = new KestrelServerOptions();
|
||||||
|
options.Limits.MaxRequestBufferSize = maxRequestBufferSize;
|
||||||
|
options.Limits.MaxRequestLineSize = (int)maxRequestBufferSize;
|
||||||
|
options.Limits.MaxRequestHeadersTotalSize = maxRequestHeadersTotalSize;
|
||||||
|
|
||||||
|
using (var server = CreateServer(options, testLogger))
|
||||||
|
{
|
||||||
|
var exception = Assert.Throws<InvalidOperationException>(() => StartDummyApplication(server));
|
||||||
|
|
||||||
|
Assert.Equal(
|
||||||
|
$"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request headers size ({maxRequestHeadersTotalSize}).",
|
||||||
|
exception.Message);
|
||||||
|
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue