Skip to main content

go_http/
status.rs

1// SPDX-License-Identifier: Apache-2.0
2
3// 1xx
4pub const CONTINUE: u16 = 100;
5pub const SWITCHING_PROTOCOLS: u16 = 101;
6pub const PROCESSING: u16 = 102;
7pub const EARLY_HINTS: u16 = 103;
8
9// 2xx
10pub const OK: u16 = 200;
11pub const CREATED: u16 = 201;
12pub const ACCEPTED: u16 = 202;
13pub const NON_AUTHORITATIVE_INFO: u16 = 203;
14pub const NO_CONTENT: u16 = 204;
15pub const RESET_CONTENT: u16 = 205;
16pub const PARTIAL_CONTENT: u16 = 206;
17pub const MULTI_STATUS: u16 = 207;
18pub const ALREADY_REPORTED: u16 = 208;
19pub const IM_USED: u16 = 226;
20
21// 3xx
22pub const MULTIPLE_CHOICES: u16 = 300;
23pub const MOVED_PERMANENTLY: u16 = 301;
24pub const FOUND: u16 = 302;
25pub const SEE_OTHER: u16 = 303;
26pub const NOT_MODIFIED: u16 = 304;
27pub const USE_PROXY: u16 = 305;
28pub const TEMPORARY_REDIRECT: u16 = 307;
29pub const PERMANENT_REDIRECT: u16 = 308;
30
31// 4xx
32pub const BAD_REQUEST: u16 = 400;
33pub const UNAUTHORIZED: u16 = 401;
34pub const PAYMENT_REQUIRED: u16 = 402;
35pub const FORBIDDEN: u16 = 403;
36pub const NOT_FOUND: u16 = 404;
37pub const METHOD_NOT_ALLOWED: u16 = 405;
38pub const NOT_ACCEPTABLE: u16 = 406;
39pub const PROXY_AUTH_REQUIRED: u16 = 407;
40pub const REQUEST_TIMEOUT: u16 = 408;
41pub const CONFLICT: u16 = 409;
42pub const GONE: u16 = 410;
43pub const LENGTH_REQUIRED: u16 = 411;
44pub const PRECONDITION_FAILED: u16 = 412;
45pub const REQUEST_ENTITY_TOO_LARGE: u16 = 413;
46pub const REQUEST_URI_TOO_LONG: u16 = 414;
47pub const UNSUPPORTED_MEDIA_TYPE: u16 = 415;
48pub const REQUESTED_RANGE_NOT_SATISFIABLE: u16 = 416;
49pub const EXPECTATION_FAILED: u16 = 417;
50pub const TEAPOT: u16 = 418;
51pub const MISDIRECTED_REQUEST: u16 = 421;
52pub const UNPROCESSABLE_ENTITY: u16 = 422;
53pub const LOCKED: u16 = 423;
54pub const FAILED_DEPENDENCY: u16 = 424;
55pub const TOO_EARLY: u16 = 425;
56pub const UPGRADE_REQUIRED: u16 = 426;
57pub const PRECONDITION_REQUIRED: u16 = 428;
58pub const TOO_MANY_REQUESTS: u16 = 429;
59pub const REQUEST_HEADER_FIELDS_TOO_LARGE: u16 = 431;
60pub const UNAVAILABLE_FOR_LEGAL_REASONS: u16 = 451;
61
62// 5xx
63pub const INTERNAL_SERVER_ERROR: u16 = 500;
64pub const NOT_IMPLEMENTED: u16 = 501;
65pub const BAD_GATEWAY: u16 = 502;
66pub const SERVICE_UNAVAILABLE: u16 = 503;
67pub const GATEWAY_TIMEOUT: u16 = 504;
68pub const HTTP_VERSION_NOT_SUPPORTED: u16 = 505;
69pub const VARIANT_ALSO_NEGOTIATES: u16 = 506;
70pub const INSUFFICIENT_STORAGE: u16 = 507;
71pub const LOOP_DETECTED: u16 = 508;
72pub const NOT_EXTENDED: u16 = 510;
73pub const NETWORK_AUTHENTICATION_REQUIRED: u16 = 511;
74
75/// Return the canonical reason phrase for a status code, or `""` if unknown.
76/// Mirrors Go's `http.StatusText`.
77pub fn status_text(code: u16) -> &'static str {
78    match code {
79        100 => "Continue",
80        101 => "Switching Protocols",
81        102 => "Processing",
82        103 => "Early Hints",
83        200 => "OK",
84        201 => "Created",
85        202 => "Accepted",
86        203 => "Non-Authoritative Information",
87        204 => "No Content",
88        205 => "Reset Content",
89        206 => "Partial Content",
90        207 => "Multi-Status",
91        208 => "Already Reported",
92        226 => "IM Used",
93        300 => "Multiple Choices",
94        301 => "Moved Permanently",
95        302 => "Found",
96        303 => "See Other",
97        304 => "Not Modified",
98        305 => "Use Proxy",
99        307 => "Temporary Redirect",
100        308 => "Permanent Redirect",
101        400 => "Bad Request",
102        401 => "Unauthorized",
103        402 => "Payment Required",
104        403 => "Forbidden",
105        404 => "Not Found",
106        405 => "Method Not Allowed",
107        406 => "Not Acceptable",
108        407 => "Proxy Authentication Required",
109        408 => "Request Timeout",
110        409 => "Conflict",
111        410 => "Gone",
112        411 => "Length Required",
113        412 => "Precondition Failed",
114        413 => "Request Entity Too Large",
115        414 => "Request-URI Too Long",
116        415 => "Unsupported Media Type",
117        416 => "Requested Range Not Satisfiable",
118        417 => "Expectation Failed",
119        418 => "I'm a teapot",
120        421 => "Misdirected Request",
121        422 => "Unprocessable Entity",
122        423 => "Locked",
123        424 => "Failed Dependency",
124        425 => "Too Early",
125        426 => "Upgrade Required",
126        428 => "Precondition Required",
127        429 => "Too Many Requests",
128        431 => "Request Header Fields Too Large",
129        451 => "Unavailable For Legal Reasons",
130        500 => "Internal Server Error",
131        501 => "Not Implemented",
132        502 => "Bad Gateway",
133        503 => "Service Unavailable",
134        504 => "Gateway Timeout",
135        505 => "HTTP Version Not Supported",
136        506 => "Variant Also Negotiates",
137        507 => "Insufficient Storage",
138        508 => "Loop Detected",
139        510 => "Not Extended",
140        511 => "Network Authentication Required",
141        _ => "",
142    }
143}
144
145#[cfg(test)]
146mod tests {
147    use super::*;
148
149    #[test]
150    fn known_codes() {
151        assert_eq!(status_text(200), "OK");
152        assert_eq!(status_text(404), "Not Found");
153        assert_eq!(status_text(500), "Internal Server Error");
154        assert_eq!(status_text(418), "I'm a teapot");
155    }
156
157    #[test]
158    fn unknown_code() {
159        assert_eq!(status_text(999), "");
160        assert_eq!(status_text(0), "");
161        assert_eq!(status_text(600), "");
162    }
163
164    #[test]
165    fn every_known_code_has_text() {
166        // Exercise every arm of status_text and confirm the constants map to
167        // their canonical reason phrases.
168        let cases: &[(u16, &str)] = &[
169            (CONTINUE, "Continue"),
170            (SWITCHING_PROTOCOLS, "Switching Protocols"),
171            (PROCESSING, "Processing"),
172            (EARLY_HINTS, "Early Hints"),
173            (OK, "OK"),
174            (CREATED, "Created"),
175            (ACCEPTED, "Accepted"),
176            (NON_AUTHORITATIVE_INFO, "Non-Authoritative Information"),
177            (NO_CONTENT, "No Content"),
178            (RESET_CONTENT, "Reset Content"),
179            (PARTIAL_CONTENT, "Partial Content"),
180            (MULTI_STATUS, "Multi-Status"),
181            (ALREADY_REPORTED, "Already Reported"),
182            (IM_USED, "IM Used"),
183            (MULTIPLE_CHOICES, "Multiple Choices"),
184            (MOVED_PERMANENTLY, "Moved Permanently"),
185            (FOUND, "Found"),
186            (SEE_OTHER, "See Other"),
187            (NOT_MODIFIED, "Not Modified"),
188            (USE_PROXY, "Use Proxy"),
189            (TEMPORARY_REDIRECT, "Temporary Redirect"),
190            (PERMANENT_REDIRECT, "Permanent Redirect"),
191            (BAD_REQUEST, "Bad Request"),
192            (UNAUTHORIZED, "Unauthorized"),
193            (PAYMENT_REQUIRED, "Payment Required"),
194            (FORBIDDEN, "Forbidden"),
195            (NOT_FOUND, "Not Found"),
196            (METHOD_NOT_ALLOWED, "Method Not Allowed"),
197            (NOT_ACCEPTABLE, "Not Acceptable"),
198            (PROXY_AUTH_REQUIRED, "Proxy Authentication Required"),
199            (REQUEST_TIMEOUT, "Request Timeout"),
200            (CONFLICT, "Conflict"),
201            (GONE, "Gone"),
202            (LENGTH_REQUIRED, "Length Required"),
203            (PRECONDITION_FAILED, "Precondition Failed"),
204            (REQUEST_ENTITY_TOO_LARGE, "Request Entity Too Large"),
205            (REQUEST_URI_TOO_LONG, "Request-URI Too Long"),
206            (UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"),
207            (REQUESTED_RANGE_NOT_SATISFIABLE, "Requested Range Not Satisfiable"),
208            (EXPECTATION_FAILED, "Expectation Failed"),
209            (TEAPOT, "I'm a teapot"),
210            (MISDIRECTED_REQUEST, "Misdirected Request"),
211            (UNPROCESSABLE_ENTITY, "Unprocessable Entity"),
212            (LOCKED, "Locked"),
213            (FAILED_DEPENDENCY, "Failed Dependency"),
214            (TOO_EARLY, "Too Early"),
215            (UPGRADE_REQUIRED, "Upgrade Required"),
216            (PRECONDITION_REQUIRED, "Precondition Required"),
217            (TOO_MANY_REQUESTS, "Too Many Requests"),
218            (REQUEST_HEADER_FIELDS_TOO_LARGE, "Request Header Fields Too Large"),
219            (UNAVAILABLE_FOR_LEGAL_REASONS, "Unavailable For Legal Reasons"),
220            (INTERNAL_SERVER_ERROR, "Internal Server Error"),
221            (NOT_IMPLEMENTED, "Not Implemented"),
222            (BAD_GATEWAY, "Bad Gateway"),
223            (SERVICE_UNAVAILABLE, "Service Unavailable"),
224            (GATEWAY_TIMEOUT, "Gateway Timeout"),
225            (HTTP_VERSION_NOT_SUPPORTED, "HTTP Version Not Supported"),
226            (VARIANT_ALSO_NEGOTIATES, "Variant Also Negotiates"),
227            (INSUFFICIENT_STORAGE, "Insufficient Storage"),
228            (LOOP_DETECTED, "Loop Detected"),
229            (NOT_EXTENDED, "Not Extended"),
230            (NETWORK_AUTHENTICATION_REQUIRED, "Network Authentication Required"),
231        ];
232        for (code, text) in cases {
233            assert_eq!(status_text(*code), *text, "wrong text for {code}");
234        }
235    }
236}