czh_http_server/
request.rs1use 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#[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 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 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}