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