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 );