Move BadHttpRequestException to Http.Abstractions (#20339)

This commit is contained in:
Chris Oliver 2020-04-06 22:42:16 +01:00 committed by GitHub
parent 1f76cce14a
commit b463e049b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 494 additions and 248 deletions

View File

@ -97,6 +97,14 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure
} }
namespace Microsoft.AspNetCore.Http namespace Microsoft.AspNetCore.Http
{ {
public partial class BadHttpRequestException : System.IO.IOException
{
public BadHttpRequestException(string message) { }
public BadHttpRequestException(string message, System.Exception innerException) { }
public BadHttpRequestException(string message, int statusCode) { }
public BadHttpRequestException(string message, int statusCode, System.Exception innerException) { }
public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
}
public abstract partial class ConnectionInfo public abstract partial class ConnectionInfo
{ {
protected ConnectionInfo() { } protected ConnectionInfo() { }

View File

@ -0,0 +1,60 @@
using System;
using System.IO;
namespace Microsoft.AspNetCore.Http
{
/// <summary>
/// Represents an HTTP request error
/// </summary>
public class BadHttpRequestException : IOException
{
/// <summary>
/// Initializes a new instance of the <see cref="BadHttpRequestException"/> class.
/// </summary>
/// <param name="message">The message to associate with this exception.</param>
/// <param name="statusCode">The HTTP status code to associate with this exception.</param>
public BadHttpRequestException(string message, int statusCode)
: base(message)
{
StatusCode = statusCode;
}
/// <summary>
/// Initializes a new instance of the <see cref="BadHttpRequestException"/> class with the <see cref="StatusCode"/> set to 400 Bad Request.
/// </summary>
/// <param name="message">The message to associate with this exception</param>
public BadHttpRequestException(string message)
: base(message)
{
StatusCode = StatusCodes.Status400BadRequest;
}
/// <summary>
/// Initializes a new instance of the <see cref="BadHttpRequestException"/> class.
/// </summary>
/// <param name="message">The message to associate with this exception.</param>
/// <param name="statusCode">The HTTP status code to associate with this exception.</param>
/// <param name="innerException">The inner exception to associate with this exception</param>
public BadHttpRequestException(string message, int statusCode, Exception innerException)
: base(message, innerException)
{
StatusCode = statusCode;
}
/// <summary>
/// Initializes a new instance of the <see cref="BadHttpRequestException"/> class with the <see cref="StatusCode"/> set to 400 Bad Request.
/// </summary>
/// <param name="message">The message to associate with this exception</param>
/// <param name="innerException">The inner exception to associate with this exception</param>
public BadHttpRequestException(string message, Exception innerException)
: base(message, innerException)
{
StatusCode = StatusCodes.Status400BadRequest;
}
/// <summary>
/// Gets the HTTP status code for this exception.
/// </summary>
public int StatusCode { get; }
}
}

View File

@ -21,10 +21,11 @@ namespace Microsoft.AspNetCore.Hosting
} }
namespace Microsoft.AspNetCore.Server.IIS namespace Microsoft.AspNetCore.Server.IIS
{ {
public sealed partial class BadHttpRequestException : System.IO.IOException [System.ObsoleteAttribute("Moved to Microsoft.AspNetCore.Http.BadHttpRequestException")]
public sealed partial class BadHttpRequestException : Microsoft.AspNetCore.Http.BadHttpRequestException
{ {
internal BadHttpRequestException() { } internal BadHttpRequestException() : base (default(string), default(int)) { }
public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public new int StatusCode { get { throw null; } }
} }
public static partial class HttpContextExtensions public static partial class HttpContextExtensions
{ {

View File

@ -1,44 +1,24 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Server.IIS namespace Microsoft.AspNetCore.Server.IIS
{ {
public sealed class BadHttpRequestException : IOException [Obsolete("Moved to Microsoft.AspNetCore.Http.BadHttpRequestException")]
public sealed class BadHttpRequestException : Microsoft.AspNetCore.Http.BadHttpRequestException
{ {
private BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason) internal BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason)
: base(message) : base(message, statusCode)
{ {
StatusCode = statusCode;
Reason = reason; Reason = reason;
} }
public int StatusCode { get; } public new int StatusCode { get => base.StatusCode; }
internal RequestRejectionReason Reason { get; } internal RequestRejectionReason Reason { get; }
internal static void Throw(RequestRejectionReason reason)
{
throw GetException(reason);
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static BadHttpRequestException GetException(RequestRejectionReason reason)
{
BadHttpRequestException ex;
switch (reason)
{
case RequestRejectionReason.RequestBodyTooLarge:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestBodyTooLarge, StatusCodes.Status413PayloadTooLarge, reason);
break;
default:
ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest, reason);
break;
}
return ex;
}
} }
} }

View File

@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
if (_consumedBytes > MaxRequestBodySize) if (_consumedBytes > MaxRequestBodySize)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge); IISBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge);
} }
var result = await _bodyInputPipe.Writer.FlushAsync(); var result = await _bodyInputPipe.Writer.FlushAsync();

View File

@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
_unexpectedError(logger, className, methodName, ex); _unexpectedError(logger, className, methodName, ex);
} }
public static void ConnectionBadRequest(ILogger logger, string connectionId, BadHttpRequestException ex) public static void ConnectionBadRequest(ILogger logger, string connectionId, Microsoft.AspNetCore.Http.BadHttpRequestException ex)
{ {
_connectionBadRequest(logger, connectionId, ex.Message, ex); _connectionBadRequest(logger, connectionId, ex.Message, ex);
} }

View File

@ -26,6 +26,8 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.IIS.Core namespace Microsoft.AspNetCore.Server.IIS.Core
{ {
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
internal abstract partial class IISHttpContext : NativeRequestContext, IThreadPoolWorkItem, IDisposable internal abstract partial class IISHttpContext : NativeRequestContext, IThreadPoolWorkItem, IDisposable
{ {
private const int MinAllocBufferSize = 2048; private const int MinAllocBufferSize = 2048;
@ -293,7 +295,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
if (RequestHeaders.ContentLength > MaxRequestBodySize) if (RequestHeaders.ContentLength > MaxRequestBodySize)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge); IISBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge);
} }
HasStartedConsumingRequestBody = true; HasStartedConsumingRequestBody = true;

View File

@ -11,6 +11,8 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.IIS.Core namespace Microsoft.AspNetCore.Server.IIS.Core
{ {
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
internal class IISHttpContextOfT<TContext> : IISHttpContext internal class IISHttpContextOfT<TContext> : IISHttpContext
{ {
private readonly IHttpApplication<TContext> _application; private readonly IHttpApplication<TContext> _application;

View File

@ -0,0 +1,36 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Server.IIS
{
internal static class IISBadHttpRequestException
{
internal static void Throw(RequestRejectionReason reason)
{
throw GetException(reason);
}
[MethodImpl(MethodImplOptions.NoInlining)]
#pragma warning disable CS0618 // Type or member is obsolete
internal static BadHttpRequestException GetException(RequestRejectionReason reason)
{
BadHttpRequestException ex;
switch (reason)
{
case RequestRejectionReason.RequestBodyTooLarge:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestBodyTooLarge, StatusCodes.Status413PayloadTooLarge, reason);
break;
default:
ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest, reason);
break;
}
return ex;
}
#pragma warning restore CS0618 // Type or member is obsolete
}
}

View File

@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Server.IIS.FunctionalTests;
using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.Logging.Testing;
using Xunit; using Xunit;
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
namespace IIS.Tests namespace IIS.Tests
{ {
@ -24,6 +25,7 @@ namespace IIS.Tests
var globalMaxRequestBodySize = 0x100000000; var globalMaxRequestBodySize = 0x100000000;
BadHttpRequestException exception = null; BadHttpRequestException exception = null;
using (var testServer = await TestServer.Create( using (var testServer = await TestServer.Create(
async ctx => async ctx =>
{ {
@ -60,6 +62,7 @@ namespace IIS.Tests
var perRequestMaxRequestBodySize = 0x100; var perRequestMaxRequestBodySize = 0x100;
BadHttpRequestException exception = null; BadHttpRequestException exception = null;
using (var testServer = await TestServer.Create( using (var testServer = await TestServer.Create(
async ctx => async ctx =>
{ {
@ -71,6 +74,7 @@ namespace IIS.Tests
await ctx.Request.Body.ReadAsync(new byte[2000]); await ctx.Request.Body.ReadAsync(new byte[2000]);
} }
catch (BadHttpRequestException ex) catch (BadHttpRequestException ex)
{ {
exception = ex; exception = ex;
@ -266,6 +270,7 @@ namespace IIS.Tests
var maxRequestSize = 0x1000; var maxRequestSize = 0x1000;
BadHttpRequestException exception = null; BadHttpRequestException exception = null;
using (var testServer = await TestServer.Create( using (var testServer = await TestServer.Create(
async ctx => async ctx =>
{ {
@ -307,13 +312,14 @@ namespace IIS.Tests
{ {
BadHttpRequestException requestRejectedEx1 = null; BadHttpRequestException requestRejectedEx1 = null;
BadHttpRequestException requestRejectedEx2 = null; BadHttpRequestException requestRejectedEx2 = null;
using (var testServer = await TestServer.Create( using (var testServer = await TestServer.Create(
async ctx => async ctx =>
{ {
var buffer = new byte[1]; var buffer = new byte[1];
requestRejectedEx1 = await Assert.ThrowsAsync<BadHttpRequestException>( requestRejectedEx1 = await Assert.ThrowsAnyAsync<BadHttpRequestException>(
async () => await ctx.Request.Body.ReadAsync(buffer, 0, 1)); async () => await ctx.Request.Body.ReadAsync(buffer, 0, 1));
requestRejectedEx2 = await Assert.ThrowsAsync<BadHttpRequestException>( requestRejectedEx2 = await Assert.ThrowsAnyAsync<BadHttpRequestException>(
async () => await ctx.Request.Body.ReadAsync(buffer, 0, 1)); async () => await ctx.Request.Body.ReadAsync(buffer, 0, 1));
throw requestRejectedEx2; throw requestRejectedEx2;
}, LoggerFactory, new IISServerOptions { MaxRequestBodySize = 0 })) }, LoggerFactory, new IISServerOptions { MaxRequestBodySize = 0 }))

View File

@ -62,10 +62,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel
} }
namespace Microsoft.AspNetCore.Server.Kestrel.Core namespace Microsoft.AspNetCore.Server.Kestrel.Core
{ {
public sealed partial class BadHttpRequestException : System.IO.IOException [System.ObsoleteAttribute("Moved to Microsoft.AspNetCore.Http.BadHttpRequestException")]
public sealed partial class BadHttpRequestException : Microsoft.AspNetCore.Http.BadHttpRequestException
{ {
internal BadHttpRequestException() { } internal BadHttpRequestException() : base (default(string), default(int)) { }
public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public new int StatusCode { get { throw null; } }
} }
public partial class Http2Limits public partial class Http2Limits
{ {

View File

@ -1,26 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics; using System;
using System.IO;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Server.Kestrel.Core namespace Microsoft.AspNetCore.Server.Kestrel.Core
{ {
public sealed class BadHttpRequestException : IOException [Obsolete("Moved to Microsoft.AspNetCore.Http.BadHttpRequestException")]
public sealed class BadHttpRequestException : Microsoft.AspNetCore.Http.BadHttpRequestException
{ {
private BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason) internal BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason)
: this(message, statusCode, reason, null) : this(message, statusCode, reason, null)
{ } { }
private BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason, HttpMethod? requiredMethod) internal BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason, HttpMethod? requiredMethod)
: base(message) : base(message, statusCode)
{ {
StatusCode = statusCode;
Reason = reason; Reason = reason;
if (requiredMethod.HasValue) if (requiredMethod.HasValue)
@ -29,151 +26,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
} }
} }
public int StatusCode { get; } public new int StatusCode { get => base.StatusCode; }
internal StringValues AllowedHeader { get; } internal StringValues AllowedHeader { get; }
internal RequestRejectionReason Reason { get; } internal RequestRejectionReason Reason { get; }
[StackTraceHidden]
internal static void Throw(RequestRejectionReason reason)
{
throw GetException(reason);
}
[StackTraceHidden]
internal static void Throw(RequestRejectionReason reason, HttpMethod method)
=> throw GetException(reason, method.ToString().ToUpperInvariant());
[MethodImpl(MethodImplOptions.NoInlining)]
internal static BadHttpRequestException GetException(RequestRejectionReason reason)
{
BadHttpRequestException ex;
switch (reason)
{
case RequestRejectionReason.InvalidRequestHeadersNoCRLF:
ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidRequestHeadersNoCRLF, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidRequestLine:
ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidRequestLine, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.MalformedRequestInvalidHeaders:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MalformedRequestInvalidHeaders, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.MultipleContentLengths:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MultipleContentLengths, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.UnexpectedEndOfRequestContent:
ex = new BadHttpRequestException(CoreStrings.BadRequest_UnexpectedEndOfRequestContent, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.BadChunkSuffix:
ex = new BadHttpRequestException(CoreStrings.BadRequest_BadChunkSuffix, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.BadChunkSizeData:
ex = new BadHttpRequestException(CoreStrings.BadRequest_BadChunkSizeData, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.ChunkedRequestIncomplete:
ex = new BadHttpRequestException(CoreStrings.BadRequest_ChunkedRequestIncomplete, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidCharactersInHeaderName:
ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidCharactersInHeaderName, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.RequestLineTooLong:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestLineTooLong, StatusCodes.Status414UriTooLong, reason);
break;
case RequestRejectionReason.HeadersExceedMaxTotalSize:
ex = new BadHttpRequestException(CoreStrings.BadRequest_HeadersExceedMaxTotalSize, StatusCodes.Status431RequestHeaderFieldsTooLarge, reason);
break;
case RequestRejectionReason.TooManyHeaders:
ex = new BadHttpRequestException(CoreStrings.BadRequest_TooManyHeaders, StatusCodes.Status431RequestHeaderFieldsTooLarge, reason);
break;
case RequestRejectionReason.RequestBodyTooLarge:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestBodyTooLarge, StatusCodes.Status413PayloadTooLarge, reason);
break;
case RequestRejectionReason.RequestHeadersTimeout:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestHeadersTimeout, StatusCodes.Status408RequestTimeout, reason);
break;
case RequestRejectionReason.RequestBodyTimeout:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestBodyTimeout, StatusCodes.Status408RequestTimeout, reason);
break;
case RequestRejectionReason.OptionsMethodRequired:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MethodNotAllowed, StatusCodes.Status405MethodNotAllowed, reason, HttpMethod.Options);
break;
case RequestRejectionReason.ConnectMethodRequired:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MethodNotAllowed, StatusCodes.Status405MethodNotAllowed, reason, HttpMethod.Connect);
break;
case RequestRejectionReason.MissingHostHeader:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MissingHostHeader, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.MultipleHostHeaders:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MultipleHostHeaders, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidHostHeader:
ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidHostHeader, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.UpgradeRequestCannotHavePayload:
ex = new BadHttpRequestException(CoreStrings.BadRequest_UpgradeRequestCannotHavePayload, StatusCodes.Status400BadRequest, reason);
break;
default:
ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest, reason);
break;
}
return ex;
}
[StackTraceHidden]
internal static void Throw(RequestRejectionReason reason, string detail)
{
throw GetException(reason, detail);
}
[StackTraceHidden]
internal static void Throw(RequestRejectionReason reason, StringValues detail)
{
throw GetException(reason, detail.ToString());
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static BadHttpRequestException GetException(RequestRejectionReason reason, string detail)
{
BadHttpRequestException ex;
switch (reason)
{
case RequestRejectionReason.TlsOverHttpError:
ex = new BadHttpRequestException(CoreStrings.HttpParserTlsOverHttpError, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidRequestLine:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidRequestTarget:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidRequestHeader:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidContentLength:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidContentLength_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.UnrecognizedHTTPVersion:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(detail), StatusCodes.Status505HttpVersionNotsupported, reason);
break;
case RequestRejectionReason.FinalTransferCodingNotChunked:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_FinalTransferCodingNotChunked(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.LengthRequired:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_LengthRequired(detail), StatusCodes.Status411LengthRequired, reason);
break;
case RequestRejectionReason.LengthRequiredHttp10:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_LengthRequiredHttp10(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidHostHeader:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidHostHeader_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
default:
ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest, reason);
break;
}
return ex;
}
} }
} }

View File

@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (_context.RequestTimedOut) if (_context.RequestTimedOut)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
} }
var readableBuffer = result.Buffer; var readableBuffer = result.Buffer;
@ -373,7 +373,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
} }
// At this point, 10 bytes have been consumed which is enough to parse the max value "7FFFFFFF\r\n". // At this point, 10 bytes have been consumed which is enough to parse the max value "7FFFFFFF\r\n".
BadHttpRequestException.Throw(RequestRejectionReason.BadChunkSizeData); KestrelBadHttpRequestException.Throw(RequestRejectionReason.BadChunkSizeData);
} }
private void ParseExtension(ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined) private void ParseExtension(ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined)
@ -469,7 +469,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
} }
else else
{ {
BadHttpRequestException.Throw(RequestRejectionReason.BadChunkSuffix); KestrelBadHttpRequestException.Throw(RequestRejectionReason.BadChunkSuffix);
} }
} }
@ -528,7 +528,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
throw new IOException(CoreStrings.BadRequest_BadChunkSizeData, ex); throw new IOException(CoreStrings.BadRequest_BadChunkSizeData, ex);
} }
BadHttpRequestException.Throw(RequestRejectionReason.BadChunkSizeData); KestrelBadHttpRequestException.Throw(RequestRejectionReason.BadChunkSizeData);
return -1; // can't happen, but compiler complains return -1; // can't happen, but compiler complains
} }

View File

@ -204,7 +204,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (!_parser.ParseRequestLine(new Http1ParsingHandler(this), trimmedBuffer, out consumed, out examined)) if (!_parser.ParseRequestLine(new Http1ParsingHandler(this), trimmedBuffer, out consumed, out examined))
{ {
// We read the maximum allowed but didn't complete the start line. // We read the maximum allowed but didn't complete the start line.
BadHttpRequestException.Throw(RequestRejectionReason.RequestLineTooLong); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestLineTooLong);
} }
return true; return true;
@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (!result) if (!result)
{ {
// We read the maximum allowed but didn't complete the headers. // We read the maximum allowed but didn't complete the headers.
BadHttpRequestException.Throw(RequestRejectionReason.HeadersExceedMaxTotalSize); KestrelBadHttpRequestException.Throw(RequestRejectionReason.HeadersExceedMaxTotalSize);
} }
TimeoutControl.CancelTimeout(); TimeoutControl.CancelTimeout();
@ -424,7 +424,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// requests (https://tools.ietf.org/html/rfc7231#section-4.3.6). // requests (https://tools.ietf.org/html/rfc7231#section-4.3.6).
if (method != HttpMethod.Connect) if (method != HttpMethod.Connect)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.ConnectMethodRequired); KestrelBadHttpRequestException.Throw(RequestRejectionReason.ConnectMethodRequired);
} }
// When making a CONNECT request to establish a tunnel through one or // When making a CONNECT request to establish a tunnel through one or
@ -468,7 +468,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// OPTIONS request (https://tools.ietf.org/html/rfc7231#section-4.3.7). // OPTIONS request (https://tools.ietf.org/html/rfc7231#section-4.3.7).
if (method != HttpMethod.Options) if (method != HttpMethod.Options)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.OptionsMethodRequired); KestrelBadHttpRequestException.Throw(RequestRejectionReason.OptionsMethodRequired);
} }
RawTarget = Asterisk; RawTarget = Asterisk;
@ -555,11 +555,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
return; return;
} }
BadHttpRequestException.Throw(RequestRejectionReason.MissingHostHeader);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MissingHostHeader);
} }
else if (hostCount > 1) else if (hostCount > 1)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.MultipleHostHeaders); KestrelBadHttpRequestException.Throw(RequestRejectionReason.MultipleHostHeaders);
} }
else if (_requestTargetForm != HttpRequestTarget.OriginForm) else if (_requestTargetForm != HttpRequestTarget.OriginForm)
{ {
@ -568,7 +569,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
} }
else if (!HttpUtilities.IsHostHeaderValid(hostText)) else if (!HttpUtilities.IsHostHeaderValid(hostText))
{ {
BadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText); KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText);
} }
} }
@ -578,7 +579,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
if (hostText != RawTarget) if (hostText != RawTarget)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText); KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText);
} }
} }
else if (_requestTargetForm == HttpRequestTarget.AbsoluteForm) else if (_requestTargetForm == HttpRequestTarget.AbsoluteForm)
@ -595,14 +596,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (!_absoluteRequestTarget.IsDefaultPort if (!_absoluteRequestTarget.IsDefaultPort
|| hostText != _absoluteRequestTarget.Authority + ":" + _absoluteRequestTarget.Port.ToString(CultureInfo.InvariantCulture)) || hostText != _absoluteRequestTarget.Authority + ":" + _absoluteRequestTarget.Port.ToString(CultureInfo.InvariantCulture))
{ {
BadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText); KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText);
} }
} }
} }
if (!HttpUtilities.IsHostHeaderValid(hostText)) if (!HttpUtilities.IsHostHeaderValid(hostText))
{ {
BadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText); KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText);
} }
} }
@ -655,7 +656,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
if (_requestProcessingStatus == RequestProcessingStatus.ParsingHeaders) if (_requestProcessingStatus == RequestProcessingStatus.ParsingHeaders)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders); KestrelBadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders);
} }
throw; throw;
} }
@ -672,10 +673,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
endConnection = true; endConnection = true;
return true; return true;
case RequestProcessingStatus.ParsingRequestLine: case RequestProcessingStatus.ParsingRequestLine:
BadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestLine); KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestLine);
break; break;
case RequestProcessingStatus.ParsingHeaders: case RequestProcessingStatus.ParsingHeaders:
BadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders); KestrelBadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders);
break; break;
} }
} }
@ -690,7 +691,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
// In this case, there is an ongoing request but the start line/header parsing has timed out, so send // In this case, there is an ongoing request but the start line/header parsing has timed out, so send
// a 408 response. // a 408 response.
BadHttpRequestException.Throw(RequestRejectionReason.RequestHeadersTimeout); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestHeadersTimeout);
} }
endConnection = false; endConnection = false;

View File

@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// which is unknown to StartTimingReadAsync. // which is unknown to StartTimingReadAsync.
if (_context.RequestTimedOut) if (_context.RequestTimedOut)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
} }
try try
@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (_context.RequestTimedOut) if (_context.RequestTimedOut)
{ {
ResetReadingState(); ResetReadingState();
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
} }
if (_readResult.IsCompleted) if (_readResult.IsCompleted)
@ -234,7 +234,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
if (_contentLength > _context.MaxRequestBodySize) if (_contentLength > _context.MaxRequestBodySize)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge);
} }
} }

View File

@ -11,6 +11,8 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
internal abstract class Http1MessageBody : MessageBody internal abstract class Http1MessageBody : MessageBody
{ {
protected readonly Http1Connection _context; protected readonly Http1Connection _context;
@ -31,7 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// closing the connection without a response as expected. // closing the connection without a response as expected.
_context.OnInputOrOutputCompleted(); _context.OnInputOrOutputCompleted();
BadHttpRequestException.Throw(RequestRejectionReason.UnexpectedEndOfRequestContent); KestrelBadHttpRequestException.Throw(RequestRejectionReason.UnexpectedEndOfRequestContent);
} }
public abstract bool TryReadInternal(out ReadResult readResult); public abstract bool TryReadInternal(out ReadResult readResult);
@ -87,7 +89,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
AdvanceTo(result.Buffer.End); AdvanceTo(result.Buffer.End);
} while (!result.IsCompleted); } while (!result.IsCompleted);
} }
catch (BadHttpRequestException ex) catch (Microsoft.AspNetCore.Http.BadHttpRequestException ex)
{ {
_context.SetBadRequestState(ex); _context.SetBadRequestState(ex);
} }
@ -130,7 +132,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
if (headers.HeaderTransferEncoding.Count > 0 || (headers.ContentLength.HasValue && headers.ContentLength.Value != 0)) if (headers.HeaderTransferEncoding.Count > 0 || (headers.ContentLength.HasValue && headers.ContentLength.Value != 0))
{ {
BadHttpRequestException.Throw(RequestRejectionReason.UpgradeRequestCannotHavePayload); KestrelBadHttpRequestException.Throw(RequestRejectionReason.UpgradeRequestCannotHavePayload);
} }
context.OnTrailersComplete(); // No trailers for these. context.OnTrailersComplete(); // No trailers for these.
@ -150,7 +152,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// status code and then close the connection. // status code and then close the connection.
if (transferCoding != TransferCoding.Chunked) if (transferCoding != TransferCoding.Chunked)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.FinalTransferCodingNotChunked, transferEncoding); KestrelBadHttpRequestException.Throw(RequestRejectionReason.FinalTransferCodingNotChunked, transferEncoding);
} }
// TODO may push more into the wrapper rather than just calling into the message body // TODO may push more into the wrapper rather than just calling into the message body
@ -175,7 +177,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (context.Method == HttpMethod.Post || context.Method == HttpMethod.Put) if (context.Method == HttpMethod.Post || context.Method == HttpMethod.Put)
{ {
var requestRejectionReason = httpVersion == HttpVersion.Http11 ? RequestRejectionReason.LengthRequired : RequestRejectionReason.LengthRequiredHttp10; var requestRejectionReason = httpVersion == HttpVersion.Http11 ? RequestRejectionReason.LengthRequired : RequestRejectionReason.LengthRequiredHttp10;
BadHttpRequestException.Throw(requestRejectionReason, context.Method); KestrelBadHttpRequestException.Throw(requestRejectionReason, context.Method);
} }
context.OnTrailersComplete(); // No trailers for these. context.OnTrailersComplete(); // No trailers for these.

View File

@ -11,6 +11,8 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
public class HttpParser<TRequestHandler> : IHttpParser<TRequestHandler> where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler public class HttpParser<TRequestHandler> : IHttpParser<TRequestHandler> where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler
{ {
private readonly bool _showErrorDetails; private readonly bool _showErrorDetails;
@ -225,7 +227,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
Debug.Assert(readAhead == 0 || readAhead == 2); Debug.Assert(readAhead == 0 || readAhead == 2);
// Headers don't end in CRLF line. // Headers don't end in CRLF line.
BadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestHeadersNoCRLF);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestHeadersNoCRLF);
} }
var length = 0; var length = 0;
@ -451,7 +454,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
private unsafe BadHttpRequestException GetInvalidRequestException(RequestRejectionReason reason, byte* detail, int length) private unsafe BadHttpRequestException GetInvalidRequestException(RequestRejectionReason reason, byte* detail, int length)
=> BadHttpRequestException.GetException( => KestrelBadHttpRequestException.GetException(
reason, reason,
_showErrorDetails _showErrorDetails
? new Span<byte>(detail, length).GetAsciiStringEscaped(Constants.MaxExceptionDetailSize) ? new Span<byte>(detail, length).GetAsciiStringEscaped(Constants.MaxExceptionDetailSize)

View File

@ -26,6 +26,8 @@ using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
internal abstract partial class HttpProtocol : IHttpResponseControl internal abstract partial class HttpProtocol : IHttpResponseControl
{ {
private static readonly byte[] _bytesConnectionClose = Encoding.ASCII.GetBytes("\r\nConnection: close"); private static readonly byte[] _bytesConnectionClose = Encoding.ASCII.GetBytes("\r\nConnection: close");
@ -513,7 +515,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_requestHeadersParsed++; _requestHeadersParsed++;
if (_requestHeadersParsed > ServerOptions.Limits.MaxRequestHeaderCount) if (_requestHeadersParsed > ServerOptions.Limits.MaxRequestHeaderCount)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders); KestrelBadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders);
} }
HttpRequestHeaders.Append(name, value); HttpRequestHeaders.Append(name, value);
@ -525,7 +527,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_requestHeadersParsed++; _requestHeadersParsed++;
if (_requestHeadersParsed > ServerOptions.Limits.MaxRequestHeaderCount) if (_requestHeadersParsed > ServerOptions.Limits.MaxRequestHeaderCount)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders); KestrelBadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders);
} }
string key = name.GetHeaderName(); string key = name.GetHeaderName();
@ -1215,9 +1217,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
SetErrorResponseHeaders(ex.StatusCode); SetErrorResponseHeaders(ex.StatusCode);
if (!StringValues.IsNullOrEmpty(ex.AllowedHeader)) #pragma warning disable CS0618 // Type or member is obsolete
if (ex is Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException kestrelEx && !StringValues.IsNullOrEmpty(kestrelEx.AllowedHeader))
#pragma warning restore CS0618 // Type or member is obsolete
{ {
HttpResponseHeaders.HeaderAllow = ex.AllowedHeader; HttpResponseHeaders.HeaderAllow = kestrelEx.AllowedHeader;
} }
} }
@ -1271,7 +1275,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
private BadHttpRequestException GetInvalidRequestTargetException(Span<byte> target) private BadHttpRequestException GetInvalidRequestTargetException(Span<byte> target)
=> BadHttpRequestException.GetException( => KestrelBadHttpRequestException.GetException(
RequestRejectionReason.InvalidRequestTarget, RequestRejectionReason.InvalidRequestTarget,
Log.IsEnabled(LogLevel.Information) Log.IsEnabled(LogLevel.Information)
? target.GetAsciiStringEscaped(Constants.MaxExceptionDetailSize) ? target.GetAsciiStringEscaped(Constants.MaxExceptionDetailSize)

View File

@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
if (!HeaderUtilities.TryParseNonNegativeInt64(value, out var parsed)) if (!HeaderUtilities.TryParseNonNegativeInt64(value, out var parsed))
{ {
BadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value); KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value);
} }
return parsed; return parsed;
@ -76,14 +76,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
if (_contentLength.HasValue) if (_contentLength.HasValue)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths); KestrelBadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths);
} }
if (!Utf8Parser.TryParse(value, out long parsed, out var consumed) || if (!Utf8Parser.TryParse(value, out long parsed, out var consumed) ||
parsed < 0 || parsed < 0 ||
consumed != value.Length) consumed != value.Length)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value.GetRequestHeaderStringNonNullCharacters(UseLatin1)); KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value.GetRequestHeaderStringNonNullCharacters(UseLatin1));
} }
_contentLength = parsed; _contentLength = parsed;

View File

@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (_consumedBytes > _context.MaxRequestBodySize) if (_consumedBytes > _context.MaxRequestBodySize)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge);
} }
} }

View File

@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
public void HandleRequestHeadersTimeout() public void HandleRequestHeadersTimeout()
{ {
Log.ConnectionBadRequest(ConnectionId, BadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout)); Log.ConnectionBadRequest(ConnectionId, KestrelBadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout));
Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout)); Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout));
} }
@ -1197,7 +1197,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
_currentHeadersStream.OnHeader(name, value); _currentHeadersStream.OnHeader(name, value);
} }
} }
catch (BadHttpRequestException bre) catch (Microsoft.AspNetCore.Http.BadHttpRequestException bre)
{ {
throw new Http2ConnectionErrorException(bre.Message, Http2ErrorCode.PROTOCOL_ERROR); throw new Http2ConnectionErrorException(bre.Message, Http2ErrorCode.PROTOCOL_ERROR);
} }

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
// Note ContentLength or MaxRequestBodySize may be null // Note ContentLength or MaxRequestBodySize may be null
if (_context.RequestHeaders.ContentLength > _context.MaxRequestBodySize) if (_context.RequestHeaders.ContentLength > _context.MaxRequestBodySize)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge);
} }
} }

View File

@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
public void HandleRequestHeadersTimeout() public void HandleRequestHeadersTimeout()
{ {
//Log.ConnectionBadRequest(ConnectionId, BadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout)); //Log.ConnectionBadRequest(ConnectionId, KestrelBadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout));
Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout)); Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout));
} }

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
// Note ContentLength or MaxRequestBodySize may be null // Note ContentLength or MaxRequestBodySize may be null
if (_context.RequestHeaders.ContentLength > _context.MaxRequestBodySize) if (_context.RequestHeaders.ContentLength > _context.MaxRequestBodySize)
{ {
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge); KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge);
} }
} }

View File

@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
base.OnHeader(name, value); base.OnHeader(name, value);
} }
} }
catch (BadHttpRequestException bre) catch (Microsoft.AspNetCore.Http.BadHttpRequestException bre)
{ {
throw new Http3StreamErrorException(bre.Message, Http3ErrorCode.ProtocolError); throw new Http3StreamErrorException(bre.Message, Http3ErrorCode.ProtocolError);
} }
@ -293,7 +293,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
public void HandleRequestHeadersTimeout() public void HandleRequestHeadersTimeout()
{ {
Log.ConnectionBadRequest(ConnectionId, BadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout)); Log.ConnectionBadRequest(ConnectionId, KestrelBadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout));
Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout), Http3ErrorCode.RequestRejected); Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout), Http3ErrorCode.RequestRejected);
} }

View File

@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
// in the string // in the string
if (!StringUtilities.TryGetAsciiString((byte*)state.ToPointer(), output, buffer.Length)) if (!StringUtilities.TryGetAsciiString((byte*)state.ToPointer(), output, buffer.Length))
{ {
BadHttpRequestException.Throw(RequestRejectionReason.InvalidCharactersInHeaderName); KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidCharactersInHeaderName);
} }
} }
} }

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
void NotAllConnectionsClosedGracefully(); void NotAllConnectionsClosedGracefully();
void ConnectionBadRequest(string connectionId, BadHttpRequestException ex); void ConnectionBadRequest(string connectionId, Microsoft.AspNetCore.Http.BadHttpRequestException ex);
void ApplicationError(string connectionId, string traceIdentifier, Exception ex); void ApplicationError(string connectionId, string traceIdentifier, Exception ex);

View File

@ -175,7 +175,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
_notAllConnectionsClosedGracefully(_logger, null); _notAllConnectionsClosedGracefully(_logger, null);
} }
public virtual void ConnectionBadRequest(string connectionId, BadHttpRequestException ex) public virtual void ConnectionBadRequest(string connectionId, Microsoft.AspNetCore.Http.BadHttpRequestException ex)
{ {
_connectionBadRequest(_logger, connectionId, ex.Message, ex); _connectionBadRequest(_logger, connectionId, ex.Message, ex);
} }

View File

@ -0,0 +1,159 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Server.Kestrel.Core
{
internal static class KestrelBadHttpRequestException
{
[StackTraceHidden]
internal static void Throw(RequestRejectionReason reason)
{
throw GetException(reason);
}
[StackTraceHidden]
internal static void Throw(RequestRejectionReason reason, HttpMethod method)
=> throw GetException(reason, method.ToString().ToUpperInvariant());
[MethodImpl(MethodImplOptions.NoInlining)]
#pragma warning disable CS0618 // Type or member is obsolete
internal static BadHttpRequestException GetException(RequestRejectionReason reason)
{
BadHttpRequestException ex;
switch (reason)
{
case RequestRejectionReason.InvalidRequestHeadersNoCRLF:
ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidRequestHeadersNoCRLF, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidRequestLine:
ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidRequestLine, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.MalformedRequestInvalidHeaders:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MalformedRequestInvalidHeaders, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.MultipleContentLengths:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MultipleContentLengths, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.UnexpectedEndOfRequestContent:
ex = new BadHttpRequestException(CoreStrings.BadRequest_UnexpectedEndOfRequestContent, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.BadChunkSuffix:
ex = new BadHttpRequestException(CoreStrings.BadRequest_BadChunkSuffix, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.BadChunkSizeData:
ex = new BadHttpRequestException(CoreStrings.BadRequest_BadChunkSizeData, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.ChunkedRequestIncomplete:
ex = new BadHttpRequestException(CoreStrings.BadRequest_ChunkedRequestIncomplete, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidCharactersInHeaderName:
ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidCharactersInHeaderName, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.RequestLineTooLong:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestLineTooLong, StatusCodes.Status414UriTooLong, reason);
break;
case RequestRejectionReason.HeadersExceedMaxTotalSize:
ex = new BadHttpRequestException(CoreStrings.BadRequest_HeadersExceedMaxTotalSize, StatusCodes.Status431RequestHeaderFieldsTooLarge, reason);
break;
case RequestRejectionReason.TooManyHeaders:
ex = new BadHttpRequestException(CoreStrings.BadRequest_TooManyHeaders, StatusCodes.Status431RequestHeaderFieldsTooLarge, reason);
break;
case RequestRejectionReason.RequestBodyTooLarge:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestBodyTooLarge, StatusCodes.Status413PayloadTooLarge, reason);
break;
case RequestRejectionReason.RequestHeadersTimeout:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestHeadersTimeout, StatusCodes.Status408RequestTimeout, reason);
break;
case RequestRejectionReason.RequestBodyTimeout:
ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestBodyTimeout, StatusCodes.Status408RequestTimeout, reason);
break;
case RequestRejectionReason.OptionsMethodRequired:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MethodNotAllowed, StatusCodes.Status405MethodNotAllowed, reason, HttpMethod.Options);
break;
case RequestRejectionReason.ConnectMethodRequired:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MethodNotAllowed, StatusCodes.Status405MethodNotAllowed, reason, HttpMethod.Connect);
break;
case RequestRejectionReason.MissingHostHeader:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MissingHostHeader, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.MultipleHostHeaders:
ex = new BadHttpRequestException(CoreStrings.BadRequest_MultipleHostHeaders, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidHostHeader:
ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidHostHeader, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.UpgradeRequestCannotHavePayload:
ex = new BadHttpRequestException(CoreStrings.BadRequest_UpgradeRequestCannotHavePayload, StatusCodes.Status400BadRequest, reason);
break;
default:
ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest, reason);
break;
}
return ex;
}
#pragma warning restore CS0618 // Type or member is obsolete
[StackTraceHidden]
internal static void Throw(RequestRejectionReason reason, string detail)
{
throw GetException(reason, detail);
}
[StackTraceHidden]
internal static void Throw(RequestRejectionReason reason, StringValues detail)
{
throw GetException(reason, detail.ToString());
}
#pragma warning disable CS0618 // Type or member is obsolete
[MethodImpl(MethodImplOptions.NoInlining)]
internal static BadHttpRequestException GetException(RequestRejectionReason reason, string detail)
{
BadHttpRequestException ex;
switch (reason)
{
case RequestRejectionReason.TlsOverHttpError:
ex = new BadHttpRequestException(CoreStrings.HttpParserTlsOverHttpError, StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidRequestLine:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidRequestTarget:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidRequestHeader:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidContentLength:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidContentLength_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.UnrecognizedHTTPVersion:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(detail), StatusCodes.Status505HttpVersionNotsupported, reason);
break;
case RequestRejectionReason.FinalTransferCodingNotChunked:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_FinalTransferCodingNotChunked(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.LengthRequired:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_LengthRequired(detail), StatusCodes.Status411LengthRequired, reason);
break;
case RequestRejectionReason.LengthRequiredHttp10:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_LengthRequiredHttp10(detail), StatusCodes.Status400BadRequest, reason);
break;
case RequestRejectionReason.InvalidHostHeader:
ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidHostHeader_Detail(detail), StatusCodes.Status400BadRequest, reason);
break;
default:
ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest, reason);
break;
}
return ex;
}
#pragma warning restore CS0618 // Type or member is obsolete
}
}

View File

@ -127,7 +127,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"{headerLine}\r\n")); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"{headerLine}\r\n"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => _http1Connection.TakeMessageHeaders(readableBuffer, trailers: false, out _consumed, out _examined)); var exception = Assert.Throws<BadHttpRequestException>(() => _http1Connection.TakeMessageHeaders(readableBuffer, trailers: false, out _consumed, out _examined));
#pragma warning restore CS0618 // Type or member is obsolete
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
Assert.Equal(CoreStrings.BadRequest_HeadersExceedMaxTotalSize, exception.Message); Assert.Equal(CoreStrings.BadRequest_HeadersExceedMaxTotalSize, exception.Message);
@ -143,7 +145,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"{headerLines}\r\n")); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"{headerLines}\r\n"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => _http1Connection.TakeMessageHeaders(readableBuffer, trailers: false, out _consumed, out _examined)); var exception = Assert.Throws<BadHttpRequestException>(() => _http1Connection.TakeMessageHeaders(readableBuffer, trailers: false, out _consumed, out _examined));
#pragma warning restore CS0618 // Type or member is obsolete
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
Assert.Equal(CoreStrings.BadRequest_TooManyHeaders, exception.Message); Assert.Equal(CoreStrings.BadRequest_TooManyHeaders, exception.Message);
@ -438,7 +442,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(requestLineBytes); await _application.Output.WriteAsync(requestLineBytes);
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined)); var exception = Assert.Throws<BadHttpRequestException>(() => _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
#pragma warning restore CS0618 // Type or member is obsolete
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
Assert.Equal(CoreStrings.BadRequest_RequestLineTooLong, exception.Message); Assert.Equal(CoreStrings.BadRequest_RequestLineTooLong, exception.Message);
@ -452,7 +458,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"GET {target} HTTP/1.1\r\n")); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"GET {target} HTTP/1.1\r\n"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined)); _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
@ -466,7 +474,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"GET {target} HTTP/1.1\r\n")); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"GET {target} HTTP/1.1\r\n"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined)); _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
@ -482,7 +492,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes(requestLine)); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes(requestLine));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined)); _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
@ -498,7 +510,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"GET {target} HTTP/1.1\r\n")); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"GET {target} HTTP/1.1\r\n"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined)); _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
@ -514,7 +528,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes(requestLine)); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes(requestLine));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined)); _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
@ -529,7 +545,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes(requestLine)); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes(requestLine));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined)); _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
@ -774,7 +792,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"GET /%00 HTTP/1.1\r\n")); await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"GET /%00 HTTP/1.1\r\n"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer; var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined)); _http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
_transport.Input.AdvanceTo(_consumed, _examined); _transport.Input.AdvanceTo(_consumed, _examined);
@ -934,7 +954,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{ {
_http1Connection.HttpVersion = "HTTP/1.0"; _http1Connection.HttpVersion = "HTTP/1.0";
_http1Connection.RequestHeaders[HeaderNames.Host] = "a=b"; _http1Connection.RequestHeaders[HeaderNames.Host] = "a=b";
#pragma warning disable CS0618 // Type or member is obsolete
var ex = Assert.Throws<BadHttpRequestException>(() => _http1Connection.EnsureHostHeaderExists()); var ex = Assert.Throws<BadHttpRequestException>(() => _http1Connection.EnsureHostHeaderExists());
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal(CoreStrings.FormatBadRequest_InvalidHostHeader_Detail("a=b"), ex.Message); Assert.Equal(CoreStrings.FormatBadRequest_InvalidHostHeader_Detail("a=b"), ex.Message);
} }
@ -943,7 +965,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{ {
_http1Connection.HttpVersion = "HTTP/1.1"; _http1Connection.HttpVersion = "HTTP/1.1";
_http1Connection.RequestHeaders[HeaderNames.Host] = "a=b"; _http1Connection.RequestHeaders[HeaderNames.Host] = "a=b";
#pragma warning disable CS0618 // Type or member is obsolete
var ex = Assert.Throws<BadHttpRequestException>(() => _http1Connection.EnsureHostHeaderExists()); var ex = Assert.Throws<BadHttpRequestException>(() => _http1Connection.EnsureHostHeaderExists());
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal(CoreStrings.FormatBadRequest_InvalidHostHeader_Detail("a=b"), ex.Message); Assert.Equal(CoreStrings.FormatBadRequest_InvalidHostHeader_Detail("a=b"), ex.Message);
} }

View File

@ -90,11 +90,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine)); var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine));
var requestHandler = new RequestHandler(); var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(requestLine.EscapeNonPrintable()), exception.Message); Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(requestLine.EscapeNonPrintable()), exception.Message);
Assert.Equal(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode); Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
} }
[Theory] [Theory]
@ -112,11 +114,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine)); var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine));
var requestHandler = new RequestHandler(); var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(method.EscapeNonPrintable() + @" / HTTP/1.1\x0D\x0A"), exception.Message); Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(method.EscapeNonPrintable() + @" / HTTP/1.1\x0D\x0A"), exception.Message);
Assert.Equal(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode); Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
} }
[Theory] [Theory]
@ -134,11 +138,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine)); var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine));
var requestHandler = new RequestHandler(); var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
Assert.Equal(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(httpVersion), exception.Message); Assert.Equal(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(httpVersion), exception.Message);
Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, (exception as BadHttpRequestException).StatusCode); Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, exception.StatusCode);
} }
[Theory] [Theory]
@ -328,7 +334,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(rawHeaders)); var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(rawHeaders));
var requestHandler = new RequestHandler(); var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
{ {
var reader = new SequenceReader<byte>(buffer); var reader = new SequenceReader<byte>(buffer);
parser.ParseHeaders(requestHandler, ref reader); parser.ParseHeaders(requestHandler, ref reader);
@ -352,25 +360,31 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes("GET % HTTP/1.1\r\n")); var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes("GET % HTTP/1.1\r\n"));
var requestHandler = new RequestHandler(); var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() => var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
Assert.Equal("Invalid request line: ''", exception.Message); Assert.Equal("Invalid request line: ''", exception.Message);
Assert.Equal(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode); Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
// Unrecognized HTTP version // Unrecognized HTTP version
buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes("GET / HTTP/1.2\r\n")); buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes("GET / HTTP/1.2\r\n"));
#pragma warning disable CS0618 // Type or member is obsolete
exception = Assert.Throws<BadHttpRequestException>(() => exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
Assert.Equal(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(string.Empty), exception.Message); Assert.Equal(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(string.Empty), exception.Message);
Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, (exception as BadHttpRequestException).StatusCode); Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, exception.StatusCode);
// Invalid request header // Invalid request header
buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes("Header: value\n\r\n")); buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes("Header: value\n\r\n"));
#pragma warning disable CS0618 // Type or member is obsolete
exception = Assert.Throws<BadHttpRequestException>(() => exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
{ {
var reader = new SequenceReader<byte>(buffer); var reader = new SequenceReader<byte>(buffer);
parser.ParseHeaders(requestHandler, ref reader); parser.ParseHeaders(requestHandler, ref reader);
@ -404,7 +418,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var requestHandler = new RequestHandler(); var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var badHttpRequestException = Assert.Throws<BadHttpRequestException>(() => var badHttpRequestException = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
{ {
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined); parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined);
}); });

View File

@ -308,7 +308,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
const string key = "\u00141\u00F3d\017c"; const string key = "\u00141\u00F3d\017c";
var encoding = Encoding.GetEncoding("iso-8859-1"); var encoding = Encoding.GetEncoding("iso-8859-1");
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>( var exception = Assert.Throws<BadHttpRequestException>(
#pragma warning restore CS0618 // Type or member is obsolete
() => headers.Append(encoding.GetBytes(key), Encoding.ASCII.GetBytes("value"))); () => headers.Append(encoding.GetBytes(key), Encoding.ASCII.GetBytes("value")));
Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode); Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
} }

View File

@ -221,7 +221,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Add("g"); input.Add("g");
input.Add("g"); input.Add("g");
#pragma warning disable CS0618 // Type or member is obsolete
await Assert.ThrowsAsync<BadHttpRequestException>(() => task); await Assert.ThrowsAsync<BadHttpRequestException>(() => task);
#pragma warning restore CS0618 // Type or member is obsolete
await body.StopAsync(); await body.StopAsync();
} }
@ -247,7 +249,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Add(i.ToString()); input.Add(i.ToString());
} }
#pragma warning disable CS0618 // Type or member is obsolete
await Assert.ThrowsAsync<BadHttpRequestException>(() => task); await Assert.ThrowsAsync<BadHttpRequestException>(() => task);
#pragma warning restore CS0618 // Type or member is obsolete
await body.StopAsync(); await body.StopAsync();
} }
@ -286,7 +290,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Add("\r"); input.Add("\r");
input.Add("n"); input.Add("n");
#pragma warning disable CS0618 // Type or member is obsolete
await Assert.ThrowsAsync<BadHttpRequestException>(() => task); await Assert.ThrowsAsync<BadHttpRequestException>(() => task);
#pragma warning restore CS0618 // Type or member is obsolete
await body.StopAsync(); await body.StopAsync();
} }
@ -388,7 +394,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Add("012345678\r"); input.Add("012345678\r");
var buffer = new byte[1024]; var buffer = new byte[1024];
#pragma warning disable CS0618 // Type or member is obsolete
var ex = await Assert.ThrowsAsync<BadHttpRequestException>(async () => var ex = await Assert.ThrowsAsync<BadHttpRequestException>(async () =>
#pragma warning restore CS0618 // Type or member is obsolete
await stream.ReadAsync(buffer, 0, buffer.Length)); await stream.ReadAsync(buffer, 0, buffer.Length));
Assert.Equal(CoreStrings.BadRequest_BadChunkSizeData, ex.Message); Assert.Equal(CoreStrings.BadRequest_BadChunkSizeData, ex.Message);
@ -536,7 +544,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{ {
using (var input = new TestInput()) using (var input = new TestInput())
{ {
#pragma warning disable CS0618 // Type or member is obsolete
var ex = Assert.Throws<BadHttpRequestException>(() => var ex = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderTransferEncoding = "chunked, not-chunked" }, input.Http1Connection)); Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderTransferEncoding = "chunked, not-chunked" }, input.Http1Connection));
Assert.Equal(StatusCodes.Status400BadRequest, ex.StatusCode); Assert.Equal(StatusCodes.Status400BadRequest, ex.StatusCode);
@ -553,7 +563,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
using (var input = new TestInput()) using (var input = new TestInput())
{ {
input.Http1Connection.Method = method; input.Http1Connection.Method = method;
#pragma warning disable CS0618 // Type or member is obsolete
var ex = Assert.Throws<BadHttpRequestException>(() => var ex = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders(), input.Http1Connection)); Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders(), input.Http1Connection));
Assert.Equal(StatusCodes.Status411LengthRequired, ex.StatusCode); Assert.Equal(StatusCodes.Status411LengthRequired, ex.StatusCode);
@ -570,7 +582,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
using (var input = new TestInput()) using (var input = new TestInput())
{ {
input.Http1Connection.Method = method; input.Http1Connection.Method = method;
#pragma warning disable CS0618 // Type or member is obsolete
var ex = Assert.Throws<BadHttpRequestException>(() => var ex = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
Http1MessageBody.For(HttpVersion.Http10, new HttpRequestHeaders(), input.Http1Connection)); Http1MessageBody.For(HttpVersion.Http10, new HttpRequestHeaders(), input.Http1Connection));
Assert.Equal(StatusCodes.Status400BadRequest, ex.StatusCode); Assert.Equal(StatusCodes.Status400BadRequest, ex.StatusCode);
@ -733,7 +747,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
// Time out on the next read // Time out on the next read
input.Http1Connection.SendTimeoutResponse(); input.Http1Connection.SendTimeoutResponse();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = await Assert.ThrowsAsync<BadHttpRequestException>(async () => await body.ReadAsync()); var exception = await Assert.ThrowsAsync<BadHttpRequestException>(async () => await body.ReadAsync());
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal(StatusCodes.Status408RequestTimeout, exception.StatusCode); Assert.Equal(StatusCodes.Status408RequestTimeout, exception.StatusCode);
await body.StopAsync(); await body.StopAsync();
@ -768,7 +784,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
mockLogger.Verify(logger => logger.ConnectionBadRequest( mockLogger.Verify(logger => logger.ConnectionBadRequest(
It.IsAny<string>(), It.IsAny<string>(),
#pragma warning disable CS0618 // Type or member is obsolete
It.Is<BadHttpRequestException>(ex => ex.Reason == RequestRejectionReason.RequestBodyTimeout))); It.Is<BadHttpRequestException>(ex => ex.Reason == RequestRejectionReason.RequestBodyTimeout)));
#pragma warning restore CS0618 // Type or member is obsolete
await body.StopAsync(); await body.StopAsync();
} }
@ -796,7 +814,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())
{ {
#pragma warning disable CS0618 // Type or member is obsolete
var exception = await Assert.ThrowsAsync<BadHttpRequestException>(() => stream.CopyToAsync(ms)); var exception = await Assert.ThrowsAsync<BadHttpRequestException>(() => stream.CopyToAsync(ms));
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal(StatusCodes.Status408RequestTimeout, exception.StatusCode); Assert.Equal(StatusCodes.Status408RequestTimeout, exception.StatusCode);
} }
@ -1206,10 +1226,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Application.Output.Complete(); input.Application.Output.Complete();
#pragma warning disable CS0618 // Type or member is obsolete
var ex0 = Assert.Throws<BadHttpRequestException>(() => reader.TryRead(out var readResult)); var ex0 = Assert.Throws<BadHttpRequestException>(() => reader.TryRead(out var readResult));
var ex1 = Assert.Throws<BadHttpRequestException>(() => reader.TryRead(out var readResult)); var ex1 = Assert.Throws<BadHttpRequestException>(() => reader.TryRead(out var readResult));
var ex2 = await Assert.ThrowsAsync<BadHttpRequestException>(() => reader.ReadAsync().AsTask()); var ex2 = await Assert.ThrowsAsync<BadHttpRequestException>(() => reader.ReadAsync().AsTask());
var ex3 = await Assert.ThrowsAsync<BadHttpRequestException>(() => reader.ReadAsync().AsTask()); var ex3 = await Assert.ThrowsAsync<BadHttpRequestException>(() => reader.ReadAsync().AsTask());
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal(RequestRejectionReason.UnexpectedEndOfRequestContent, ex0.Reason); Assert.Equal(RequestRejectionReason.UnexpectedEndOfRequestContent, ex0.Reason);
Assert.Equal(RequestRejectionReason.UnexpectedEndOfRequestContent, ex1.Reason); Assert.Equal(RequestRejectionReason.UnexpectedEndOfRequestContent, ex1.Reason);
@ -1231,10 +1253,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Application.Output.Complete(); input.Application.Output.Complete();
#pragma warning disable CS0618 // Type or member is obsolete
var ex0 = Assert.Throws<BadHttpRequestException>(() => reader.TryRead(out var readResult)); var ex0 = Assert.Throws<BadHttpRequestException>(() => reader.TryRead(out var readResult));
var ex1 = Assert.Throws<BadHttpRequestException>(() => reader.TryRead(out var readResult)); var ex1 = Assert.Throws<BadHttpRequestException>(() => reader.TryRead(out var readResult));
var ex2 = await Assert.ThrowsAsync<BadHttpRequestException>(() => reader.ReadAsync().AsTask()); var ex2 = await Assert.ThrowsAsync<BadHttpRequestException>(() => reader.ReadAsync().AsTask());
var ex3 = await Assert.ThrowsAsync<BadHttpRequestException>(() => reader.ReadAsync().AsTask()); var ex3 = await Assert.ThrowsAsync<BadHttpRequestException>(() => reader.ReadAsync().AsTask());
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal(RequestRejectionReason.UnexpectedEndOfRequestContent, ex0.Reason); Assert.Equal(RequestRejectionReason.UnexpectedEndOfRequestContent, ex0.Reason);
Assert.Equal(RequestRejectionReason.UnexpectedEndOfRequestContent, ex1.Reason); Assert.Equal(RequestRejectionReason.UnexpectedEndOfRequestContent, ex1.Reason);

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Net.Http.HPack; using System.Net.Http.HPack;
using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -16,7 +15,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
public void ApplicationError(string connectionId, string requestId, Exception ex) { } public void ApplicationError(string connectionId, string requestId, Exception ex) { }
public IDisposable BeginScope<TState>(TState state) => null; public IDisposable BeginScope<TState>(TState state) => null;
public void ConnectionAccepted(string connectionId) { } public void ConnectionAccepted(string connectionId) { }
public void ConnectionBadRequest(string connectionId, BadHttpRequestException ex) { } public void ConnectionBadRequest(string connectionId, Microsoft.AspNetCore.Http.BadHttpRequestException ex) { }
public void ConnectionDisconnect(string connectionId) { } public void ConnectionDisconnect(string connectionId) { }
public void ConnectionError(string connectionId, Exception ex) { } public void ConnectionError(string connectionId, Exception ex) { }
public void ConnectionHeadResponseBodyWrite(string connectionId, long count) { } public void ConnectionHeadResponseBodyWrite(string connectionId, long count) { }

View File

@ -36,7 +36,7 @@ namespace SampleApp
{ {
await next.Invoke(); await next.Invoke();
} }
catch (BadHttpRequestException ex) when (ex.StatusCode == StatusCodes.Status413RequestEntityTooLarge) { } catch (Microsoft.AspNetCore.Http.BadHttpRequestException ex) when (ex.StatusCode == StatusCodes.Status413RequestEntityTooLarge) { }
}); });
app.Run(async context => app.Run(async context =>

View File

@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Testing
_trace2.NotAllConnectionsClosedGracefully(); _trace2.NotAllConnectionsClosedGracefully();
} }
public void ConnectionBadRequest(string connectionId, BadHttpRequestException ex) public void ConnectionBadRequest(string connectionId, Microsoft.AspNetCore.Http.BadHttpRequestException ex)
{ {
_trace1.ConnectionBadRequest(connectionId, ex); _trace1.ConnectionBadRequest(connectionId, ex);
_trace2.ConnectionBadRequest(connectionId, ex); _trace2.ConnectionBadRequest(connectionId, ex);

View File

@ -12,6 +12,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.Logging.Testing;
using Moq; using Moq;
using Xunit; using Xunit;
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
@ -191,6 +192,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
private async Task TestBadRequest(string request, string expectedResponseStatusCode, string expectedExceptionMessage, string expectedAllowHeader = null) private async Task TestBadRequest(string request, string expectedResponseStatusCode, string expectedExceptionMessage, string expectedAllowHeader = null)
{ {
BadHttpRequestException loggedException = null; BadHttpRequestException loggedException = null;
var mockKestrelTrace = new Mock<IKestrelTrace>(); var mockKestrelTrace = new Mock<IKestrelTrace>();
mockKestrelTrace mockKestrelTrace
.Setup(trace => trace.IsEnabled(LogLevel.Information)) .Setup(trace => trace.IsEnabled(LogLevel.Information))

View File

@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.Logging.Testing;
using Xunit; using Xunit;
using BadHttpRequestException = Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
@ -842,7 +843,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
var testContext = new TestServiceContext(LoggerFactory); var testContext = new TestServiceContext(LoggerFactory);
var readStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); var readStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
#pragma warning disable CS0618 // Type or member is obsolete
var exTcs = new TaskCompletionSource<BadHttpRequestException>(TaskCreationOptions.RunContinuationsAsynchronously); var exTcs = new TaskCompletionSource<BadHttpRequestException>(TaskCreationOptions.RunContinuationsAsynchronously);
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async httpContext => await using (var server = new TestServer(async httpContext =>
{ {
@ -853,7 +856,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
await readTask; await readTask;
} }
#pragma warning disable CS0618 // Type or member is obsolete
catch (BadHttpRequestException badRequestEx) catch (BadHttpRequestException badRequestEx)
#pragma warning restore CS0618 // Type or member is obsolete
{ {
exTcs.TrySetResult(badRequestEx); exTcs.TrySetResult(badRequestEx);
} }

View File

@ -1569,7 +1569,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
[Fact] [Fact]
public async Task MaxRequestBodySize_ContentLengthOver_413() public async Task MaxRequestBodySize_ContentLengthOver_413()
{ {
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException exception = null; BadHttpRequestException exception = null;
#pragma warning restore CS0618 // Type or member is obsolete
_serviceContext.ServerOptions.Limits.MaxRequestBodySize = 10; _serviceContext.ServerOptions.Limits.MaxRequestBodySize = 10;
var headers = new[] var headers = new[]
{ {
@ -1580,7 +1582,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
}; };
await InitializeConnectionAsync(async context => await InitializeConnectionAsync(async context =>
{ {
#pragma warning disable CS0618 // Type or member is obsolete
exception = await Assert.ThrowsAsync<BadHttpRequestException>(async () => exception = await Assert.ThrowsAsync<BadHttpRequestException>(async () =>
#pragma warning restore CS0618 // Type or member is obsolete
{ {
var buffer = new byte[100]; var buffer = new byte[100];
while (await context.Request.Body.ReadAsync(buffer, 0, buffer.Length) > 0) { } while (await context.Request.Body.ReadAsync(buffer, 0, buffer.Length) > 0) { }
@ -1651,7 +1655,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
[Fact] [Fact]
public async Task MaxRequestBodySize_NoContentLength_Over_413() public async Task MaxRequestBodySize_NoContentLength_Over_413()
{ {
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException exception = null; BadHttpRequestException exception = null;
#pragma warning restore CS0618 // Type or member is obsolete
_serviceContext.ServerOptions.Limits.MaxRequestBodySize = 10; _serviceContext.ServerOptions.Limits.MaxRequestBodySize = 10;
var headers = new[] var headers = new[]
{ {
@ -1661,7 +1667,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
}; };
await InitializeConnectionAsync(async context => await InitializeConnectionAsync(async context =>
{ {
#pragma warning disable CS0618 // Type or member is obsolete
exception = await Assert.ThrowsAsync<BadHttpRequestException>(async () => exception = await Assert.ThrowsAsync<BadHttpRequestException>(async () =>
#pragma warning restore CS0618 // Type or member is obsolete
{ {
var buffer = new byte[100]; var buffer = new byte[100];
while (await context.Request.Body.ReadAsync(buffer, 0, buffer.Length) > 0) { } while (await context.Request.Body.ReadAsync(buffer, 0, buffer.Length) > 0) { }
@ -1699,7 +1707,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
[InlineData(false)] [InlineData(false)]
public async Task MaxRequestBodySize_AppCanLowerLimit(bool includeContentLength) public async Task MaxRequestBodySize_AppCanLowerLimit(bool includeContentLength)
{ {
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException exception = null; BadHttpRequestException exception = null;
#pragma warning restore CS0618 // Type or member is obsolete
_serviceContext.ServerOptions.Limits.MaxRequestBodySize = 20; _serviceContext.ServerOptions.Limits.MaxRequestBodySize = 20;
var headers = new[] var headers = new[]
{ {
@ -1718,7 +1728,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{ {
Assert.False(context.Features.Get<IHttpMaxRequestBodySizeFeature>().IsReadOnly); Assert.False(context.Features.Get<IHttpMaxRequestBodySizeFeature>().IsReadOnly);
context.Features.Get<IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize = 17; context.Features.Get<IHttpMaxRequestBodySizeFeature>().MaxRequestBodySize = 17;
#pragma warning disable CS0618 // Type or member is obsolete
exception = await Assert.ThrowsAsync<BadHttpRequestException>(async () => exception = await Assert.ThrowsAsync<BadHttpRequestException>(async () =>
#pragma warning restore CS0618 // Type or member is obsolete
{ {
var buffer = new byte[100]; var buffer = new byte[100];
while (await context.Request.Body.ReadAsync(buffer, 0, buffer.Length) > 0) { } while (await context.Request.Body.ReadAsync(buffer, 0, buffer.Length) > 0) { }

View File

@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
_mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.RequestHeaders), Times.Once); _mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.RequestHeaders), Times.Once);
await WaitForConnectionErrorAsync<BadHttpRequestException>( await WaitForConnectionErrorAsync<Microsoft.AspNetCore.Http.BadHttpRequestException>(
ignoreNonGoAwayFrames: false, ignoreNonGoAwayFrames: false,
expectedLastStreamId: int.MaxValue, expectedLastStreamId: int.MaxValue,
Http2ErrorCode.INTERNAL_ERROR, Http2ErrorCode.INTERNAL_ERROR,

View File

@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport
using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.Logging.Testing;
using Xunit; using Xunit;
using BadHttpRequestException = Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
@ -22,12 +23,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
// 4 GiB // 4 GiB
var globalMaxRequestBodySize = 0x100000000; var globalMaxRequestBodySize = 0x100000000;
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException requestRejectedEx = null; BadHttpRequestException requestRejectedEx = null;
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async context => await using (var server = new TestServer(async context =>
{ {
var buffer = new byte[1]; var buffer = new byte[1];
#pragma warning disable CS0618 // Type or member is obsolete
requestRejectedEx = await Assert.ThrowsAsync<BadHttpRequestException>( requestRejectedEx = await Assert.ThrowsAsync<BadHttpRequestException>(
#pragma warning restore CS0618 // Type or member is obsolete
async () => await context.Request.Body.ReadAsync(buffer, 0, 1)); async () => await context.Request.Body.ReadAsync(buffer, 0, 1));
throw requestRejectedEx; throw requestRejectedEx;
}, },
@ -62,7 +67,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
var globalMaxRequestBodySize = 0x200000000; var globalMaxRequestBodySize = 0x200000000;
// 4 GiB // 4 GiB
var perRequestMaxRequestBodySize = 0x100000000; var perRequestMaxRequestBodySize = 0x100000000;
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException requestRejectedEx = null; BadHttpRequestException requestRejectedEx = null;
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async context => await using (var server = new TestServer(async context =>
{ {
@ -73,7 +80,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
feature.MaxRequestBodySize = perRequestMaxRequestBodySize; feature.MaxRequestBodySize = perRequestMaxRequestBodySize;
var buffer = new byte[1]; var buffer = new byte[1];
#pragma warning disable CS0618 // Type or member is obsolete
requestRejectedEx = await Assert.ThrowsAsync<BadHttpRequestException>( requestRejectedEx = await Assert.ThrowsAsync<BadHttpRequestException>(
#pragma warning restore CS0618 // Type or member is obsolete
async () => await context.Request.Body.ReadAsync(buffer, 0, 1)); async () => await context.Request.Body.ReadAsync(buffer, 0, 1));
throw requestRejectedEx; throw requestRejectedEx;
}, },
@ -258,16 +267,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
[Fact] [Fact]
public async Task EveryReadFailsWhenContentLengthHeaderExceedsGlobalLimit() public async Task EveryReadFailsWhenContentLengthHeaderExceedsGlobalLimit()
{ {
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException requestRejectedEx1 = null; BadHttpRequestException requestRejectedEx1 = null;
BadHttpRequestException requestRejectedEx2 = null; BadHttpRequestException requestRejectedEx2 = null;
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async context => await using (var server = new TestServer(async context =>
{ {
var buffer = new byte[1]; var buffer = new byte[1];
#pragma warning disable CS0618 // Type or member is obsolete
requestRejectedEx1 = await Assert.ThrowsAsync<BadHttpRequestException>( requestRejectedEx1 = await Assert.ThrowsAsync<BadHttpRequestException>(
async () => await context.Request.Body.ReadAsync(buffer, 0, 1)); async () => await context.Request.Body.ReadAsync(buffer, 0, 1));
requestRejectedEx2 = await Assert.ThrowsAsync<BadHttpRequestException>( requestRejectedEx2 = await Assert.ThrowsAsync<BadHttpRequestException>(
async () => await context.Request.Body.ReadAsync(buffer, 0, 1)); async () => await context.Request.Body.ReadAsync(buffer, 0, 1));
#pragma warning restore CS0618 // Type or member is obsolete
throw requestRejectedEx2; throw requestRejectedEx2;
}, },
new TestServiceContext(LoggerFactory) { ServerOptions = { Limits = { MaxRequestBodySize = 0 } } })) new TestServiceContext(LoggerFactory) { ServerOptions = { Limits = { MaxRequestBodySize = 0 } } }))
@ -301,12 +314,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
var chunkedPayload = "5;random chunk extension\r\nHello\r\n6\r\n World\r\n0\r\n\r\n"; var chunkedPayload = "5;random chunk extension\r\nHello\r\n6\r\n World\r\n0\r\n\r\n";
var globalMaxRequestBodySize = chunkedPayload.Length - 1; var globalMaxRequestBodySize = chunkedPayload.Length - 1;
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException requestRejectedEx = null; BadHttpRequestException requestRejectedEx = null;
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async context => await using (var server = new TestServer(async context =>
{ {
var buffer = new byte[11]; var buffer = new byte[11];
#pragma warning disable CS0618 // Type or member is obsolete
requestRejectedEx = await Assert.ThrowsAsync<BadHttpRequestException>(async () => requestRejectedEx = await Assert.ThrowsAsync<BadHttpRequestException>(async () =>
#pragma warning restore CS0618 // Type or member is obsolete
{ {
var count = 0; var count = 0;
do do
@ -389,7 +406,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
var chunkedPayload = "5;random chunk extension\r\nHello\r\n6\r\n World\r\n0\r\n\r\n"; var chunkedPayload = "5;random chunk extension\r\nHello\r\n6\r\n World\r\n0\r\n\r\n";
var globalMaxRequestBodySize = chunkedPayload.Length - 1; var globalMaxRequestBodySize = chunkedPayload.Length - 1;
var firstRequest = true; var firstRequest = true;
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException requestRejectedEx = null; BadHttpRequestException requestRejectedEx = null;
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async context => await using (var server = new TestServer(async context =>
{ {
@ -411,7 +430,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
else else
{ {
#pragma warning disable CS0618 // Type or member is obsolete
requestRejectedEx = await Assert.ThrowsAsync<BadHttpRequestException>(async () => requestRejectedEx = await Assert.ThrowsAsync<BadHttpRequestException>(async () =>
#pragma warning restore CS0618 // Type or member is obsolete
{ {
do do
{ {
@ -457,16 +478,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
[Fact] [Fact]
public async Task EveryReadFailsWhenChunkedPayloadExceedsGlobalLimit() public async Task EveryReadFailsWhenChunkedPayloadExceedsGlobalLimit()
{ {
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException requestRejectedEx1 = null; BadHttpRequestException requestRejectedEx1 = null;
BadHttpRequestException requestRejectedEx2 = null; BadHttpRequestException requestRejectedEx2 = null;
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async context => await using (var server = new TestServer(async context =>
{ {
var buffer = new byte[1]; var buffer = new byte[1];
#pragma warning disable CS0618 // Type or member is obsolete
requestRejectedEx1 = await Assert.ThrowsAsync<BadHttpRequestException>( requestRejectedEx1 = await Assert.ThrowsAsync<BadHttpRequestException>(
async () => await context.Request.Body.ReadAsync(buffer, 0, 1)); async () => await context.Request.Body.ReadAsync(buffer, 0, 1));
requestRejectedEx2 = await Assert.ThrowsAsync<BadHttpRequestException>( requestRejectedEx2 = await Assert.ThrowsAsync<BadHttpRequestException>(
async () => await context.Request.Body.ReadAsync(buffer, 0, 1)); async () => await context.Request.Body.ReadAsync(buffer, 0, 1));
#pragma warning restore CS0618 // Type or member is obsolete
throw requestRejectedEx2; throw requestRejectedEx2;
}, },
new TestServiceContext(LoggerFactory) { ServerOptions = { Limits = { MaxRequestBodySize = 0 } } })) new TestServiceContext(LoggerFactory) { ServerOptions = { Limits = { MaxRequestBodySize = 0 } } }))

View File

@ -163,7 +163,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
await readTask; await readTask;
} }
catch (BadHttpRequestException ex) when (ex.StatusCode == 408) catch (Microsoft.AspNetCore.Http.BadHttpRequestException ex) when (ex.StatusCode == 408)
{ {
exceptionSwallowedTcs.SetResult(null); exceptionSwallowedTcs.SetResult(null);
} }

View File

@ -24,6 +24,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.Logging.Testing;
using Moq; using Moq;
using Xunit; using Xunit;
using BadHttpRequestException = Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException;
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
@ -288,7 +289,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
await context.Request.Body.ReadAsync(new byte[1], 0, 1); await context.Request.Body.ReadAsync(new byte[1], 0, 1);
} }
catch (BadHttpRequestException) catch (Microsoft.AspNetCore.Http.BadHttpRequestException)
{ {
} }
}, },
@ -403,11 +404,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
[Fact] [Fact]
public async Task NoErrorResponseSentWhenAppSwallowsBadRequestException() public async Task NoErrorResponseSentWhenAppSwallowsBadRequestException()
{ {
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException readException = null; BadHttpRequestException readException = null;
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async httpContext => await using (var server = new TestServer(async httpContext =>
{ {
#pragma warning disable CS0618 // Type or member is obsolete
readException = await Assert.ThrowsAsync<BadHttpRequestException>( readException = await Assert.ThrowsAsync<BadHttpRequestException>(
#pragma warning restore CS0618 // Type or member is obsolete
async () => await httpContext.Request.Body.ReadAsync(new byte[1], 0, 1)); async () => await httpContext.Request.Body.ReadAsync(new byte[1], 0, 1));
}, new TestServiceContext(LoggerFactory))) }, new TestServiceContext(LoggerFactory)))
{ {
@ -430,8 +435,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
Assert.NotNull(readException); Assert.NotNull(readException);
#pragma warning disable CS0618 // Type or member is obsolete
Assert.Contains(TestSink.Writes, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException Assert.Contains(TestSink.Writes, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest); && ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
#pragma warning restore CS0618 // Type or member is obsolete
} }
[Fact] [Fact]
@ -1265,7 +1272,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
await httpContext.Request.Body.ReadAsync(new byte[1], 0, 1); await httpContext.Request.Body.ReadAsync(new byte[1], 0, 1);
} }
catch (BadHttpRequestException ex) catch (Microsoft.AspNetCore.Http.BadHttpRequestException ex)
{ {
expectedResponse = ex.Message; expectedResponse = ex.Message;
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest; httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
@ -1749,8 +1756,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
} }
#pragma warning disable CS0618 // Type or member is obsolete
Assert.Contains(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException Assert.Contains(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest); && ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
#pragma warning restore CS0618 // Type or member is obsolete
} }
[Fact] [Fact]
@ -1801,8 +1810,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{ {
while (TestApplicationErrorLogger.Messages.TryDequeue(out var message)) while (TestApplicationErrorLogger.Messages.TryDequeue(out var message))
{ {
#pragma warning disable CS0618 // Type or member is obsolete
if (message.EventId.Id == 17 && message.LogLevel <= LogLevel.Debug && message.Exception is BadHttpRequestException if (message.EventId.Id == 17 && message.LogLevel <= LogLevel.Debug && message.Exception is BadHttpRequestException
&& ((BadHttpRequestException)message.Exception).StatusCode == StatusCodes.Status400BadRequest) && ((BadHttpRequestException)message.Exception).StatusCode == StatusCodes.Status400BadRequest)
#pragma warning restore CS0618 // Type or member is obsolete
{ {
foundMessage = true; foundMessage = true;
break; break;
@ -1862,8 +1873,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
} }
} }
#pragma warning disable CS0618 // Type or member is obsolete
Assert.Contains(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException Assert.Contains(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest); && ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
#pragma warning restore CS0618 // Type or member is obsolete
} }
[Fact] [Fact]
@ -4117,8 +4130,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
if (sendMalformedRequest) if (sendMalformedRequest)
{ {
#pragma warning disable CS0618 // Type or member is obsolete
Assert.Contains(testSink.Writes, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException Assert.Contains(testSink.Writes, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest); && ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
#pragma warning restore CS0618 // Type or member is obsolete
} }
else else
{ {