diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs index 08f13a59592b..62ebe1425b40 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/MessageBody.cs @@ -172,13 +172,15 @@ protected void AddAndCheckObservedBytes(long observedBytes) protected ValueTask StartTimingReadAsync(ValueTask readAwaitable, CancellationToken cancellationToken) { - - if (!readAwaitable.IsCompleted && _timingEnabled) + if (!readAwaitable.IsCompleted) { TryProduceContinue(); - _backpressure = true; - _context.TimeoutControl.StartTimingRead(); + if (_timingEnabled) + { + _backpressure = true; + _context.TimeoutControl.StartTimingRead(); + } } return readAwaitable; diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs index dd32baf2bbfc..d4cdab4bfef8 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs @@ -846,6 +846,42 @@ await connection.ReceiveEnd( } } + [Fact] + public async Task Expect100ContinueHonoredWhenMinRequestBodyDataRateIsDisabled() + { + var testContext = new TestServiceContext(LoggerFactory); + + // This may seem unrelated, but this is a regression test for + // https://github.com/dotnet/aspnetcore/issues/30449 + testContext.ServerOptions.Limits.MinRequestBodyDataRate = null; + + await using (var server = new TestServer(TestApp.EchoAppChunked, testContext)) + { + using (var connection = server.CreateConnection()) + { + await connection.Send( + "POST / HTTP/1.1", + "Host:", + "Expect: 100-continue", + "Connection: close", + "Content-Length: 11", + "\r\n"); + await connection.Receive( + "HTTP/1.1 100 Continue", + "", + ""); + await connection.Send("Hello World"); + await connection.ReceiveEnd( + "HTTP/1.1 200 OK", + "Connection: close", + $"Date: {testContext.DateHeaderValue}", + "Content-Length: 11", + "", + "Hello World"); + } + } + } + [Fact] public async Task ZeroContentLengthAssumedOnNonKeepAliveRequestsWithoutContentLengthOrTransferEncodingHeader() {