http_routing_kenji/
request.rs

1use crate::{method::Method, Response, Status};
2
3pub struct Request {
4    pub request_line: RequestLine,
5    pub content_type: Option<String>,
6    pub user_agent: Option<String>,
7    pub accept: Option<String>,
8    pub cache_control: Option<String>,
9    pub postman_token: Option<String>,
10    pub host: Option<String>,
11    pub accept_encoding: Option<String>,
12    pub connection: Option<String>,
13    pub content_length: Option<usize>,
14    pub body: Option<String>
15}
16
17impl Request {
18    pub fn new(buffer: &[u8]) -> Result<Request, Response> {
19        let request_as_string = String::from_utf8_lossy(buffer);
20
21        let mut parts = request_as_string.split("\r\n\r\n");
22        let mut head = parts.next().unwrap().split("\r\n");
23
24        let request_line = head.next().unwrap().to_string();
25
26        if request_line == "" {
27            return Err(Response::new("Request Line not found".to_string(), Status::BADREQUEST));
28        }
29
30        let mut request = Request {
31            request_line: RequestLine::new(request_line),
32            content_type:None, user_agent:None, accept:None,
33            cache_control:None, postman_token:None, host:None,
34            accept_encoding:None, connection:None, content_length:None,
35            body: None
36        };
37
38        for line in head.into_iter() {
39            let mut split = line.split(": ");
40            let property = split.next().unwrap();
41            let value = split.next().unwrap();
42            Self::set_property_by_string(&mut request, property, value.to_string());
43        }
44
45        if request.content_length == None {
46            return Ok(request);
47        }
48
49        if let Some(body) = parts.next() {
50            let length: usize = request.content_length.unwrap();
51            request.body = Some(body.chars().take(length).collect());
52        }
53
54        Ok(request)
55    }
56
57    fn set_property_by_string(&mut self, property: &str, value: String) {
58        match property {
59            "Content-Type" => self.content_type = Some(value),
60            "User-Agent" => self.user_agent = Some(value),
61            "Accept" => self.user_agent = Some(value),
62            "Cache-Control" => self.cache_control = Some(value),
63            "Postman-Token" => self.postman_token = Some(value),
64            "Host" => self.host = Some(value),
65            "Accept-Encoding" => self.accept_encoding = Some(value),
66            "Connection" => self.connection = Some(value),
67            "Content-Length" => self.content_length = Some(value.parse().unwrap()),
68            _ => ()
69        }
70    }
71}
72
73pub struct RequestLine {
74    pub method: Method,
75    pub path: String,
76    pub http_version: String
77}
78
79impl RequestLine {
80    pub fn new(request_line: String) -> RequestLine {
81        let mut request_arr = request_line.split(" ");
82
83        let method_string = request_arr.next().unwrap();
84        let method = Method::from_str(&method_string).unwrap();
85        let path = request_arr.next().unwrap().to_string();
86        let http_version = request_arr.next().unwrap().to_string();
87
88        RequestLine { method, path, http_version }
89    }
90}
91