Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 81a182a

Browse files
author
Cesar Blum Silveira
committed
Ensure status code is 400 if MessageBody.Consume() throws when consuming the rest of the request body.
1 parent 9c476b1 commit 81a182a

File tree

2 files changed

+61
-26
lines changed
  • src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http
  • test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests

2 files changed

+61
-26
lines changed

src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/FrameOfT.cs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,29 @@ public override async Task RequestProcessingAsync()
115115
await FireOnCompleted();
116116
}
117117

118-
// If _requestAbort is set, the connection has already been closed.
119-
if (Volatile.Read(ref _requestAborted) == 0)
118+
try
120119
{
121-
ResumeStreams();
122-
123-
if (_keepAlive)
120+
// If _requestAbort is set, the connection has already been closed.
121+
if (Volatile.Read(ref _requestAborted) == 0)
124122
{
125-
// Finish reading the request body in case the app did not.
126-
await messageBody.Consume();
123+
ResumeStreams();
124+
125+
if (_keepAlive)
126+
{
127+
// Finish reading the request body in case the app did not.
128+
await messageBody.Consume();
129+
}
127130
}
128131

132+
// ProduceEnd() must be called before _application.DisposeContext(), to ensure
133+
// HttpContext.Response.StatusCode is correctly set when
134+
// IHttpContextFactory.Dispose(HttpContext) is called.
135+
await ProduceEnd();
136+
}
137+
finally
138+
{
139+
_application.DisposeContext(context, _applicationException);
129140
}
130-
131-
// ProduceEnd() must be called before _application.DisposeContext(), to ensure
132-
// HttpContext.Response.StatusCode is correctly set when
133-
// IHttpContextFactory.Dispose(HttpContext) is called.
134-
await ProduceEnd();
135-
136-
_application.DisposeContext(context, _applicationException);
137141
}
138142

139143
StopStreams();

test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/ResponseTests.cs

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Net;
77
using System.Net.Http;
8+
using System.Net.Sockets;
89
using System.Text;
910
using System.Threading.Tasks;
1011
using Microsoft.AspNetCore.Builder;
@@ -223,8 +224,24 @@ public Task ResponseStatusCodeSetBeforeHttpContextDisposeRequestAbortedAppExcept
223224
expectedServerStatusCode: HttpStatusCode.InternalServerError);
224225
}
225226

226-
private static async Task ResponseStatusCodeSetBeforeHttpContextDispose(RequestDelegate handler,
227-
HttpStatusCode? expectedClientStatusCode, HttpStatusCode expectedServerStatusCode)
227+
[Fact]
228+
public Task ResponseStatusCodeSetBeforeHttpContextDisposedRequestMalformed()
229+
{
230+
return ResponseStatusCodeSetBeforeHttpContextDispose(
231+
context =>
232+
{
233+
return TaskCache.CompletedTask;
234+
},
235+
expectedClientStatusCode: null,
236+
expectedServerStatusCode: HttpStatusCode.BadRequest,
237+
sendMalformedRequest: true);
238+
}
239+
240+
private static async Task ResponseStatusCodeSetBeforeHttpContextDispose(
241+
RequestDelegate handler,
242+
HttpStatusCode? expectedClientStatusCode,
243+
HttpStatusCode expectedServerStatusCode,
244+
bool sendMalformedRequest = false)
228245
{
229246
var mockHttpContextFactory = new Mock<IHttpContextFactory>();
230247
mockHttpContextFactory.Setup(f => f.Create(It.IsAny<IFeatureCollection>()))
@@ -250,24 +267,38 @@ private static async Task ResponseStatusCodeSetBeforeHttpContextDispose(RequestD
250267
{
251268
host.Start();
252269

253-
using (var client = new HttpClient())
270+
if (!sendMalformedRequest)
254271
{
255-
try
256-
{
257-
var response = await client.GetAsync($"http://localhost:{host.GetPort()}/");
258-
Assert.Equal(expectedClientStatusCode, response.StatusCode);
259-
}
260-
catch
272+
using (var client = new HttpClient())
261273
{
262-
if (expectedClientStatusCode != null)
274+
try
275+
{
276+
var response = await client.GetAsync($"http://localhost:{host.GetPort()}/");
277+
Assert.Equal(expectedClientStatusCode, response.StatusCode);
278+
}
279+
catch
263280
{
264-
throw;
281+
if (expectedClientStatusCode != null)
282+
{
283+
throw;
284+
}
265285
}
266286
}
267287
}
288+
else
289+
{
290+
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
291+
{
292+
socket.Connect(new IPEndPoint(IPAddress.Loopback, host.GetPort()));
293+
socket.Send(Encoding.ASCII.GetBytes(
294+
"POST / HTTP/1.1\r\n" +
295+
"Transfer-Encoding: chunked\r\n" +
296+
"\r\n" +
297+
"wrong"));
298+
}
299+
}
268300

269301
var disposedStatusCode = await disposedTcs.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
270-
271302
Assert.Equal(expectedServerStatusCode, (HttpStatusCode)disposedStatusCode);
272303
}
273304
}

0 commit comments

Comments
 (0)