czh_http_server/
request.rs

1use std::{
2    cell::RefCell, collections::HashMap, fs::read, io::{BufRead, BufReader, Error, Read, Result}, net::TcpStream, ops::DerefMut, rc::Rc
3};
4
5use serde::de::{self, Error as SerdeError};
6
7
8// use serde::{de::{self, Error}, Deserialize, Serialize};
9#[derive(Debug)]
10struct StatusLine {
11    method: String,
12    version: String,
13    url: String,
14}
15#[derive(Debug)]
16pub struct HttpRequest {
17    status_line: StatusLine,
18    headers: HashMap<String, String>,
19    stream: Option<Rc<RefCell<TcpStream>>>,
20    buffer: Vec<u8>,
21}
22
23impl HttpRequest {
24    pub fn build(stream: Rc<RefCell<TcpStream>>) -> Result<Self> {
25        let mut stream_ref = stream.borrow_mut();
26        let mut reader = BufReader::new(stream_ref.deref_mut());
27
28        let (method, url, version) = parse_request_row(&mut reader)?;
29
30        let mut buffer = String::new();
31        let mut headers = HashMap::new();
32        
33        loop {
34            let size = reader.read_line(&mut buffer)?;
35            if size == 2 {
36                break;
37            }
38            let key_v = buffer.trim().split_once(':').unwrap();
39            headers.insert(String::from(key_v.0.trim()), String::from(key_v.1.trim()));
40            buffer.clear();
41        }
42        //bufReader will preread some date storing in its inner buffer ,so when droping it
43        //,we have to store the buffs that have already been read.        
44        let buffer = Vec::from_iter(reader.buffer().iter().map(|x| *x));
45
46        Ok(Self {
47            status_line: StatusLine {
48                method,
49                version,
50                url,
51            },
52            headers,
53            stream: Some(stream.clone()),
54            buffer
55        })
56    }
57    pub fn headers(&self) -> &HashMap<String, String> {
58        &self.headers
59    }
60    pub fn version(&self) -> &str {
61        &self.status_line.version
62    }
63
64    pub fn method(&self) -> &str {
65        self.status_line.method.as_str()
66    }
67
68    pub fn cookies(&self) -> Option<HashMap<&str, &str>> {
69        
70        if let Some(cookie) = self.headers.get("Cookie") {
71            let mut cookies = HashMap::new();
72            let key_value = cookie.split("; ").collect::<Vec<&str>>();
73            key_value.iter().for_each(|x| {
74                
75                if let Some(key_value) = x.split_once("=") {
76                    cookies.insert(key_value.0, key_value.1);
77                }else {
78                    println!("{:#?}","cookie parse error");
79                }
80            });
81            Some(cookies)
82        }else {
83            None
84        }
85        
86    }
87
88    pub fn url(&self) -> &str {
89        self.status_line.url.as_str()
90    }
91
92    /// /abc/abc => /abc
93    /// / => /
94    /// /efg/avc => /efg
95    /// /abc => /
96    pub(crate) fn prefix_url(&self) -> &str {
97        let mut stop = 1;
98        for i in 1..self.url().len() {
99            if self.url().as_bytes()[i] == b'/' {
100                stop = i;
101                break;
102            }
103        }
104        if stop == 1 {
105            self.url()
106        } else {
107            &self.url()[0..stop]
108        }
109    }
110    
111    pub fn json<T>(&mut self) -> serde_json::Result<T>
112    where
113        T: de::DeserializeOwned,
114    {
115        let size = self.get_content_length()?;
116        if size == self.buffer.len() {
117            return serde_json::from_slice(&self.buffer);
118        }else {
119            let remind = size - self.buffer.len();
120            let mut stream = self.stream.as_mut().unwrap().borrow_mut();
121            let  mut reader = BufReader::new(stream.deref_mut());
122            let mut total = 0;
123            loop {
124                let size = reader.read(self.buffer.as_mut_slice()).unwrap();
125                total += size;
126                if total == remind {
127                    break;
128                }
129            }
130            serde_json::from_slice(&self.buffer)
131        }
132    }
133    fn get_content_length(&self) -> serde_json::Result<usize> {
134        match self.headers
135            .get("Content-Length") {
136                Some(v) => Ok(v.parse().unwrap()),
137                None => Err(serde_json::Error::custom("msg"))
138            }
139    }
140}
141fn parse_request_row(reader: &mut BufReader<&mut TcpStream>) -> Result<(String, String, String)> {
142    let mut buffer = String::new();
143    let mut method = String::new();
144    let mut url = String::new();
145    let mut version = String::new();
146    reader.read_line(&mut buffer)?;
147    let row = buffer.split_whitespace().collect::<Vec<&str>>();
148    if row.len() != 3 {
149        Err(Error::new(std::io::ErrorKind::Other, "error"))
150    } else {
151        let u: Vec<&str> = row[1].split("?").collect();
152        method.push_str(row[0]);
153        url.push_str(u[0]);
154        version.push_str(row[2]);
155        Ok((method, url, version))
156    }
157}
158
159#[cfg(test)]
160mod tests {
161
162    #[test]
163    fn it_works() {
164
165    }
166}