Throw BadHttpRequestException in HttpSys (#24213)
This commit is contained in:
parent
d0cca519b4
commit
799014cfe7
|
|
@ -289,7 +289,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Response.Trailers.IsReadOnly = false;
|
Response.Trailers.IsReadOnly = false;
|
||||||
Response.Headers.Clear();
|
Response.Headers.Clear();
|
||||||
Response.Trailers.Clear();
|
Response.Trailers.Clear();
|
||||||
SetFatalResponse(500);
|
|
||||||
|
if (ex is BadHttpRequestException badHttpRequestException)
|
||||||
|
{
|
||||||
|
SetFatalResponse(badHttpRequestException.StatusCode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetFatalResponse(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.HttpSys.Internal;
|
using Microsoft.AspNetCore.HttpSys.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|
@ -432,8 +433,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
var contentLength = RequestContext.Request.ContentLength;
|
var contentLength = RequestContext.Request.ContentLength;
|
||||||
if (contentLength.HasValue && _maxSize.HasValue && contentLength.Value > _maxSize.Value)
|
if (contentLength.HasValue && _maxSize.HasValue && contentLength.Value > _maxSize.Value)
|
||||||
{
|
{
|
||||||
throw new IOException(
|
throw new BadHttpRequestException(
|
||||||
$"The request's Content-Length {contentLength.Value} is larger than the request body size limit {_maxSize.Value}.");
|
$"The request's Content-Length {contentLength.Value} is larger than the request body size limit {_maxSize.Value}.",
|
||||||
|
StatusCodes.Status413PayloadTooLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
HasStarted = true;
|
HasStarted = true;
|
||||||
|
|
@ -450,7 +452,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
_totalRead += bytesRead;
|
_totalRead += bytesRead;
|
||||||
if (_maxSize.HasValue && _totalRead > _maxSize.Value)
|
if (_maxSize.HasValue && _totalRead > _maxSize.Value)
|
||||||
{
|
{
|
||||||
exception = new IOException($"The total number of bytes read {_totalRead} has exceeded the request body size limit {_maxSize.Value}.");
|
exception = new BadHttpRequestException(
|
||||||
|
$"The total number of bytes read {_totalRead} has exceeded the request body size limit {_maxSize.Value}.",
|
||||||
|
StatusCodes.Status413PayloadTooLarge);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
exception = null;
|
exception = null;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -159,10 +160,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
Assert.Equal(11, httpContext.Request.ContentLength);
|
Assert.Equal(11, httpContext.Request.ContentLength);
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
var ex = Assert.Throws<IOException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
var ex = Assert.Throws<BadHttpRequestException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
||||||
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
||||||
ex = Assert.Throws<IOException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
|
ex = Assert.Throws<BadHttpRequestException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
||||||
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
||||||
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}, options => options.MaxRequestBodySize = 10))
|
}, options => options.MaxRequestBodySize = 10))
|
||||||
{
|
{
|
||||||
|
|
@ -182,10 +185,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
Assert.Equal(11, httpContext.Request.ContentLength);
|
Assert.Equal(11, httpContext.Request.ContentLength);
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
var ex = Assert.Throws<IOException>(() => { var t = httpContext.Request.Body.ReadAsync(input, 0, input.Length); });
|
var ex = Assert.Throws<BadHttpRequestException>(() => { var t = httpContext.Request.Body.ReadAsync(input, 0, input.Length); });
|
||||||
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
||||||
ex = Assert.Throws<IOException>(() => { var t = httpContext.Request.Body.ReadAsync(input, 0, input.Length); });
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
|
ex = Assert.Throws<BadHttpRequestException>(() => { var t = httpContext.Request.Body.ReadAsync(input, 0, input.Length); });
|
||||||
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
||||||
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}, options => options.MaxRequestBodySize = 10))
|
}, options => options.MaxRequestBodySize = 10))
|
||||||
{
|
{
|
||||||
|
|
@ -205,10 +210,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
Assert.Equal(11, httpContext.Request.ContentLength);
|
Assert.Equal(11, httpContext.Request.ContentLength);
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
var ex = Assert.Throws<IOException>(() => httpContext.Request.Body.BeginRead(input, 0, input.Length, null, null));
|
var ex = Assert.Throws<BadHttpRequestException>(() => httpContext.Request.Body.BeginRead(input, 0, input.Length, null, null));
|
||||||
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
||||||
ex = Assert.Throws<IOException>(() => httpContext.Request.Body.BeginRead(input, 0, input.Length, null, null));
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
|
ex = Assert.Throws<BadHttpRequestException>(() => httpContext.Request.Body.BeginRead(input, 0, input.Length, null, null));
|
||||||
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
Assert.Equal("The request's Content-Length 11 is larger than the request body size limit 10.", ex.Message);
|
||||||
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}, options => options.MaxRequestBodySize = 10))
|
}, options => options.MaxRequestBodySize = 10))
|
||||||
{
|
{
|
||||||
|
|
@ -229,10 +236,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
Assert.Null(httpContext.Request.ContentLength);
|
Assert.Null(httpContext.Request.ContentLength);
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
var ex = Assert.Throws<IOException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
var ex = Assert.Throws<BadHttpRequestException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
||||||
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
||||||
ex = Assert.Throws<IOException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
|
ex = Assert.Throws<BadHttpRequestException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
||||||
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
||||||
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}, options => options.MaxRequestBodySize = 10))
|
}, options => options.MaxRequestBodySize = 10))
|
||||||
{
|
{
|
||||||
|
|
@ -252,9 +261,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Assert.False(feature.IsReadOnly);
|
Assert.False(feature.IsReadOnly);
|
||||||
Assert.Null(httpContext.Request.ContentLength);
|
Assert.Null(httpContext.Request.ContentLength);
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
var ex = await Assert.ThrowsAsync<IOException>(() => httpContext.Request.Body.ReadAsync(input, 0, input.Length));
|
var ex = await Assert.ThrowsAsync<BadHttpRequestException>(() => httpContext.Request.Body.ReadAsync(input, 0, input.Length));
|
||||||
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
||||||
ex = await Assert.ThrowsAsync<IOException>(() => httpContext.Request.Body.ReadAsync(input, 0, input.Length));
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
|
ex = await Assert.ThrowsAsync<BadHttpRequestException>(() => httpContext.Request.Body.ReadAsync(input, 0, input.Length));
|
||||||
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
||||||
}, options => options.MaxRequestBodySize = 10))
|
}, options => options.MaxRequestBodySize = 10))
|
||||||
{
|
{
|
||||||
|
|
@ -275,10 +286,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
Assert.Null(httpContext.Request.ContentLength);
|
Assert.Null(httpContext.Request.ContentLength);
|
||||||
byte[] input = new byte[100];
|
byte[] input = new byte[100];
|
||||||
var body = httpContext.Request.Body;
|
var body = httpContext.Request.Body;
|
||||||
var ex = Assert.Throws<IOException>(() => body.EndRead(body.BeginRead(input, 0, input.Length, null, null)));
|
var ex = Assert.Throws<BadHttpRequestException>(() => body.EndRead(body.BeginRead(input, 0, input.Length, null, null)));
|
||||||
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
||||||
ex = Assert.Throws<IOException>(() => body.EndRead(body.BeginRead(input, 0, input.Length, null, null)));
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
|
ex = Assert.Throws<BadHttpRequestException>(() => body.EndRead(body.BeginRead(input, 0, input.Length, null, null)));
|
||||||
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
Assert.Equal("The total number of bytes read 11 has exceeded the request body size limit 10.", ex.Message);
|
||||||
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}, options => options.MaxRequestBodySize = 10))
|
}, options => options.MaxRequestBodySize = 10))
|
||||||
{
|
{
|
||||||
|
|
@ -303,8 +316,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
int read = httpContext.Request.Body.Read(input, 0, input.Length);
|
int read = httpContext.Request.Body.Read(input, 0, input.Length);
|
||||||
Assert.Equal(10, read);
|
Assert.Equal(10, read);
|
||||||
content.Block.Release();
|
content.Block.Release();
|
||||||
var ex = Assert.Throws<IOException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
var ex = Assert.Throws<BadHttpRequestException>(() => httpContext.Request.Body.Read(input, 0, input.Length));
|
||||||
Assert.Equal("The total number of bytes read 20 has exceeded the request body size limit 10.", ex.Message);
|
Assert.Equal("The total number of bytes read 20 has exceeded the request body size limit 10.", ex.Message);
|
||||||
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}, options => options.MaxRequestBodySize = 10))
|
}, options => options.MaxRequestBodySize = 10))
|
||||||
{
|
{
|
||||||
|
|
@ -328,8 +342,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
int read = await httpContext.Request.Body.ReadAsync(input, 0, input.Length);
|
int read = await httpContext.Request.Body.ReadAsync(input, 0, input.Length);
|
||||||
Assert.Equal(10, read);
|
Assert.Equal(10, read);
|
||||||
content.Block.Release();
|
content.Block.Release();
|
||||||
var ex = await Assert.ThrowsAsync<IOException>(() => httpContext.Request.Body.ReadAsync(input, 0, input.Length));
|
var ex = await Assert.ThrowsAsync<BadHttpRequestException>(() => httpContext.Request.Body.ReadAsync(input, 0, input.Length));
|
||||||
Assert.Equal("The total number of bytes read 20 has exceeded the request body size limit 10.", ex.Message);
|
Assert.Equal("The total number of bytes read 20 has exceeded the request body size limit 10.", ex.Message);
|
||||||
|
Assert.Equal(StatusCodes.Status413PayloadTooLarge, ex.StatusCode);
|
||||||
}, options => options.MaxRequestBodySize = 10))
|
}, options => options.MaxRequestBodySize = 10))
|
||||||
{
|
{
|
||||||
string response = await SendRequestAsync(address, content, chunked: true);
|
string response = await SendRequestAsync(address, content, chunked: true);
|
||||||
|
|
|
||||||
|
|
@ -204,11 +204,33 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
Task<string> requestTask = SendRequestAsync(address);
|
Task<string> requestTask = SendRequestAsync(address);
|
||||||
await Assert.ThrowsAsync<HttpRequestException>(async () => await requestTask);
|
var ex = await Assert.ThrowsAsync<HttpRequestException>(async () => await requestTask);
|
||||||
|
Assert.Equal(StatusCodes.Status500InternalServerError, (int)ex.StatusCode);
|
||||||
|
|
||||||
// Do it again to make sure the server didn't crash
|
// Do it again to make sure the server didn't crash
|
||||||
requestTask = SendRequestAsync(address);
|
requestTask = SendRequestAsync(address);
|
||||||
await Assert.ThrowsAsync<HttpRequestException>(async () => await requestTask);
|
ex = await Assert.ThrowsAsync<HttpRequestException>(async () => await requestTask);
|
||||||
|
Assert.Equal(StatusCodes.Status500InternalServerError, (int)ex.StatusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
public async Task Server_BadHttpRequestException_SetStatusCode()
|
||||||
|
{
|
||||||
|
string address;
|
||||||
|
using (Utilities.CreateHttpServer(out address, httpContext =>
|
||||||
|
{
|
||||||
|
throw new BadHttpRequestException("Something happened", StatusCodes.Status418ImATeapot);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
Task<string> requestTask = SendRequestAsync(address);
|
||||||
|
var ex = await Assert.ThrowsAsync<HttpRequestException>(async () => await requestTask);
|
||||||
|
Assert.Equal(StatusCodes.Status418ImATeapot, (int)ex.StatusCode);
|
||||||
|
|
||||||
|
// Do it again to make sure the server didn't crash
|
||||||
|
requestTask = SendRequestAsync(address);
|
||||||
|
ex = await Assert.ThrowsAsync<HttpRequestException>(async () => await requestTask);
|
||||||
|
Assert.Equal(StatusCodes.Status418ImATeapot, (int)ex.StatusCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue