From 42fbba3520fe188f35a83e5f9542893b64c5284f Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Fri, 2 Mar 2018 10:51:48 -0800 Subject: [PATCH] More detailed request timeout exceptions #2245 --- src/Kestrel.Core/BadHttpRequestException.cs | 7 ++- src/Kestrel.Core/CoreStrings.resx | 7 ++- .../Internal/Http/Http1Connection.cs | 2 +- .../Internal/Http/Http1MessageBody.cs | 2 +- .../Internal/Http/RequestRejectionReason.cs | 3 +- .../Properties/CoreStrings.Designer.cs | 48 +++++++++++++------ 6 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/Kestrel.Core/BadHttpRequestException.cs b/src/Kestrel.Core/BadHttpRequestException.cs index 4fc2bb1521..0530f53854 100644 --- a/src/Kestrel.Core/BadHttpRequestException.cs +++ b/src/Kestrel.Core/BadHttpRequestException.cs @@ -87,8 +87,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core case RequestRejectionReason.RequestBodyTooLarge: ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestBodyTooLarge, StatusCodes.Status413PayloadTooLarge); break; - case RequestRejectionReason.RequestTimeout: - ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestTimeout, StatusCodes.Status408RequestTimeout); + case RequestRejectionReason.RequestHeadersTimeout: + ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestHeadersTimeout, StatusCodes.Status408RequestTimeout); + break; + case RequestRejectionReason.RequestBodyTimeout: + ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestBodyTimeout, StatusCodes.Status408RequestTimeout); break; case RequestRejectionReason.OptionsMethodRequired: ex = new BadHttpRequestException(CoreStrings.BadRequest_MethodNotAllowed, StatusCodes.Status405MethodNotAllowed, HttpMethod.Options); diff --git a/src/Kestrel.Core/CoreStrings.resx b/src/Kestrel.Core/CoreStrings.resx index 966dbfd1bb..286f64efc9 100644 --- a/src/Kestrel.Core/CoreStrings.resx +++ b/src/Kestrel.Core/CoreStrings.resx @@ -186,8 +186,8 @@ Request line too long. - - Request timed out. + + Reading the request headers timed out. Request contains too many headers. @@ -503,4 +503,7 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l Cannot write to the response body, the response has completed. + + Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate. + \ No newline at end of file diff --git a/src/Kestrel.Core/Internal/Http/Http1Connection.cs b/src/Kestrel.Core/Internal/Http/Http1Connection.cs index c8bab28d31..3876e63194 100644 --- a/src/Kestrel.Core/Internal/Http/Http1Connection.cs +++ b/src/Kestrel.Core/Internal/Http/Http1Connection.cs @@ -484,7 +484,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.RequestTimeout); + BadHttpRequestException.Throw(RequestRejectionReason.RequestHeadersTimeout); } endConnection = false; diff --git a/src/Kestrel.Core/Internal/Http/Http1MessageBody.cs b/src/Kestrel.Core/Internal/Http/Http1MessageBody.cs index 1e7f3caf2d..503e21e5bd 100644 --- a/src/Kestrel.Core/Internal/Http/Http1MessageBody.cs +++ b/src/Kestrel.Core/Internal/Http/Http1MessageBody.cs @@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (_context.RequestTimedOut) { - BadHttpRequestException.Throw(RequestRejectionReason.RequestTimeout); + BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTimeout); } var readableBuffer = result.Buffer; diff --git a/src/Kestrel.Core/Internal/Http/RequestRejectionReason.cs b/src/Kestrel.Core/Internal/Http/RequestRejectionReason.cs index 0a7cb1eeb1..ee27b5cb96 100644 --- a/src/Kestrel.Core/Internal/Http/RequestRejectionReason.cs +++ b/src/Kestrel.Core/Internal/Http/RequestRejectionReason.cs @@ -22,7 +22,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http HeadersExceedMaxTotalSize, TooManyHeaders, RequestBodyTooLarge, - RequestTimeout, + RequestHeadersTimeout, + RequestBodyTimeout, FinalTransferCodingNotChunked, LengthRequired, LengthRequiredHttp10, diff --git a/src/Kestrel.Core/Properties/CoreStrings.Designer.cs b/src/Kestrel.Core/Properties/CoreStrings.Designer.cs index c915e95dff..a8a1937505 100644 --- a/src/Kestrel.Core/Properties/CoreStrings.Designer.cs +++ b/src/Kestrel.Core/Properties/CoreStrings.Designer.cs @@ -333,18 +333,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core => GetString("BadRequest_RequestLineTooLong"); /// - /// Request timed out. + /// Reading the request headers timed out. /// - internal static string BadRequest_RequestTimeout + internal static string BadRequest_RequestHeadersTimeout { - get => GetString("BadRequest_RequestTimeout"); + get => GetString("BadRequest_RequestHeadersTimeout"); } /// - /// Request timed out. + /// Reading the request headers timed out. /// - internal static string FormatBadRequest_RequestTimeout() - => GetString("BadRequest_RequestTimeout"); + internal static string FormatBadRequest_RequestHeadersTimeout() + => GetString("BadRequest_RequestHeadersTimeout"); /// /// Request contains too many headers. @@ -878,14 +878,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core internal static string FormatWritingToResponseBodyNotSupported(object statusCode) => string.Format(CultureInfo.CurrentCulture, GetString("WritingToResponseBodyNotSupported", "statusCode"), statusCode); - /// - /// Cannot write to the response body, the response has completed. - /// - internal static string WritingToResponseBodyAfterResponseCompleted - { - get => GetString("WritingToResponseBodyAfterResponseCompleted"); - } - /// /// Connection shutdown abnormally. /// @@ -1800,6 +1792,34 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core internal static string FormatHttp2NotSupported() => GetString("Http2NotSupported"); + /// + /// Cannot write to the response body, the response has completed. + /// + internal static string WritingToResponseBodyAfterResponseCompleted + { + get => GetString("WritingToResponseBodyAfterResponseCompleted"); + } + + /// + /// Cannot write to the response body, the response has completed. + /// + internal static string FormatWritingToResponseBodyAfterResponseCompleted() + => GetString("WritingToResponseBodyAfterResponseCompleted"); + + /// + /// Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate. + /// + internal static string BadRequest_RequestBodyTimeout + { + get => GetString("BadRequest_RequestBodyTimeout"); + } + + /// + /// Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate. + /// + internal static string FormatBadRequest_RequestBodyTimeout() + => GetString("BadRequest_RequestBodyTimeout"); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name);