Created
February 22, 2021 08:25
-
-
Save MihaZupan/81ecaf69acd23a69d06e5eba228a2fb0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Globalization; | |
using System.Text; | |
namespace ReasonPhrasesBenchmarks | |
{ | |
class Program | |
{ | |
static void Main() => BenchmarkRunner.Run<Benchmarks>(); | |
} | |
public class Benchmarks | |
{ | |
public const int StatusCode = 404; | |
[Params(null, "Not Found", "Something custom")] | |
public string ReasonPhrase; | |
[Benchmark] | |
public byte[] New() => ReasonPhrases.ToStatusBytes(StatusCode, ReasonPhrase); | |
[Benchmark] | |
public byte[] Old() => ReasonPhrases.ToStatusBytesOld(StatusCode, ReasonPhrase); | |
} | |
public static class StatusCodes | |
{ | |
/// <summary> | |
/// HTTP status code 100. | |
/// </summary> | |
public const int Status100Continue = 100; | |
/// <summary> | |
/// HTTP status code 101. | |
/// </summary> | |
public const int Status101SwitchingProtocols = 101; | |
/// <summary> | |
/// HTTP status code 102. | |
/// </summary> | |
public const int Status102Processing = 102; | |
/// <summary> | |
/// HTTP status code 200. | |
/// </summary> | |
public const int Status200OK = 200; | |
/// <summary> | |
/// HTTP status code 201. | |
/// </summary> | |
public const int Status201Created = 201; | |
/// <summary> | |
/// HTTP status code 202. | |
/// </summary> | |
public const int Status202Accepted = 202; | |
/// <summary> | |
/// HTTP status code 203. | |
/// </summary> | |
public const int Status203NonAuthoritative = 203; | |
/// <summary> | |
/// HTTP status code 204. | |
/// </summary> | |
public const int Status204NoContent = 204; | |
/// <summary> | |
/// HTTP status code 205. | |
/// </summary> | |
public const int Status205ResetContent = 205; | |
/// <summary> | |
/// HTTP status code 206. | |
/// </summary> | |
public const int Status206PartialContent = 206; | |
/// <summary> | |
/// HTTP status code 207. | |
/// </summary> | |
public const int Status207MultiStatus = 207; | |
/// <summary> | |
/// HTTP status code 208. | |
/// </summary> | |
public const int Status208AlreadyReported = 208; | |
/// <summary> | |
/// HTTP status code 226. | |
/// </summary> | |
public const int Status226IMUsed = 226; | |
/// <summary> | |
/// HTTP status code 300. | |
/// </summary> | |
public const int Status300MultipleChoices = 300; | |
/// <summary> | |
/// HTTP status code 301. | |
/// </summary> | |
public const int Status301MovedPermanently = 301; | |
/// <summary> | |
/// HTTP status code 302. | |
/// </summary> | |
public const int Status302Found = 302; | |
/// <summary> | |
/// HTTP status code 303. | |
/// </summary> | |
public const int Status303SeeOther = 303; | |
/// <summary> | |
/// HTTP status code 304. | |
/// </summary> | |
public const int Status304NotModified = 304; | |
/// <summary> | |
/// HTTP status code 305. | |
/// </summary> | |
public const int Status305UseProxy = 305; | |
/// <summary> | |
/// HTTP status code 306. | |
/// </summary> | |
public const int Status306SwitchProxy = 306; // RFC 2616, removed | |
/// <summary> | |
/// HTTP status code 307. | |
/// </summary> | |
public const int Status307TemporaryRedirect = 307; | |
/// <summary> | |
/// HTTP status code 308. | |
/// </summary> | |
public const int Status308PermanentRedirect = 308; | |
/// <summary> | |
/// HTTP status code 400. | |
/// </summary> | |
public const int Status400BadRequest = 400; | |
/// <summary> | |
/// HTTP status code 401. | |
/// </summary> | |
public const int Status401Unauthorized = 401; | |
/// <summary> | |
/// HTTP status code 402. | |
/// </summary> | |
public const int Status402PaymentRequired = 402; | |
/// <summary> | |
/// HTTP status code 403. | |
/// </summary> | |
public const int Status403Forbidden = 403; | |
/// <summary> | |
/// HTTP status code 404. | |
/// </summary> | |
public const int Status404NotFound = 404; | |
/// <summary> | |
/// HTTP status code 405. | |
/// </summary> | |
public const int Status405MethodNotAllowed = 405; | |
/// <summary> | |
/// HTTP status code 406. | |
/// </summary> | |
public const int Status406NotAcceptable = 406; | |
/// <summary> | |
/// HTTP status code 407. | |
/// </summary> | |
public const int Status407ProxyAuthenticationRequired = 407; | |
/// <summary> | |
/// HTTP status code 408. | |
/// </summary> | |
public const int Status408RequestTimeout = 408; | |
/// <summary> | |
/// HTTP status code 409. | |
/// </summary> | |
public const int Status409Conflict = 409; | |
/// <summary> | |
/// HTTP status code 410. | |
/// </summary> | |
public const int Status410Gone = 410; | |
/// <summary> | |
/// HTTP status code 411. | |
/// </summary> | |
public const int Status411LengthRequired = 411; | |
/// <summary> | |
/// HTTP status code 412. | |
/// </summary> | |
public const int Status412PreconditionFailed = 412; | |
/// <summary> | |
/// HTTP status code 413. | |
/// </summary> | |
public const int Status413RequestEntityTooLarge = 413; // RFC 2616, renamed | |
/// <summary> | |
/// HTTP status code 413. | |
/// </summary> | |
public const int Status413PayloadTooLarge = 413; // RFC 7231 | |
/// <summary> | |
/// HTTP status code 414. | |
/// </summary> | |
public const int Status414RequestUriTooLong = 414; // RFC 2616, renamed | |
/// <summary> | |
/// HTTP status code 414. | |
/// </summary> | |
public const int Status414UriTooLong = 414; // RFC 7231 | |
/// <summary> | |
/// HTTP status code 415. | |
/// </summary> | |
public const int Status415UnsupportedMediaType = 415; | |
/// <summary> | |
/// HTTP status code 416. | |
/// </summary> | |
public const int Status416RequestedRangeNotSatisfiable = 416; // RFC 2616, renamed | |
/// <summary> | |
/// HTTP status code 416. | |
/// </summary> | |
public const int Status416RangeNotSatisfiable = 416; // RFC 7233 | |
/// <summary> | |
/// HTTP status code 417. | |
/// </summary> | |
public const int Status417ExpectationFailed = 417; | |
/// <summary> | |
/// HTTP status code 418. | |
/// </summary> | |
public const int Status418ImATeapot = 418; | |
/// <summary> | |
/// HTTP status code 419. | |
/// </summary> | |
public const int Status419AuthenticationTimeout = 419; // Not defined in any RFC | |
/// <summary> | |
/// HTTP status code 422. | |
/// </summary> | |
public const int Status421MisdirectedRequest = 421; | |
/// <summary> | |
/// HTTP status code 422. | |
/// </summary> | |
public const int Status422UnprocessableEntity = 422; | |
/// <summary> | |
/// HTTP status code 423. | |
/// </summary> | |
public const int Status423Locked = 423; | |
/// <summary> | |
/// HTTP status code 424. | |
/// </summary> | |
public const int Status424FailedDependency = 424; | |
/// <summary> | |
/// HTTP status code 426. | |
/// </summary> | |
public const int Status426UpgradeRequired = 426; | |
/// <summary> | |
/// HTTP status code 428. | |
/// </summary> | |
public const int Status428PreconditionRequired = 428; | |
/// <summary> | |
/// HTTP status code 429. | |
/// </summary> | |
public const int Status429TooManyRequests = 429; | |
/// <summary> | |
/// HTTP status code 431. | |
/// </summary> | |
public const int Status431RequestHeaderFieldsTooLarge = 431; | |
/// <summary> | |
/// HTTP status code 451. | |
/// </summary> | |
public const int Status451UnavailableForLegalReasons = 451; | |
/// <summary> | |
/// HTTP status code 500. | |
/// </summary> | |
public const int Status500InternalServerError = 500; | |
/// <summary> | |
/// HTTP status code 501. | |
/// </summary> | |
public const int Status501NotImplemented = 501; | |
/// <summary> | |
/// HTTP status code 502. | |
/// </summary> | |
public const int Status502BadGateway = 502; | |
/// <summary> | |
/// HTTP status code 503. | |
/// </summary> | |
public const int Status503ServiceUnavailable = 503; | |
/// <summary> | |
/// HTTP status code 504. | |
/// </summary> | |
public const int Status504GatewayTimeout = 504; | |
/// <summary> | |
/// HTTP status code 505. | |
/// </summary> | |
public const int Status505HttpVersionNotsupported = 505; | |
/// <summary> | |
/// HTTP status code 506. | |
/// </summary> | |
public const int Status506VariantAlsoNegotiates = 506; | |
/// <summary> | |
/// HTTP status code 507. | |
/// </summary> | |
public const int Status507InsufficientStorage = 507; | |
/// <summary> | |
/// HTTP status code 508. | |
/// </summary> | |
public const int Status508LoopDetected = 508; | |
/// <summary> | |
/// HTTP status code 510. | |
/// </summary> | |
public const int Status510NotExtended = 510; | |
/// <summary> | |
/// HTTP status code 511. | |
/// </summary> | |
public const int Status511NetworkAuthenticationRequired = 511; | |
} | |
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[] _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 = WebUtilitiesReasonPhrases.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.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) || WebUtilitiesReasonPhrases.GetReasonPhrase(statusCode) == reasonPhrase)) | |
{ | |
return candidate; | |
} | |
return CreateStatusBytes(statusCode, reasonPhrase); | |
} | |
public static byte[] ToStatusBytesOld(int statusCode, string? reasonPhrase = null) | |
{ | |
if (string.IsNullOrEmpty(reasonPhrase)) | |
{ | |
switch (statusCode) | |
{ | |
case StatusCodes.Status100Continue: | |
return _bytesStatus100; | |
case StatusCodes.Status101SwitchingProtocols: | |
return _bytesStatus101; | |
case StatusCodes.Status102Processing: | |
return _bytesStatus102; | |
case StatusCodes.Status200OK: | |
return _bytesStatus200; | |
case StatusCodes.Status201Created: | |
return _bytesStatus201; | |
case StatusCodes.Status202Accepted: | |
return _bytesStatus202; | |
case StatusCodes.Status203NonAuthoritative: | |
return _bytesStatus203; | |
case StatusCodes.Status204NoContent: | |
return _bytesStatus204; | |
case StatusCodes.Status205ResetContent: | |
return _bytesStatus205; | |
case StatusCodes.Status206PartialContent: | |
return _bytesStatus206; | |
case StatusCodes.Status207MultiStatus: | |
return _bytesStatus207; | |
case StatusCodes.Status208AlreadyReported: | |
return _bytesStatus208; | |
case StatusCodes.Status226IMUsed: | |
return _bytesStatus226; | |
case StatusCodes.Status300MultipleChoices: | |
return _bytesStatus300; | |
case StatusCodes.Status301MovedPermanently: | |
return _bytesStatus301; | |
case StatusCodes.Status302Found: | |
return _bytesStatus302; | |
case StatusCodes.Status303SeeOther: | |
return _bytesStatus303; | |
case StatusCodes.Status304NotModified: | |
return _bytesStatus304; | |
case StatusCodes.Status305UseProxy: | |
return _bytesStatus305; | |
case StatusCodes.Status306SwitchProxy: | |
return _bytesStatus306; | |
case StatusCodes.Status307TemporaryRedirect: | |
return _bytesStatus307; | |
case StatusCodes.Status308PermanentRedirect: | |
return _bytesStatus308; | |
case StatusCodes.Status400BadRequest: | |
return _bytesStatus400; | |
case StatusCodes.Status401Unauthorized: | |
return _bytesStatus401; | |
case StatusCodes.Status402PaymentRequired: | |
return _bytesStatus402; | |
case StatusCodes.Status403Forbidden: | |
return _bytesStatus403; | |
case StatusCodes.Status404NotFound: | |
return _bytesStatus404; | |
case StatusCodes.Status405MethodNotAllowed: | |
return _bytesStatus405; | |
case StatusCodes.Status406NotAcceptable: | |
return _bytesStatus406; | |
case StatusCodes.Status407ProxyAuthenticationRequired: | |
return _bytesStatus407; | |
case StatusCodes.Status408RequestTimeout: | |
return _bytesStatus408; | |
case StatusCodes.Status409Conflict: | |
return _bytesStatus409; | |
case StatusCodes.Status410Gone: | |
return _bytesStatus410; | |
case StatusCodes.Status411LengthRequired: | |
return _bytesStatus411; | |
case StatusCodes.Status412PreconditionFailed: | |
return _bytesStatus412; | |
case StatusCodes.Status413PayloadTooLarge: | |
return _bytesStatus413; | |
case StatusCodes.Status414UriTooLong: | |
return _bytesStatus414; | |
case StatusCodes.Status415UnsupportedMediaType: | |
return _bytesStatus415; | |
case StatusCodes.Status416RangeNotSatisfiable: | |
return _bytesStatus416; | |
case StatusCodes.Status417ExpectationFailed: | |
return _bytesStatus417; | |
case StatusCodes.Status418ImATeapot: | |
return _bytesStatus418; | |
case StatusCodes.Status419AuthenticationTimeout: | |
return _bytesStatus419; | |
case StatusCodes.Status421MisdirectedRequest: | |
return _bytesStatus421; | |
case StatusCodes.Status422UnprocessableEntity: | |
return _bytesStatus422; | |
case StatusCodes.Status423Locked: | |
return _bytesStatus423; | |
case StatusCodes.Status424FailedDependency: | |
return _bytesStatus424; | |
case StatusCodes.Status426UpgradeRequired: | |
return _bytesStatus426; | |
case StatusCodes.Status428PreconditionRequired: | |
return _bytesStatus428; | |
case StatusCodes.Status429TooManyRequests: | |
return _bytesStatus429; | |
case StatusCodes.Status431RequestHeaderFieldsTooLarge: | |
return _bytesStatus431; | |
case StatusCodes.Status451UnavailableForLegalReasons: | |
return _bytesStatus451; | |
case StatusCodes.Status500InternalServerError: | |
return _bytesStatus500; | |
case StatusCodes.Status501NotImplemented: | |
return _bytesStatus501; | |
case StatusCodes.Status502BadGateway: | |
return _bytesStatus502; | |
case StatusCodes.Status503ServiceUnavailable: | |
return _bytesStatus503; | |
case StatusCodes.Status504GatewayTimeout: | |
return _bytesStatus504; | |
case StatusCodes.Status505HttpVersionNotsupported: | |
return _bytesStatus505; | |
case StatusCodes.Status506VariantAlsoNegotiates: | |
return _bytesStatus506; | |
case StatusCodes.Status507InsufficientStorage: | |
return _bytesStatus507; | |
case StatusCodes.Status508LoopDetected: | |
return _bytesStatus508; | |
case StatusCodes.Status510NotExtended: | |
return _bytesStatus510; | |
case StatusCodes.Status511NetworkAuthenticationRequired: | |
return _bytesStatus511; | |
default: | |
var predefinedReasonPhrase = WebUtilitiesReasonPhrases.GetReasonPhrase(statusCode); | |
// https://tools.ietf.org/html/rfc7230#section-3.1.2 requires trailing whitespace regardless of reason phrase | |
var formattedStatusCode = statusCode.ToString(CultureInfo.InvariantCulture) + " "; | |
return string.IsNullOrEmpty(predefinedReasonPhrase) | |
? Encoding.ASCII.GetBytes(formattedStatusCode) | |
: Encoding.ASCII.GetBytes(formattedStatusCode + predefinedReasonPhrase); | |
} | |
} | |
return Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture) + " " + reasonPhrase); | |
} | |
} | |
public static class WebUtilitiesReasonPhrases | |
{ | |
// Status Codes listed at http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml | |
private static readonly Dictionary<int, string> Phrases = new() | |
{ | |
{ 100, "Continue" }, | |
{ 101, "Switching Protocols" }, | |
{ 102, "Processing" }, | |
{ 200, "OK" }, | |
{ 201, "Created" }, | |
{ 202, "Accepted" }, | |
{ 203, "Non-Authoritative Information" }, | |
{ 204, "No Content" }, | |
{ 205, "Reset Content" }, | |
{ 206, "Partial Content" }, | |
{ 207, "Multi-Status" }, | |
{ 208, "Already Reported" }, | |
{ 226, "IM Used" }, | |
{ 300, "Multiple Choices" }, | |
{ 301, "Moved Permanently" }, | |
{ 302, "Found" }, | |
{ 303, "See Other" }, | |
{ 304, "Not Modified" }, | |
{ 305, "Use Proxy" }, | |
{ 306, "Switch Proxy" }, | |
{ 307, "Temporary Redirect" }, | |
{ 308, "Permanent Redirect" }, | |
{ 400, "Bad Request" }, | |
{ 401, "Unauthorized" }, | |
{ 402, "Payment Required" }, | |
{ 403, "Forbidden" }, | |
{ 404, "Not Found" }, | |
{ 405, "Method Not Allowed" }, | |
{ 406, "Not Acceptable" }, | |
{ 407, "Proxy Authentication Required" }, | |
{ 408, "Request Timeout" }, | |
{ 409, "Conflict" }, | |
{ 410, "Gone" }, | |
{ 411, "Length Required" }, | |
{ 412, "Precondition Failed" }, | |
{ 413, "Payload Too Large" }, | |
{ 414, "URI Too Long" }, | |
{ 415, "Unsupported Media Type" }, | |
{ 416, "Range Not Satisfiable" }, | |
{ 417, "Expectation Failed" }, | |
{ 418, "I'm a teapot" }, | |
{ 419, "Authentication Timeout" }, | |
{ 421, "Misdirected Request" }, | |
{ 422, "Unprocessable Entity" }, | |
{ 423, "Locked" }, | |
{ 424, "Failed Dependency" }, | |
{ 426, "Upgrade Required" }, | |
{ 428, "Precondition Required" }, | |
{ 429, "Too Many Requests" }, | |
{ 431, "Request Header Fields Too Large" }, | |
{ 451, "Unavailable For Legal Reasons" }, | |
{ 500, "Internal Server Error" }, | |
{ 501, "Not Implemented" }, | |
{ 502, "Bad Gateway" }, | |
{ 503, "Service Unavailable" }, | |
{ 504, "Gateway Timeout" }, | |
{ 505, "HTTP Version Not Supported" }, | |
{ 506, "Variant Also Negotiates" }, | |
{ 507, "Insufficient Storage" }, | |
{ 508, "Loop Detected" }, | |
{ 510, "Not Extended" }, | |
{ 511, "Network Authentication Required" }, | |
}; | |
/// <summary> | |
/// Gets the reason phrase for the specified status code. | |
/// </summary> | |
/// <param name="statusCode">The status code.</param> | |
/// <returns>The reason phrase, or <see cref="string.Empty"/> if the status code is unknown.</returns> | |
public static string GetReasonPhrase(int statusCode) | |
{ | |
return Phrases.TryGetValue(statusCode, out var phrase) ? phrase : string.Empty; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment