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(
|
||||
$"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)
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -24,13 +22,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
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
|
||||
{
|
||||
get
|
||||
{
|
||||
var maxRequestBufferSizeValues = new Tuple<long?, bool>[] {
|
||||
// Smallest buffer that can hold a POST request line to the root.
|
||||
Tuple.Create((long?)"POST / HTTP/1.1\r\n".Length, true),
|
||||
// Smallest buffer that can hold a test request line without causing
|
||||
// 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.
|
||||
Tuple.Create((long?)16 * 1024, true),
|
||||
|
|
@ -186,6 +193,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
options.Limits.MaxRequestLineSize = (int)maxRequestBufferSize;
|
||||
}
|
||||
|
||||
if (maxRequestBufferSize.HasValue &&
|
||||
maxRequestBufferSize.Value < options.Limits.MaxRequestHeadersTotalSize)
|
||||
{
|
||||
options.Limits.MaxRequestHeadersTotalSize = (int)maxRequestBufferSize;
|
||||
}
|
||||
})
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.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))
|
||||
{
|
||||
await writer.WriteAsync("POST / HTTP/1.0\r\n");
|
||||
await writer.WriteAsync($"Content-Length: {contentLength}\r\n");
|
||||
await writer.WriteAsync("\r\n");
|
||||
foreach (var line in _requestLines)
|
||||
{
|
||||
await writer.WriteAsync(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,25 +24,30 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
public void StartWithNonPositiveThreadCountThrows(int threadCount)
|
||||
{
|
||||
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(1, testLogger.CriticalErrorsLogged);
|
||||
Assert.Equal("threadCount", exception.ParamName);
|
||||
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StartWithInvalidAddressThrows()
|
||||
{
|
||||
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);
|
||||
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||
var exception = Assert.Throws<FormatException>(() => StartDummyApplication(server));
|
||||
|
||||
Assert.Contains("Invalid URL", exception.Message);
|
||||
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -77,14 +82,37 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
|||
options.Limits.MaxRequestBufferSize = maxRequestBufferSize;
|
||||
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(
|
||||
$"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request line size ({maxRequestLineSize}).",
|
||||
exception.Message);
|
||||
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||
[Theory]
|
||||
[InlineData(1, 2)]
|
||||
[InlineData(int.MaxValue - 1, int.MaxValue)]
|
||||
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]
|
||||
|
|
|
|||
Loading…
Reference in New Issue