http_async/request.rs
1use
2{
3 super::
4 {
5 KeyValuePair,
6 header::
7 {
8 Header,
9 },
10 method::
11 {
12 Method,
13 },
14 path::
15 {
16 Path,
17 },
18 version::
19 {
20 Version,
21 },
22 },
23 async_std::
24 {
25 net::
26 {
27 TcpStream,
28 },
29 prelude::*,
30 task,
31 },
32 std::
33 {
34 str::
35 {
36 FromStr,
37 },
38 },
39};
40
41/// Hyper Text Transfer Protocol Request.
42pub struct Request
43{
44 /// Method to use to get the desired Resource.
45 pub method: Method,
46 /// Path to the desired Resource.
47 pub path: String,
48 /// When parsing a Request, how should I differentiate the Key Value Pairs of the Query?
49 pub querySeperator: char,
50 /// List of Query Key Value Pairs.
51 pub query: Vec < KeyValuePair >,
52 /// Protocol Version.
53 pub version: Version,
54 /// List of Header Key Value Pairs.
55 pub header: Vec < KeyValuePair >,
56 /// Content of Request.
57 pub content: Vec < u8 >,
58}
59
60/// Constructor for a dummy `Request`.
61pub fn Request ()
62-> Request
63{
64 Request
65 {
66 method: Method::Dummy,
67 path: "".to_owned(),
68 querySeperator: '&',
69 query: Vec::new(),
70 version: Version::Dummy,
71 header: Vec::new(),
72 content: Vec::new(),
73 }
74}
75
76impl Request
77{
78 /// Read `char` from `stream` and compare it with `character`.
79 ///
80 /// # Arguments
81 /// * `character` – `char` to compare with,
82 /// * `stream` – Transmission Control Protocol Stream,
83 /// * `inner` – inner value to return on success.
84 pub fn ifChar
85 <
86 Inner,
87 >
88 (
89 character: char,
90 stream: &mut TcpStream,
91 inner: Inner,
92 )
93 -> Option < Inner >
94 {
95 if let Some ( this ) = Self::readChar ( stream )
96 {
97 if character == this
98 {
99 Some ( inner )
100 }
101 else
102 {
103 None
104 }
105 }
106 else
107 {
108 None
109 }
110 }
111
112 /// Try to read a single `char` from Transmission Control Protocol stream.
113 ///
114 /// # Arguments
115 /// * `stream` – Transmission Control Protocol Stream.
116 pub fn readChar
117 (
118 stream: &mut TcpStream,
119 )
120 -> Option < char >
121 {
122 task::block_on
123 (
124 async
125 {
126 let mut buffer = vec! [ 0u8; 1 ];
127 if let Ok ( length ) = stream.read ( &mut buffer ).await
128 {
129 if length == 1
130 {
131 Some ( buffer [ 0 ] as char )
132 }
133 else
134 {
135 None
136 }
137 }
138 else
139 {
140 None
141 }
142 }
143 )
144 }
145
146 /// Parse `TcpStream` as Hyper Text Transfer Protocol Request.
147 ///
148 /// # Arguments
149 /// * `stream` – Transmission Control Protocol Stream.
150 pub async fn parse
151 (
152 mut self,
153 mut stream: &mut TcpStream,
154 )
155 -> Result
156 <
157 Self,
158 String,
159 >
160 {
161 if let Some ( method ) = Method::parse ( &mut stream ).await
162 {
163 self.method = method;
164 if let Some ( path ) = Path::parse ( &mut stream, self.querySeperator ).await
165 {
166 self.path = path.path;
167 self.query = path.query;
168 if let Some ( version ) = Version::parse ( &mut stream ).await
169 {
170 self.version = version;
171 let mut error = Some ( "Could not parse List of headers".to_owned ( ) );
172 let mut length = 0;
173 while let Ok ( entry ) = Header::parse ( &mut stream ).await
174 {
175 if length < 32
176 {
177 if let Some ( entry ) = entry
178 {
179 self
180 .header
181 .push ( entry );
182 }
183 else
184 {
185 error = None;
186 break;
187 }
188 }
189 else
190 {
191 error = Some ( "Too many Header Entries, Slow Lorris Attack?".to_owned ( ) );
192 break;
193 }
194 length += 1
195 }
196 if let Some ( message )
197 = error
198 {
199 Err ( message )
200 }
201 else if let Some ( entry )
202 = self
203 .header
204 .iter()
205 .find
206 (
207 | entry |
208 entry.key == "Content-Length"
209 )
210 {
211 if let Ok ( length ) = usize::from_str ( &entry.value )
212 {
213 if length < 0x0008_0000
214 {
215 let mut buffer = vec! [ 0u8; length ];
216 if let Ok ( size ) = stream.read ( &mut buffer ).await
217 {
218 if let Ok ( text )
219 = String::from_utf8 ( buffer.clone ( ) )
220 {
221 println!
222 (
223 "\n<{}> {}?({:?})\n{}Length: {}\nContent:\n»{}« ({:?})",
224 self.method,
225 self.path,
226 self.query,
227 self
228 .header
229 .iter()
230 .fold
231 (
232 "".to_owned(),
233 | mut text, entry |
234 {
235 text
236 .push_str
237 (
238 &format!
239 (
240 "→{} = {}\n",
241 entry.key,
242 entry.value,
243 )
244 );
245 text
246 }
247 ),
248 length,
249 text,
250 buffer,
251 );
252 }
253 self
254 .content = buffer;
255 if size == length
256 {
257 Ok ( self )
258 }
259 else
260 {
261 Err
262 (
263 format!
264 (
265 "Expected Content with {} bytes, but received only {}",
266 length,
267 size,
268 )
269 )
270 }
271 }
272 else
273 {
274 Err
275 (
276 format!
277 (
278 "Could not read {} bytes of content",
279 length,
280 )
281 )
282 }
283 }
284 else
285 {
286 Err
287 (
288 format!
289 (
290 "To avoid Denial of Service by Remote Allocation of a Buffer, the Upper Limit is below {} bytes",
291 length,
292 )
293 )
294 }
295 }
296 else
297 {
298 Err ( "Could not parse length of content".to_owned ( ) )
299 }
300 }
301 else
302 {
303 println!
304 (
305 "\n<{}> {}?({:?})\n{}No Content.",
306 self.method,
307 self.path,
308 self.query,
309 self
310 .header
311 .iter()
312 .fold
313 (
314 "".to_owned(),
315 | mut text, entry |
316 {
317 text
318 .push_str
319 (
320 &format!
321 (
322 "→{} = {}\n",
323 entry.key,
324 entry.value,
325 )
326 );
327 text
328 }
329 ),
330 );
331 Ok ( self )
332 }
333 }
334 else
335 {
336 Err ( "Could not parse version".to_owned ( ) )
337 }
338 }
339 else
340 {
341 Err ( "Could not parse path".to_owned ( ) )
342 }
343 }
344 else
345 {
346 Err ( "Could not parse method.".to_owned ( ) )
347 }
348 }
349}