1use std::collections::HashMap;
2use std::net::TcpStream;
3use std::sync::{Arc};
4use std::sync::atomic::{AtomicBool, Ordering};
5use tempfile::NamedTempFile;
6use crate::headers;
7use crate::headers::{Headers};
8use crate::parser::{body, multipart, url_encoded};
9use crate::parser::body::Limits;
10use crate::parser::body::reader::BodyReader;
11use crate::parser::multipart::{FormPart, MultipartFormDataError};
12use crate::parser::multipart::reader::FormDataReader;
13use crate::parser::url_encoded::{FormFields, UrlEncodedFormDataError};
14use crate::parser::url_encoded::reader::UrlEncodedReader;
15use crate::request::form::{FormFiles, FormData, FormFile};
16use crate::server::Context;
17
18fn map_first_vec_value(map: &HashMap<String, Vec<String>>, key: &str) -> Option<String> {
19 if let Some(values) = map.get(key) {
20 if values.len() > 0 {
21 let value = values.get(0).unwrap();
22 return Some(value.to_owned());
23 }
24 }
25
26 return None;
27}
28
29pub mod form {
30 use std::collections::HashMap;
31 use tempfile::NamedTempFile;
32 use crate::request::map_first_vec_value;
33
34 pub struct FormFile {
35 pub filename: String,
36 pub temp_file: NamedTempFile,
37 }
38
39 pub type MapFirstString = HashMap<String, Vec<String>>;
40
41 pub trait MapFirstStringMethod {
42 fn value(&self, name: &str) -> Option<String>;
43 }
44
45 impl MapFirstStringMethod for MapFirstString {
46 fn value(&self, name: &str) -> Option<String> {
47 return map_first_vec_value(self, name);
48 }
49 }
50
51 pub type FormData = HashMap<String, Vec<String>>;
52 pub type FormFiles = HashMap<String, Vec<FormFile>>;
53
54 pub trait FormFileMethods {
55 fn value(&self, name: &str) -> Option<&FormFile>;
56 }
57
58 impl FormFileMethods for FormFiles {
59 fn value(&self, name: &str) -> Option<&FormFile> {
60 if let Some(values) = self.get(name) {
61 if values.len() > 0 {
62 let value = values.get(0).unwrap();
63 return Some(value);
64 }
65 }
66
67 return None;
68 }
69 }
70
71 pub struct File {
72 pub name: String,
73 pub content_type: String,
74 }
75}
76
77pub type QueryParams = HashMap<String, Vec<String>>;
78
79pub struct Request {
80 pub context: Arc<Context>,
81 pub stream: TcpStream,
82 pub method: String,
83 pub raw_path: String,
84 pub pathname: String,
85 pub query_params: QueryParams,
86 pub headers: Headers,
87 pub partial_body: Option<Vec<u8>>,
88 form_data: FormData,
89 form_files: FormFiles,
90 pub body_read: Arc<AtomicBool>,
94 pub body_parsed: Arc<AtomicBool>,
95}
96
97impl Request {
98 pub fn new(context: Arc<Context>, stream: TcpStream, request_method: String, raw_path: String,
99 headers: HashMap<String, Vec<String>>, body_read: Arc<AtomicBool>,
100 body_parsed: Arc<AtomicBool>) -> Self {
101 let form_data = FormData::new();
102 let form_files = FormFiles::new();
103
104 let pathname = Self::pathname_from_raw(&raw_path);
105 let query_params = headers::query_params_from_raw(&raw_path);
106
107 return Request {
108 context,
109 stream,
110 method: request_method,
111 raw_path,
112 pathname,
113 query_params,
114 headers,
115 partial_body: None,
116 form_data,
117 form_files,
118 body_read,
119 body_parsed,
120 };
121 }
122
123 fn pathname_from_raw(raw_path: &String) -> String {
124 if let Some(index) = raw_path.find("?") {
125 let slice = &raw_path.as_str()[0..index];
126 return slice.to_string();
127 }
128
129 return raw_path.to_string();
130 }
131
132 pub fn setup(&mut self) {
133 let content_length = headers::content_length(&self.headers);
134 let request_method = self.method.to_uppercase();
135
136 if matches!(request_method.as_str(), "GET" | "HEAD" | "OPTIONS" | "DELETE" | "TRACE" | "CONNECT") {
137 if !content_length.is_some() {
139 self.body_read.store(true, Ordering::Relaxed);
141 }
142 }
143 }
144
145
146 pub fn set_partial_body_bytes(&mut self, bytes: Vec<u8>) {
147 self.partial_body = Some(bytes);
148 }
149
150 pub fn should_close_connection(&self) -> bool {
151 let connection_type = headers::connection_type(&self.headers);
152
153 if let Some(connection_type) = &connection_type {
154 if connection_type.to_lowercase() == "keep-alive" && self.body_read.load(Ordering::Relaxed) {
155 return false;
156 }
157 }
158
159 return true;
160 }
161
162 pub fn body(&mut self) -> Option<NamedTempFile> {
163 if self.body_read.load(Ordering::Relaxed) {
164 eprintln!("Body already read");
165 return None;
166 }
167
168 let content_length = headers::content_length(&self.headers);
169
170 if !content_length.is_some() {
171 eprintln!("Content-Length header is missing");
172 return None;
173 }
174
175 let cloned_stream = self.stream.try_clone();
176 if !cloned_stream.is_ok() {
177 eprintln!("Failed to clone stream");
178 return None;
179 }
180
181 let limits = Limits {
182 max_body_size: 512 * 1024 * 1024, };
184
185 let mut partial_bytes: Vec<u8> = Vec::new();
186 if let Some(partial) = self.partial_body.as_mut() {
187 partial_bytes.extend(partial.clone());
188 partial.clear();
189 }
190
191 let reader = BodyReader::new(cloned_stream.unwrap(), content_length.unwrap(),
192 partial_bytes.len(), limits);
193
194 let parse_result = body::parse(
195 partial_bytes,
196 &self.headers,
197 reader,
198 );
199
200 self.body_read.store(true, Ordering::Relaxed);
201
202 match parse_result {
203 Ok(temp_file) => {
204 self.body_parsed.store(true, Ordering::Relaxed);
205 return Some(temp_file);
206 }
207
208 Err(error) => {
209 eprintln!("Error: {:?}", error);
210 }
211 }
212
213 return None;
214 }
215
216 pub fn form_data(&mut self) -> &mut FormData {
217 if !self.body_read.load(Ordering::Relaxed) {
218 self.parse_request_body();
219 }
220 return &mut self.form_data;
221 }
222
223 pub fn files(&mut self) -> &mut FormFiles {
224 if !self.body_read.load(Ordering::Relaxed) {
225 self.parse_request_body();
226 }
227
228 return &mut self.form_files;
229 }
230
231 pub fn parse_request_body(&mut self) {
232 let content_type = headers::extract_content_type(&self.headers);
233
234 if !content_type.is_some() {
236 let content_length = headers::content_length(&self.headers);
238
239 if content_length.is_some() && content_length.unwrap() > 0 {
240 eprintln!("Body has content, but missing content type.");
241 }
242
243 return;
244 }
245
246 let content_type_binding = content_type.unwrap();
247 let content_type_value = content_type_binding.trim();
248 let content_length = headers::content_length(&self.headers);
249
250 if content_type_value.starts_with("multipart/form-data;") {
251 const MAX_BODY_SIZE: usize = 512 * 1024 * 1024; const MAX_HEADER_SIZE: usize = 1024 * 1024; const MAX_VALUE_SIZE: usize = 2 * 1024; let limits = multipart::Limits {
256 max_body_size: Some(MAX_BODY_SIZE),
257 max_header_size: Some(MAX_HEADER_SIZE),
258 max_value_size: Some(MAX_VALUE_SIZE),
259 form_part_limits: HashMap::new(),
260 };
261
262 let result = self.multipart_form_data(
263 content_type_value.to_string(),
264 content_length,
265 limits,
266 );
267
268 self.body_read.store(true, Ordering::Relaxed);
270
271 match result {
272 Ok(form_parts) => {
273 let (form_data, form_files) = self.multipart_form_data_and_files(form_parts);
274 self.body_parsed.store(true, Ordering::Relaxed);
276 self.form_data = form_data;
277 self.form_files = form_files;
278 }
279
280 Err(error) => {
281 self.body_parsed.store(true, Ordering::Relaxed);
282 eprintln!("Error: {:?}", error);
283 }
284 }
285 } else if content_type_value.starts_with("application/x-www-form-urlencoded") {
286 let limits = url_encoded::Limits {
287 max_body_size: 2 * 1024 * 1024 };
289
290 if !content_length.is_some() {
291 eprintln!("Content-Length is missing.");
293 return;
294 }
295
296 let result = self.parse_url_encoded(
297 content_length.unwrap(),
298 limits,
299 );
300 self.body_read.store(true, Ordering::Relaxed);
301
302 match result {
303 Ok(form_fields) => {
304 self.body_parsed.store(true, Ordering::Relaxed);
305 self.form_data = form_fields;
306 }
307
308 Err(error) => {
309 eprintln!("Error: {:?}", error);
310 }
311 }
312 }
313 }
314
315 pub fn multipart_form_data(&mut self, content_type: String, content_length: Option<usize>,
316 limits: multipart::Limits) -> Result<Vec<FormPart>, MultipartFormDataError> {
317 let boundary = multipart::extract_boundary(&content_type);
318 if !boundary.is_some() {
319 return Err(MultipartFormDataError::Others("Boundary is missing from Content-Type"));
320 }
321
322 let partial_body;
324 if let Some(partial) = self.partial_body.as_mut() {
325 partial_body = partial.clone();
326 partial.clear();
327 } else {
328 partial_body = Vec::new();
329 }
330
331 return match self.stream.try_clone() {
332 Ok(cloned_stream) => {
333 let reader = FormDataReader::new(
335 cloned_stream,
336 boundary.unwrap(),
337 content_length,
338 partial_body.len(),
339 );
340
341 multipart::parse(
342 partial_body,
343 &self.headers,
344 reader,
345 limits,
346 )
347 }
348 Err(_) => {
349 Err(MultipartFormDataError::Others("Failed to copy stream"))
350 }
351 };
352 }
353
354 pub fn parse_url_encoded(&mut self, content_length: usize, limits: url_encoded::Limits)
355 -> Result<FormFields, UrlEncodedFormDataError> {
356 let mut partial_bytes = Vec::new();
357
358 if let Some(partial_body) = self.partial_body.as_mut() {
359 partial_bytes.extend(partial_body.clone());
360 partial_body.clear();
361 }
362
363 let cloned_stream = self.stream.try_clone().expect("Failed to clone stream");
364 let mut reader = UrlEncodedReader::new(
365 cloned_stream,
366 content_length,
367 partial_bytes.len(),
368 );
369
370 return url_encoded::parse(partial_bytes, &self.headers, &mut reader, limits);
371 }
372
373 pub fn multipart_form_data_and_files(&self, form_parts: Vec<FormPart>) -> (FormData, FormFiles) {
374 let mut form_data = FormData::new();
375 let mut form_files = FormFiles::new();
376
377 for form_part in form_parts {
378 if !form_part.name.is_some() {
379 continue;
380 }
381
382
383 if form_part.value.is_some() {
384 let name = form_part.name.unwrap();
387 if !form_data.contains_key(&name) {
388 let vec = Vec::new();
389 form_data.insert(name.clone(), vec);
390 }
391
392 let values = form_data.get_mut(&name).unwrap();
393 let value_bytes = form_part.value.expect("Error in value parsing");
394 let value = String::from_utf8_lossy(value_bytes.as_slice());
395 values.push(value.to_string());
396 } else if form_part.filename.is_some() {
397 let name = form_part.name.unwrap();
399 if !form_files.contains_key(&name) {
400 let vec = Vec::new();
401 form_files.insert(name.clone(), vec);
402 }
403
404 let values = form_files.get_mut(&name).unwrap();
405 let temp_file = form_part.temp_file;
406
407 let filename = form_part.filename.expect("Error in parsing file body. At least expected filename.");
408 let temp_file = temp_file.expect("Error in parsing file body. At least expected one temp file.");
409 let form_file = FormFile {
410 filename,
411 temp_file,
412 };
413
414 values.push(form_file);
415 }
416 }
417
418 return (form_data, form_files);
419 }
420}
421
422impl Clone for Request {
423 fn clone(&self) -> Self {
424 return Request {
425 context: self.context.clone(),
426 stream: self.stream.try_clone().unwrap(),
427 method: self.method.clone(),
428 raw_path: self.raw_path.clone(),
429 pathname: self.pathname.clone(),
430 query_params: self.query_params.clone(),
431 headers: self.headers.clone(),
432 partial_body: self.partial_body.clone(),
433 form_data: FormData::new(),
435 form_files: FormFiles::new(),
436 body_read: self.body_read.clone(),
437 body_parsed: self.body_parsed.clone(),
438 };
439 }
440}
441
442