diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs index f05d250a4b..13546271e5 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs @@ -196,6 +196,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http await FireOnCompleted(); await ProduceEnd(); + + // Finish reading the request body in case the app did not. + await RequestBody.CopyToAsync(Stream.Null); } terminated = !_keepAlive; diff --git a/test/Microsoft.AspNet.Server.KestrelTests/EngineTests.cs b/test/Microsoft.AspNet.Server.KestrelTests/EngineTests.cs index 633c131c53..c2d2ad06bb 100644 --- a/test/Microsoft.AspNet.Server.KestrelTests/EngineTests.cs +++ b/test/Microsoft.AspNet.Server.KestrelTests/EngineTests.cs @@ -876,6 +876,52 @@ namespace Microsoft.AspNet.Server.KestrelTests } } + [Theory] + [MemberData(nameof(ConnectionFilterData))] + public async Task RequestBodyIsConsumedAutomaticallyIfAppDoesntConsumeItFully(ServiceContext testContext) + { + using (var server = new TestServer(async frame => + { + var response = frame.Get(); + var request = frame.Get(); + + Assert.Equal("POST", request.Method); + + response.Headers.Clear(); + response.Headers["Content-Length"] = new[] { "11" }; + + await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World"), 0, 11); + }, testContext)) + { + using (var connection = new TestConnection()) + { + await connection.SendEnd( + "POST / HTTP/1.1", + "Content-Length: 5", + "", + "HelloPOST / HTTP/1.1", + "Transfer-Encoding: chunked", + "", + "C", "HelloChunked", "0", + "POST / HTTP/1.1", + "Content-Length: 7", + "", + "Goodbye"); + await connection.ReceiveEnd( + "HTTP/1.1 200 OK", + "Content-Length: 11", + "", + "Hello WorldHTTP/1.1 200 OK", + "Content-Length: 11", + "", + "Hello WorldHTTP/1.1 200 OK", + "Content-Length: 11", + "", + "Hello World"); + } + } + } + private class TestApplicationErrorLogger : ILogger { public int ApplicationErrorsLogged { get; set; }