proxy_server/http/
status.rs

1///! Module [`StatusDefault`]
2use std::str;
3
4use regex::Regex;
5
6use crate::{http::CRLF, prelude::constants::HTTP_VERSION_DEFAULT};
7
8/// HTTP status
9#[derive(Debug)]
10pub struct Status {
11    pub text: String,
12    pub code: u16,
13}
14
15/// HTTP defaul status
16#[derive(Debug)]
17pub struct StatusDefault {
18    pub text: &'static str,
19    pub code: u16,
20}
21
22/// HTTP statuses
23/// Reference https://developer.mozilla.org/en-US/docs/Web/HTTP/StatusDefault
24pub const STATUSES: [StatusDefault; 61] = [
25    StatusDefault {
26        text: "Continue",
27        code: 100,
28    },
29    StatusDefault {
30        text: "Switching Protocols",
31        code: 101,
32    },
33    StatusDefault {
34        text: "Processing",
35        code: 102,
36    },
37    StatusDefault {
38        text: "Early Hints",
39        code: 103,
40    },
41    StatusDefault {
42        text: "OK",
43        code: 200,
44    },
45    StatusDefault {
46        text: "Created",
47        code: 201,
48    },
49    StatusDefault {
50        text: "Accepted",
51        code: 202,
52    },
53    StatusDefault {
54        text: "Non-Authoritative Information",
55        code: 203,
56    },
57    StatusDefault {
58        text: "No Content",
59        code: 204,
60    },
61    StatusDefault {
62        text: "Reset Content",
63        code: 205,
64    },
65    StatusDefault {
66        text: "Partial Content",
67        code: 206,
68    },
69    StatusDefault {
70        text: "Multi-StatusDefault",
71        code: 207,
72    },
73    StatusDefault {
74        text: "Already Reported",
75        code: 208,
76    },
77    StatusDefault {
78        text: "IM Used",
79        code: 226,
80    },
81    StatusDefault {
82        text: "Multiple Choices",
83        code: 300,
84    },
85    StatusDefault {
86        text: "Moved Permanently",
87        code: 301,
88    },
89    StatusDefault {
90        text: "Found",
91        code: 302,
92    },
93    StatusDefault {
94        text: "See Other",
95        code: 303,
96    },
97    StatusDefault {
98        text: "Not Modified",
99        code: 304,
100    },
101    StatusDefault {
102        text: "Temporary Redirect",
103        code: 307,
104    },
105    StatusDefault {
106        text: "Permanent Redirect",
107        code: 308,
108    },
109    StatusDefault {
110        text: "Bad Request",
111        code: 400,
112    },
113    StatusDefault {
114        text: "Unauthorized",
115        code: 401,
116    },
117    StatusDefault {
118        text: "Payment Required",
119        code: 402,
120    },
121    StatusDefault {
122        text: "Forbidden",
123        code: 403,
124    },
125    StatusDefault {
126        text: "Not Found",
127        code: 404,
128    },
129    StatusDefault {
130        text: "Method Not Allowed",
131        code: 405,
132    },
133    StatusDefault {
134        text: "Not Acceptable",
135        code: 406,
136    },
137    StatusDefault {
138        text: "Proxy Authentication Required",
139        code: 407,
140    },
141    StatusDefault {
142        text: "Request Timeout",
143        code: 408,
144    },
145    StatusDefault {
146        text: "Conflict",
147        code: 409,
148    },
149    StatusDefault {
150        text: "Gone",
151        code: 410,
152    },
153    StatusDefault {
154        text: "Length Required",
155        code: 411,
156    },
157    StatusDefault {
158        text: "Precondition Failed",
159        code: 412,
160    },
161    StatusDefault {
162        text: "Payload Too Large",
163        code: 413,
164    },
165    StatusDefault {
166        text: "URI Too Long",
167        code: 414,
168    },
169    StatusDefault {
170        text: "Unsupported Media Type",
171        code: 415,
172    },
173    StatusDefault {
174        text: "Range Not Satisfiable",
175        code: 416,
176    },
177    StatusDefault {
178        text: "Expectation Failed",
179        code: 417,
180    },
181    StatusDefault {
182        text: "I'm a teapot",
183        code: 418,
184    },
185    StatusDefault {
186        text: "Misdirected Request",
187        code: 421,
188    },
189    StatusDefault {
190        text: "Unprocessable Content",
191        code: 422,
192    },
193    StatusDefault {
194        text: "Locked",
195        code: 423,
196    },
197    StatusDefault {
198        text: "Failed Dependency",
199        code: 424,
200    },
201    StatusDefault {
202        text: "Upgrade Required",
203        code: 426,
204    },
205    StatusDefault {
206        text: "Precondition Required",
207        code: 428,
208    },
209    StatusDefault {
210        text: "Too Many Requests",
211        code: 429,
212    },
213    StatusDefault {
214        text: "Request Header Fields Too Large",
215        code: 431,
216    },
217    StatusDefault {
218        text: "Request Header Fields Too Large",
219        code: 431,
220    },
221    StatusDefault {
222        text: "Unavailable For Legal Reasons",
223        code: 451,
224    },
225    StatusDefault {
226        text: "Internal Server Error",
227        code: 500,
228    },
229    StatusDefault {
230        text: "Not Implemented",
231        code: 501,
232    },
233    StatusDefault {
234        text: "Bad Gateway",
235        code: 502,
236    },
237    StatusDefault {
238        text: "Service Unavailable",
239        code: 503,
240    },
241    StatusDefault {
242        text: "Gateway Timeout",
243        code: 504,
244    },
245    StatusDefault {
246        text: "HTTP Version Not Supported",
247        code: 505,
248    },
249    StatusDefault {
250        text: "Variant Also Negotiates",
251        code: 506,
252    },
253    StatusDefault {
254        text: "Insufficient Storage",
255        code: 507,
256    },
257    StatusDefault {
258        text: "Loop Detected",
259        code: 508,
260    },
261    StatusDefault {
262        text: "Not Extended",
263        code: 510,
264    },
265    StatusDefault {
266        text: "Network Authentication Required",
267        code: 511,
268    },
269];
270
271impl Status {
272    /// Create HTTP status from code
273    pub fn new(code: u16) -> Status {
274        let mut status = Status {
275            text: "Not Implemented".to_string(),
276            code: 501,
277        };
278        for f in STATUSES {
279            if code == f.code {
280                status = Status {
281                    code: f.code,
282                    text: f.text.to_string(),
283                };
284            }
285        }
286        status
287    }
288
289    /// Get HTTP protocol prefix like `HTTP/1.1 200 OK`
290    pub fn to_full_string(&self) -> String {
291        let d = self.to_string();
292        let res = Regex::new(format!(r"{CRLF}$").as_str())
293            .unwrap()
294            .replace_all(d.as_str(), "");
295        format!("{HTTP_VERSION_DEFAULT} {}", res)
296    }
297
298    pub fn to_string(&self) -> String {
299        format!("{} {}", self.code, self.text)
300    }
301}