Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4fc1a87

Browse files
authored
Perf: ReasonPhrases as Array instead of Dictionary (#56304)
1 parent 8aec8fd commit 4fc1a87

File tree

5 files changed

+180
-174
lines changed

5 files changed

+180
-174
lines changed

src/Http/WebUtilities/src/ReasonPhrases.cs

+174-71
Original file line numberDiff line numberDiff line change
@@ -10,76 +10,170 @@ namespace Microsoft.AspNetCore.WebUtilities;
1010
public static class ReasonPhrases
1111
{
1212
// Status Codes listed at http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
13-
private static readonly Dictionary<int, string> Phrases = new()
14-
{
15-
{ 100, "Continue" },
16-
{ 101, "Switching Protocols" },
17-
{ 102, "Processing" },
18-
19-
{ 200, "OK" },
20-
{ 201, "Created" },
21-
{ 202, "Accepted" },
22-
{ 203, "Non-Authoritative Information" },
23-
{ 204, "No Content" },
24-
{ 205, "Reset Content" },
25-
{ 206, "Partial Content" },
26-
{ 207, "Multi-Status" },
27-
{ 208, "Already Reported" },
28-
{ 226, "IM Used" },
29-
30-
{ 300, "Multiple Choices" },
31-
{ 301, "Moved Permanently" },
32-
{ 302, "Found" },
33-
{ 303, "See Other" },
34-
{ 304, "Not Modified" },
35-
{ 305, "Use Proxy" },
36-
{ 306, "Switch Proxy" },
37-
{ 307, "Temporary Redirect" },
38-
{ 308, "Permanent Redirect" },
39-
40-
{ 400, "Bad Request" },
41-
{ 401, "Unauthorized" },
42-
{ 402, "Payment Required" },
43-
{ 403, "Forbidden" },
44-
{ 404, "Not Found" },
45-
{ 405, "Method Not Allowed" },
46-
{ 406, "Not Acceptable" },
47-
{ 407, "Proxy Authentication Required" },
48-
{ 408, "Request Timeout" },
49-
{ 409, "Conflict" },
50-
{ 410, "Gone" },
51-
{ 411, "Length Required" },
52-
{ 412, "Precondition Failed" },
53-
{ 413, "Payload Too Large" },
54-
{ 414, "URI Too Long" },
55-
{ 415, "Unsupported Media Type" },
56-
{ 416, "Range Not Satisfiable" },
57-
{ 417, "Expectation Failed" },
58-
{ 418, "I'm a teapot" },
59-
{ 419, "Authentication Timeout" },
60-
{ 421, "Misdirected Request" },
61-
{ 422, "Unprocessable Entity" },
62-
{ 423, "Locked" },
63-
{ 424, "Failed Dependency" },
64-
{ 426, "Upgrade Required" },
65-
{ 428, "Precondition Required" },
66-
{ 429, "Too Many Requests" },
67-
{ 431, "Request Header Fields Too Large" },
68-
{ 451, "Unavailable For Legal Reasons" },
69-
{ 499, "Client Closed Request" },
70-
71-
{ 500, "Internal Server Error" },
72-
{ 501, "Not Implemented" },
73-
{ 502, "Bad Gateway" },
74-
{ 503, "Service Unavailable" },
75-
{ 504, "Gateway Timeout" },
76-
{ 505, "HTTP Version Not Supported" },
77-
{ 506, "Variant Also Negotiates" },
78-
{ 507, "Insufficient Storage" },
79-
{ 508, "Loop Detected" },
80-
{ 510, "Not Extended" },
81-
{ 511, "Network Authentication Required" },
82-
};
13+
private static readonly string[][] HttpReasonPhrases = [
14+
[],
15+
[
16+
/* 100 */ "Continue",
17+
/* 101 */ "Switching Protocols",
18+
/* 102 */ "Processing"
19+
],
20+
[
21+
/* 200 */ "OK",
22+
/* 201 */ "Created",
23+
/* 202 */ "Accepted",
24+
/* 203 */ "Non-Authoritative Information",
25+
/* 204 */ "No Content",
26+
/* 205 */ "Reset Content",
27+
/* 206 */ "Partial Content",
28+
/* 207 */ "Multi-Status",
29+
/* 208 */ "Already Reported",
30+
/* 209 */ string.Empty,
31+
/* 210 */ string.Empty,
32+
/* 211 */ string.Empty,
33+
/* 212 */ string.Empty,
34+
/* 213 */ string.Empty,
35+
/* 214 */ string.Empty,
36+
/* 215 */ string.Empty,
37+
/* 216 */ string.Empty,
38+
/* 217 */ string.Empty,
39+
/* 218 */ string.Empty,
40+
/* 219 */ string.Empty,
41+
/* 220 */ string.Empty,
42+
/* 221 */ string.Empty,
43+
/* 222 */ string.Empty,
44+
/* 223 */ string.Empty,
45+
/* 224 */ string.Empty,
46+
/* 225 */ string.Empty,
47+
/* 226 */ "IM Used"
48+
],
49+
[
50+
/* 300 */ "Multiple Choices",
51+
/* 301 */ "Moved Permanently",
52+
/* 302 */ "Found",
53+
/* 303 */ "See Other",
54+
/* 304 */ "Not Modified",
55+
/* 305 */ "Use Proxy",
56+
/* 306 */ "Switch Proxy",
57+
/* 307 */ "Temporary Redirect",
58+
/* 308 */ "Permanent Redirect"
59+
],
60+
[
61+
/* 400 */ "Bad Request",
62+
/* 401 */ "Unauthorized",
63+
/* 402 */ "Payment Required",
64+
/* 403 */ "Forbidden",
65+
/* 404 */ "Not Found",
66+
/* 405 */ "Method Not Allowed",
67+
/* 406 */ "Not Acceptable",
68+
/* 407 */ "Proxy Authentication Required",
69+
/* 408 */ "Request Timeout",
70+
/* 409 */ "Conflict",
71+
/* 410 */ "Gone",
72+
/* 411 */ "Length Required",
73+
/* 412 */ "Precondition Failed",
74+
/* 413 */ "Payload Too Large",
75+
/* 414 */ "URI Too Long",
76+
/* 415 */ "Unsupported Media Type",
77+
/* 416 */ "Range Not Satisfiable",
78+
/* 417 */ "Expectation Failed",
79+
/* 418 */ "I'm a teapot",
80+
/* 419 */ "Authentication Timeout",
81+
/* 420 */ string.Empty,
82+
/* 421 */ "Misdirected Request",
83+
/* 422 */ "Unprocessable Entity",
84+
/* 423 */ "Locked",
85+
/* 424 */ "Failed Dependency",
86+
/* 425 */ string.Empty,
87+
/* 426 */ "Upgrade Required",
88+
/* 427 */ string.Empty,
89+
/* 428 */ "Precondition Required",
90+
/* 429 */ "Too Many Requests",
91+
/* 430 */ string.Empty,
92+
/* 431 */ "Request Header Fields Too Large",
93+
/* 432 */ string.Empty,
94+
/* 433 */ string.Empty,
95+
/* 434 */ string.Empty,
96+
/* 435 */ string.Empty,
97+
/* 436 */ string.Empty,
98+
/* 437 */ string.Empty,
99+
/* 438 */ string.Empty,
100+
/* 439 */ string.Empty,
101+
/* 440 */ string.Empty,
102+
/* 441 */ string.Empty,
103+
/* 442 */ string.Empty,
104+
/* 443 */ string.Empty,
105+
/* 444 */ string.Empty,
106+
/* 445 */ string.Empty,
107+
/* 446 */ string.Empty,
108+
/* 447 */ string.Empty,
109+
/* 448 */ string.Empty,
110+
/* 449 */ string.Empty,
111+
/* 450 */ string.Empty,
112+
/* 451 */ "Unavailable For Legal Reasons",
113+
/* 452 */ string.Empty,
114+
/* 453 */ string.Empty,
115+
/* 454 */ string.Empty,
116+
/* 455 */ string.Empty,
117+
/* 456 */ string.Empty,
118+
/* 457 */ string.Empty,
119+
/* 458 */ string.Empty,
120+
/* 459 */ string.Empty,
121+
/* 460 */ string.Empty,
122+
/* 461 */ string.Empty,
123+
/* 462 */ string.Empty,
124+
/* 463 */ string.Empty,
125+
/* 464 */ string.Empty,
126+
/* 465 */ string.Empty,
127+
/* 466 */ string.Empty,
128+
/* 467 */ string.Empty,
129+
/* 468 */ string.Empty,
130+
/* 469 */ string.Empty,
131+
/* 470 */ string.Empty,
132+
/* 471 */ string.Empty,
133+
/* 472 */ string.Empty,
134+
/* 473 */ string.Empty,
135+
/* 474 */ string.Empty,
136+
/* 475 */ string.Empty,
137+
/* 476 */ string.Empty,
138+
/* 477 */ string.Empty,
139+
/* 478 */ string.Empty,
140+
/* 479 */ string.Empty,
141+
/* 480 */ string.Empty,
142+
/* 481 */ string.Empty,
143+
/* 482 */ string.Empty,
144+
/* 483 */ string.Empty,
145+
/* 484 */ string.Empty,
146+
/* 485 */ string.Empty,
147+
/* 486 */ string.Empty,
148+
/* 487 */ string.Empty,
149+
/* 488 */ string.Empty,
150+
/* 489 */ string.Empty,
151+
/* 490 */ string.Empty,
152+
/* 491 */ string.Empty,
153+
/* 492 */ string.Empty,
154+
/* 493 */ string.Empty,
155+
/* 494 */ string.Empty,
156+
/* 495 */ string.Empty,
157+
/* 496 */ string.Empty,
158+
/* 497 */ string.Empty,
159+
/* 498 */ string.Empty,
160+
/* 499 */ "Client Closed Request"
161+
],
162+
[
163+
/* 500 */ "Internal Server Error",
164+
/* 501 */ "Not Implemented",
165+
/* 502 */ "Bad Gateway",
166+
/* 503 */ "Service Unavailable",
167+
/* 504 */ "Gateway Timeout",
168+
/* 505 */ "HTTP Version Not Supported",
169+
/* 506 */ "Variant Also Negotiates",
170+
/* 507 */ "Insufficient Storage",
171+
/* 508 */ "Loop Detected",
172+
/* 509 */ string.Empty,
173+
/* 510 */ "Not Extended",
174+
/* 511 */ "Network Authentication Required"
175+
]
176+
];
83177

84178
/// <summary>
85179
/// Gets the reason phrase for the specified status code.
@@ -88,6 +182,15 @@ public static class ReasonPhrases
88182
/// <returns>The reason phrase, or <see cref="string.Empty"/> if the status code is unknown.</returns>
89183
public static string GetReasonPhrase(int statusCode)
90184
{
91-
return Phrases.TryGetValue(statusCode, out var phrase) ? phrase : string.Empty;
185+
if ((uint)(statusCode - 100) < 500)
186+
{
187+
var (i, j) = Math.DivRem((uint)statusCode, 100);
188+
string[] phrases = HttpReasonPhrases[i];
189+
if (j < (uint)phrases.Length)
190+
{
191+
return phrases[j];
192+
}
193+
}
194+
return string.Empty;
92195
}
93196
}

src/Servers/HttpSys/src/HttpSysListener.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Diagnostics;
66
using Microsoft.AspNetCore.Http;
77
using Microsoft.AspNetCore.HttpSys.Internal;
8+
using Microsoft.AspNetCore.WebUtilities;
89
using Microsoft.Extensions.Logging;
910
using Windows.Win32;
1011
using Windows.Win32.Foundation;
@@ -352,7 +353,7 @@ internal unsafe void SendError(ulong requestId, int httpStatusCode, IList<string
352353
}
353354

354355
httpResponse.Base.StatusCode = checked((ushort)httpStatusCode);
355-
var statusDescription = HttpReasonPhrase.Get(httpStatusCode) ?? string.Empty;
356+
var statusDescription = ReasonPhrases.GetReasonPhrase(httpStatusCode);
356357
uint dataWritten = 0;
357358
uint statusCode;
358359

src/Servers/HttpSys/src/RequestProcessing/HttpReasonPhrase.cs

-100
This file was deleted.

src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Security.Principal;
66
using Microsoft.AspNetCore.Http;
77
using Microsoft.AspNetCore.HttpSys.Internal;
8+
using Microsoft.AspNetCore.WebUtilities;
89
using Microsoft.Extensions.Logging;
910
using Windows.Win32;
1011
using Windows.Win32.Networking.HttpServer;
@@ -101,7 +102,7 @@ public Task<Stream> UpgradeAsync()
101102

102103
// Set the status code and reason phrase
103104
Response.StatusCode = StatusCodes.Status101SwitchingProtocols;
104-
Response.ReasonPhrase = HttpReasonPhrase.Get(StatusCodes.Status101SwitchingProtocols);
105+
Response.ReasonPhrase = ReasonPhrases.GetReasonPhrase(StatusCodes.Status101SwitchingProtocols);
105106

106107
Response.SendOpaqueUpgrade(); // TODO: Async
107108
Request.SwitchToOpaqueMode();

0 commit comments

Comments
 (0)