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
{
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
{
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
{
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() { }
public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
internal BadHttpRequestException() : base (default(string), default(int)) { }
public new int StatusCode { get { throw null; } }
}
public static partial class HttpContextExtensions
{

View File

@ -1,44 +1,24 @@
// 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
{
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)
: base(message)
internal BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason)
: base(message, statusCode)
{
StatusCode = statusCode;
Reason = reason;
}
public int StatusCode { get; }
public new int StatusCode { get => base.StatusCode; }
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)
{
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge);
IISBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge);
}
var result = await _bodyInputPipe.Writer.FlushAsync();

View File

@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
_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);
}

View File

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

View File

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

View File

@ -62,10 +62,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel
}
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() { }
public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
internal BadHttpRequestException() : base (default(string), default(int)) { }
public new int StatusCode { get { throw null; } }
}
public partial class Http2Limits
{

View File

@ -1,26 +1,23 @@
// 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.IO;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
using System;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.Extensions.Primitives;
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)
{ }
private BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason, HttpMethod? requiredMethod)
: base(message)
internal BadHttpRequestException(string message, int statusCode, RequestRejectionReason reason, HttpMethod? requiredMethod)
: base(message, statusCode)
{
StatusCode = statusCode;
Reason = reason;
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 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)
{
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
}
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".
BadHttpRequestException.Throw(RequestRejectionReason.BadChunkSizeData);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.BadChunkSizeData);
}
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
{
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);
}
BadHttpRequestException.Throw(RequestRejectionReason.BadChunkSizeData);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.BadChunkSizeData);
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))
{
// We read the maximum allowed but didn't complete the start line.
BadHttpRequestException.Throw(RequestRejectionReason.RequestLineTooLong);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestLineTooLong);
}
return true;
@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (!result)
{
// We read the maximum allowed but didn't complete the headers.
BadHttpRequestException.Throw(RequestRejectionReason.HeadersExceedMaxTotalSize);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.HeadersExceedMaxTotalSize);
}
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).
if (method != HttpMethod.Connect)
{
BadHttpRequestException.Throw(RequestRejectionReason.ConnectMethodRequired);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.ConnectMethodRequired);
}
// 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).
if (method != HttpMethod.Options)
{
BadHttpRequestException.Throw(RequestRejectionReason.OptionsMethodRequired);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.OptionsMethodRequired);
}
RawTarget = Asterisk;
@ -555,11 +555,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{
return;
}
BadHttpRequestException.Throw(RequestRejectionReason.MissingHostHeader);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MissingHostHeader);
}
else if (hostCount > 1)
{
BadHttpRequestException.Throw(RequestRejectionReason.MultipleHostHeaders);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MultipleHostHeaders);
}
else if (_requestTargetForm != HttpRequestTarget.OriginForm)
{
@ -568,7 +569,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
}
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)
{
BadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText);
}
}
else if (_requestTargetForm == HttpRequestTarget.AbsoluteForm)
@ -595,14 +596,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (!_absoluteRequestTarget.IsDefaultPort
|| hostText != _absoluteRequestTarget.Authority + ":" + _absoluteRequestTarget.Port.ToString(CultureInfo.InvariantCulture))
{
BadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, hostText);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidHostHeader, 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)
{
BadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders);
}
throw;
}
@ -672,10 +673,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
endConnection = true;
return true;
case RequestProcessingStatus.ParsingRequestLine:
BadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestLine);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestLine);
break;
case RequestProcessingStatus.ParsingHeaders:
BadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MalformedRequestInvalidHeaders);
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
// a 408 response.
BadHttpRequestException.Throw(RequestRejectionReason.RequestHeadersTimeout);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestHeadersTimeout);
}
endConnection = false;

View File

@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// which is unknown to StartTimingReadAsync.
if (_context.RequestTimedOut)
{
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
}
try
@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (_context.RequestTimedOut)
{
ResetReadingState();
BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout);
}
if (_readResult.IsCompleted)
@ -234,7 +234,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{
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
{
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
internal abstract class Http1MessageBody : MessageBody
{
protected readonly Http1Connection _context;
@ -31,7 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// closing the connection without a response as expected.
_context.OnInputOrOutputCompleted();
BadHttpRequestException.Throw(RequestRejectionReason.UnexpectedEndOfRequestContent);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.UnexpectedEndOfRequestContent);
}
public abstract bool TryReadInternal(out ReadResult readResult);
@ -87,7 +89,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
AdvanceTo(result.Buffer.End);
} while (!result.IsCompleted);
}
catch (BadHttpRequestException ex)
catch (Microsoft.AspNetCore.Http.BadHttpRequestException 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))
{
BadHttpRequestException.Throw(RequestRejectionReason.UpgradeRequestCannotHavePayload);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.UpgradeRequestCannotHavePayload);
}
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.
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
@ -175,7 +177,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
if (context.Method == HttpMethod.Post || context.Method == HttpMethod.Put)
{
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.

View File

@ -11,6 +11,8 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
public class HttpParser<TRequestHandler> : IHttpParser<TRequestHandler> where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler
{
private readonly bool _showErrorDetails;
@ -225,7 +227,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
Debug.Assert(readAhead == 0 || readAhead == 2);
// Headers don't end in CRLF line.
BadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestHeadersNoCRLF);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidRequestHeadersNoCRLF);
}
var length = 0;
@ -451,7 +454,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
[MethodImpl(MethodImplOptions.NoInlining)]
private unsafe BadHttpRequestException GetInvalidRequestException(RequestRejectionReason reason, byte* detail, int length)
=> BadHttpRequestException.GetException(
=> KestrelBadHttpRequestException.GetException(
reason,
_showErrorDetails
? 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
{
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
internal abstract partial class HttpProtocol : IHttpResponseControl
{
private static readonly byte[] _bytesConnectionClose = Encoding.ASCII.GetBytes("\r\nConnection: close");
@ -513,7 +515,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_requestHeadersParsed++;
if (_requestHeadersParsed > ServerOptions.Limits.MaxRequestHeaderCount)
{
BadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders);
}
HttpRequestHeaders.Append(name, value);
@ -525,7 +527,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_requestHeadersParsed++;
if (_requestHeadersParsed > ServerOptions.Limits.MaxRequestHeaderCount)
{
BadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders);
}
string key = name.GetHeaderName();
@ -1215,9 +1217,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{
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)]
private BadHttpRequestException GetInvalidRequestTargetException(Span<byte> target)
=> BadHttpRequestException.GetException(
=> KestrelBadHttpRequestException.GetException(
RequestRejectionReason.InvalidRequestTarget,
Log.IsEnabled(LogLevel.Information)
? 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))
{
BadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value);
}
return parsed;
@ -76,14 +76,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{
if (_contentLength.HasValue)
{
BadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths);
KestrelBadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths);
}
if (!Utf8Parser.TryParse(value, out long parsed, out var consumed) ||
parsed < 0 ||
consumed != value.Length)
{
BadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value.GetRequestHeaderStringNonNullCharacters(UseLatin1));
KestrelBadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value.GetRequestHeaderStringNonNullCharacters(UseLatin1));
}
_contentLength = parsed;

View File

@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
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()
{
Log.ConnectionBadRequest(ConnectionId, BadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout));
Log.ConnectionBadRequest(ConnectionId, KestrelBadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout));
Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout));
}
@ -1197,7 +1197,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
_currentHeadersStream.OnHeader(name, value);
}
}
catch (BadHttpRequestException bre)
catch (Microsoft.AspNetCore.Http.BadHttpRequestException bre)
{
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
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()
{
//Log.ConnectionBadRequest(ConnectionId, BadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout));
//Log.ConnectionBadRequest(ConnectionId, KestrelBadHttpRequestException.GetException(RequestRejectionReason.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
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);
}
}
catch (BadHttpRequestException bre)
catch (Microsoft.AspNetCore.Http.BadHttpRequestException bre)
{
throw new Http3StreamErrorException(bre.Message, Http3ErrorCode.ProtocolError);
}
@ -293,7 +293,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
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);
}

View File

@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
// in the string
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 ConnectionBadRequest(string connectionId, BadHttpRequestException ex);
void ConnectionBadRequest(string connectionId, Microsoft.AspNetCore.Http.BadHttpRequestException 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);
}
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);
}

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"));
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));
#pragma warning restore CS0618 // Type or member is obsolete
_transport.Input.AdvanceTo(_consumed, _examined);
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"));
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));
#pragma warning restore CS0618 // Type or member is obsolete
_transport.Input.AdvanceTo(_consumed, _examined);
Assert.Equal(CoreStrings.BadRequest_TooManyHeaders, exception.Message);
@ -438,7 +442,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await _application.Output.WriteAsync(requestLineBytes);
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));
#pragma warning restore CS0618 // Type or member is obsolete
_transport.Input.AdvanceTo(_consumed, _examined);
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"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _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"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _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));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _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"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _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));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _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));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _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"));
var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
_http1Connection.TakeStartLine(readableBuffer, out _consumed, out _examined));
_transport.Input.AdvanceTo(_consumed, _examined);
@ -934,7 +954,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{
_http1Connection.HttpVersion = "HTTP/1.0";
_http1Connection.RequestHeaders[HeaderNames.Host] = "a=b";
#pragma warning disable CS0618 // Type or member is obsolete
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);
}
@ -943,7 +965,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{
_http1Connection.HttpVersion = "HTTP/1.1";
_http1Connection.RequestHeaders[HeaderNames.Host] = "a=b";
#pragma warning disable CS0618 // Type or member is obsolete
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);
}

View File

@ -90,11 +90,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine));
var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
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]
@ -112,11 +114,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine));
var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
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(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode);
Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
}
[Theory]
@ -134,11 +138,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(requestLine));
var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
Assert.Equal(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(httpVersion), exception.Message);
Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, (exception as BadHttpRequestException).StatusCode);
Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, exception.StatusCode);
}
[Theory]
@ -328,7 +334,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var buffer = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes(rawHeaders));
var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
{
var reader = new SequenceReader<byte>(buffer);
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 requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
Assert.Equal("Invalid request line: ''", exception.Message);
Assert.Equal(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode);
Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
// Unrecognized HTTP version
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>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
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
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>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
{
var reader = new SequenceReader<byte>(buffer);
parser.ParseHeaders(requestHandler, ref reader);
@ -404,7 +418,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var requestHandler = new RequestHandler();
#pragma warning disable CS0618 // Type or member is obsolete
var badHttpRequestException = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
{
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";
var encoding = Encoding.GetEncoding("iso-8859-1");
#pragma warning disable CS0618 // Type or member is obsolete
var exception = Assert.Throws<BadHttpRequestException>(
#pragma warning restore CS0618 // Type or member is obsolete
() => headers.Append(encoding.GetBytes(key), Encoding.ASCII.GetBytes("value")));
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");
#pragma warning disable CS0618 // Type or member is obsolete
await Assert.ThrowsAsync<BadHttpRequestException>(() => task);
#pragma warning restore CS0618 // Type or member is obsolete
await body.StopAsync();
}
@ -247,7 +249,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Add(i.ToString());
}
#pragma warning disable CS0618 // Type or member is obsolete
await Assert.ThrowsAsync<BadHttpRequestException>(() => task);
#pragma warning restore CS0618 // Type or member is obsolete
await body.StopAsync();
}
@ -286,7 +290,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Add("\r");
input.Add("n");
#pragma warning disable CS0618 // Type or member is obsolete
await Assert.ThrowsAsync<BadHttpRequestException>(() => task);
#pragma warning restore CS0618 // Type or member is obsolete
await body.StopAsync();
}
@ -388,7 +394,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Add("012345678\r");
var buffer = new byte[1024];
#pragma warning disable CS0618 // Type or member is obsolete
var ex = await Assert.ThrowsAsync<BadHttpRequestException>(async () =>
#pragma warning restore CS0618 // Type or member is obsolete
await stream.ReadAsync(buffer, 0, buffer.Length));
Assert.Equal(CoreStrings.BadRequest_BadChunkSizeData, ex.Message);
@ -536,7 +544,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
{
using (var input = new TestInput())
{
#pragma warning disable CS0618 // Type or member is obsolete
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));
Assert.Equal(StatusCodes.Status400BadRequest, ex.StatusCode);
@ -553,7 +563,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
using (var input = new TestInput())
{
input.Http1Connection.Method = method;
#pragma warning disable CS0618 // Type or member is obsolete
var ex = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders(), input.Http1Connection));
Assert.Equal(StatusCodes.Status411LengthRequired, ex.StatusCode);
@ -570,7 +582,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
using (var input = new TestInput())
{
input.Http1Connection.Method = method;
#pragma warning disable CS0618 // Type or member is obsolete
var ex = Assert.Throws<BadHttpRequestException>(() =>
#pragma warning restore CS0618 // Type or member is obsolete
Http1MessageBody.For(HttpVersion.Http10, new HttpRequestHeaders(), input.Http1Connection));
Assert.Equal(StatusCodes.Status400BadRequest, ex.StatusCode);
@ -733,7 +747,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
// Time out on the next read
input.Http1Connection.SendTimeoutResponse();
#pragma warning disable CS0618 // Type or member is obsolete
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);
await body.StopAsync();
@ -768,7 +784,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
mockLogger.Verify(logger => logger.ConnectionBadRequest(
It.IsAny<string>(),
#pragma warning disable CS0618 // Type or member is obsolete
It.Is<BadHttpRequestException>(ex => ex.Reason == RequestRejectionReason.RequestBodyTimeout)));
#pragma warning restore CS0618 // Type or member is obsolete
await body.StopAsync();
}
@ -796,7 +814,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
using (var ms = new MemoryStream())
{
#pragma warning disable CS0618 // Type or member is obsolete
var exception = await Assert.ThrowsAsync<BadHttpRequestException>(() => stream.CopyToAsync(ms));
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal(StatusCodes.Status408RequestTimeout, exception.StatusCode);
}
@ -1206,10 +1226,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Application.Output.Complete();
#pragma warning disable CS0618 // Type or member is obsolete
var ex0 = 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 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, ex1.Reason);
@ -1231,10 +1253,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
input.Application.Output.Complete();
#pragma warning disable CS0618 // Type or member is obsolete
var ex0 = 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 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, ex1.Reason);

View File

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

View File

@ -36,7 +36,7 @@ namespace SampleApp
{
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 =>

View File

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

View File

@ -12,6 +12,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
using Moq;
using Xunit;
using BadHttpRequestException = Microsoft.AspNetCore.Http.BadHttpRequestException;
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)
{
BadHttpRequestException loggedException = null;
var mockKestrelTrace = new Mock<IKestrelTrace>();
mockKestrelTrace
.Setup(trace => trace.IsEnabled(LogLevel.Information))

View File

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

View File

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

View File

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

View File

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

View File

@ -24,6 +24,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Testing;
using Moq;
using Xunit;
using BadHttpRequestException = Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException;
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);
}
catch (BadHttpRequestException)
catch (Microsoft.AspNetCore.Http.BadHttpRequestException)
{
}
},
@ -403,11 +404,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
[Fact]
public async Task NoErrorResponseSentWhenAppSwallowsBadRequestException()
{
#pragma warning disable CS0618 // Type or member is obsolete
BadHttpRequestException readException = null;
#pragma warning restore CS0618 // Type or member is obsolete
await using (var server = new TestServer(async httpContext =>
{
#pragma warning disable CS0618 // Type or member is obsolete
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));
}, new TestServiceContext(LoggerFactory)))
{
@ -430,8 +435,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
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
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
#pragma warning restore CS0618 // Type or member is obsolete
}
[Fact]
@ -1265,7 +1272,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{
await httpContext.Request.Body.ReadAsync(new byte[1], 0, 1);
}
catch (BadHttpRequestException ex)
catch (Microsoft.AspNetCore.Http.BadHttpRequestException ex)
{
expectedResponse = ex.Message;
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
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
#pragma warning restore CS0618 // Type or member is obsolete
}
[Fact]
@ -1801,8 +1810,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
{
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
&& ((BadHttpRequestException)message.Exception).StatusCode == StatusCodes.Status400BadRequest)
#pragma warning restore CS0618 // Type or member is obsolete
{
foundMessage = true;
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
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
#pragma warning restore CS0618 // Type or member is obsolete
}
[Fact]
@ -4117,8 +4130,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
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
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
#pragma warning restore CS0618 // Type or member is obsolete
}
else
{