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}