/ src / http / http_init.rs
http_init.rs
 1  use crate::needed::Polar;
 2  
 3  // references: https://datatracker.ietf.org/doc/html/rfc1945#section-5.1
 4  pub(crate) struct RequestLine {
 5      pub(crate) method: RequestMethod,
 6      pub(crate) uri: String,
 7      pub(crate) version: HttpVersion,
 8  }
 9  
10  pub(crate) struct StatusLine {
11      pub(crate) version: HttpVersion,
12      pub(crate) status_code: u16,
13      pub(crate) reason_phrase: String,
14  }
15  
16  #[allow(clippy::upper_case_acronyms)] // why clippy, why
17  #[derive(Debug, PartialEq)]
18  pub(crate) enum RequestMethod {
19      GET,
20      HEAD,
21      POST,
22      NotImplemented,
23  }
24  
25  #[allow(non_camel_case_types)] // I am NOT writing the http versions as "Http11" LMAO
26  #[derive(Debug)]
27  pub(crate) enum HttpVersion {
28      HTTP_0_9,
29      HTTP_1_0,
30      HTTP_1_1,
31      HTTP_2_0,
32      HTTP_3_0,
33  }
34  
35  // Goal is to parse the first line, get the method, uri and version, and then send it off to the correct parser, simple right?
36  pub(crate) fn parser(http_request_line: &String) -> Polar<RequestLine> {
37      // step one, get the values
38      let temp_vec: Vec<&str> = http_request_line.split(" ").collect();
39  
40      let method = match temp_vec.first() {
41          Some(method) => *method,
42          None => return Polar::Silly(400), // return 400 (bad request)
43      };
44  
45      let uri = match temp_vec.get(1) {
46          Some(uri) => uri.to_string(),
47          None => return Polar::Silly(400), // return 400 (bad request)
48      };
49  
50      let version = match temp_vec.get(2) {
51          Some(version) => *version,
52          None => "", // do this so if it's http 0.9 it can be handled
53      };
54  
55      // step two, set the enum's
56      let (request_method, http_version) = {
57          let request_method = match method {
58              "GET" => RequestMethod::GET,
59              "HEAD" => RequestMethod::HEAD,
60              "POST" => RequestMethod::POST,
61              _ => return Polar::Silly(501), // return 501 (not implemented)
62          };
63  
64          let http_version = match version {
65              "HTTP/0.9\r\n" => HttpVersion::HTTP_0_9,
66              "HTTP/1.0\r\n" => HttpVersion::HTTP_1_0,
67              "HTTP/1.1\r\n" => HttpVersion::HTTP_1_1,
68              "HTTP/2.0\r\n" => HttpVersion::HTTP_2_0,
69              "HTTP/3.0\r\n" => HttpVersion::HTTP_3_0,
70              _ => {
71                  // check if it is http 0.9
72                  if version.is_empty() && request_method == RequestMethod::GET {
73                      HttpVersion::HTTP_0_9
74                  } else {
75                      return Polar::Silly(505); // return 505 (http version not supported)
76                  }
77              }
78          };
79  
80          (request_method, http_version)
81      };
82  
83      // step three, return the struct :D!
84      Polar::Some(RequestLine {
85          method: request_method,
86          uri,
87          version: http_version,
88      })
89  }
90