|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System.Globalization;
using System.Text;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
internal static class ReasonPhrases
{
private static readonly byte[] _bytesStatus100 = CreateStatusBytes(StatusCodes.Status100Continue);
private static readonly byte[] _bytesStatus101 = CreateStatusBytes(StatusCodes.Status101SwitchingProtocols);
private static readonly byte[] _bytesStatus102 = CreateStatusBytes(StatusCodes.Status102Processing);
private static readonly byte[] _bytesStatus200 = CreateStatusBytes(StatusCodes.Status200OK);
private static readonly byte[] _bytesStatus201 = CreateStatusBytes(StatusCodes.Status201Created);
private static readonly byte[] _bytesStatus202 = CreateStatusBytes(StatusCodes.Status202Accepted);
private static readonly byte[] _bytesStatus203 = CreateStatusBytes(StatusCodes.Status203NonAuthoritative);
private static readonly byte[] _bytesStatus204 = CreateStatusBytes(StatusCodes.Status204NoContent);
private static readonly byte[] _bytesStatus205 = CreateStatusBytes(StatusCodes.Status205ResetContent);
private static readonly byte[] _bytesStatus206 = CreateStatusBytes(StatusCodes.Status206PartialContent);
private static readonly byte[] _bytesStatus207 = CreateStatusBytes(StatusCodes.Status207MultiStatus);
private static readonly byte[] _bytesStatus208 = CreateStatusBytes(StatusCodes.Status208AlreadyReported);
private static readonly byte[] _bytesStatus226 = CreateStatusBytes(StatusCodes.Status226IMUsed);
private static readonly byte[] _bytesStatus300 = CreateStatusBytes(StatusCodes.Status300MultipleChoices);
private static readonly byte[] _bytesStatus301 = CreateStatusBytes(StatusCodes.Status301MovedPermanently);
private static readonly byte[] _bytesStatus302 = CreateStatusBytes(StatusCodes.Status302Found);
private static readonly byte[] _bytesStatus303 = CreateStatusBytes(StatusCodes.Status303SeeOther);
private static readonly byte[] _bytesStatus304 = CreateStatusBytes(StatusCodes.Status304NotModified);
private static readonly byte[] _bytesStatus305 = CreateStatusBytes(StatusCodes.Status305UseProxy);
private static readonly byte[] _bytesStatus306 = CreateStatusBytes(StatusCodes.Status306SwitchProxy);
private static readonly byte[] _bytesStatus307 = CreateStatusBytes(StatusCodes.Status307TemporaryRedirect);
private static readonly byte[] _bytesStatus308 = CreateStatusBytes(StatusCodes.Status308PermanentRedirect);
private static readonly byte[] _bytesStatus400 = CreateStatusBytes(StatusCodes.Status400BadRequest);
private static readonly byte[] _bytesStatus401 = CreateStatusBytes(StatusCodes.Status401Unauthorized);
private static readonly byte[] _bytesStatus402 = CreateStatusBytes(StatusCodes.Status402PaymentRequired);
private static readonly byte[] _bytesStatus403 = CreateStatusBytes(StatusCodes.Status403Forbidden);
private static readonly byte[] _bytesStatus404 = CreateStatusBytes(StatusCodes.Status404NotFound);
private static readonly byte[] _bytesStatus405 = CreateStatusBytes(StatusCodes.Status405MethodNotAllowed);
private static readonly byte[] _bytesStatus406 = CreateStatusBytes(StatusCodes.Status406NotAcceptable);
private static readonly byte[] _bytesStatus407 = CreateStatusBytes(StatusCodes.Status407ProxyAuthenticationRequired);
private static readonly byte[] _bytesStatus408 = CreateStatusBytes(StatusCodes.Status408RequestTimeout);
private static readonly byte[] _bytesStatus409 = CreateStatusBytes(StatusCodes.Status409Conflict);
private static readonly byte[] _bytesStatus410 = CreateStatusBytes(StatusCodes.Status410Gone);
private static readonly byte[] _bytesStatus411 = CreateStatusBytes(StatusCodes.Status411LengthRequired);
private static readonly byte[] _bytesStatus412 = CreateStatusBytes(StatusCodes.Status412PreconditionFailed);
private static readonly byte[] _bytesStatus413 = CreateStatusBytes(StatusCodes.Status413PayloadTooLarge);
private static readonly byte[] _bytesStatus414 = CreateStatusBytes(StatusCodes.Status414UriTooLong);
private static readonly byte[] _bytesStatus415 = CreateStatusBytes(StatusCodes.Status415UnsupportedMediaType);
private static readonly byte[] _bytesStatus416 = CreateStatusBytes(StatusCodes.Status416RangeNotSatisfiable);
private static readonly byte[] _bytesStatus417 = CreateStatusBytes(StatusCodes.Status417ExpectationFailed);
private static readonly byte[] _bytesStatus418 = CreateStatusBytes(StatusCodes.Status418ImATeapot);
private static readonly byte[] _bytesStatus419 = CreateStatusBytes(StatusCodes.Status419AuthenticationTimeout);
private static readonly byte[] _bytesStatus421 = CreateStatusBytes(StatusCodes.Status421MisdirectedRequest);
private static readonly byte[] _bytesStatus422 = CreateStatusBytes(StatusCodes.Status422UnprocessableEntity);
private static readonly byte[] _bytesStatus423 = CreateStatusBytes(StatusCodes.Status423Locked);
private static readonly byte[] _bytesStatus424 = CreateStatusBytes(StatusCodes.Status424FailedDependency);
private static readonly byte[] _bytesStatus426 = CreateStatusBytes(StatusCodes.Status426UpgradeRequired);
private static readonly byte[] _bytesStatus428 = CreateStatusBytes(StatusCodes.Status428PreconditionRequired);
private static readonly byte[] _bytesStatus429 = CreateStatusBytes(StatusCodes.Status429TooManyRequests);
private static readonly byte[] _bytesStatus431 = CreateStatusBytes(StatusCodes.Status431RequestHeaderFieldsTooLarge);
private static readonly byte[] _bytesStatus451 = CreateStatusBytes(StatusCodes.Status451UnavailableForLegalReasons);
private static readonly byte[] _bytesStatus499 = CreateStatusBytes(StatusCodes.Status499ClientClosedRequest);
private static readonly byte[] _bytesStatus500 = CreateStatusBytes(StatusCodes.Status500InternalServerError);
private static readonly byte[] _bytesStatus501 = CreateStatusBytes(StatusCodes.Status501NotImplemented);
private static readonly byte[] _bytesStatus502 = CreateStatusBytes(StatusCodes.Status502BadGateway);
private static readonly byte[] _bytesStatus503 = CreateStatusBytes(StatusCodes.Status503ServiceUnavailable);
private static readonly byte[] _bytesStatus504 = CreateStatusBytes(StatusCodes.Status504GatewayTimeout);
private static readonly byte[] _bytesStatus505 = CreateStatusBytes(StatusCodes.Status505HttpVersionNotsupported);
private static readonly byte[] _bytesStatus506 = CreateStatusBytes(StatusCodes.Status506VariantAlsoNegotiates);
private static readonly byte[] _bytesStatus507 = CreateStatusBytes(StatusCodes.Status507InsufficientStorage);
private static readonly byte[] _bytesStatus508 = CreateStatusBytes(StatusCodes.Status508LoopDetected);
private static readonly byte[] _bytesStatus510 = CreateStatusBytes(StatusCodes.Status510NotExtended);
private static readonly byte[] _bytesStatus511 = CreateStatusBytes(StatusCodes.Status511NetworkAuthenticationRequired);
private static byte[] CreateStatusBytes(int statusCode)
{
var reasonPhrase = WebUtilities.ReasonPhrases.GetReasonPhrase(statusCode);
Debug.Assert(!string.IsNullOrEmpty(reasonPhrase));
return CreateStatusBytes(statusCode, reasonPhrase);
}
private static byte[] CreateStatusBytes(int statusCode, string? reasonPhrase)
{
// https://tools.ietf.org/html/rfc7230#section-3.1.2 requires trailing whitespace regardless of reason phrase
return Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture) + " " + reasonPhrase);
}
public static byte[] ToStatusBytes(int statusCode, string? reasonPhrase = null)
{
var candidate = statusCode switch
{
StatusCodes.Status100Continue => _bytesStatus100,
StatusCodes.Status101SwitchingProtocols => _bytesStatus101,
StatusCodes.Status102Processing => _bytesStatus102,
StatusCodes.Status200OK => _bytesStatus200,
StatusCodes.Status201Created => _bytesStatus201,
StatusCodes.Status202Accepted => _bytesStatus202,
StatusCodes.Status203NonAuthoritative => _bytesStatus203,
StatusCodes.Status204NoContent => _bytesStatus204,
StatusCodes.Status205ResetContent => _bytesStatus205,
StatusCodes.Status206PartialContent => _bytesStatus206,
StatusCodes.Status207MultiStatus => _bytesStatus207,
StatusCodes.Status208AlreadyReported => _bytesStatus208,
StatusCodes.Status226IMUsed => _bytesStatus226,
StatusCodes.Status300MultipleChoices => _bytesStatus300,
StatusCodes.Status301MovedPermanently => _bytesStatus301,
StatusCodes.Status302Found => _bytesStatus302,
StatusCodes.Status303SeeOther => _bytesStatus303,
StatusCodes.Status304NotModified => _bytesStatus304,
StatusCodes.Status305UseProxy => _bytesStatus305,
StatusCodes.Status306SwitchProxy => _bytesStatus306,
StatusCodes.Status307TemporaryRedirect => _bytesStatus307,
StatusCodes.Status308PermanentRedirect => _bytesStatus308,
StatusCodes.Status400BadRequest => _bytesStatus400,
StatusCodes.Status401Unauthorized => _bytesStatus401,
StatusCodes.Status402PaymentRequired => _bytesStatus402,
StatusCodes.Status403Forbidden => _bytesStatus403,
StatusCodes.Status404NotFound => _bytesStatus404,
StatusCodes.Status405MethodNotAllowed => _bytesStatus405,
StatusCodes.Status406NotAcceptable => _bytesStatus406,
StatusCodes.Status407ProxyAuthenticationRequired => _bytesStatus407,
StatusCodes.Status408RequestTimeout => _bytesStatus408,
StatusCodes.Status409Conflict => _bytesStatus409,
StatusCodes.Status410Gone => _bytesStatus410,
StatusCodes.Status411LengthRequired => _bytesStatus411,
StatusCodes.Status412PreconditionFailed => _bytesStatus412,
StatusCodes.Status413PayloadTooLarge => _bytesStatus413,
StatusCodes.Status414UriTooLong => _bytesStatus414,
StatusCodes.Status415UnsupportedMediaType => _bytesStatus415,
StatusCodes.Status416RangeNotSatisfiable => _bytesStatus416,
StatusCodes.Status417ExpectationFailed => _bytesStatus417,
StatusCodes.Status418ImATeapot => _bytesStatus418,
StatusCodes.Status419AuthenticationTimeout => _bytesStatus419,
StatusCodes.Status421MisdirectedRequest => _bytesStatus421,
StatusCodes.Status422UnprocessableEntity => _bytesStatus422,
StatusCodes.Status423Locked => _bytesStatus423,
StatusCodes.Status424FailedDependency => _bytesStatus424,
StatusCodes.Status426UpgradeRequired => _bytesStatus426,
StatusCodes.Status428PreconditionRequired => _bytesStatus428,
StatusCodes.Status429TooManyRequests => _bytesStatus429,
StatusCodes.Status431RequestHeaderFieldsTooLarge => _bytesStatus431,
StatusCodes.Status451UnavailableForLegalReasons => _bytesStatus451,
StatusCodes.Status499ClientClosedRequest => _bytesStatus499,
StatusCodes.Status500InternalServerError => _bytesStatus500,
StatusCodes.Status501NotImplemented => _bytesStatus501,
StatusCodes.Status502BadGateway => _bytesStatus502,
StatusCodes.Status503ServiceUnavailable => _bytesStatus503,
StatusCodes.Status504GatewayTimeout => _bytesStatus504,
StatusCodes.Status505HttpVersionNotsupported => _bytesStatus505,
StatusCodes.Status506VariantAlsoNegotiates => _bytesStatus506,
StatusCodes.Status507InsufficientStorage => _bytesStatus507,
StatusCodes.Status508LoopDetected => _bytesStatus508,
StatusCodes.Status510NotExtended => _bytesStatus510,
StatusCodes.Status511NetworkAuthenticationRequired => _bytesStatus511,
_ => null
};
if (candidate is not null && (string.IsNullOrEmpty(reasonPhrase) || WebUtilities.ReasonPhrases.GetReasonPhrase(statusCode) == reasonPhrase))
{
return candidate;
}
return CreateStatusBytes(statusCode, reasonPhrase);
}
}
|