http_with_url/
status.rs

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