1 | //! HTTP status codes |
2 | //! |
3 | //! This module contains HTTP-status code related structs an errors. The main |
4 | //! type in this module is `StatusCode` which is not intended to be used through |
5 | //! this module but rather the `http::StatusCode` type. |
6 | //! |
7 | //! # Examples |
8 | //! |
9 | //! ``` |
10 | //! use http::StatusCode; |
11 | //! |
12 | //! assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK); |
13 | //! assert_eq!(StatusCode::NOT_FOUND, 404); |
14 | //! assert!(StatusCode::OK.is_success()); |
15 | //! ``` |
16 | |
17 | use std::convert::TryFrom; |
18 | use std::num::NonZeroU16; |
19 | use std::error::Error; |
20 | use std::fmt; |
21 | use std::str::FromStr; |
22 | |
23 | /// An HTTP status code (`status-code` in RFC 7230 et al.). |
24 | /// |
25 | /// Constants are provided for known status codes, including those in the IANA |
26 | /// [HTTP Status Code Registry]( |
27 | /// https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml). |
28 | /// |
29 | /// Status code values in the range 100-999 (inclusive) are supported by this |
30 | /// type. Values in the range 100-599 are semantically classified by the most |
31 | /// significant digit. See [`StatusCode::is_success`], etc. Values above 599 |
32 | /// are unclassified but allowed for legacy compatibility, though their use is |
33 | /// discouraged. Applications may interpret such values as protocol errors. |
34 | /// |
35 | /// # Examples |
36 | /// |
37 | /// ``` |
38 | /// use http::StatusCode; |
39 | /// |
40 | /// assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK); |
41 | /// assert_eq!(StatusCode::NOT_FOUND.as_u16(), 404); |
42 | /// assert!(StatusCode::OK.is_success()); |
43 | /// ``` |
44 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
45 | pub struct StatusCode(NonZeroU16); |
46 | |
47 | /// A possible error value when converting a `StatusCode` from a `u16` or `&str` |
48 | /// |
49 | /// This error indicates that the supplied input was not a valid number, was less |
50 | /// than 100, or was greater than 999. |
51 | pub struct InvalidStatusCode { |
52 | _priv: (), |
53 | } |
54 | |
55 | impl StatusCode { |
56 | /// Converts a u16 to a status code. |
57 | /// |
58 | /// The function validates the correctness of the supplied u16. It must be |
59 | /// greater or equal to 100 and less than 1000. |
60 | /// |
61 | /// # Example |
62 | /// |
63 | /// ``` |
64 | /// use http::StatusCode; |
65 | /// |
66 | /// let ok = StatusCode::from_u16(200).unwrap(); |
67 | /// assert_eq!(ok, StatusCode::OK); |
68 | /// |
69 | /// let err = StatusCode::from_u16(99); |
70 | /// assert!(err.is_err()); |
71 | /// ``` |
72 | #[inline ] |
73 | pub fn from_u16(src: u16) -> Result<StatusCode, InvalidStatusCode> { |
74 | if src < 100 || src >= 1000 { |
75 | return Err(InvalidStatusCode::new()); |
76 | } |
77 | |
78 | NonZeroU16::new(src) |
79 | .map(StatusCode) |
80 | .ok_or_else(InvalidStatusCode::new) |
81 | } |
82 | |
83 | /// Converts a &[u8] to a status code |
84 | pub fn from_bytes(src: &[u8]) -> Result<StatusCode, InvalidStatusCode> { |
85 | if src.len() != 3 { |
86 | return Err(InvalidStatusCode::new()); |
87 | } |
88 | |
89 | let a = src[0].wrapping_sub(b'0' ) as u16; |
90 | let b = src[1].wrapping_sub(b'0' ) as u16; |
91 | let c = src[2].wrapping_sub(b'0' ) as u16; |
92 | |
93 | if a == 0 || a > 9 || b > 9 || c > 9 { |
94 | return Err(InvalidStatusCode::new()); |
95 | } |
96 | |
97 | let status = (a * 100) + (b * 10) + c; |
98 | NonZeroU16::new(status) |
99 | .map(StatusCode) |
100 | .ok_or_else(InvalidStatusCode::new) |
101 | } |
102 | |
103 | /// Returns the `u16` corresponding to this `StatusCode`. |
104 | /// |
105 | /// # Note |
106 | /// |
107 | /// This is the same as the `From<StatusCode>` implementation, but |
108 | /// included as an inherent method because that implementation doesn't |
109 | /// appear in rustdocs, as well as a way to force the type instead of |
110 | /// relying on inference. |
111 | /// |
112 | /// # Example |
113 | /// |
114 | /// ``` |
115 | /// let status = http::StatusCode::OK; |
116 | /// assert_eq!(status.as_u16(), 200); |
117 | /// ``` |
118 | #[inline ] |
119 | pub fn as_u16(&self) -> u16 { |
120 | (*self).into() |
121 | } |
122 | |
123 | /// Returns a &str representation of the `StatusCode` |
124 | /// |
125 | /// The return value only includes a numerical representation of the |
126 | /// status code. The canonical reason is not included. |
127 | /// |
128 | /// # Example |
129 | /// |
130 | /// ``` |
131 | /// let status = http::StatusCode::OK; |
132 | /// assert_eq!(status.as_str(), "200" ); |
133 | /// ``` |
134 | #[inline ] |
135 | pub fn as_str(&self) -> &str { |
136 | let offset = (self.0.get() - 100) as usize; |
137 | let offset = offset * 3; |
138 | |
139 | // Invariant: self has checked range [100, 999] and CODE_DIGITS is |
140 | // ASCII-only, of length 900 * 3 = 2700 bytes |
141 | |
142 | #[cfg (debug_assertions)] |
143 | { &CODE_DIGITS[offset..offset+3] } |
144 | |
145 | #[cfg (not(debug_assertions))] |
146 | unsafe { CODE_DIGITS.get_unchecked(offset..offset+3) } |
147 | } |
148 | |
149 | /// Get the standardised `reason-phrase` for this status code. |
150 | /// |
151 | /// This is mostly here for servers writing responses, but could potentially have application |
152 | /// at other times. |
153 | /// |
154 | /// The reason phrase is defined as being exclusively for human readers. You should avoid |
155 | /// deriving any meaning from it at all costs. |
156 | /// |
157 | /// Bear in mind also that in HTTP/2.0 and HTTP/3.0 the reason phrase is abolished from |
158 | /// transmission, and so this canonical reason phrase really is the only reason phrase you’ll |
159 | /// find. |
160 | /// |
161 | /// # Example |
162 | /// |
163 | /// ``` |
164 | /// let status = http::StatusCode::OK; |
165 | /// assert_eq!(status.canonical_reason(), Some("OK" )); |
166 | /// ``` |
167 | pub fn canonical_reason(&self) -> Option<&'static str> { |
168 | canonical_reason(self.0.get()) |
169 | } |
170 | |
171 | /// Check if status is within 100-199. |
172 | #[inline ] |
173 | pub fn is_informational(&self) -> bool { |
174 | 200 > self.0.get() && self.0.get() >= 100 |
175 | } |
176 | |
177 | /// Check if status is within 200-299. |
178 | #[inline ] |
179 | pub fn is_success(&self) -> bool { |
180 | 300 > self.0.get() && self.0.get() >= 200 |
181 | } |
182 | |
183 | /// Check if status is within 300-399. |
184 | #[inline ] |
185 | pub fn is_redirection(&self) -> bool { |
186 | 400 > self.0.get() && self.0.get() >= 300 |
187 | } |
188 | |
189 | /// Check if status is within 400-499. |
190 | #[inline ] |
191 | pub fn is_client_error(&self) -> bool { |
192 | 500 > self.0.get() && self.0.get() >= 400 |
193 | } |
194 | |
195 | /// Check if status is within 500-599. |
196 | #[inline ] |
197 | pub fn is_server_error(&self) -> bool { |
198 | 600 > self.0.get() && self.0.get() >= 500 |
199 | } |
200 | } |
201 | |
202 | impl fmt::Debug for StatusCode { |
203 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
204 | fmt::Debug::fmt(&self.0, f) |
205 | } |
206 | } |
207 | |
208 | /// Formats the status code, *including* the canonical reason. |
209 | /// |
210 | /// # Example |
211 | /// |
212 | /// ``` |
213 | /// # use http::StatusCode; |
214 | /// assert_eq!(format!("{}" , StatusCode::OK), "200 OK" ); |
215 | /// ``` |
216 | impl fmt::Display for StatusCode { |
217 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
218 | write!( |
219 | f, |
220 | "{} {}" , |
221 | u16::from(*self), |
222 | self.canonical_reason().unwrap_or("<unknown status code>" ) |
223 | ) |
224 | } |
225 | } |
226 | |
227 | impl Default for StatusCode { |
228 | #[inline ] |
229 | fn default() -> StatusCode { |
230 | StatusCode::OK |
231 | } |
232 | } |
233 | |
234 | impl PartialEq<u16> for StatusCode { |
235 | #[inline ] |
236 | fn eq(&self, other: &u16) -> bool { |
237 | self.as_u16() == *other |
238 | } |
239 | } |
240 | |
241 | impl PartialEq<StatusCode> for u16 { |
242 | #[inline ] |
243 | fn eq(&self, other: &StatusCode) -> bool { |
244 | *self == other.as_u16() |
245 | } |
246 | } |
247 | |
248 | impl From<StatusCode> for u16 { |
249 | #[inline ] |
250 | fn from(status: StatusCode) -> u16 { |
251 | status.0.get() |
252 | } |
253 | } |
254 | |
255 | impl FromStr for StatusCode { |
256 | type Err = InvalidStatusCode; |
257 | |
258 | fn from_str(s: &str) -> Result<StatusCode, InvalidStatusCode> { |
259 | StatusCode::from_bytes(s.as_ref()) |
260 | } |
261 | } |
262 | |
263 | impl<'a> From<&'a StatusCode> for StatusCode { |
264 | #[inline ] |
265 | fn from(t: &'a StatusCode) -> Self { |
266 | t.clone() |
267 | } |
268 | } |
269 | |
270 | impl<'a> TryFrom<&'a [u8]> for StatusCode { |
271 | type Error = InvalidStatusCode; |
272 | |
273 | #[inline ] |
274 | fn try_from(t: &'a [u8]) -> Result<Self, Self::Error> { |
275 | StatusCode::from_bytes(t) |
276 | } |
277 | } |
278 | |
279 | impl<'a> TryFrom<&'a str> for StatusCode { |
280 | type Error = InvalidStatusCode; |
281 | |
282 | #[inline ] |
283 | fn try_from(t: &'a str) -> Result<Self, Self::Error> { |
284 | t.parse() |
285 | } |
286 | } |
287 | |
288 | impl TryFrom<u16> for StatusCode { |
289 | type Error = InvalidStatusCode; |
290 | |
291 | #[inline ] |
292 | fn try_from(t: u16) -> Result<Self, Self::Error> { |
293 | StatusCode::from_u16(t) |
294 | } |
295 | } |
296 | |
297 | macro_rules! status_codes { |
298 | ( |
299 | $( |
300 | $(#[$docs:meta])* |
301 | ($num:expr, $konst:ident, $phrase:expr); |
302 | )+ |
303 | ) => { |
304 | impl StatusCode { |
305 | $( |
306 | $(#[$docs])* |
307 | pub const $konst: StatusCode = StatusCode(unsafe { NonZeroU16::new_unchecked($num) }); |
308 | )+ |
309 | |
310 | } |
311 | |
312 | fn canonical_reason(num: u16) -> Option<&'static str> { |
313 | match num { |
314 | $( |
315 | $num => Some($phrase), |
316 | )+ |
317 | _ => None |
318 | } |
319 | } |
320 | } |
321 | } |
322 | |
323 | status_codes! { |
324 | /// 100 Continue |
325 | /// [[RFC7231, Section 6.2.1](https://tools.ietf.org/html/rfc7231#section-6.2.1)] |
326 | (100, CONTINUE, "Continue" ); |
327 | /// 101 Switching Protocols |
328 | /// [[RFC7231, Section 6.2.2](https://tools.ietf.org/html/rfc7231#section-6.2.2)] |
329 | (101, SWITCHING_PROTOCOLS, "Switching Protocols" ); |
330 | /// 102 Processing |
331 | /// [[RFC2518](https://tools.ietf.org/html/rfc2518)] |
332 | (102, PROCESSING, "Processing" ); |
333 | |
334 | /// 200 OK |
335 | /// [[RFC7231, Section 6.3.1](https://tools.ietf.org/html/rfc7231#section-6.3.1)] |
336 | (200, OK, "OK" ); |
337 | /// 201 Created |
338 | /// [[RFC7231, Section 6.3.2](https://tools.ietf.org/html/rfc7231#section-6.3.2)] |
339 | (201, CREATED, "Created" ); |
340 | /// 202 Accepted |
341 | /// [[RFC7231, Section 6.3.3](https://tools.ietf.org/html/rfc7231#section-6.3.3)] |
342 | (202, ACCEPTED, "Accepted" ); |
343 | /// 203 Non-Authoritative Information |
344 | /// [[RFC7231, Section 6.3.4](https://tools.ietf.org/html/rfc7231#section-6.3.4)] |
345 | (203, NON_AUTHORITATIVE_INFORMATION, "Non Authoritative Information" ); |
346 | /// 204 No Content |
347 | /// [[RFC7231, Section 6.3.5](https://tools.ietf.org/html/rfc7231#section-6.3.5)] |
348 | (204, NO_CONTENT, "No Content" ); |
349 | /// 205 Reset Content |
350 | /// [[RFC7231, Section 6.3.6](https://tools.ietf.org/html/rfc7231#section-6.3.6)] |
351 | (205, RESET_CONTENT, "Reset Content" ); |
352 | /// 206 Partial Content |
353 | /// [[RFC7233, Section 4.1](https://tools.ietf.org/html/rfc7233#section-4.1)] |
354 | (206, PARTIAL_CONTENT, "Partial Content" ); |
355 | /// 207 Multi-Status |
356 | /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
357 | (207, MULTI_STATUS, "Multi-Status" ); |
358 | /// 208 Already Reported |
359 | /// [[RFC5842](https://tools.ietf.org/html/rfc5842)] |
360 | (208, ALREADY_REPORTED, "Already Reported" ); |
361 | |
362 | /// 226 IM Used |
363 | /// [[RFC3229](https://tools.ietf.org/html/rfc3229)] |
364 | (226, IM_USED, "IM Used" ); |
365 | |
366 | /// 300 Multiple Choices |
367 | /// [[RFC7231, Section 6.4.1](https://tools.ietf.org/html/rfc7231#section-6.4.1)] |
368 | (300, MULTIPLE_CHOICES, "Multiple Choices" ); |
369 | /// 301 Moved Permanently |
370 | /// [[RFC7231, Section 6.4.2](https://tools.ietf.org/html/rfc7231#section-6.4.2)] |
371 | (301, MOVED_PERMANENTLY, "Moved Permanently" ); |
372 | /// 302 Found |
373 | /// [[RFC7231, Section 6.4.3](https://tools.ietf.org/html/rfc7231#section-6.4.3)] |
374 | (302, FOUND, "Found" ); |
375 | /// 303 See Other |
376 | /// [[RFC7231, Section 6.4.4](https://tools.ietf.org/html/rfc7231#section-6.4.4)] |
377 | (303, SEE_OTHER, "See Other" ); |
378 | /// 304 Not Modified |
379 | /// [[RFC7232, Section 4.1](https://tools.ietf.org/html/rfc7232#section-4.1)] |
380 | (304, NOT_MODIFIED, "Not Modified" ); |
381 | /// 305 Use Proxy |
382 | /// [[RFC7231, Section 6.4.5](https://tools.ietf.org/html/rfc7231#section-6.4.5)] |
383 | (305, USE_PROXY, "Use Proxy" ); |
384 | /// 307 Temporary Redirect |
385 | /// [[RFC7231, Section 6.4.7](https://tools.ietf.org/html/rfc7231#section-6.4.7)] |
386 | (307, TEMPORARY_REDIRECT, "Temporary Redirect" ); |
387 | /// 308 Permanent Redirect |
388 | /// [[RFC7238](https://tools.ietf.org/html/rfc7238)] |
389 | (308, PERMANENT_REDIRECT, "Permanent Redirect" ); |
390 | |
391 | /// 400 Bad Request |
392 | /// [[RFC7231, Section 6.5.1](https://tools.ietf.org/html/rfc7231#section-6.5.1)] |
393 | (400, BAD_REQUEST, "Bad Request" ); |
394 | /// 401 Unauthorized |
395 | /// [[RFC7235, Section 3.1](https://tools.ietf.org/html/rfc7235#section-3.1)] |
396 | (401, UNAUTHORIZED, "Unauthorized" ); |
397 | /// 402 Payment Required |
398 | /// [[RFC7231, Section 6.5.2](https://tools.ietf.org/html/rfc7231#section-6.5.2)] |
399 | (402, PAYMENT_REQUIRED, "Payment Required" ); |
400 | /// 403 Forbidden |
401 | /// [[RFC7231, Section 6.5.3](https://tools.ietf.org/html/rfc7231#section-6.5.3)] |
402 | (403, FORBIDDEN, "Forbidden" ); |
403 | /// 404 Not Found |
404 | /// [[RFC7231, Section 6.5.4](https://tools.ietf.org/html/rfc7231#section-6.5.4)] |
405 | (404, NOT_FOUND, "Not Found" ); |
406 | /// 405 Method Not Allowed |
407 | /// [[RFC7231, Section 6.5.5](https://tools.ietf.org/html/rfc7231#section-6.5.5)] |
408 | (405, METHOD_NOT_ALLOWED, "Method Not Allowed" ); |
409 | /// 406 Not Acceptable |
410 | /// [[RFC7231, Section 6.5.6](https://tools.ietf.org/html/rfc7231#section-6.5.6)] |
411 | (406, NOT_ACCEPTABLE, "Not Acceptable" ); |
412 | /// 407 Proxy Authentication Required |
413 | /// [[RFC7235, Section 3.2](https://tools.ietf.org/html/rfc7235#section-3.2)] |
414 | (407, PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required" ); |
415 | /// 408 Request Timeout |
416 | /// [[RFC7231, Section 6.5.7](https://tools.ietf.org/html/rfc7231#section-6.5.7)] |
417 | (408, REQUEST_TIMEOUT, "Request Timeout" ); |
418 | /// 409 Conflict |
419 | /// [[RFC7231, Section 6.5.8](https://tools.ietf.org/html/rfc7231#section-6.5.8)] |
420 | (409, CONFLICT, "Conflict" ); |
421 | /// 410 Gone |
422 | /// [[RFC7231, Section 6.5.9](https://tools.ietf.org/html/rfc7231#section-6.5.9)] |
423 | (410, GONE, "Gone" ); |
424 | /// 411 Length Required |
425 | /// [[RFC7231, Section 6.5.10](https://tools.ietf.org/html/rfc7231#section-6.5.10)] |
426 | (411, LENGTH_REQUIRED, "Length Required" ); |
427 | /// 412 Precondition Failed |
428 | /// [[RFC7232, Section 4.2](https://tools.ietf.org/html/rfc7232#section-4.2)] |
429 | (412, PRECONDITION_FAILED, "Precondition Failed" ); |
430 | /// 413 Payload Too Large |
431 | /// [[RFC7231, Section 6.5.11](https://tools.ietf.org/html/rfc7231#section-6.5.11)] |
432 | (413, PAYLOAD_TOO_LARGE, "Payload Too Large" ); |
433 | /// 414 URI Too Long |
434 | /// [[RFC7231, Section 6.5.12](https://tools.ietf.org/html/rfc7231#section-6.5.12)] |
435 | (414, URI_TOO_LONG, "URI Too Long" ); |
436 | /// 415 Unsupported Media Type |
437 | /// [[RFC7231, Section 6.5.13](https://tools.ietf.org/html/rfc7231#section-6.5.13)] |
438 | (415, UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type" ); |
439 | /// 416 Range Not Satisfiable |
440 | /// [[RFC7233, Section 4.4](https://tools.ietf.org/html/rfc7233#section-4.4)] |
441 | (416, RANGE_NOT_SATISFIABLE, "Range Not Satisfiable" ); |
442 | /// 417 Expectation Failed |
443 | /// [[RFC7231, Section 6.5.14](https://tools.ietf.org/html/rfc7231#section-6.5.14)] |
444 | (417, EXPECTATION_FAILED, "Expectation Failed" ); |
445 | /// 418 I'm a teapot |
446 | /// [curiously not registered by IANA but [RFC2324](https://tools.ietf.org/html/rfc2324)] |
447 | (418, IM_A_TEAPOT, "I'm a teapot" ); |
448 | |
449 | /// 421 Misdirected Request |
450 | /// [RFC7540, Section 9.1.2](http://tools.ietf.org/html/rfc7540#section-9.1.2) |
451 | (421, MISDIRECTED_REQUEST, "Misdirected Request" ); |
452 | /// 422 Unprocessable Entity |
453 | /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
454 | (422, UNPROCESSABLE_ENTITY, "Unprocessable Entity" ); |
455 | /// 423 Locked |
456 | /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
457 | (423, LOCKED, "Locked" ); |
458 | /// 424 Failed Dependency |
459 | /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
460 | (424, FAILED_DEPENDENCY, "Failed Dependency" ); |
461 | |
462 | /// 426 Upgrade Required |
463 | /// [[RFC7231, Section 6.5.15](https://tools.ietf.org/html/rfc7231#section-6.5.15)] |
464 | (426, UPGRADE_REQUIRED, "Upgrade Required" ); |
465 | |
466 | /// 428 Precondition Required |
467 | /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] |
468 | (428, PRECONDITION_REQUIRED, "Precondition Required" ); |
469 | /// 429 Too Many Requests |
470 | /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] |
471 | (429, TOO_MANY_REQUESTS, "Too Many Requests" ); |
472 | |
473 | /// 431 Request Header Fields Too Large |
474 | /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] |
475 | (431, REQUEST_HEADER_FIELDS_TOO_LARGE, "Request Header Fields Too Large" ); |
476 | |
477 | /// 451 Unavailable For Legal Reasons |
478 | /// [[RFC7725](http://tools.ietf.org/html/rfc7725)] |
479 | (451, UNAVAILABLE_FOR_LEGAL_REASONS, "Unavailable For Legal Reasons" ); |
480 | |
481 | /// 500 Internal Server Error |
482 | /// [[RFC7231, Section 6.6.1](https://tools.ietf.org/html/rfc7231#section-6.6.1)] |
483 | (500, INTERNAL_SERVER_ERROR, "Internal Server Error" ); |
484 | /// 501 Not Implemented |
485 | /// [[RFC7231, Section 6.6.2](https://tools.ietf.org/html/rfc7231#section-6.6.2)] |
486 | (501, NOT_IMPLEMENTED, "Not Implemented" ); |
487 | /// 502 Bad Gateway |
488 | /// [[RFC7231, Section 6.6.3](https://tools.ietf.org/html/rfc7231#section-6.6.3)] |
489 | (502, BAD_GATEWAY, "Bad Gateway" ); |
490 | /// 503 Service Unavailable |
491 | /// [[RFC7231, Section 6.6.4](https://tools.ietf.org/html/rfc7231#section-6.6.4)] |
492 | (503, SERVICE_UNAVAILABLE, "Service Unavailable" ); |
493 | /// 504 Gateway Timeout |
494 | /// [[RFC7231, Section 6.6.5](https://tools.ietf.org/html/rfc7231#section-6.6.5)] |
495 | (504, GATEWAY_TIMEOUT, "Gateway Timeout" ); |
496 | /// 505 HTTP Version Not Supported |
497 | /// [[RFC7231, Section 6.6.6](https://tools.ietf.org/html/rfc7231#section-6.6.6)] |
498 | (505, HTTP_VERSION_NOT_SUPPORTED, "HTTP Version Not Supported" ); |
499 | /// 506 Variant Also Negotiates |
500 | /// [[RFC2295](https://tools.ietf.org/html/rfc2295)] |
501 | (506, VARIANT_ALSO_NEGOTIATES, "Variant Also Negotiates" ); |
502 | /// 507 Insufficient Storage |
503 | /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] |
504 | (507, INSUFFICIENT_STORAGE, "Insufficient Storage" ); |
505 | /// 508 Loop Detected |
506 | /// [[RFC5842](https://tools.ietf.org/html/rfc5842)] |
507 | (508, LOOP_DETECTED, "Loop Detected" ); |
508 | |
509 | /// 510 Not Extended |
510 | /// [[RFC2774](https://tools.ietf.org/html/rfc2774)] |
511 | (510, NOT_EXTENDED, "Not Extended" ); |
512 | /// 511 Network Authentication Required |
513 | /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] |
514 | (511, NETWORK_AUTHENTICATION_REQUIRED, "Network Authentication Required" ); |
515 | } |
516 | |
517 | impl InvalidStatusCode { |
518 | fn new() -> InvalidStatusCode { |
519 | InvalidStatusCode { |
520 | _priv: (), |
521 | } |
522 | } |
523 | } |
524 | |
525 | impl fmt::Debug for InvalidStatusCode { |
526 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
527 | f.debug_struct("InvalidStatusCode" ) |
528 | // skip _priv noise |
529 | .finish() |
530 | } |
531 | } |
532 | |
533 | impl fmt::Display for InvalidStatusCode { |
534 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
535 | f.write_str("invalid status code" ) |
536 | } |
537 | } |
538 | |
539 | impl Error for InvalidStatusCode {} |
540 | |
541 | // A string of packed 3-ASCII-digit status code values for the supported range |
542 | // of [100, 999] (900 codes, 2700 bytes). |
543 | const CODE_DIGITS: &'static str = "\ |
544 | 100101102103104105106107108109110111112113114115116117118119\ |
545 | 120121122123124125126127128129130131132133134135136137138139\ |
546 | 140141142143144145146147148149150151152153154155156157158159\ |
547 | 160161162163164165166167168169170171172173174175176177178179\ |
548 | 180181182183184185186187188189190191192193194195196197198199\ |
549 | 200201202203204205206207208209210211212213214215216217218219\ |
550 | 220221222223224225226227228229230231232233234235236237238239\ |
551 | 240241242243244245246247248249250251252253254255256257258259\ |
552 | 260261262263264265266267268269270271272273274275276277278279\ |
553 | 280281282283284285286287288289290291292293294295296297298299\ |
554 | 300301302303304305306307308309310311312313314315316317318319\ |
555 | 320321322323324325326327328329330331332333334335336337338339\ |
556 | 340341342343344345346347348349350351352353354355356357358359\ |
557 | 360361362363364365366367368369370371372373374375376377378379\ |
558 | 380381382383384385386387388389390391392393394395396397398399\ |
559 | 400401402403404405406407408409410411412413414415416417418419\ |
560 | 420421422423424425426427428429430431432433434435436437438439\ |
561 | 440441442443444445446447448449450451452453454455456457458459\ |
562 | 460461462463464465466467468469470471472473474475476477478479\ |
563 | 480481482483484485486487488489490491492493494495496497498499\ |
564 | 500501502503504505506507508509510511512513514515516517518519\ |
565 | 520521522523524525526527528529530531532533534535536537538539\ |
566 | 540541542543544545546547548549550551552553554555556557558559\ |
567 | 560561562563564565566567568569570571572573574575576577578579\ |
568 | 580581582583584585586587588589590591592593594595596597598599\ |
569 | 600601602603604605606607608609610611612613614615616617618619\ |
570 | 620621622623624625626627628629630631632633634635636637638639\ |
571 | 640641642643644645646647648649650651652653654655656657658659\ |
572 | 660661662663664665666667668669670671672673674675676677678679\ |
573 | 680681682683684685686687688689690691692693694695696697698699\ |
574 | 700701702703704705706707708709710711712713714715716717718719\ |
575 | 720721722723724725726727728729730731732733734735736737738739\ |
576 | 740741742743744745746747748749750751752753754755756757758759\ |
577 | 760761762763764765766767768769770771772773774775776777778779\ |
578 | 780781782783784785786787788789790791792793794795796797798799\ |
579 | 800801802803804805806807808809810811812813814815816817818819\ |
580 | 820821822823824825826827828829830831832833834835836837838839\ |
581 | 840841842843844845846847848849850851852853854855856857858859\ |
582 | 860861862863864865866867868869870871872873874875876877878879\ |
583 | 880881882883884885886887888889890891892893894895896897898899\ |
584 | 900901902903904905906907908909910911912913914915916917918919\ |
585 | 920921922923924925926927928929930931932933934935936937938939\ |
586 | 940941942943944945946947948949950951952953954955956957958959\ |
587 | 960961962963964965966967968969970971972973974975976977978979\ |
588 | 980981982983984985986987988989990991992993994995996997998999" ; |
589 | |