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;

            case RequestRejectionReason.RequestBodyTooLarge:
                ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_RequestBodyTooLarge(detail), StatusCodes.Status413PayloadTooLarge, reason);
                break;

            default:
                ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest, reason);
                break;
            }
            return(ex);
        }
    public async Task RejectsRequestWithContentLengthHeaderExceedingPerRequestLimit()
    {
        // 8 GiB
        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 =>
        {
            var feature = context.Features.Get <IHttpMaxRequestBodySizeFeature>();
            Assert.Equal(globalMaxRequestBodySize, feature.MaxRequestBodySize);

            // Disable the MaxRequestBodySize prior to calling Request.Body.ReadAsync();
            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;
        },
                                                 new TestServiceContext(LoggerFactory)
        {
            ServerOptions = { Limits = { MaxRequestBodySize = globalMaxRequestBodySize } }
        }))
        {
            using (var connection = server.CreateConnection())
            {
                await connection.Send(
                    "POST / HTTP/1.1",
                    "Host:",
                    "Content-Length: " + (perRequestMaxRequestBodySize + 1),
                    "",
                    "");

                await connection.ReceiveEnd(
                    "HTTP/1.1 413 Payload Too Large",
                    "Content-Length: 0",
                    "Connection: close",
                    $"Date: {server.Context.DateHeaderValue}",
                    "",
                    "");
            }
        }

        Assert.NotNull(requestRejectedEx);
        Assert.Equal(CoreStrings.FormatBadRequest_RequestBodyTooLarge(perRequestMaxRequestBodySize), requestRejectedEx.Message);
    }
    public async Task ChunkFramingAndExtensionsCountTowardsRequestBodySize()
    {
        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
                {
                    count = await context.Request.Body.ReadAsync(buffer, 0, 11);
                } while (count != 0);
            });

            throw requestRejectedEx;
        },
                                                 new TestServiceContext(LoggerFactory)
        {
            ServerOptions = { Limits = { MaxRequestBodySize = globalMaxRequestBodySize } }
        }))
        {
            using (var connection = server.CreateConnection())
            {
                await connection.Send(
                    "POST / HTTP/1.1",
                    "Host:",
                    "Transfer-Encoding: chunked",
                    "",
                    chunkedPayload);

                await connection.ReceiveEnd(
                    "HTTP/1.1 413 Payload Too Large",
                    "Content-Length: 0",
                    "Connection: close",
                    $"Date: {server.Context.DateHeaderValue}",
                    "",
                    "");
            }
        }

        Assert.NotNull(requestRejectedEx);
        Assert.Equal(CoreStrings.FormatBadRequest_RequestBodyTooLarge(globalMaxRequestBodySize), requestRejectedEx.Message);
    }
    public async Task RejectsRequestWithBodySizeExceedingPerRequestLimitAndExceptionWasCaughtByApplication()
    {
        var maxRequestBodySize        = 3;
        var requestBody               = "client content";
        var customApplicationResponse = "custom";

        Assert.True(requestBody.Length > maxRequestBodySize);

        await using (var server = new TestServer(async context =>
        {
#pragma warning disable CS0618 // Type or member is obsolete
            BadHttpRequestException requestRejectedEx = await Assert.ThrowsAsync <BadHttpRequestException>(async() =>
#pragma warning restore CS0618 // Type or member is obsolete
            {
                using (var stream = new StreamReader(context.Request.Body))
                {
                    string body = await stream.ReadToEndAsync();
                }
            });
            context.Response.StatusCode = requestRejectedEx.StatusCode;
            await context.Response.WriteAsync(customApplicationResponse);
            throw requestRejectedEx;
        },
                                                 new TestServiceContext(LoggerFactory)
        {
            ServerOptions = { Limits = { MaxRequestBodySize = maxRequestBodySize } }
        }))
        {
            using var connection = server.CreateConnection();
            await connection.Send(
                "POST / HTTP/1.1",
                "Host:",
                $"Content-Length: {requestBody.Length}",
                "",
                requestBody);

            await connection.ReceiveEnd(
                "HTTP/1.1 413 Payload Too Large",
                "Connection: close",
                $"Date: {server.Context.DateHeaderValue}",
                "Transfer-Encoding: chunked",
                "",
                $"{customApplicationResponse.Length}",
                customApplicationResponse,
                "");
        }
    }
    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 } }
        }))
        {
            using (var connection = server.CreateConnection())
            {
                await connection.Send(
                    "POST / HTTP/1.1",
                    "Host:",
                    "Transfer-Encoding: chunked",
                    "",
                    "1\r\n");

                await connection.ReceiveEnd(
                    "HTTP/1.1 413 Payload Too Large",
                    "Content-Length: 0",
                    "Connection: close",
                    $"Date: {server.Context.DateHeaderValue}",
                    "",
                    "");
            }
        }

        Assert.NotNull(requestRejectedEx1);
        Assert.NotNull(requestRejectedEx2);
        Assert.Equal(CoreStrings.FormatBadRequest_RequestBodyTooLarge(0), requestRejectedEx1.Message);
        Assert.Equal(CoreStrings.FormatBadRequest_RequestBodyTooLarge(0), requestRejectedEx2.Message);
    }
#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.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;

            default:
                ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest, reason);
                break;
            }
            return(ex);
        }