diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/BadHttpRequestException.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/BadHttpRequestException.cs index c7d2e69042..034465d212 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/BadHttpRequestException.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/BadHttpRequestException.cs @@ -36,64 +36,64 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core switch (reason) { case RequestRejectionReason.InvalidRequestHeadersNoCRLF: - ex = new BadHttpRequestException("Invalid request headers: missing final CRLF in header fields.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidRequestHeadersNoCRLF, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.InvalidRequestLine: - ex = new BadHttpRequestException("Invalid request line.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidRequestLine, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.MalformedRequestInvalidHeaders: - ex = new BadHttpRequestException("Malformed request: invalid headers.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_MalformedRequestInvalidHeaders, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.MultipleContentLengths: - ex = new BadHttpRequestException("Multiple Content-Length headers.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_MultipleContentLengths, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.UnexpectedEndOfRequestContent: - ex = new BadHttpRequestException("Unexpected end of request content.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_UnexpectedEndOfRequestContent, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.BadChunkSuffix: - ex = new BadHttpRequestException("Bad chunk suffix.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_BadChunkSuffix, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.BadChunkSizeData: - ex = new BadHttpRequestException("Bad chunk size data.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_BadChunkSizeData, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.ChunkedRequestIncomplete: - ex = new BadHttpRequestException("Chunked request incomplete.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_ChunkedRequestIncomplete, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.InvalidCharactersInHeaderName: - ex = new BadHttpRequestException("Invalid characters in header name.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidCharactersInHeaderName, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.RequestLineTooLong: - ex = new BadHttpRequestException("Request line too long.", StatusCodes.Status414UriTooLong); + ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestLineTooLong, StatusCodes.Status414UriTooLong); break; case RequestRejectionReason.HeadersExceedMaxTotalSize: - ex = new BadHttpRequestException("Request headers too long.", StatusCodes.Status431RequestHeaderFieldsTooLarge); + ex = new BadHttpRequestException(CoreStrings.BadRequest_HeadersExceedMaxTotalSize, StatusCodes.Status431RequestHeaderFieldsTooLarge); break; case RequestRejectionReason.TooManyHeaders: - ex = new BadHttpRequestException("Request contains too many headers.", StatusCodes.Status431RequestHeaderFieldsTooLarge); + ex = new BadHttpRequestException(CoreStrings.BadRequest_TooManyHeaders, StatusCodes.Status431RequestHeaderFieldsTooLarge); break; case RequestRejectionReason.RequestTimeout: - ex = new BadHttpRequestException("Request timed out.", StatusCodes.Status408RequestTimeout); + ex = new BadHttpRequestException(CoreStrings.BadRequest_RequestTimeout, StatusCodes.Status408RequestTimeout); break; case RequestRejectionReason.OptionsMethodRequired: - ex = new BadHttpRequestException("Method not allowed.", StatusCodes.Status405MethodNotAllowed, HttpMethod.Options); + ex = new BadHttpRequestException(CoreStrings.BadRequest_MethodNotAllowed, StatusCodes.Status405MethodNotAllowed, HttpMethod.Options); break; case RequestRejectionReason.ConnectMethodRequired: - ex = new BadHttpRequestException("Method not allowed.", StatusCodes.Status405MethodNotAllowed, HttpMethod.Connect); + ex = new BadHttpRequestException(CoreStrings.BadRequest_MethodNotAllowed, StatusCodes.Status405MethodNotAllowed, HttpMethod.Connect); break; case RequestRejectionReason.MissingHostHeader: - ex = new BadHttpRequestException("Request is missing Host header.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_MissingHostHeader, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.MultipleHostHeaders: - ex = new BadHttpRequestException("Multiple Host headers.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_MultipleHostHeaders, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.InvalidHostHeader: - ex = new BadHttpRequestException("Invalid Host header.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_InvalidHostHeader, StatusCodes.Status400BadRequest); break; case RequestRejectionReason.UpgradeRequestCannotHavePayload: - ex = new BadHttpRequestException("Requests with 'Connection: Upgrade' cannot have content in the request body.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest_UpgradeRequestCannotHavePayload, StatusCodes.Status400BadRequest); break; default: - ex = new BadHttpRequestException("Bad request.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest); break; } return ex; @@ -105,34 +105,34 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core switch (reason) { case RequestRejectionReason.InvalidRequestLine: - ex = new BadHttpRequestException($"Invalid request line: '{detail}'", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(detail), StatusCodes.Status400BadRequest); break; case RequestRejectionReason.InvalidRequestTarget: - ex = new BadHttpRequestException($"Invalid request target: '{detail}'", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(detail), StatusCodes.Status400BadRequest); break; case RequestRejectionReason.InvalidRequestHeader: - ex = new BadHttpRequestException($"Invalid request header: '{detail}'", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(detail), StatusCodes.Status400BadRequest); break; case RequestRejectionReason.InvalidContentLength: - ex = new BadHttpRequestException($"Invalid content length: {detail}", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidContentLength_Detail(detail), StatusCodes.Status400BadRequest); break; case RequestRejectionReason.UnrecognizedHTTPVersion: - ex = new BadHttpRequestException($"Unrecognized HTTP version: '{detail}'", StatusCodes.Status505HttpVersionNotsupported); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(detail), StatusCodes.Status505HttpVersionNotsupported); break; case RequestRejectionReason.FinalTransferCodingNotChunked: - ex = new BadHttpRequestException($"Final transfer coding is not \"chunked\": \"{detail}\"", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_FinalTransferCodingNotChunked(detail), StatusCodes.Status400BadRequest); break; case RequestRejectionReason.LengthRequired: - ex = new BadHttpRequestException($"{detail} request contains no Content-Length or Transfer-Encoding header", StatusCodes.Status411LengthRequired); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_LengthRequired(detail), StatusCodes.Status411LengthRequired); break; case RequestRejectionReason.LengthRequiredHttp10: - ex = new BadHttpRequestException($"{detail} request contains no Content-Length header", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_LengthRequiredHttp10(detail), StatusCodes.Status400BadRequest); break; case RequestRejectionReason.InvalidHostHeader: - ex = new BadHttpRequestException($"Invalid Host header: '{detail}'", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidHostHeader_Detail(detail), StatusCodes.Status400BadRequest); break; default: - ex = new BadHttpRequestException("Bad request.", StatusCodes.Status400BadRequest); + ex = new BadHttpRequestException(CoreStrings.BadRequest, StatusCodes.Status400BadRequest); break; } return ex; diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/CoreStrings.resx b/src/Microsoft.AspNetCore.Server.Kestrel.Core/CoreStrings.resx index 03a86be5db..e85918600f 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/CoreStrings.resx +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/CoreStrings.resx @@ -117,10 +117,193 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Bad request. + + + Bad chunk size data. + + + Bad chunk suffix. + + + Chunked request incomplete. + + + The message body length cannot be determined because the final transfer coding was set to '{detail}' instead of 'chunked'. + + + Request headers too long. + + + Invalid characters in header name. + + + Invalid content length: {detail} + + + Invalid Host header. + + + Invalid Host header: '{detail}' + + + Invalid request headers: missing final CRLF in header fields. + + + Invalid request header: '{detail}' + + + Invalid request line. + + + Invalid request line: '{detail}' + + + Invalid request target: '{detail}' + + + {detail} request contains no Content-Length or Transfer-Encoding header. + + + {detail} request contains no Content-Length header. + + + Malformed request: invalid headers. + + + Method not allowed. + + + Request is missing Host header. + + + Multiple Content-Length headers. + + + Multiple Host headers. + + + Request line too long. + + + Request timed out. + + + Request contains too many headers. + + + Unexpected end of request content. + + + Unrecognized HTTP version: '{detail}' + + + Requests with 'Connection: Upgrade' cannot have content in the request body. + Failed to bind to http://[::]:{port} (IPv6Any). Attempting to bind to http://0.0.0.0:{port} instead. Cannot write to response body after connection has been upgraded. + + Kestrel does not support big-endian architectures. + + + Maximum request buffer size ({requestBufferSize}) must be greater than or equal to maximum request header size ({requestHeaderSize}). + + + Maximum request buffer size ({requestBufferSize}) must be greater than or equal to maximum request line size ({requestLineSize}). + + + Server has already started. + + + Unknown transport mode: '{mode}'. + + + Invalid non-ASCII or control character in header: {character} + + + Invalid Content-Length: "{value}". Value must be a positive integral number. + + + Value must be null or a non-negative integer. + + + Value must be a positive integer. + + + Value must be null or a positive integer. + + + Unix socket path must be absolute. + + + Failed to bind to address {address}. + + + No listening endpoints were configured. Binding to {address} by default. + + + HTTPS endpoints can only be configured using {methodName}. + + + A path base can only be configured using {methodName}. + + + Dynamic port binding is not supported when binding to localhost. You must either bind to 127.0.0.1:0 or [::1]:0, or both. + + + Failed to bind to address {endpoint}: address already in use. + + + Invalid URL: '{url}'. + + + Unable to bind to {address} on the {interfaceName} interface: '{error}'. + + + Overriding address(es) '{addresses}'. Binding to endpoints defined in {methodName} instead. + + + Overriding endpoints defined in UseKestrel() because {settingName} is set to true. Binding to address(es) '{addresses}' instead. + + + Unrecognized scheme in server address '{address}'. Only 'http://' is supported. + + + Headers are read-only, response has already started. + + + An item with the same key has already been added. + + + Setting the header {name} is not allowed on responses with status code {statusCode}. + + + {name} cannot be set because the response has already started. + + + Request processing didn't complete within the shutdown timeout. + + + Response Content-Length mismatch: too few bytes written ({written} of {expected}). + + + Response Content-Length mismatch: too many bytes written ({written} of {expected}). + + + The response has been aborted due to an unhandled application exception. + + + Writing to the response body is invalid for responses with status code {statusCode}. + + + Connection shutdown abnormally. + + + Connection processing ended abnormally. + \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/AddressBinder.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/AddressBinder.cs index d041c3bec0..b8a34d69f5 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/AddressBinder.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/AddressBinder.cs @@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal } catch (AddressInUseException ex) { - throw new IOException($"Failed to bind to address {endpoint}: address already in use.", ex); + throw new IOException(CoreStrings.FormatEndpointAlreadyInUse(endpoint), ex); } context.ListenOptions.Add(endpoint); @@ -124,7 +124,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal { if (address.Port == 0) { - throw new InvalidOperationException("Dynamic port binding is not supported when binding to localhost. You must either bind to 127.0.0.1:0 or [::1]:0, or both."); + throw new InvalidOperationException(CoreStrings.DynamicPortOnLocalhostNotSupported); } var exceptions = new List(); @@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal } catch (Exception ex) when (!(ex is IOException)) { - context.Logger.LogWarning(0, $"Unable to bind to {address} on the IPv4 loopback interface: ({ex.Message})"); + context.Logger.LogWarning(0, CoreStrings.NetworkInterfaceBindingFailed, address, "IPv4 loopback", ex.Message); exceptions.Add(ex); } @@ -145,13 +145,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal } catch (Exception ex) when (!(ex is IOException)) { - context.Logger.LogWarning(0, $"Unable to bind to {address} on the IPv6 loopback interface: ({ex.Message})"); + context.Logger.LogWarning(0, CoreStrings.NetworkInterfaceBindingFailed, address, "IPv6 loopback", ex.Message); exceptions.Add(ex); } if (exceptions.Count == 2) { - throw new IOException($"Failed to bind to address {address}.", new AggregateException(exceptions)); + throw new IOException(CoreStrings.FormatAddressBindingFailed(address), new AggregateException(exceptions)); } // If StartLocalhost doesn't throw, there is at least one listener. @@ -165,16 +165,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal if (parsedAddress.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)) { - throw new InvalidOperationException($"HTTPS endpoints can only be configured using {nameof(KestrelServerOptions)}.{nameof(KestrelServerOptions.Listen)}()."); + throw new InvalidOperationException(CoreStrings.FormatConfigureHttpsFromMethodCall($"{nameof(KestrelServerOptions)}.{nameof(KestrelServerOptions.Listen)}()")); } else if (!parsedAddress.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase)) { - throw new InvalidOperationException($"Unrecognized scheme in server address '{address}'. Only 'http://' is supported."); + throw new InvalidOperationException(CoreStrings.FormatUnsupportedAddressScheme(address)); } if (!string.IsNullOrEmpty(parsedAddress.PathBase)) { - throw new InvalidOperationException($"A path base can only be configured using {nameof(IApplicationBuilder)}.UsePathBase()."); + throw new InvalidOperationException(CoreStrings.FormatConfigurePathBaseFromMethodCall($"{nameof(IApplicationBuilder)}.UsePathBase()")); } if (parsedAddress.IsUnixPipe) @@ -227,7 +227,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal { public async Task BindAsync(AddressBindContext context) { - context.Logger.LogDebug($"No listening endpoints were configured. Binding to {Constants.DefaultServerAddress} by default."); + context.Logger.LogDebug(CoreStrings.BindingToDefaultAddress, Constants.DefaultServerAddress); await BindLocalhostAsync(ServerAddress.FromUrl(Constants.DefaultServerAddress), context).ConfigureAwait(false); } @@ -243,7 +243,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal public override Task BindAsync(AddressBindContext context) { var joined = string.Join(", ", _addresses); - context.Logger.LogInformation($"Overriding endpoints defined in UseKestrel() since {nameof(IServerAddressesFeature.PreferHostingUrls)} is set to true. Binding to address(es) '{joined}' instead."); + context.Logger.LogInformation(CoreStrings.OverridingWithPreferHostingUrls, nameof(IServerAddressesFeature.PreferHostingUrls), joined); return base.BindAsync(context); } @@ -262,7 +262,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal public override Task BindAsync(AddressBindContext context) { var joined = string.Join(", ", _originalAddresses); - context.Logger.LogWarning($"Overriding address(es) {joined}. Binding to endpoints defined in UseKestrel() instead."); + context.Logger.LogWarning(CoreStrings.OverridingWithKestrelOptions, joined, "UseKestrel()"); return base.BindAsync(context); } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs index a63fec9407..01ae9a5c81 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs @@ -661,7 +661,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { _keepAlive = false; throw new InvalidOperationException( - $"Response Content-Length mismatch: too many bytes written ({_responseBytesWritten + count} of {responseHeaders.ContentLength.Value})."); + CoreStrings.FormatTooManyBytesWritten(_responseBytesWritten + count, responseHeaders.ContentLength.Value)); } _responseBytesWritten += count; @@ -702,7 +702,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } ReportApplicationError(new InvalidOperationException( - $"Response Content-Length mismatch: too few bytes written ({_responseBytesWritten} of {responseHeaders.ContentLength.Value}).")); + CoreStrings.FormatTooFewBytesWritten(_responseBytesWritten, responseHeaders.ContentLength.Value))); } } @@ -1081,12 +1081,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private void ThrowResponseAlreadyStartedException(string value) { - throw new InvalidOperationException($"{value} cannot be set, response has already started."); + throw new InvalidOperationException(CoreStrings.FormatParameterReadOnlyAfterResponseStarted(value)); } private void RejectNonBodyTransferEncodingResponse(bool appCompleted) { - var ex = new InvalidOperationException($"Transfer-Encoding set on a {StatusCode} non-body request."); + var ex = new InvalidOperationException(CoreStrings.FormatHeaderNotAllowedOnResponse("Transfer-Encoding", StatusCode)); if (!appCompleted) { // Back out of header creation surface exeception in user code @@ -1143,15 +1143,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (Method != "HEAD") { // Throw Exception for 204, 205, 304 responses. - throw new InvalidOperationException($"Write to non-body {StatusCode} response."); + throw new InvalidOperationException(CoreStrings.FormatWritingToResponseBodyNotSupported(StatusCode)); } } private void ThrowResponseAbortedException() { - throw new ObjectDisposedException( - "The response has been aborted due to an unhandled application exception.", - _applicationException); + throw new ObjectDisposedException(CoreStrings.UnhandledApplicationException, _applicationException); } public void RejectRequest(RequestRejectionReason reason) diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameHeaders.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameHeaders.cs index 2432afa6a3..7331ceeadf 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameHeaders.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameHeaders.cs @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http protected void ThrowHeadersReadOnlyException() { - throw new InvalidOperationException("Headers are read-only, response has already started."); + throw new InvalidOperationException(CoreStrings.HeadersAreReadOnly); } protected void ThrowArgumentException() @@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http protected void ThrowDuplicateKeyException() { - throw new ArgumentException("An item with the same key has already been added."); + throw new ArgumentException(CoreStrings.KeyAlreadyExists); } int ICollection>.Count => GetCountFast(); @@ -426,12 +426,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private static void ThrowInvalidContentLengthException(long value) { - throw new ArgumentOutOfRangeException($"Invalid Content-Length: \"{value}\". Value must be a positive integral number."); + throw new ArgumentOutOfRangeException(CoreStrings.FormatInvalidContentLength_InvalidNumber(value)); } private static void ThrowInvalidHeaderCharacter(char ch) { - throw new InvalidOperationException(string.Format("Invalid non-ASCII or control character in header: 0x{0:X4}", (ushort)ch)); + throw new InvalidOperationException(CoreStrings.FormatInvalidAsciiOrControlChar(string.Format("0x{0:X4}", (ushort)ch))); } } } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameOfT.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameOfT.cs index b95a42c6a8..fce5bcae6c 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameOfT.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameOfT.cs @@ -227,7 +227,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } catch (Exception ex) { - Log.LogWarning(0, ex, "Connection processing ended abnormally"); + Log.LogWarning(0, ex, CoreStrings.RequestProcessingEndError); } finally { @@ -243,7 +243,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } catch (Exception ex) { - Log.LogWarning(0, ex, "Connection shutdown abnormally"); + Log.LogWarning(0, ex, CoreStrings.ConnectionShutdownError); } } } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameRequestStream.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameRequestStream.cs index 35bbf73302..f7a92e37a0 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameRequestStream.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameRequestStream.cs @@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (bufferSize <= 0) { - throw new ArgumentException($"{nameof(bufferSize)} must be positive.", nameof(bufferSize)); + throw new ArgumentException(CoreStrings.PositiveIntRequired, nameof(bufferSize)); } var task = ValidateState(cancellationToken); diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameResponseHeaders.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameResponseHeaders.cs index f5093f691f..6409f372db 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameResponseHeaders.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameResponseHeaders.cs @@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private static void ThrowInvalidContentLengthException(string value) { - throw new InvalidOperationException($"Invalid Content-Length: \"{value}\". Value must be a positive integral number."); + throw new InvalidOperationException(CoreStrings.FormatInvalidContentLength_InvalidNumber(value)); } public partial struct Enumerator : IEnumerator> diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Infrastructure/FrameConnectionManagerShutdownExtensions.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Infrastructure/FrameConnectionManagerShutdownExtensions.cs index 7bbd1f1ca7..88aae5e6c7 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Infrastructure/FrameConnectionManagerShutdownExtensions.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Infrastructure/FrameConnectionManagerShutdownExtensions.cs @@ -1,9 +1,7 @@ // 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.Collections.Generic; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -27,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure public static async Task AbortAllConnectionsAsync(this FrameConnectionManager connectionManager) { var abortTasks = new List(); - var canceledException = new TaskCanceledException("Request processing didn't complete within the shutdown timeout."); + var canceledException = new TaskCanceledException(CoreStrings.RequestProcessingAborted); connectionManager.Walk(connection => { diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs index b325ab723a..8d1c26f453 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs @@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core threadPool = new InlineLoggingThreadPool(trace); break; default: - throw new NotSupportedException($"Unknown transport mode {serverOptions.ApplicationSchedulingMode}"); + throw new NotSupportedException(CoreStrings.FormatUnknownTransportMode(serverOptions.ApplicationSchedulingMode)); } return new ServiceContext @@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core { if (!BitConverter.IsLittleEndian) { - throw new PlatformNotSupportedException("Kestrel does not support big-endian architectures."); + throw new PlatformNotSupportedException(CoreStrings.BigEndianNotSupported); } ValidateOptions(); @@ -124,7 +124,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core if (_hasStarted) { // The server has already started and/or has not been cleaned up yet - throw new InvalidOperationException("Server has already started."); + throw new InvalidOperationException(CoreStrings.ServerAlreadyStarted); } _hasStarted = true; _heartbeat.Start(); @@ -196,14 +196,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core Options.Limits.MaxRequestBufferSize < Options.Limits.MaxRequestLineSize) { throw new InvalidOperationException( - $"Maximum request buffer size ({Options.Limits.MaxRequestBufferSize.Value}) must be greater than or equal to maximum request line size ({Options.Limits.MaxRequestLineSize})."); + CoreStrings.FormatMaxRequestBufferSmallerThanRequestLineBuffer(Options.Limits.MaxRequestBufferSize.Value, Options.Limits.MaxRequestLineSize)); } if (Options.Limits.MaxRequestBufferSize.HasValue && Options.Limits.MaxRequestBufferSize < Options.Limits.MaxRequestHeadersTotalSize) { throw new InvalidOperationException( - $"Maximum request buffer size ({Options.Limits.MaxRequestBufferSize.Value}) must be greater than or equal to maximum request headers size ({Options.Limits.MaxRequestHeadersTotalSize})."); + CoreStrings.FormatMaxRequestBufferSmallerThanRequestHeaderBuffer(Options.Limits.MaxRequestBufferSize.Value, Options.Limits.MaxRequestHeadersTotalSize)); } } } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerLimits.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerLimits.cs index b42d2db6a9..9ed2293b6b 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerLimits.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerLimits.cs @@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core { if (value.HasValue && value.Value < 0) { - throw new ArgumentOutOfRangeException(nameof(value), "Value must be null or a non-negative integer."); + throw new ArgumentOutOfRangeException(nameof(value), CoreStrings.NonNegativeNullableIntRequired); } _maxResponseBufferSize = value; } @@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core { if (value.HasValue && value.Value <= 0) { - throw new ArgumentOutOfRangeException(nameof(value), "Value must be null or a positive integer."); + throw new ArgumentOutOfRangeException(nameof(value), CoreStrings.PositiveNullableIntRequired); } _maxRequestBufferSize = value; } @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core { if (value <= 0) { - throw new ArgumentOutOfRangeException(nameof(value), "Value must be a positive integer."); + throw new ArgumentOutOfRangeException(nameof(value), CoreStrings.PositiveIntRequired); } _maxRequestLineSize = value; } @@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core { if (value <= 0) { - throw new ArgumentOutOfRangeException(nameof(value), "Value must a positive integer."); + throw new ArgumentOutOfRangeException(nameof(value), CoreStrings.PositiveIntRequired); } _maxRequestHeadersTotalSize = value; } @@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core { if (value <= 0) { - throw new ArgumentOutOfRangeException(nameof(value), "Value must a positive integer."); + throw new ArgumentOutOfRangeException(nameof(value), CoreStrings.PositiveIntRequired); } _maxRequestHeaderCount = value; } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerOptions.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerOptions.cs index f97e5c3dd3..1f4301418a 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerOptions.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServerOptions.cs @@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core } if (socketPath.Length == 0 || socketPath[0] != '/') { - throw new ArgumentException("Unix socket path must be absolute.", nameof(socketPath)); + throw new ArgumentException(CoreStrings.UnixSocketPathMustBeAbsolute, nameof(socketPath)); } if (configure == null) { diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Properties/CoreStrings.Designer.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Properties/CoreStrings.Designer.cs index c97aefeac9..1a86007def 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Properties/CoreStrings.Designer.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Properties/CoreStrings.Designer.cs @@ -10,6 +10,398 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core private static readonly ResourceManager _resourceManager = new ResourceManager("Microsoft.AspNetCore.Server.Kestrel.Core.CoreStrings", typeof(CoreStrings).GetTypeInfo().Assembly); + /// + /// Bad request. + /// + internal static string BadRequest + { + get => GetString("BadRequest"); + } + + /// + /// Bad request. + /// + internal static string FormatBadRequest() + => GetString("BadRequest"); + + /// + /// Bad chunk size data. + /// + internal static string BadRequest_BadChunkSizeData + { + get => GetString("BadRequest_BadChunkSizeData"); + } + + /// + /// Bad chunk size data. + /// + internal static string FormatBadRequest_BadChunkSizeData() + => GetString("BadRequest_BadChunkSizeData"); + + /// + /// Bad chunk suffix. + /// + internal static string BadRequest_BadChunkSuffix + { + get => GetString("BadRequest_BadChunkSuffix"); + } + + /// + /// Bad chunk suffix. + /// + internal static string FormatBadRequest_BadChunkSuffix() + => GetString("BadRequest_BadChunkSuffix"); + + /// + /// Chunked request incomplete. + /// + internal static string BadRequest_ChunkedRequestIncomplete + { + get => GetString("BadRequest_ChunkedRequestIncomplete"); + } + + /// + /// Chunked request incomplete. + /// + internal static string FormatBadRequest_ChunkedRequestIncomplete() + => GetString("BadRequest_ChunkedRequestIncomplete"); + + /// + /// The message body length cannot be determined because the final transfer coding was set to '{detail}' instead of 'chunked'. + /// + internal static string BadRequest_FinalTransferCodingNotChunked + { + get => GetString("BadRequest_FinalTransferCodingNotChunked"); + } + + /// + /// The message body length cannot be determined because the final transfer coding was set to '{detail}' instead of 'chunked'. + /// + internal static string FormatBadRequest_FinalTransferCodingNotChunked(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_FinalTransferCodingNotChunked", "detail"), detail); + + /// + /// Request headers too long. + /// + internal static string BadRequest_HeadersExceedMaxTotalSize + { + get => GetString("BadRequest_HeadersExceedMaxTotalSize"); + } + + /// + /// Request headers too long. + /// + internal static string FormatBadRequest_HeadersExceedMaxTotalSize() + => GetString("BadRequest_HeadersExceedMaxTotalSize"); + + /// + /// Invalid characters in header name. + /// + internal static string BadRequest_InvalidCharactersInHeaderName + { + get => GetString("BadRequest_InvalidCharactersInHeaderName"); + } + + /// + /// Invalid characters in header name. + /// + internal static string FormatBadRequest_InvalidCharactersInHeaderName() + => GetString("BadRequest_InvalidCharactersInHeaderName"); + + /// + /// Invalid content length: {detail} + /// + internal static string BadRequest_InvalidContentLength_Detail + { + get => GetString("BadRequest_InvalidContentLength_Detail"); + } + + /// + /// Invalid content length: {detail} + /// + internal static string FormatBadRequest_InvalidContentLength_Detail(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_InvalidContentLength_Detail", "detail"), detail); + + /// + /// Invalid Host header. + /// + internal static string BadRequest_InvalidHostHeader + { + get => GetString("BadRequest_InvalidHostHeader"); + } + + /// + /// Invalid Host header. + /// + internal static string FormatBadRequest_InvalidHostHeader() + => GetString("BadRequest_InvalidHostHeader"); + + /// + /// Invalid Host header: '{detail}' + /// + internal static string BadRequest_InvalidHostHeader_Detail + { + get => GetString("BadRequest_InvalidHostHeader_Detail"); + } + + /// + /// Invalid Host header: '{detail}' + /// + internal static string FormatBadRequest_InvalidHostHeader_Detail(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_InvalidHostHeader_Detail", "detail"), detail); + + /// + /// Invalid request headers: missing final CRLF in header fields. + /// + internal static string BadRequest_InvalidRequestHeadersNoCRLF + { + get => GetString("BadRequest_InvalidRequestHeadersNoCRLF"); + } + + /// + /// Invalid request headers: missing final CRLF in header fields. + /// + internal static string FormatBadRequest_InvalidRequestHeadersNoCRLF() + => GetString("BadRequest_InvalidRequestHeadersNoCRLF"); + + /// + /// Invalid request header: '{detail}' + /// + internal static string BadRequest_InvalidRequestHeader_Detail + { + get => GetString("BadRequest_InvalidRequestHeader_Detail"); + } + + /// + /// Invalid request header: '{detail}' + /// + internal static string FormatBadRequest_InvalidRequestHeader_Detail(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_InvalidRequestHeader_Detail", "detail"), detail); + + /// + /// Invalid request line. + /// + internal static string BadRequest_InvalidRequestLine + { + get => GetString("BadRequest_InvalidRequestLine"); + } + + /// + /// Invalid request line. + /// + internal static string FormatBadRequest_InvalidRequestLine() + => GetString("BadRequest_InvalidRequestLine"); + + /// + /// Invalid request line: '{detail}' + /// + internal static string BadRequest_InvalidRequestLine_Detail + { + get => GetString("BadRequest_InvalidRequestLine_Detail"); + } + + /// + /// Invalid request line: '{detail}' + /// + internal static string FormatBadRequest_InvalidRequestLine_Detail(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_InvalidRequestLine_Detail", "detail"), detail); + + /// + /// Invalid request target: '{detail}' + /// + internal static string BadRequest_InvalidRequestTarget_Detail + { + get => GetString("BadRequest_InvalidRequestTarget_Detail"); + } + + /// + /// Invalid request target: '{detail}' + /// + internal static string FormatBadRequest_InvalidRequestTarget_Detail(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_InvalidRequestTarget_Detail", "detail"), detail); + + /// + /// {detail} request contains no Content-Length or Transfer-Encoding header. + /// + internal static string BadRequest_LengthRequired + { + get => GetString("BadRequest_LengthRequired"); + } + + /// + /// {detail} request contains no Content-Length or Transfer-Encoding header. + /// + internal static string FormatBadRequest_LengthRequired(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_LengthRequired", "detail"), detail); + + /// + /// {detail} request contains no Content-Length header. + /// + internal static string BadRequest_LengthRequiredHttp10 + { + get => GetString("BadRequest_LengthRequiredHttp10"); + } + + /// + /// {detail} request contains no Content-Length header. + /// + internal static string FormatBadRequest_LengthRequiredHttp10(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_LengthRequiredHttp10", "detail"), detail); + + /// + /// Malformed request: invalid headers. + /// + internal static string BadRequest_MalformedRequestInvalidHeaders + { + get => GetString("BadRequest_MalformedRequestInvalidHeaders"); + } + + /// + /// Malformed request: invalid headers. + /// + internal static string FormatBadRequest_MalformedRequestInvalidHeaders() + => GetString("BadRequest_MalformedRequestInvalidHeaders"); + + /// + /// Method not allowed. + /// + internal static string BadRequest_MethodNotAllowed + { + get => GetString("BadRequest_MethodNotAllowed"); + } + + /// + /// Method not allowed. + /// + internal static string FormatBadRequest_MethodNotAllowed() + => GetString("BadRequest_MethodNotAllowed"); + + /// + /// Request is missing Host header. + /// + internal static string BadRequest_MissingHostHeader + { + get => GetString("BadRequest_MissingHostHeader"); + } + + /// + /// Request is missing Host header. + /// + internal static string FormatBadRequest_MissingHostHeader() + => GetString("BadRequest_MissingHostHeader"); + + /// + /// Multiple Content-Length headers. + /// + internal static string BadRequest_MultipleContentLengths + { + get => GetString("BadRequest_MultipleContentLengths"); + } + + /// + /// Multiple Content-Length headers. + /// + internal static string FormatBadRequest_MultipleContentLengths() + => GetString("BadRequest_MultipleContentLengths"); + + /// + /// Multiple Host headers. + /// + internal static string BadRequest_MultipleHostHeaders + { + get => GetString("BadRequest_MultipleHostHeaders"); + } + + /// + /// Multiple Host headers. + /// + internal static string FormatBadRequest_MultipleHostHeaders() + => GetString("BadRequest_MultipleHostHeaders"); + + /// + /// Request line too long. + /// + internal static string BadRequest_RequestLineTooLong + { + get => GetString("BadRequest_RequestLineTooLong"); + } + + /// + /// Request line too long. + /// + internal static string FormatBadRequest_RequestLineTooLong() + => GetString("BadRequest_RequestLineTooLong"); + + /// + /// Request timed out. + /// + internal static string BadRequest_RequestTimeout + { + get => GetString("BadRequest_RequestTimeout"); + } + + /// + /// Request timed out. + /// + internal static string FormatBadRequest_RequestTimeout() + => GetString("BadRequest_RequestTimeout"); + + /// + /// Request contains too many headers. + /// + internal static string BadRequest_TooManyHeaders + { + get => GetString("BadRequest_TooManyHeaders"); + } + + /// + /// Request contains too many headers. + /// + internal static string FormatBadRequest_TooManyHeaders() + => GetString("BadRequest_TooManyHeaders"); + + /// + /// Unexpected end of request content. + /// + internal static string BadRequest_UnexpectedEndOfRequestContent + { + get => GetString("BadRequest_UnexpectedEndOfRequestContent"); + } + + /// + /// Unexpected end of request content. + /// + internal static string FormatBadRequest_UnexpectedEndOfRequestContent() + => GetString("BadRequest_UnexpectedEndOfRequestContent"); + + /// + /// Unrecognized HTTP version: '{detail}' + /// + internal static string BadRequest_UnrecognizedHTTPVersion + { + get => GetString("BadRequest_UnrecognizedHTTPVersion"); + } + + /// + /// Unrecognized HTTP version: '{detail}' + /// + internal static string FormatBadRequest_UnrecognizedHTTPVersion(object detail) + => string.Format(CultureInfo.CurrentCulture, GetString("BadRequest_UnrecognizedHTTPVersion", "detail"), detail); + + /// + /// Requests with 'Connection: Upgrade' cannot have content in the request body. + /// + internal static string BadRequest_UpgradeRequestCannotHavePayload + { + get => GetString("BadRequest_UpgradeRequestCannotHavePayload"); + } + + /// + /// Requests with 'Connection: Upgrade' cannot have content in the request body. + /// + internal static string FormatBadRequest_UpgradeRequestCannotHavePayload() + => GetString("BadRequest_UpgradeRequestCannotHavePayload"); + /// /// Failed to bind to http://[::]:{port} (IPv6Any). Attempting to bind to http://0.0.0.0:{port} instead. /// @@ -38,6 +430,468 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core internal static string FormatResponseStreamWasUpgraded() => GetString("ResponseStreamWasUpgraded"); + /// + /// Kestrel does not support big-endian architectures. + /// + internal static string BigEndianNotSupported + { + get => GetString("BigEndianNotSupported"); + } + + /// + /// Kestrel does not support big-endian architectures. + /// + internal static string FormatBigEndianNotSupported() + => GetString("BigEndianNotSupported"); + + /// + /// Maximum request buffer size ({requestBufferSize}) must be greater than or equal to maximum request header size ({requestHeaderSize}). + /// + internal static string MaxRequestBufferSmallerThanRequestHeaderBuffer + { + get => GetString("MaxRequestBufferSmallerThanRequestHeaderBuffer"); + } + + /// + /// Maximum request buffer size ({requestBufferSize}) must be greater than or equal to maximum request header size ({requestHeaderSize}). + /// + internal static string FormatMaxRequestBufferSmallerThanRequestHeaderBuffer(object requestBufferSize, object requestHeaderSize) + => string.Format(CultureInfo.CurrentCulture, GetString("MaxRequestBufferSmallerThanRequestHeaderBuffer", "requestBufferSize", "requestHeaderSize"), requestBufferSize, requestHeaderSize); + + /// + /// Maximum request buffer size ({requestBufferSize}) must be greater than or equal to maximum request line size ({requestLineSize}). + /// + internal static string MaxRequestBufferSmallerThanRequestLineBuffer + { + get => GetString("MaxRequestBufferSmallerThanRequestLineBuffer"); + } + + /// + /// Maximum request buffer size ({requestBufferSize}) must be greater than or equal to maximum request line size ({requestLineSize}). + /// + internal static string FormatMaxRequestBufferSmallerThanRequestLineBuffer(object requestBufferSize, object requestLineSize) + => string.Format(CultureInfo.CurrentCulture, GetString("MaxRequestBufferSmallerThanRequestLineBuffer", "requestBufferSize", "requestLineSize"), requestBufferSize, requestLineSize); + + /// + /// Server has already started. + /// + internal static string ServerAlreadyStarted + { + get => GetString("ServerAlreadyStarted"); + } + + /// + /// Server has already started. + /// + internal static string FormatServerAlreadyStarted() + => GetString("ServerAlreadyStarted"); + + /// + /// Unknown transport mode: '{mode}'. + /// + internal static string UnknownTransportMode + { + get => GetString("UnknownTransportMode"); + } + + /// + /// Unknown transport mode: '{mode}'. + /// + internal static string FormatUnknownTransportMode(object mode) + => string.Format(CultureInfo.CurrentCulture, GetString("UnknownTransportMode", "mode"), mode); + + /// + /// Invalid non-ASCII or control character in header: {character} + /// + internal static string InvalidAsciiOrControlChar + { + get => GetString("InvalidAsciiOrControlChar"); + } + + /// + /// Invalid non-ASCII or control character in header: {character} + /// + internal static string FormatInvalidAsciiOrControlChar(object character) + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidAsciiOrControlChar", "character"), character); + + /// + /// Invalid Content-Length: "{value}". Value must be a positive integral number. + /// + internal static string InvalidContentLength_InvalidNumber + { + get => GetString("InvalidContentLength_InvalidNumber"); + } + + /// + /// Invalid Content-Length: "{value}". Value must be a positive integral number. + /// + internal static string FormatInvalidContentLength_InvalidNumber(object value) + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidContentLength_InvalidNumber", "value"), value); + + /// + /// Value must be null or a non-negative integer. + /// + internal static string NonNegativeNullableIntRequired + { + get => GetString("NonNegativeNullableIntRequired"); + } + + /// + /// Value must be null or a non-negative integer. + /// + internal static string FormatNonNegativeNullableIntRequired() + => GetString("NonNegativeNullableIntRequired"); + + /// + /// Value must be a positive integer. + /// + internal static string PositiveIntRequired + { + get => GetString("PositiveIntRequired"); + } + + /// + /// Value must be a positive integer. + /// + internal static string FormatPositiveIntRequired() + => GetString("PositiveIntRequired"); + + /// + /// Value must be null or a positive integer. + /// + internal static string PositiveNullableIntRequired + { + get => GetString("PositiveNullableIntRequired"); + } + + /// + /// Value must be null or a positive integer. + /// + internal static string FormatPositiveNullableIntRequired() + => GetString("PositiveNullableIntRequired"); + + /// + /// Unix socket path must be absolute. + /// + internal static string UnixSocketPathMustBeAbsolute + { + get => GetString("UnixSocketPathMustBeAbsolute"); + } + + /// + /// Unix socket path must be absolute. + /// + internal static string FormatUnixSocketPathMustBeAbsolute() + => GetString("UnixSocketPathMustBeAbsolute"); + + /// + /// Failed to bind to address {address}. + /// + internal static string AddressBindingFailed + { + get => GetString("AddressBindingFailed"); + } + + /// + /// Failed to bind to address {address}. + /// + internal static string FormatAddressBindingFailed(object address) + => string.Format(CultureInfo.CurrentCulture, GetString("AddressBindingFailed", "address"), address); + + /// + /// No listening endpoints were configured. Binding to {address} by default. + /// + internal static string BindingToDefaultAddress + { + get => GetString("BindingToDefaultAddress"); + } + + /// + /// No listening endpoints were configured. Binding to {address} by default. + /// + internal static string FormatBindingToDefaultAddress(object address) + => string.Format(CultureInfo.CurrentCulture, GetString("BindingToDefaultAddress", "address"), address); + + /// + /// HTTPS endpoints can only be configured using {methodName}. + /// + internal static string ConfigureHttpsFromMethodCall + { + get => GetString("ConfigureHttpsFromMethodCall"); + } + + /// + /// HTTPS endpoints can only be configured using {methodName}. + /// + internal static string FormatConfigureHttpsFromMethodCall(object methodName) + => string.Format(CultureInfo.CurrentCulture, GetString("ConfigureHttpsFromMethodCall", "methodName"), methodName); + + /// + /// A path base can only be configured using {methodName}. + /// + internal static string ConfigurePathBaseFromMethodCall + { + get => GetString("ConfigurePathBaseFromMethodCall"); + } + + /// + /// A path base can only be configured using {methodName}. + /// + internal static string FormatConfigurePathBaseFromMethodCall(object methodName) + => string.Format(CultureInfo.CurrentCulture, GetString("ConfigurePathBaseFromMethodCall", "methodName"), methodName); + + /// + /// Dynamic port binding is not supported when binding to localhost. You must either bind to 127.0.0.1:0 or [::1]:0, or both. + /// + internal static string DynamicPortOnLocalhostNotSupported + { + get => GetString("DynamicPortOnLocalhostNotSupported"); + } + + /// + /// Dynamic port binding is not supported when binding to localhost. You must either bind to 127.0.0.1:0 or [::1]:0, or both. + /// + internal static string FormatDynamicPortOnLocalhostNotSupported() + => GetString("DynamicPortOnLocalhostNotSupported"); + + /// + /// Failed to bind to address {endpoint}: address already in use. + /// + internal static string EndpointAlreadyInUse + { + get => GetString("EndpointAlreadyInUse"); + } + + /// + /// Failed to bind to address {endpoint}: address already in use. + /// + internal static string FormatEndpointAlreadyInUse(object endpoint) + => string.Format(CultureInfo.CurrentCulture, GetString("EndpointAlreadyInUse", "endpoint"), endpoint); + + /// + /// Invalid URL: '{url}'. + /// + internal static string InvalidUrl + { + get => GetString("InvalidUrl"); + } + + /// + /// Invalid URL: '{url}'. + /// + internal static string FormatInvalidUrl(object url) + => string.Format(CultureInfo.CurrentCulture, GetString("InvalidUrl", "url"), url); + + /// + /// Unable to bind to {address} on the {interfaceName} interface: '{error}'. + /// + internal static string NetworkInterfaceBindingFailed + { + get => GetString("NetworkInterfaceBindingFailed"); + } + + /// + /// Unable to bind to {address} on the {interfaceName} interface: '{error}'. + /// + internal static string FormatNetworkInterfaceBindingFailed(object address, object interfaceName, object error) + => string.Format(CultureInfo.CurrentCulture, GetString("NetworkInterfaceBindingFailed", "address", "interfaceName", "error"), address, interfaceName, error); + + /// + /// Overriding address(es) '{addresses}'. Binding to endpoints defined in {methodName} instead. + /// + internal static string OverridingWithKestrelOptions + { + get => GetString("OverridingWithKestrelOptions"); + } + + /// + /// Overriding address(es) '{addresses}'. Binding to endpoints defined in {methodName} instead. + /// + internal static string FormatOverridingWithKestrelOptions(object addresses, object methodName) + => string.Format(CultureInfo.CurrentCulture, GetString("OverridingWithKestrelOptions", "addresses", "methodName"), addresses, methodName); + + /// + /// Overriding endpoints defined in UseKestrel() because {settingName} is set to true. Binding to address(es) '{addresses}' instead. + /// + internal static string OverridingWithPreferHostingUrls + { + get => GetString("OverridingWithPreferHostingUrls"); + } + + /// + /// Overriding endpoints defined in UseKestrel() because {settingName} is set to true. Binding to address(es) '{addresses}' instead. + /// + internal static string FormatOverridingWithPreferHostingUrls(object settingName, object addresses) + => string.Format(CultureInfo.CurrentCulture, GetString("OverridingWithPreferHostingUrls", "settingName", "addresses"), settingName, addresses); + + /// + /// Unrecognized scheme in server address '{address}'. Only 'http://' is supported. + /// + internal static string UnsupportedAddressScheme + { + get => GetString("UnsupportedAddressScheme"); + } + + /// + /// Unrecognized scheme in server address '{address}'. Only 'http://' is supported. + /// + internal static string FormatUnsupportedAddressScheme(object address) + => string.Format(CultureInfo.CurrentCulture, GetString("UnsupportedAddressScheme", "address"), address); + + /// + /// Headers are read-only, response has already started. + /// + internal static string HeadersAreReadOnly + { + get => GetString("HeadersAreReadOnly"); + } + + /// + /// Headers are read-only, response has already started. + /// + internal static string FormatHeadersAreReadOnly() + => GetString("HeadersAreReadOnly"); + + /// + /// An item with the same key has already been added. + /// + internal static string KeyAlreadyExists + { + get => GetString("KeyAlreadyExists"); + } + + /// + /// An item with the same key has already been added. + /// + internal static string FormatKeyAlreadyExists() + => GetString("KeyAlreadyExists"); + + /// + /// Setting the header {name} is not allowed on responses with status code {statusCode}. + /// + internal static string HeaderNotAllowedOnResponse + { + get => GetString("HeaderNotAllowedOnResponse"); + } + + /// + /// Setting the header {name} is not allowed on responses with status code {statusCode}. + /// + internal static string FormatHeaderNotAllowedOnResponse(object name, object statusCode) + => string.Format(CultureInfo.CurrentCulture, GetString("HeaderNotAllowedOnResponse", "name", "statusCode"), name, statusCode); + + /// + /// {name} cannot be set because the response has already started. + /// + internal static string ParameterReadOnlyAfterResponseStarted + { + get => GetString("ParameterReadOnlyAfterResponseStarted"); + } + + /// + /// {name} cannot be set because the response has already started. + /// + internal static string FormatParameterReadOnlyAfterResponseStarted(object name) + => string.Format(CultureInfo.CurrentCulture, GetString("ParameterReadOnlyAfterResponseStarted", "name"), name); + + /// + /// Request processing didn't complete within the shutdown timeout. + /// + internal static string RequestProcessingAborted + { + get => GetString("RequestProcessingAborted"); + } + + /// + /// Request processing didn't complete within the shutdown timeout. + /// + internal static string FormatRequestProcessingAborted() + => GetString("RequestProcessingAborted"); + + /// + /// Response Content-Length mismatch: too few bytes written ({written} of {expected}). + /// + internal static string TooFewBytesWritten + { + get => GetString("TooFewBytesWritten"); + } + + /// + /// Response Content-Length mismatch: too few bytes written ({written} of {expected}). + /// + internal static string FormatTooFewBytesWritten(object written, object expected) + => string.Format(CultureInfo.CurrentCulture, GetString("TooFewBytesWritten", "written", "expected"), written, expected); + + /// + /// Response Content-Length mismatch: too many bytes written ({written} of {expected}). + /// + internal static string TooManyBytesWritten + { + get => GetString("TooManyBytesWritten"); + } + + /// + /// Response Content-Length mismatch: too many bytes written ({written} of {expected}). + /// + internal static string FormatTooManyBytesWritten(object written, object expected) + => string.Format(CultureInfo.CurrentCulture, GetString("TooManyBytesWritten", "written", "expected"), written, expected); + + /// + /// The response has been aborted due to an unhandled application exception. + /// + internal static string UnhandledApplicationException + { + get => GetString("UnhandledApplicationException"); + } + + /// + /// The response has been aborted due to an unhandled application exception. + /// + internal static string FormatUnhandledApplicationException() + => GetString("UnhandledApplicationException"); + + /// + /// Writing to the response body is invalid for responses with status code {statusCode}. + /// + internal static string WritingToResponseBodyNotSupported + { + get => GetString("WritingToResponseBodyNotSupported"); + } + + /// + /// Writing to the response body is invalid for responses with status code {statusCode}. + /// + internal static string FormatWritingToResponseBodyNotSupported(object statusCode) + => string.Format(CultureInfo.CurrentCulture, GetString("WritingToResponseBodyNotSupported", "statusCode"), statusCode); + + /// + /// Connection shutdown abnormally. + /// + internal static string ConnectionShutdownError + { + get => GetString("ConnectionShutdownError"); + } + + /// + /// Connection shutdown abnormally. + /// + internal static string FormatConnectionShutdownError() + => GetString("ConnectionShutdownError"); + + /// + /// Connection processing ended abnormally. + /// + internal static string RequestProcessingEndError + { + get => GetString("RequestProcessingEndError"); + } + + /// + /// Connection processing ended abnormally. + /// + internal static string FormatRequestProcessingEndError() + => GetString("RequestProcessingEndError"); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/ServerAddress.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/ServerAddress.cs index 4f64268087..0b7f019c85 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/ServerAddress.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/ServerAddress.cs @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core int schemeDelimiterStart = url.IndexOf("://", StringComparison.Ordinal); if (schemeDelimiterStart < 0) { - throw new FormatException($"Invalid URL: {url}"); + throw new FormatException(CoreStrings.FormatInvalidUrl(url)); } int schemeDelimiterEnd = schemeDelimiterStart + "://".Length; @@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core if (string.IsNullOrEmpty(serverAddress.Host)) { - throw new FormatException($"Invalid URL: {url}"); + throw new FormatException(CoreStrings.FormatInvalidUrl(url)); } if (url[url.Length - 1] == '/') diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Https/HttpsConnectionAdapter.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Https/HttpsConnectionAdapter.cs index 298c501bea..f87d05e8e8 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Https/HttpsConnectionAdapter.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Https/HttpsConnectionAdapter.cs @@ -31,9 +31,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https { throw new ArgumentNullException(nameof(options)); } + if (options.ServerCertificate == null) { - throw new ArgumentException("The server certificate parameter is required."); + throw new ArgumentException(HttpsStrings.ServiceCertificateRequired, nameof(options)); } _options = options; @@ -97,7 +98,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https } catch (IOException ex) { - _logger?.LogInformation(1, ex, "Failed to authenticate HTTPS connection."); + _logger?.LogInformation(1, ex, HttpsStrings.AuthenticationFailed); sslStream.Dispose(); return _closedAdaptedConnection; } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Https/HttpsStrings.resx b/src/Microsoft.AspNetCore.Server.Kestrel.Https/HttpsStrings.resx new file mode 100644 index 0000000000..d0745abab8 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Https/HttpsStrings.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Failed to authenticate HTTPS connection. + + + The server certificate parameter is required. + + \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Https/Microsoft.AspNetCore.Server.Kestrel.Https.csproj b/src/Microsoft.AspNetCore.Server.Kestrel.Https/Microsoft.AspNetCore.Server.Kestrel.Https.csproj index 6ee24eba77..6205bd9037 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Https/Microsoft.AspNetCore.Server.Kestrel.Https.csproj +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Https/Microsoft.AspNetCore.Server.Kestrel.Https.csproj @@ -24,4 +24,10 @@ + + + + + + diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Https/Properties/HttpsStrings.Designer.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Https/Properties/HttpsStrings.Designer.cs new file mode 100644 index 0000000000..1b86a18e5d --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Https/Properties/HttpsStrings.Designer.cs @@ -0,0 +1,58 @@ +// +namespace Microsoft.AspNetCore.Server.Kestrel.Https +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class HttpsStrings + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNetCore.Server.Kestrel.Https.HttpsStrings", typeof(HttpsStrings).GetTypeInfo().Assembly); + + /// + /// Failed to authenticate HTTPS connection. + /// + internal static string AuthenticationFailed + { + get => GetString("AuthenticationFailed"); + } + + /// + /// Failed to authenticate HTTPS connection. + /// + internal static string FormatAuthenticationFailed() + => GetString("AuthenticationFailed"); + + /// + /// The server certificate parameter is required. + /// + internal static string ServiceCertificateRequired + { + get => GetString("ServiceCertificateRequired"); + } + + /// + /// The server certificate parameter is required. + /// + internal static string FormatServiceCertificateRequired() + => GetString("ServiceCertificateRequired"); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj index 911f42f7b2..960578b878 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj @@ -21,4 +21,10 @@ + + + + + + diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/Properties/SocketsStrings.Designer.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/Properties/SocketsStrings.Designer.cs new file mode 100644 index 0000000000..9d2e7e0182 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/Properties/SocketsStrings.Designer.cs @@ -0,0 +1,58 @@ +// +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets +{ + using System.Globalization; + using System.Reflection; + using System.Resources; + + internal static class SocketsStrings + { + private static readonly ResourceManager _resourceManager + = new ResourceManager("Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketsStrings", typeof(SocketsStrings).GetTypeInfo().Assembly); + + /// + /// Only ListenType.IPEndPoint is supported. + /// + internal static string OnlyIPEndPointsSupported + { + get => GetString("OnlyIPEndPointsSupported"); + } + + /// + /// Only ListenType.IPEndPoint is supported. + /// + internal static string FormatOnlyIPEndPointsSupported() + => GetString("OnlyIPEndPointsSupported"); + + /// + /// Transport is already bound. + /// + internal static string TransportAlreadyBound + { + get => GetString("TransportAlreadyBound"); + } + + /// + /// Transport is already bound. + /// + internal static string FormatTransportAlreadyBound() + => GetString("TransportAlreadyBound"); + + private static string GetString(string name, params string[] formatterNames) + { + var value = _resourceManager.GetString(name); + + System.Diagnostics.Debug.Assert(value != null); + + if (formatterNames != null) + { + for (var i = 0; i < formatterNames.Length; i++) + { + value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}"); + } + } + + return value; + } + } +} diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketTransport.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketTransport.cs index 4832b5676a..c55fbd550a 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketTransport.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketTransport.cs @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets { if (_listenSocket != null) { - throw new InvalidOperationException("Transport is already bound"); + throw new InvalidOperationException(SocketsStrings.TransportAlreadyBound); } IPEndPoint endPoint = _endPointInformation.IPEndPoint; diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketTransportFactory.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketTransportFactory.cs index 9dc2768bbf..3746f5d206 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketTransportFactory.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketTransportFactory.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets if (endPointInformation.Type != ListenType.IPEndPoint) { - throw new ArgumentException("Only ListenType.IPEndPoint is supported", nameof(endPointInformation)); + throw new ArgumentException(SocketsStrings.OnlyIPEndPointsSupported, nameof(endPointInformation)); } if (handler == null) diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketsStrings.resx b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketsStrings.resx new file mode 100644 index 0000000000..79cd2d7303 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets/SocketsStrings.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Only ListenType.IPEndPoint is supported. + + + Transport is already bound. + + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameResponseHeadersTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameResponseHeadersTests.cs index 2d6f6bb706..9ec614ef16 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameResponseHeadersTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameResponseHeadersTests.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Globalization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; -using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Primitives; using Xunit; @@ -149,7 +148,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var dictionary = (IDictionary)headers; var exception = Assert.Throws(() => dictionary.Add("Content-Length", new[] { contentLength })); - Assert.Equal($"Invalid Content-Length: \"{contentLength}\". Value must be a positive integral number.", exception.Message); + Assert.Equal(CoreStrings.FormatInvalidContentLength_InvalidNumber(contentLength), exception.Message); } [Theory] @@ -160,7 +159,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var dictionary = (IDictionary)headers; var exception = Assert.Throws(() => ((IHeaderDictionary)headers)["Content-Length"] = contentLength); - Assert.Equal($"Invalid Content-Length: \"{contentLength}\". Value must be a positive integral number.", exception.Message); + Assert.Equal(CoreStrings.FormatInvalidContentLength_InvalidNumber(contentLength), exception.Message); } [Theory] @@ -170,7 +169,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var headers = new FrameResponseHeaders(); var exception = Assert.Throws(() => headers.HeaderContentLength = contentLength); - Assert.Equal($"Invalid Content-Length: \"{contentLength}\". Value must be a positive integral number.", exception.Message); + Assert.Equal(CoreStrings.FormatInvalidContentLength_InvalidNumber(contentLength), exception.Message); } [Theory] diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameTests.cs index d050e7f43d..0f0a2d4ffa 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameTests.cs @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var exception = Assert.Throws(() => _frame.TakeMessageHeaders(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal("Request headers too long.", exception.Message); + Assert.Equal(CoreStrings.BadRequest_HeadersExceedMaxTotalSize, exception.Message); Assert.Equal(StatusCodes.Status431RequestHeaderFieldsTooLarge, exception.StatusCode); } @@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var exception = Assert.Throws(() => _frame.TakeMessageHeaders(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal("Request contains too many headers.", exception.Message); + Assert.Equal(CoreStrings.BadRequest_TooManyHeaders, exception.Message); Assert.Equal(StatusCodes.Status431RequestHeaderFieldsTooLarge, exception.StatusCode); } @@ -341,7 +341,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var exception = Assert.Throws(() => _frame.TakeStartLine(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal("Request line too long.", exception.Message); + Assert.Equal(CoreStrings.BadRequest_RequestLineTooLong, exception.Message); Assert.Equal(StatusCodes.Status414UriTooLong, exception.StatusCode); } @@ -356,7 +356,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _frame.TakeStartLine(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal($"Invalid request target: '{target}'", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(target), exception.Message); } [Theory] @@ -370,7 +370,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _frame.TakeStartLine(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal($"Invalid request target: '{target.EscapeNonPrintable()}'", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(target.EscapeNonPrintable()), exception.Message); } [Theory] @@ -386,7 +386,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _frame.TakeStartLine(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal($"Invalid request line: '{requestLine.EscapeNonPrintable()}'", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(requestLine.EscapeNonPrintable()), exception.Message); } [Theory] @@ -402,7 +402,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _frame.TakeStartLine(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal($"Invalid request target: '{target.EscapeNonPrintable()}'", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(target.EscapeNonPrintable()), exception.Message); } [Theory] @@ -418,7 +418,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _frame.TakeStartLine(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal($"Invalid request target: '{target.EscapeNonPrintable()}'", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(target.EscapeNonPrintable()), exception.Message); } [Theory] @@ -433,7 +433,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _input.Reader.Advance(_consumed, _examined); Assert.Equal(405, exception.StatusCode); - Assert.Equal("Method not allowed.", exception.Message); + Assert.Equal(CoreStrings.BadRequest_MethodNotAllowed, exception.Message); Assert.Equal(HttpUtilities.MethodToString(allowedMethod), exception.AllowedHeader); } @@ -629,7 +629,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _frame.TakeStartLine(readableBuffer, out _consumed, out _examined)); _input.Reader.Advance(_consumed, _examined); - Assert.Equal("Invalid request target: ''", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(string.Empty), exception.Message); Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode); } finally diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/HttpParserTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/HttpParserTests.cs index 2a953005cc..b9cc700f1a 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/HttpParserTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/HttpParserTests.cs @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var exception = Assert.Throws(() => parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); - Assert.Equal($"Invalid request line: '{requestLine.EscapeNonPrintable()}'", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(requestLine.EscapeNonPrintable()), exception.Message); Assert.Equal(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode); } @@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var exception = Assert.Throws(() => parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); - Assert.Equal($"Invalid request line: '{method.EscapeNonPrintable()} / HTTP/1.1\\x0D\\x0A'", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(method.EscapeNonPrintable() + @" / HTTP/1.1\x0D\x0A"), exception.Message); Assert.Equal(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode); } @@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var exception = Assert.Throws(() => parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); - Assert.Equal($"Unrecognized HTTP version: '{httpVersion}'", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(httpVersion), exception.Message); Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, (exception as BadHttpRequestException).StatusCode); } @@ -352,7 +352,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests exception = Assert.Throws(() => parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined)); - Assert.Equal("Unrecognized HTTP version: ''", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(string.Empty), exception.Message); Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, (exception as BadHttpRequestException).StatusCode); // Invalid request header @@ -361,7 +361,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests exception = Assert.Throws(() => parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes)); - Assert.Equal("Invalid request header: ''", exception.Message); + Assert.Equal(CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(string.Empty), exception.Message); Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode); } diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/KestrelServerTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/KestrelServerTests.cs index 2f1346c9d2..75ab8a3dbb 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/KestrelServerTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/KestrelServerTests.cs @@ -8,7 +8,6 @@ using System.Threading; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; -using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Internal; @@ -110,7 +109,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var exception = Assert.Throws(() => StartDummyApplication(server)); Assert.Equal( - $"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request line size ({maxRequestLineSize}).", + CoreStrings.FormatMaxRequestBufferSmallerThanRequestLineBuffer(maxRequestBufferSize, maxRequestLineSize), exception.Message); Assert.Equal(1, testLogger.CriticalErrorsLogged); } @@ -132,7 +131,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var exception = Assert.Throws(() => StartDummyApplication(server)); Assert.Equal( - $"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request headers size ({maxRequestHeadersTotalSize}).", + CoreStrings.FormatMaxRequestBufferSmallerThanRequestHeaderBuffer(maxRequestBufferSize, maxRequestHeadersTotalSize), exception.Message); Assert.Equal(1, testLogger.CriticalErrorsLogged); } diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/MessageBodyTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/MessageBodyTests.cs index 95a35b2882..6b69166ab6 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/MessageBodyTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/MessageBodyTests.cs @@ -231,7 +231,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderTransferEncoding = "chunked, not-chunked" }, input.FrameContext)); Assert.Equal(StatusCodes.Status400BadRequest, ex.StatusCode); - Assert.Equal("Final transfer coding is not \"chunked\": \"chunked, not-chunked\"", ex.Message); + Assert.Equal(CoreStrings.FormatBadRequest_FinalTransferCodingNotChunked("chunked, not-chunked"), ex.Message); } } @@ -247,7 +247,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders(), input.FrameContext)); Assert.Equal(StatusCodes.Status411LengthRequired, ex.StatusCode); - Assert.Equal($"{method} request contains no Content-Length or Transfer-Encoding header", ex.Message); + Assert.Equal(CoreStrings.FormatBadRequest_LengthRequired(method), ex.Message); } } @@ -263,7 +263,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests MessageBody.For(HttpVersion.Http10, new FrameRequestHeaders(), input.FrameContext)); Assert.Equal(StatusCodes.Status400BadRequest, ex.StatusCode); - Assert.Equal($"{method} request contains no Content-Length header", ex.Message); + Assert.Equal(CoreStrings.FormatBadRequest_LengthRequiredHttp10(method), ex.Message); } } diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs index abd6ec612c..9525d7b406 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs @@ -200,7 +200,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests Assert.Equal(5000, host.GetPort()); Assert.Single(testLogger.Messages, log => log.LogLevel == LogLevel.Debug && - string.Equals($"No listening endpoints were configured. Binding to {Constants.DefaultServerAddress} by default.", + string.Equals(CoreStrings.FormatBindingToDefaultAddress(Constants.DefaultServerAddress), log.Message, StringComparison.Ordinal)); foreach (var address in addresses) @@ -227,7 +227,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests using (var host = hostBuilder.Build()) { var exception = Assert.Throws(() => host.Start()); - Assert.Equal($"Failed to bind to address http://127.0.0.1:{port}: address already in use.", exception.Message); + Assert.Equal(CoreStrings.FormatEndpointAlreadyInUse($"http://127.0.0.1:{port}"), exception.Message); } } } @@ -250,7 +250,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests using (var host = hostBuilder.Build()) { var exception = Assert.Throws(() => host.Start()); - Assert.Equal($"Failed to bind to address http://[::1]:{port}: address already in use.", exception.Message); + Assert.Equal(CoreStrings.FormatEndpointAlreadyInUse($"http://[::1]:{port}"), exception.Message); } } } @@ -277,7 +277,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests Assert.Equal(overrideAddressPort, host.GetPort()); Assert.Single(testLogger.Messages, log => log.LogLevel == LogLevel.Information && - string.Equals($"Overriding endpoints defined in UseKestrel() since {nameof(IServerAddressesFeature.PreferHostingUrls)} is set to true. Binding to address(es) '{overrideAddress}' instead.", + string.Equals(CoreStrings.FormatOverridingWithPreferHostingUrls(nameof(IServerAddressesFeature.PreferHostingUrls), overrideAddress), log.Message, StringComparison.Ordinal)); Assert.Equal(new Uri(overrideAddress).ToString(), await HttpClientSlim.GetStringAsync(overrideAddress)); @@ -389,7 +389,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests { var exception = Assert.Throws(() => host.Start()); Assert.Equal( - $"Failed to bind to address http://{(addressFamily == AddressFamily.InterNetwork ? "127.0.0.1" : "[::1]")}:{port}: address already in use.", + CoreStrings.FormatEndpointAlreadyInUse($"http://{(addressFamily == AddressFamily.InterNetwork ? "127.0.0.1" : "[::1]")}:{port}"), exception.Message); } } @@ -677,21 +677,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests _portSupported = new Lazy(CanBindToPort); } - public bool IsMet - { - get - { - return _portSupported.Value; - } - } + public bool IsMet => _portSupported.Value; - public string SkipReason - { - get - { - return $"Cannot bind to port {_port} on the host."; - } - } + public string SkipReason => $"Cannot bind to port {_port} on the host."; private bool CanBindToPort() { diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/BadHttpRequestTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/BadHttpRequestTests.cs index d97289edd8..089b86006d 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/BadHttpRequestTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/BadHttpRequestTests.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests return TestBadRequest( $"GET / {httpVersion}\r\n", "505 HTTP Version Not Supported", - $"Unrecognized HTTP version: '{httpVersion}'"); + CoreStrings.FormatBadRequest_UnrecognizedHTTPVersion(httpVersion)); } [Theory] @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests return TestBadRequest( $"{method} / HTTP/1.1\r\nHost:\r\n\r\n", "411 Length Required", - $"{method} request contains no Content-Length or Transfer-Encoding header"); + CoreStrings.FormatBadRequest_LengthRequired(method)); } [Theory] @@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests return TestBadRequest( $"{method} / HTTP/1.0\r\n\r\n", "400 Bad Request", - $"{method} request contains no Content-Length header"); + CoreStrings.FormatBadRequest_LengthRequiredHttp10(method)); } [Theory] @@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests return TestBadRequest( $"POST / HTTP/1.1\r\nHost:\r\nContent-Length: {contentLength}\r\n\r\n", "400 Bad Request", - $"Invalid content length: {contentLength}"); + CoreStrings.FormatBadRequest_InvalidContentLength_Detail(contentLength)); } [Theory] @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests return TestBadRequest( $"{request} HTTP/1.1\r\n", "405 Method Not Allowed", - "Method not allowed.", + CoreStrings.BadRequest_MethodNotAllowed, $"Allow: {allowedMethod}"); } @@ -112,7 +112,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests return TestBadRequest( "GET / HTTP/1.1\r\n\r\n", "400 Bad Request", - "Request is missing Host header."); + CoreStrings.BadRequest_MissingHostHeader); } [Fact] @@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests { return TestBadRequest("GET / HTTP/1.1\r\nHost: localhost\r\nHost: localhost\r\n\r\n", "400 Bad Request", - "Multiple Host headers."); + CoreStrings.BadRequest_MultipleHostHeaders); } [Theory] @@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests return TestBadRequest( $"{requestTarget} HTTP/1.1\r\nHost: {host}\r\n\r\n", "400 Bad Request", - $"Invalid Host header: '{host.Trim()}'"); + CoreStrings.FormatBadRequest_InvalidHostHeader_Detail(host.Trim())); } [Fact] @@ -218,17 +218,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests foreach (var requestLine in HttpParsingData.RequestLineInvalidData) { - data.Add(requestLine, $"Invalid request line: '{requestLine.EscapeNonPrintable()}'"); + data.Add(requestLine, CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(requestLine.EscapeNonPrintable())); } foreach (var target in HttpParsingData.TargetWithEncodedNullCharData) { - data.Add($"GET {target} HTTP/1.1\r\n", $"Invalid request target: '{target.EscapeNonPrintable()}'"); + data.Add($"GET {target} HTTP/1.1\r\n", CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(target.EscapeNonPrintable())); } foreach (var target in HttpParsingData.TargetWithNullCharData) { - data.Add($"GET {target} HTTP/1.1\r\n", $"Invalid request target: '{target.EscapeNonPrintable()}'"); + data.Add($"GET {target} HTTP/1.1\r\n", CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail(target.EscapeNonPrintable())); } return data; @@ -239,6 +239,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests public static IEnumerable InvalidRequestHeaderData => HttpParsingData.RequestHeaderInvalidData; - public static TheoryData InvalidHostHeaderData => HttpParsingData.HostHeaderInvalidData; + public static TheoryData InvalidHostHeaderData => HttpParsingData.HostHeaderInvalidData; } } diff --git a/test/shared/HttpParsingData.cs b/test/shared/HttpParsingData.cs index 658fad2528..c25771cd48 100644 --- a/test/shared/HttpParsingData.cs +++ b/test/shared/HttpParsingData.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Xunit; @@ -356,76 +357,76 @@ namespace Microsoft.AspNetCore.Testing public static IEnumerable RequestHeaderInvalidData => new[] { // Missing CR - new[] { "Header: value\n\r\n", @"Invalid request header: 'Header: value\x0A'" }, - new[] { "Header-1: value1\nHeader-2: value2\r\n\r\n", @"Invalid request header: 'Header-1: value1\x0A'" }, - new[] { "Header-1: value1\r\nHeader-2: value2\n\r\n", @"Invalid request header: 'Header-2: value2\x0A'" }, + new[] { "Header: value\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header: value\x0A") }, + new[] { "Header-1: value1\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: value1\x0A") }, + new[] { "Header-1: value1\r\nHeader-2: value2\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-2: value2\x0A") }, // Line folding - new[] { "Header: line1\r\n line2\r\n\r\n", @"Invalid request header: ' line2\x0D\x0A'" }, - new[] { "Header: line1\r\n\tline2\r\n\r\n", @"Invalid request header: '\x09line2\x0D\x0A'" }, - new[] { "Header: line1\r\n line2\r\n\r\n", @"Invalid request header: ' line2\x0D\x0A'" }, - new[] { "Header: line1\r\n \tline2\r\n\r\n", @"Invalid request header: ' \x09line2\x0D\x0A'" }, - new[] { "Header: line1\r\n\t line2\r\n\r\n", @"Invalid request header: '\x09 line2\x0D\x0A'" }, - new[] { "Header: line1\r\n\t\tline2\r\n\r\n", @"Invalid request header: '\x09\x09line2\x0D\x0A'" }, - new[] { "Header: line1\r\n \t\t line2\r\n\r\n", @"Invalid request header: ' \x09\x09 line2\x0D\x0A'" }, - new[] { "Header: line1\r\n \t \t line2\r\n\r\n", @"Invalid request header: ' \x09 \x09 line2\x0D\x0A'" }, - new[] { "Header-1: multi\r\n line\r\nHeader-2: value2\r\n\r\n", @"Invalid request header: ' line\x0D\x0A'" }, - new[] { "Header-1: value1\r\nHeader-2: multi\r\n line\r\n\r\n", @"Invalid request header: ' line\x0D\x0A'" }, - new[] { "Header-1: value1\r\n Header-2: value2\r\n\r\n", @"Invalid request header: ' Header-2: value2\x0D\x0A'" }, - new[] { "Header-1: value1\r\n\tHeader-2: value2\r\n\r\n", @"Invalid request header: '\x09Header-2: value2\x0D\x0A'" }, + new[] { "Header: line1\r\n line2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" line2\x0D\x0A") }, + new[] { "Header: line1\r\n\tline2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"\x09line2\x0D\x0A") }, + new[] { "Header: line1\r\n line2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" line2\x0D\x0A") }, + new[] { "Header: line1\r\n \tline2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" \x09line2\x0D\x0A") }, + new[] { "Header: line1\r\n\t line2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"\x09 line2\x0D\x0A") }, + new[] { "Header: line1\r\n\t\tline2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"\x09\x09line2\x0D\x0A") }, + new[] { "Header: line1\r\n \t\t line2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" \x09\x09 line2\x0D\x0A") }, + new[] { "Header: line1\r\n \t \t line2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" \x09 \x09 line2\x0D\x0A") }, + new[] { "Header-1: multi\r\n line\r\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" line\x0D\x0A") }, + new[] { "Header-1: value1\r\nHeader-2: multi\r\n line\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" line\x0D\x0A") }, + new[] { "Header-1: value1\r\n Header-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" Header-2: value2\x0D\x0A") }, + new[] { "Header-1: value1\r\n\tHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"\x09Header-2: value2\x0D\x0A") }, // CR in value - new[] { "Header-1: value1\r\r\n", @"Invalid request header: 'Header-1: value1\x0D\x0D\x0A'" }, - new[] { "Header-1: val\rue1\r\n", @"Invalid request header: 'Header-1: val\x0Due1\x0D\x0A'" }, - new[] { "Header-1: value1\rHeader-2: value2\r\n\r\n", @"Invalid request header: 'Header-1: value1\x0DHeader-2: value2\x0D\x0A'" }, - new[] { "Header-1: value1\r\nHeader-2: value2\r\r\n", @"Invalid request header: 'Header-2: value2\x0D\x0D\x0A'" }, - new[] { "Header-1: value1\r\nHeader-2: v\ralue2\r\n", @"Invalid request header: 'Header-2: v\x0Dalue2\x0D\x0A'" }, - new[] { "Header-1: Value__\rVector16________Vector32\r\n", @"Invalid request header: 'Header-1: Value__\x0DVector16________Vector32\x0D\x0A'" }, - new[] { "Header-1: Value___Vector16\r________Vector32\r\n", @"Invalid request header: 'Header-1: Value___Vector16\x0D________Vector32\x0D\x0A'" }, - new[] { "Header-1: Value___Vector16_______\rVector32\r\n", @"Invalid request header: 'Header-1: Value___Vector16_______\x0DVector32\x0D\x0A'" }, - new[] { "Header-1: Value___Vector16________Vector32\r\r\n", @"Invalid request header: 'Header-1: Value___Vector16________Vector32\x0D\x0D\x0A'" }, - new[] { "Header-1: Value___Vector16________Vector32_\r\r\n", @"Invalid request header: 'Header-1: Value___Vector16________Vector32_\x0D\x0D\x0A'" }, - new[] { "Header-1: Value___Vector16________Vector32Value___Vector16_______\rVector32\r\n", @"Invalid request header: 'Header-1: Value___Vector16________Vector32Value___Vector16_______\x0DVector32\x0D\x0A'" }, - new[] { "Header-1: Value___Vector16________Vector32Value___Vector16________Vector32\r\r\n", @"Invalid request header: 'Header-1: Value___Vector16________Vector32Value___Vector16________Vector32\x0D\x0D\x0A'" }, - new[] { "Header-1: Value___Vector16________Vector32Value___Vector16________Vector32_\r\r\n", @"Invalid request header: 'Header-1: Value___Vector16________Vector32Value___Vector16________Vector32_\x0D\x0D\x0A'" }, + new[] { "Header-1: value1\r\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: value1\x0D\x0D\x0A") }, + new[] { "Header-1: val\rue1\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: val\x0Due1\x0D\x0A") }, + new[] { "Header-1: value1\rHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: value1\x0DHeader-2: value2\x0D\x0A") }, + new[] { "Header-1: value1\r\nHeader-2: value2\r\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-2: value2\x0D\x0D\x0A") }, + new[] { "Header-1: value1\r\nHeader-2: v\ralue2\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-2: v\x0Dalue2\x0D\x0A") }, + new[] { "Header-1: Value__\rVector16________Vector32\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: Value__\x0DVector16________Vector32\x0D\x0A") }, + new[] { "Header-1: Value___Vector16\r________Vector32\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: Value___Vector16\x0D________Vector32\x0D\x0A") }, + new[] { "Header-1: Value___Vector16_______\rVector32\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: Value___Vector16_______\x0DVector32\x0D\x0A") }, + new[] { "Header-1: Value___Vector16________Vector32\r\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: Value___Vector16________Vector32\x0D\x0D\x0A") }, + new[] { "Header-1: Value___Vector16________Vector32_\r\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: Value___Vector16________Vector32_\x0D\x0D\x0A") }, + new[] { "Header-1: Value___Vector16________Vector32Value___Vector16_______\rVector32\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: Value___Vector16________Vector32Value___Vector16_______\x0DVector32\x0D\x0A") }, + new[] { "Header-1: Value___Vector16________Vector32Value___Vector16________Vector32\r\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: Value___Vector16________Vector32Value___Vector16________Vector32\x0D\x0D\x0A") }, + new[] { "Header-1: Value___Vector16________Vector32Value___Vector16________Vector32_\r\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1: Value___Vector16________Vector32Value___Vector16________Vector32_\x0D\x0D\x0A") }, // Missing colon - new[] { "Header-1 value1\r\n\r\n", @"Invalid request header: 'Header-1 value1\x0D\x0A'" }, - new[] { "Header-1 value1\r\nHeader-2: value2\r\n\r\n", @"Invalid request header: 'Header-1 value1\x0D\x0A'" }, - new[] { "Header-1: value1\r\nHeader-2 value2\r\n\r\n", @"Invalid request header: 'Header-2 value2\x0D\x0A'" }, - new[] { "\n", @"Invalid request header: '\x0A'" }, + new[] { "Header-1 value1\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1 value1\x0D\x0A") }, + new[] { "Header-1 value1\r\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-1 value1\x0D\x0A") }, + new[] { "Header-1: value1\r\nHeader-2 value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-2 value2\x0D\x0A") }, + new[] { "\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"\x0A") }, // Starting with whitespace - new[] { " Header: value\r\n\r\n", @"Invalid request header: ' Header: value\x0D\x0A'" }, - new[] { "\tHeader: value\r\n\r\n", @"Invalid request header: '\x09Header: value\x0D\x0A'" }, - new[] { " Header-1: value1\r\nHeader-2: value2\r\n\r\n", @"Invalid request header: ' Header-1: value1\x0D\x0A'" }, - new[] { "\tHeader-1: value1\r\nHeader-2: value2\r\n\r\n", @"Invalid request header: '\x09Header-1: value1\x0D\x0A'" }, + new[] { " Header: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" Header: value\x0D\x0A") }, + new[] { "\tHeader: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"\x09Header: value\x0D\x0A") }, + new[] { " Header-1: value1\r\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@" Header-1: value1\x0D\x0A") }, + new[] { "\tHeader-1: value1\r\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"\x09Header-1: value1\x0D\x0A") }, // Whitespace in header name - new[] { "Header : value\r\n\r\n", @"Invalid request header: 'Header : value\x0D\x0A'" }, - new[] { "Header\t: value\r\n\r\n", @"Invalid request header: 'Header\x09: value\x0D\x0A'" }, - new[] { "Header\r: value\r\n\r\n", @"Invalid request header: 'Header\x0D: value\x0D\x0A'" }, - new[] { "Header_\rVector16: value\r\n\r\n", @"Invalid request header: 'Header_\x0DVector16: value\x0D\x0A'" }, - new[] { "Header__Vector16\r: value\r\n\r\n", @"Invalid request header: 'Header__Vector16\x0D: value\x0D\x0A'" }, - new[] { "Header__Vector16_\r: value\r\n\r\n", @"Invalid request header: 'Header__Vector16_\x0D: value\x0D\x0A'" }, - new[] { "Header_\rVector16________Vector32: value\r\n\r\n", @"Invalid request header: 'Header_\x0DVector16________Vector32: value\x0D\x0A'" }, - new[] { "Header__Vector16________Vector32\r: value\r\n\r\n", @"Invalid request header: 'Header__Vector16________Vector32\x0D: value\x0D\x0A'" }, - new[] { "Header__Vector16________Vector32_\r: value\r\n\r\n", @"Invalid request header: 'Header__Vector16________Vector32_\x0D: value\x0D\x0A'" }, - new[] { "Header__Vector16________Vector32Header_\rVector16________Vector32: value\r\n\r\n", @"Invalid request header: 'Header__Vector16________Vector32Header_\x0DVector16________Vector32: value\x0D\x0A'" }, - new[] { "Header__Vector16________Vector32Header__Vector16________Vector32\r: value\r\n\r\n", @"Invalid request header: 'Header__Vector16________Vector32Header__Vector16________Vector32\x0D: value\x0D\x0A'" }, - new[] { "Header__Vector16________Vector32Header__Vector16________Vector32_\r: value\r\n\r\n", @"Invalid request header: 'Header__Vector16________Vector32Header__Vector16________Vector32_\x0D: value\x0D\x0A'" }, - new[] { "Header 1: value1\r\nHeader-2: value2\r\n\r\n", @"Invalid request header: 'Header 1: value1\x0D\x0A'" }, - new[] { "Header 1 : value1\r\nHeader-2: value2\r\n\r\n", @"Invalid request header: 'Header 1 : value1\x0D\x0A'" }, - new[] { "Header 1\t: value1\r\nHeader-2: value2\r\n\r\n", @"Invalid request header: 'Header 1\x09: value1\x0D\x0A'" }, - new[] { "Header 1\r: value1\r\nHeader-2: value2\r\n\r\n", @"Invalid request header: 'Header 1\x0D: value1\x0D\x0A'" }, - new[] { "Header-1: value1\r\nHeader 2: value2\r\n\r\n", @"Invalid request header: 'Header 2: value2\x0D\x0A'" }, - new[] { "Header-1: value1\r\nHeader-2 : value2\r\n\r\n", @"Invalid request header: 'Header-2 : value2\x0D\x0A'" }, - new[] { "Header-1: value1\r\nHeader-2\t: value2\r\n\r\n", @"Invalid request header: 'Header-2\x09: value2\x0D\x0A'" }, + new[] { "Header : value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header : value\x0D\x0A") }, + new[] { "Header\t: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header\x09: value\x0D\x0A") }, + new[] { "Header\r: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header\x0D: value\x0D\x0A") }, + new[] { "Header_\rVector16: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header_\x0DVector16: value\x0D\x0A") }, + new[] { "Header__Vector16\r: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header__Vector16\x0D: value\x0D\x0A") }, + new[] { "Header__Vector16_\r: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header__Vector16_\x0D: value\x0D\x0A") }, + new[] { "Header_\rVector16________Vector32: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header_\x0DVector16________Vector32: value\x0D\x0A") }, + new[] { "Header__Vector16________Vector32\r: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header__Vector16________Vector32\x0D: value\x0D\x0A") }, + new[] { "Header__Vector16________Vector32_\r: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header__Vector16________Vector32_\x0D: value\x0D\x0A") }, + new[] { "Header__Vector16________Vector32Header_\rVector16________Vector32: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header__Vector16________Vector32Header_\x0DVector16________Vector32: value\x0D\x0A") }, + new[] { "Header__Vector16________Vector32Header__Vector16________Vector32\r: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header__Vector16________Vector32Header__Vector16________Vector32\x0D: value\x0D\x0A") }, + new[] { "Header__Vector16________Vector32Header__Vector16________Vector32_\r: value\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header__Vector16________Vector32Header__Vector16________Vector32_\x0D: value\x0D\x0A") }, + new[] { "Header 1: value1\r\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header 1: value1\x0D\x0A") }, + new[] { "Header 1 : value1\r\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header 1 : value1\x0D\x0A") }, + new[] { "Header 1\t: value1\r\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header 1\x09: value1\x0D\x0A") }, + new[] { "Header 1\r: value1\r\nHeader-2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header 1\x0D: value1\x0D\x0A") }, + new[] { "Header-1: value1\r\nHeader 2: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header 2: value2\x0D\x0A") }, + new[] { "Header-1: value1\r\nHeader-2 : value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-2 : value2\x0D\x0A") }, + new[] { "Header-1: value1\r\nHeader-2\t: value2\r\n\r\n", CoreStrings.FormatBadRequest_InvalidRequestHeader_Detail(@"Header-2\x09: value2\x0D\x0A") }, // Headers not ending in CRLF line - new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r\r", @"Invalid request headers: missing final CRLF in header fields." }, - new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r ", @"Invalid request headers: missing final CRLF in header fields." }, - new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r \n", @"Invalid request headers: missing final CRLF in header fields." }, + new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r\r", CoreStrings.BadRequest_InvalidRequestHeadersNoCRLF }, + new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r ", CoreStrings.BadRequest_InvalidRequestHeadersNoCRLF }, + new[] { "Header-1: value1\r\nHeader-2: value2\r\n\r \n", CoreStrings.BadRequest_InvalidRequestHeadersNoCRLF }, }; public static TheoryData HostHeaderData