pillow_http/request/
mod.rs1use std::collections::HashMap;
2use std::fmt;
3
4use crate::header::Header;
5use crate::http_methods::HttpMethods;
6use crate::uri::Uri;
7
8use crate::body::Body;
9
10#[derive(Debug, Clone)]
12pub struct Request {
13 method: HttpMethods,
14 version: String,
15 headers: HashMap<Header, String>,
16 uri: Uri,
17 params: HashMap<String, String>,
18 body: Body,
19}
20
21impl Default for Request {
22 fn default() -> Self {
23 Self::new_empty()
24 }
25}
26
27impl Request {
28 pub fn new_empty() -> Self {
30 Self {
31 method: HttpMethods::GET,
32 version: "HTTP/1.1".to_string(),
33 headers: HashMap::new(),
34 uri: Uri("".to_string()),
35 params: HashMap::new(),
36 body: Body::NONE,
37 }
38 }
39}
40
41impl Request {
42 pub fn method(&self) -> &HttpMethods {
44 &self.method
45 }
46
47 pub fn version(&self) -> &String {
49 &self.version
50 }
51
52 pub fn uri(&self) -> &Uri {
54 &self.uri
55 }
56
57 pub fn headers(&self) -> &HashMap<Header, String> {
59 &self.headers
60 }
61
62 pub fn params(&self) -> &HashMap<String, String> {
64 &self.params
65 }
66
67 pub fn body(&self) -> &Body {
69 &self.body
70 }
71}
72
73impl Request {
74 pub fn add_params(&mut self, params: (String, String)) {
75 self.params.insert(params.0, params.1);
76 }
77}
78
79impl Request {
80 pub fn from_vec(data: &Vec<u8>) -> Result<Request, std::str::Utf8Error> {
86 let request_str_full = Self::from_vec_to_str(data)?;
87
88 let mut req_vec: Vec<&str> = request_str_full.split("\n").collect();
89
90 let (method_str, uri_str, version_str) = Self::separate_method_uri_version(req_vec[0]);
91
92 let method = crate::http_methods::from_str_to_http_method(method_str).unwrap();
93 let uri = Self::get_uri(uri_str);
94
95 let params = match Self::get_params(uri_str) {
96 Some(hashmap) => hashmap,
97 None => HashMap::new(),
98 };
99
100 let headers = Self::get_headers(&mut req_vec);
101 let body = Self::get_body(req_vec, headers.len());
102
103 Ok(Self {
104 method,
105 version: version_str.to_string(),
106 uri,
107 headers,
108 params,
109 body,
110 })
111 }
112
113 fn get_body(headers_vec: Vec<&str>, lenght: usize) -> crate::body::Body {
121 let mut body_vec: Vec<Vec<&str>> = headers_vec.chunks(lenght).map(|x| x.into()).collect();
122 body_vec.remove(0);
123
124 let body_vec = body_vec[0].clone();
125
126 let mut body = String::new();
127
128 for body_items in &body_vec {
129 if !body_vec.is_empty() {
130 body = body + body_items;
131 }
132 }
133
134 let body = Self::remove_0(&body);
135
136 crate::body::from_string_to_body(body.to_string())
137 }
138
139 fn remove_0(string: &String) -> &str {
145 let vec_str: Vec<&str> = string.split("\0").collect();
146
147 vec_str[0]
148 }
149
150 fn get_headers(headers_vec: &mut Vec<&str>) -> HashMap<Header, String> {
152 headers_vec.remove(0);
153
154 let mut header_hash_map = HashMap::new();
155
156 for header in headers_vec {
157 let key_value_vec: Vec<&str> = header.split(":").map(|x| x.trim()).collect();
158
159 if key_value_vec.len() > 1 {
160 let key = crate::header::from_string_to_header(key_value_vec[0].to_string());
161 let value = key_value_vec[1].to_string();
162
163 if key_value_vec.len() > 2 {
164 let value = value + key_value_vec[2];
165 header_hash_map.insert(key, value);
166 } else {
167 header_hash_map.insert(key, value);
168 }
169 }
170 }
171
172 header_hash_map
173 }
174
175 fn separate_method_uri_version(header: &str) -> (&str, &str, &str) {
177 let header_vec: Vec<&str> = header.split_whitespace().collect();
178
179 if header_vec.len() < 2 {
180 panic!("Err in get header or uri or version");
181 }
182
183 (header_vec[0], header_vec[1], header_vec[2])
184 }
185
186 fn from_vec_to_str(data: &Vec<u8>) -> Result<&str, std::str::Utf8Error> {
188 std::str::from_utf8(data)
189 }
190
191 fn get_uri(uri_str: &str) -> Uri {
193 let uri_vec: Vec<&str> = uri_str.split("?").collect();
194
195 Uri(uri_vec[0].to_string())
196 }
197
198 fn get_params(uri: &str) -> Option<HashMap<String, String>> {
200 let mut params_vec: Vec<&str> = uri.split("?").collect();
201 let mut params_hash_map = HashMap::new();
202
203 if params_vec.len() > 1 {
204 params_vec.remove(0);
205
206 let params_vec: Vec<&str> = params_vec[0].split("&").collect();
207
208 for params in params_vec {
209 let p_vec: Vec<&str> = params.split("=").collect();
210
211 params_hash_map.insert(p_vec[0].to_string(), p_vec[1].to_string());
212 }
213
214 return Some(params_hash_map);
215 }
216
217 None
218 }
219}
220
221impl Request {
222 pub fn get_param(&self, param: &'static str) -> String {
223 self.params.get(param).unwrap().clone()
224 }
225}
226
227impl fmt::Display for Request {
228 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229 f.debug_struct("Request")
230 .field("method", &self.method)
231 .field("version", &self.version)
232 .field("headers", &self.headers)
233 .field("uri", &self.uri)
234 .field("params", &self.params)
235 .field("body", &self.body)
236 .finish()
237 }
238}