1use std::collections::HashMap;
2
3pub mod body {
4 use std::io::{Seek, SeekFrom, Write};
5 use tempfile::NamedTempFile;
6 use crate::headers;
7 use crate::headers::Headers;
8 use crate::parser::body::reader::StreamReader;
9
10 pub struct Limits {
11 pub max_body_size: usize,
12 }
13
14 #[derive(Debug)]
15 pub enum BodyReadError {
16 MaxBodySizeExceed,
17 ContentLengthMissing,
18 BodyAlreadyRead,
19 Others(&'static str),
20 }
21
22 pub mod reader {
23 use std::io::Read;
24 use std::net::TcpStream;
25 use crate::parser::body::{BodyReadError, Limits};
26
27 pub trait StreamReader {
28 fn get_chunk(&mut self) -> Result<Vec<u8>, BodyReadError>;
29 fn get_exact(&mut self, size: usize) -> Result<Vec<u8>, BodyReadError>;
30 }
31
32 pub struct BodyReader {
33 stream: TcpStream,
34 content_length: usize,
35 bytes_read: usize,
36 limits: Limits,
37 }
38
39 impl BodyReader {
40 pub fn new(stream: TcpStream, content_length: usize, bytes_read: usize, limits: Limits) -> Self {
41 return Self {
42 stream,
43 content_length,
44 bytes_read,
45 limits,
46 };
47 }
48 }
49
50 impl StreamReader for BodyReader {
51 fn get_chunk(&mut self) -> Result<Vec<u8>, BodyReadError> {
52 if self.bytes_read >= self.content_length {
53 return Err(BodyReadError::MaxBodySizeExceed);
54 }
55
56 if self.bytes_read >= self.limits.max_body_size {
57 return Err(BodyReadError::BodyAlreadyRead);
58 }
59
60 let mut buffer = [0u8; 1024];
61 let read_result = self.stream.read(&mut buffer);
62 if !read_result.is_ok() {
63 return Err(BodyReadError::Others(
64 "Unable to read stream. May be client disconnected."
65 ));
66 }
67
68 let chunk_length = read_result.unwrap();
69 let chunk = Vec::from(&buffer[0..chunk_length]);
70 self.bytes_read += chunk_length;
71 return Ok(chunk);
72 }
73
74 fn get_exact(&mut self, size: usize) -> Result<Vec<u8>, BodyReadError> {
75 if self.bytes_read >= self.content_length {
76 return Err(BodyReadError::MaxBodySizeExceed);
77 }
78
79 if self.bytes_read >= self.limits.max_body_size {
80 return Err(BodyReadError::BodyAlreadyRead);
81 }
82
83 let mut buffer = vec![0u8; size];
84 let read_result = self.stream.read_exact(&mut buffer);
85 if !read_result.is_ok() {
86 return Err(BodyReadError::Others(
87 "Unable to read stream. May be client disconnected."
88 ));
89 }
90 self.bytes_read += size;
91 return Ok(buffer);
92 }
93 }
94 }
95
96 pub fn parse<T: StreamReader>(partial_bytes: Vec<u8>, headers: &Headers, mut reader: T)
97 -> Result<NamedTempFile, BodyReadError> {
98 let mut body_buffer = Vec::from(partial_bytes);
99 let mut body_read = body_buffer.len();
100
101 let content_length = headers::content_length(&headers);
102 if !content_length.is_some() {
103 return Err(BodyReadError::ContentLengthMissing);
104 }
105
106 let temp_file_create = NamedTempFile::new();
108 let mut temp_file;
109
110 match temp_file_create {
111 Ok(file) => {
112 temp_file = file;
113 }
114
115 Err(_) => {
116 return Err(BodyReadError::Others("Error creating temporary file"));
117 }
118 }
119
120 let content_length = content_length.unwrap();
121
122 loop {
123 let write_result = temp_file.write_all(&body_buffer);
124 if !write_result.is_ok() {
125 return Err(BodyReadError::Others("Error writing to temporary file"));
126 }
127
128 if body_read >= content_length {
129 let seek_result = temp_file.seek(SeekFrom::Start(0));
130 if !seek_result.is_ok() {
131 return Err(BodyReadError::Others("Failed to seek temporary file"));
132 }
133 return Ok(temp_file);
134 }
135
136 body_buffer.clear();
137
138 let read_result = reader.get_chunk();
139 match read_result {
140 Ok(chunk) => {
141 body_read += chunk.len();
142 body_buffer.extend(chunk);
143 }
144 Err(error) => {
145 return Err(error);
146 }
147 }
148 }
149 }
150}
151
152pub fn parse_url_encoded(text: &str) -> HashMap<String, Vec<String>> {
153 let mut params = HashMap::new();
154 let values = text.split("&");
155
156 for value in values {
157 let key_values: Vec<&str> = value.split("=").collect();
158 if key_values.len() >= 2 {
159 let name = key_values.get(0).unwrap();
160 let value = key_values.get(1).unwrap();
161
162 let name_formatted = url_decode(name);
163 let value_formatted = url_decode(value);
164
165 if !params.contains_key(&name_formatted) {
166 params.insert(name.to_string(), Vec::new());
167 }
168
169 let values = params.get_mut(&name_formatted).unwrap();
170 values.push(value_formatted);
171 }
172 }
173 return params;
174}
175
176pub fn url_decode(value: &str) -> String {
177 return match urlencoding::decode(value) {
178 Ok(decoded_value) => {
179 decoded_value.to_string()
180 }
181 Err(_) => {
182 value.to_string()
183 }
184 };
185}
186
187pub mod url_encoded {
188 use std::collections::HashMap;
189 use crate::headers;
190 use crate::headers::{Headers};
191 use crate::parser::parse_url_encoded;
192 use crate::parser::url_encoded::reader::StreamReader;
193
194 #[derive(Debug)]
195 pub enum UrlEncodedFormDataError {
196 InvalidFormat(&'static str),
198 ContentLengthMissing(&'static str),
200 ParsingError(&'static str),
202 MaxBodySizeExceed(&'static str),
204 BodyReadEnd,
206 Others(&'static str),
208 }
209
210 pub mod reader {
211 use std::io::Read;
212 use std::net::TcpStream;
213 use crate::parser::url_encoded::UrlEncodedFormDataError;
214
215 pub trait StreamReader {
217 fn get_chunk(&mut self) -> Result<Vec<u8>, UrlEncodedFormDataError>;
218 fn get_exact(&mut self, size: usize) -> Result<Vec<u8>, UrlEncodedFormDataError>;
219 }
220
221 pub struct UrlEncodedReader {
222 pub stream: TcpStream,
223 pub content_length: usize,
224 pub bytes_read: usize,
226 pub body_ended: bool,
227 }
228
229 impl UrlEncodedReader {
230 pub fn new(stream: TcpStream, content_length: usize, bytes_read: usize) -> Self {
231 let body_ended;
232
233 if bytes_read == content_length {
234 body_ended = true;
235 } else {
236 body_ended = false;
237 };
238
239 return Self {
240 stream,
241 content_length,
242 bytes_read,
243 body_ended,
244 };
245 }
246
247 fn update_read_status(&mut self, new_chunk: &[u8]) {
248 self.bytes_read += new_chunk.len();
249
250 if self.bytes_read >= self.content_length {
251 self.body_ended = true;
252 }
253 }
254 }
255
256 impl StreamReader for UrlEncodedReader {
257 fn get_chunk(&mut self) -> Result<Vec<u8>, UrlEncodedFormDataError> {
258 if self.body_ended {
259 return Err(UrlEncodedFormDataError::BodyReadEnd);
260 }
261
262 let mut buffer = [0u8; 1024];
263 let read_result = self.stream.read(&mut buffer);
264
265 if !read_result.is_ok() {
266 return Err(UrlEncodedFormDataError::Others(
267 "Unable to read stream. May be client disconnected."
268 ));
269 }
270
271 let read_size = read_result.unwrap();
272
273 if read_size == 0 {
274 return Err(UrlEncodedFormDataError::Others("Bytes read size is 0. Probably client disconnected."));
275 }
276
277 let chunk = &buffer[0..read_size];
278 self.update_read_status(chunk);
279 return Ok(chunk.to_vec());
280 }
281
282 fn get_exact(&mut self, size: usize) -> Result<Vec<u8>, UrlEncodedFormDataError> {
283 if self.body_ended {
284 return Err(UrlEncodedFormDataError::BodyReadEnd);
285 }
286
287 let mut buffer = vec![0u8; size];
288 let result = self.stream.read_exact(&mut buffer);
289 if !result.is_ok() {
290 return Err(UrlEncodedFormDataError::Others(
291 "Unable to read stream. May be client disconnected."
292 ));
293 }
294
295 return Ok(buffer.to_vec());
296 }
297 }
298 }
299
300 pub struct Limits {
301 pub max_body_size: usize,
302 }
303
304 pub type FormFields = HashMap<String, Vec<String>>;
305
306 pub fn parse<T: StreamReader>(partial_bytes: Vec<u8>, headers: &Headers, reader: &mut T,
307 limits: Limits) -> Result<FormFields, UrlEncodedFormDataError> {
308 let mut body_buffer = Vec::from(partial_bytes);
309 let content_length = headers::content_length(headers);
310
311 if let Some(content_length) = content_length {
312 if content_length > limits.max_body_size {
313 return Err(UrlEncodedFormDataError::MaxBodySizeExceed(
314 "Request body size is larger than the limit."
315 ));
316 }
317 } else {
318 return Err(UrlEncodedFormDataError::ContentLengthMissing(
319 "Content-Length header is missing."
320 ));
321 }
322
323 let content_length = content_length.unwrap();
324 let bytes_read = body_buffer.len();
325
326 while content_length > bytes_read {
328 let request_chunk = reader.get_chunk();
329
330 match request_chunk {
331 Ok(chunk) => {
332 body_buffer.extend(chunk);
333 }
334
335 Err(error) => {
336 return Err(error);
337 }
338 }
339 };
340
341 let value = String::from_utf8_lossy(&body_buffer).to_string();
342 let form_values = parse_url_encoded(value.as_str());
343 return Ok(form_values);
344 }
345}
346
347pub mod multipart {
348 use std::collections::HashMap;
349 use std::io::{Seek, SeekFrom, Write};
350 use regex::Regex;
351 use tempfile::NamedTempFile;
352 use crate::headers;
353 use crate::headers::Headers;
354
355 #[derive(Debug)]
356 pub enum MultipartFormDataError {
357 InvalidMultiPart(&'static str),
359 ParsingError(&'static str),
361 HeaderSizeExceed(&'static str),
363 MaxBodySizeExceed(&'static str),
365 MaxFieldSizeExceed(String, &'static str),
367 BodyReadEnd,
369 Others(&'static str),
371 }
372
373
374 pub trait StreamReader {
376 fn get_chunk(&mut self) -> Result<Vec<u8>, MultipartFormDataError>;
377 fn get_exact(&mut self, size: usize) -> Result<Vec<u8>, MultipartFormDataError>;
378 }
379
380 pub fn extract_boundary(content_type: &String) -> Option<String> {
382 let value: Vec<&str> = content_type.split(";").collect();
383
384 if value.len() >= 2 {
385 let content_type_text = value.get(1).unwrap().trim();
386 let boundary = content_type_text.strip_prefix("boundary=").unwrap();
387 return Some(boundary.to_string());
388 }
389
390 return None;
391 }
392
393 pub mod reader {
394 use std::io::Read;
395 use std::net::TcpStream;
396 use crate::parser::multipart::{MultipartFormDataError, StreamReader};
397
398 pub struct FormDataReader {
399 pub stream: TcpStream,
400 pub boundary_end_bytes: Vec<u8>,
401 pub content_length: Option<usize>,
402 pub bytes_read: usize,
404 pub body_ended: bool,
405 body_buffer: Vec<u8>,
407 }
408
409 impl FormDataReader {
410 pub fn new(stream: TcpStream, boundary: String, content_length: Option<usize>, body_read: usize) -> Self {
411 let boundary_end = format!("--{}\r\n", boundary);
412 let boundary_end_bytes = boundary_end.as_bytes().to_vec();
413 let body_buffer = Vec::with_capacity(boundary_end_bytes.len());
414
415 let body_ended;
416 if let Some(content_length) = content_length {
417 body_ended = body_read >= content_length;
418 } else if body_buffer.ends_with(&boundary_end_bytes) {
419 body_ended = true;
420 } else {
421 body_ended = false;
422 }
423
424 return Self {
425 stream,
426 boundary_end_bytes,
427 content_length,
428 bytes_read: body_read,
429 body_ended,
430 body_buffer,
431 };
432 }
433
434 fn update_read_status(&mut self, new_chunk: &[u8]) {
436 self.bytes_read += new_chunk.len();
437
438 if self.content_length.is_some() {
439 let body_ended = self.bytes_read >= self.content_length.unwrap();
440 if body_ended {
441 self.body_ended = true;
442 }
443 } else {
444 if self.body_buffer.ends_with(&self.boundary_end_bytes) {
445 self.body_ended = true;
446 return;
447 }
448
449 if new_chunk.len() > self.boundary_end_bytes.len() {
453 self.body_buffer.clear();
454 let last_sice = &new_chunk[(self.boundary_end_bytes.len() - self.boundary_end_bytes.len())..self.boundary_end_bytes.len()];
455 self.body_buffer.extend(last_sice);
456 } else {
457 let start_index = self.boundary_end_bytes.len() - new_chunk.len() - 1;
460 let old_slice_to_copy = &self.body_buffer[start_index..].to_owned();
461
462 self.body_buffer.clear();
463 self.body_buffer.extend(old_slice_to_copy);
464 self.body_buffer.extend(new_chunk);
465 }
466 }
467 }
468 }
469
470 impl StreamReader for FormDataReader {
471 fn get_chunk(&mut self) -> Result<Vec<u8>, MultipartFormDataError> {
472 if self.body_ended {
473 return Err(MultipartFormDataError::BodyReadEnd);
474 }
475
476 const BUFFER_SIZE: usize = 8 * 1024; let mut buffer = [0u8; BUFFER_SIZE];
478 let result = self.stream.read(&mut buffer);
479
480 if !result.is_ok() {
481 return Err(MultipartFormDataError::Others("Unable to read stream. May be client disconnected."));
482 }
483
484 let read_size = result.unwrap();
485 if read_size == 0 {
486 return Err(MultipartFormDataError::Others("Bytes read size is 0. Probably client disconnected."));
487 }
488
489 let chunk_slice = &buffer[0..read_size];
490 self.update_read_status(&chunk_slice);
491
492 let chunk = Vec::from(chunk_slice);
493 return Ok(chunk);
494 }
495
496 fn get_exact(&mut self, size: usize) -> Result<Vec<u8>, MultipartFormDataError> {
497 if self.body_ended {
498 return Err(MultipartFormDataError::BodyReadEnd);
499 }
500
501 let mut buffer: Vec<u8> = vec![0u8; size];
502 let result = self.stream.read_exact(&mut buffer);
503 if !result.is_ok() {
504 return Err(MultipartFormDataError::Others("Unable to read stream. May be client disconnected."));
505 }
506
507 self.update_read_status(&buffer);
508 return Ok(buffer);
509 }
510 }
511 }
512
513 #[derive(Debug)]
514 pub struct FormPart {
515 pub name: Option<String>,
516 pub filename: Option<String>,
517 pub content_type: Option<String>,
518 pub temp_file: Option<NamedTempFile>,
519 pub value: Option<Vec<u8>>,
520 }
521
522 #[derive(Debug)]
523 pub struct FormPartLimit {
524 pub max_size: Option<usize>,
525 pub content_type: Option<String>,
526 }
527
528 #[derive(Debug)]
529 pub struct Limits {
530 pub max_body_size: Option<usize>,
531 pub max_header_size: Option<usize>,
532 pub max_value_size: Option<usize>,
533 pub form_part_limits: HashMap<String, FormPartLimit>,
534 }
535
536 impl Limits {
537 pub fn none() -> Self {
538 return Self {
539 max_body_size: None,
540 max_header_size: None,
541 max_value_size: None,
542 form_part_limits: HashMap::new(),
543 };
544 }
545 }
546
547 #[derive(Debug)]
548 pub enum FormPartResult {
549 CheckNext,
550 BodyCompleted,
551 }
552
553 impl FormPart {
554 pub fn empty() -> Self {
555 return FormPart {
556 name: None,
557 filename: None,
558 content_type: None,
559 temp_file: None,
560 value: None,
561 };
562 }
563 }
564
565 pub fn parse<T: StreamReader>(partial_bytes: Vec<u8>, headers: &Headers, reader: T, limits: Limits)
588 -> Result<Vec<FormPart>, MultipartFormDataError> {
589 let content_type_bytes = headers.get("Content-Type");
590
591 let content_type: String;
592 if let Some(content_type_bytes) = content_type_bytes {
593 content_type = content_type_bytes.get(0).unwrap().to_owned();
594 } else {
595 return Err(MultipartFormDataError::InvalidMultiPart("Content-Type header missing."));
596 };
597
598 let multipart_boundary: String;
599 if let Some(boundary) = extract_boundary(&content_type) {
600 multipart_boundary = boundary;
601 } else {
602 return Err(MultipartFormDataError::InvalidMultiPart("Unable to extract multipart boundary."));
603 }
604
605 if let Some(max_body_size) = limits.max_body_size {
607 if let Some(content_length) = headers::content_length(&headers) {
608 if content_length > max_body_size {
609 return Err(MultipartFormDataError::MaxBodySizeExceed("Maximum specified body size exceed."));
610 }
611 }
612 }
613
614 let body_buffer = Vec::from(partial_bytes);
615 return parse_body_parts(reader, body_buffer, &multipart_boundary, limits);
616 }
617
618 pub fn parse_body_parts<T: StreamReader>(mut reader: T, mut body_buffer: Vec<u8>, boundary: &String,
619 limits: Limits) -> Result<Vec<FormPart>, MultipartFormDataError> {
620 let mut form_parts = Vec::new();
621
622 let start_boundary = format!("--{}\r\n", boundary);
625 let start_boundary_bytes = start_boundary.as_bytes();
626
627 if body_buffer.len() <= start_boundary_bytes.len() {
629 let bytes_required = start_boundary_bytes.len() - body_buffer.len();
631 let chunk_request_result = reader.get_exact(bytes_required);
632
633 match chunk_request_result {
634 Ok(chunk) => {
635 body_buffer.extend(chunk);
636 }
637
638 Err(error) => {
639 return Err(error);
640 }
641 }
642 };
643
644 if !body_buffer_starts_with_boundary(&body_buffer, start_boundary_bytes) {
645 return Err(MultipartFormDataError::InvalidMultiPart("Body does not start with boundary"));
646 }
647
648 body_buffer = Vec::from(&body_buffer[start_boundary_bytes.len()..]);
650
651 loop {
653 let header_result = extract_form_part_header(
655 &mut reader,
656 &mut body_buffer,
657 &limits,
658 );
659 if !header_result.is_ok() {
660 return Err(header_result.unwrap_err());
661 }
662
663 let form_part_header = header_result.unwrap();
664 let header_text = String::from_utf8_lossy(&form_part_header).to_string();
665
666 let header_parse_result = parse_form_part_header(header_text);
668 if !header_parse_result.is_ok() {
669 return Err(header_parse_result.unwrap_err());
670 }
671
672 let mut form_part = header_parse_result.unwrap();
675
676 let body_parse_result = extract_form_part_body(
679 &mut reader,
680 &mut body_buffer,
681 boundary,
682 &mut form_part,
683 &limits,
684 );
685
686 match body_parse_result {
687 Ok(result) => {
688 match result {
689 FormPartResult::BodyCompleted => {
690 form_parts.push(form_part);
691 return Ok(form_parts);
692 }
693
694 FormPartResult::CheckNext => {
695 form_parts.push(form_part);
696 }
698 }
699 }
700
701 Err(error) => {
702 return Err(error);
703 }
704 }
705 }
706 }
707
708 pub fn body_buffer_starts_with_boundary(body_buffer: &Vec<u8>, start_boundary_bytes: &[u8]) -> bool {
709 let extracted_boundary_slice = &body_buffer[0..start_boundary_bytes.len()];
711 return extracted_boundary_slice == start_boundary_bytes;
712 }
713
714 pub fn extract_form_part_header<T: StreamReader>(reader: &mut T, body_buffer: &mut Vec<u8>, limits: &Limits)
729 -> Result<Vec<u8>, MultipartFormDataError> {
730 let header_end_bytes = b"\r\n\r\n";
732 let mut form_part_header_buffer = Vec::new();
733
734 let max_header_size = limits.max_header_size;
735
736 loop {
737 let scan_result = body_buffer.windows(header_end_bytes.len())
738 .position(|window| window == header_end_bytes);
739
740 if let Some(found_index) = scan_result {
741 form_part_header_buffer.extend(&body_buffer[0..found_index]);
743
744 if max_header_size.is_some() && (form_part_header_buffer.len() >= max_header_size.unwrap()) {
746 return Err(MultipartFormDataError::HeaderSizeExceed("Header size exceed max specified size"));
747 }
748
749 *body_buffer = Vec::from(&body_buffer[found_index + header_end_bytes.len()..]);
751 return Ok(form_part_header_buffer);
752 } else {
753 let to_copy_to_header_buffer = body_buffer.len() as i32 - header_end_bytes.len() as i32;
758 if to_copy_to_header_buffer > 0 {
759 form_part_header_buffer.extend(header_end_bytes);
761 *body_buffer = Vec::from(&body_buffer[to_copy_to_header_buffer as usize..]);
763 }
764
765 if max_header_size.is_some() && (form_part_header_buffer.len() >= max_header_size.unwrap()) {
767 return Err(MultipartFormDataError::HeaderSizeExceed("Header size exceed max specified size"));
768 } else {
769 let request_new_chunk = reader.get_chunk();
770
771 match request_new_chunk {
772 Ok(new_chunk) => {
773 body_buffer.extend(new_chunk);
774 }
775
776 Err(error) => {
777 return Err(error);
778 }
779 }
780 }
781 };
782 }
783 }
784
785 pub fn parse_form_part_header(part_header: String) -> Result<FormPart, MultipartFormDataError> {
787 let mut form_part = FormPart::empty();
788
789 let headers: Vec<&str> = part_header.split("\r\n").collect();
790
791 for header_line in headers {
793 parse_header_line(header_line, &mut form_part);
795 }
796
797 return Ok(form_part);
798 }
799
800 pub fn parse_header_line(line: &str, form_part: &mut FormPart) {
801 let line = line.trim();
802
803 if line.is_empty() {
804 return;
805 }
806
807 let name_value: Vec<&str> = line.split(":").collect();
808 if name_value.len() >= 2 {
809 let header_name = name_value.get(0).unwrap().trim();
810 let header_value = name_value.get(1).unwrap().trim();
811
812 if header_name.to_lowercase() == "Content-Disposition".to_lowercase() {
814 parse_content_disposition_value(header_value, form_part);
815 } else if header_name.to_lowercase() == "Content-Type".to_lowercase() {
816 parse_content_type(header_value, form_part);
817 }
818 }
819 }
820
821
822 pub fn parse_content_disposition_value(value: &str, form_part: &mut FormPart) {
830 let value = value.trim();
831
832 if !value.starts_with("form-data;") {
833 return;
835 }
836
837 let remaining = value.strip_prefix("form-data;").unwrap().trim();
838 let pattern = Regex::new(r#"(?<attribute>\w+)="(?<value>[^"]*)""#).unwrap();
839
840 for captured in pattern.captures_iter(remaining) {
841 let attribute = &captured["attribute"];
842 let value = &captured["value"];
843
844 if attribute == "name" {
845 form_part.name = Some(value.to_string());
846 } else if attribute == "filename" {
847 form_part.filename = Some(value.to_string());
848 }
849 }
850 }
851
852 pub fn parse_content_type(value: &str, form_part: &mut FormPart) {
853 form_part.content_type = Some(value.to_string());
854 }
855
856 pub fn extract_form_part_body<T: StreamReader>(reader: &mut T, body_buffer: &mut Vec<u8>, boundary: &String,
857 form_part: &mut FormPart, limits: &Limits) ->
858 Result<FormPartResult, MultipartFormDataError> {
859 let field_name = &form_part.name;
860
861 let mut form_part_limit: Option<&FormPartLimit> = None;
862 if field_name.is_some() {
863 let field_name = field_name.clone().unwrap();
864 form_part_limit = limits.form_part_limits.get(&field_name);
865 }
866
867 let is_file = form_part.filename.is_some();
868 if is_file {
869 return extract_form_file_body(reader, body_buffer, boundary, form_part, form_part_limit);
870 }
871
872 let field_value_limit;
873 if form_part_limit.is_some() {
874 field_value_limit = FormPartLimit {
877 max_size: form_part_limit.unwrap().max_size,
878 content_type: None,
879 };
880 } else {
881 field_value_limit = FormPartLimit {
882 max_size: limits.max_value_size,
883 content_type: None,
884 }
885 }
886
887 form_part_limit = Some(&field_value_limit);
888 return extract_form_value(reader, body_buffer, boundary, form_part, form_part_limit);
889 }
890
891 pub fn extract_form_file_body<T: StreamReader>(reader: &mut T, body_buffer: &mut Vec<u8>, boundary: &String,
903 form_part: &mut FormPart, form_part_limit: Option<&FormPartLimit>)
904 -> Result<FormPartResult, MultipartFormDataError> {
905 let temp_file_create = NamedTempFile::new();
907 let mut temp_file;
908
909 match temp_file_create {
910 Ok(file) => {
911 temp_file = file;
912 }
913
914 Err(_) => {
915 return Err(MultipartFormDataError::Others("Error creating temporary file"));
916 }
917 }
918
919 let file_end_matcher = format!("\r\n--{}", boundary);
922 let file_end_matching_bytes = file_end_matcher.as_bytes();
923
924 let mut bytes_written: usize = 0;
925
926 loop {
927 let search_file_end = body_buffer.windows(file_end_matching_bytes.len())
928 .position(|window| window == file_end_matching_bytes);
929
930 if let Some(body_end_index) = search_file_end {
932 if body_end_index > 0 {
936 let mut bytes_to_copy = &body_buffer[0..body_end_index];
939 bytes_written += bytes_to_copy.len();
940
941 if bytes_to_copy.ends_with(b"\r\n") {
944 bytes_to_copy = &bytes_to_copy[0..bytes_to_copy.len() - 2];
945 }
946
947 let write_result = temp_file.write_all(bytes_to_copy);
948 if !write_result.is_ok() {
949 return Err(MultipartFormDataError::Others("Error writing to temporary file"));
950 }
951
952 *body_buffer = Vec::from(&body_buffer[body_end_index + file_end_matching_bytes.len()..]);
954 }
955
956 if form_part_limit.is_some() && (bytes_written > form_part_limit.unwrap().max_size.unwrap()) {
958 return Err(MultipartFormDataError::MaxFieldSizeExceed(
959 form_part.name.clone().unwrap().to_string(),
960 "The file is bigger than the maximum allowed size")
961 );
962 }
963
964 let end_body_bytes = b"--\r\n";
970 let next_part_bytes = b"\r\n";
971 if body_buffer.len() < 4 {
975 let bytes_to_read = 4 - body_buffer.len();
977
978 let request_new_chunk = reader.get_exact(bytes_to_read);
979 match request_new_chunk {
980 Ok(chunk) => {
981 body_buffer.extend(chunk);
982 }
983 Err(error) => {
984 return Err(error);
985 }
986 }
987 }
988
989 let body_end_compare = &body_buffer[0..4];
991 if body_end_compare == end_body_bytes {
992 body_buffer.clear();
994 if !temp_file.seek(SeekFrom::Start(0)).is_ok() {
995 return Err(MultipartFormDataError::Others("Error to seek start 0 temporary file."));
996 }
997
998 form_part.temp_file = Some(temp_file);
999 return Ok(FormPartResult::BodyCompleted);
1000 }
1001
1002 let form_part_next_compare = &body_buffer[0..2];
1004 if form_part_next_compare == next_part_bytes {
1005 *body_buffer = Vec::from(&body_buffer[2..]);
1007
1008 if !temp_file.seek(SeekFrom::Start(0)).is_ok() {
1009 return Err(MultipartFormDataError::Others("Error seek to start 0 temporary file."));
1010 }
1011
1012 form_part.temp_file = Some(temp_file);
1013 return Ok(FormPartResult::CheckNext);
1014 }
1015
1016 return Err(MultipartFormDataError::ParsingError("Form content did not end with \r\n"));
1018 } else {
1019 let to_copy_size = body_buffer.len() as i32 - (file_end_matching_bytes.len() as i32 + 2);
1031
1032 if to_copy_size > 0 {
1033 let to_copy = &body_buffer[0..to_copy_size as usize];
1034
1035 let write_result = temp_file.write_all(to_copy);
1036 if !write_result.is_ok() {
1037 return Err(MultipartFormDataError::Others("Error writing to temporary file"));
1038 }
1039
1040 *body_buffer = Vec::from(&body_buffer[to_copy_size as usize..]);
1042 bytes_written += to_copy_size as usize;
1043 }
1044
1045 if form_part_limit.is_some() && (bytes_written > form_part_limit.unwrap().max_size.unwrap()) {
1046 return Err(MultipartFormDataError::MaxFieldSizeExceed(
1047 form_part.name.clone().unwrap().to_string(),
1048 "The file is bigger than the maximum allowed size"));
1049 }
1050
1051 let request_new_chunk = reader.get_chunk();
1052
1053 match request_new_chunk {
1054 Ok(new_chunk) => {
1055 body_buffer.extend(new_chunk);
1056 }
1057
1058 Err(error) => {
1059 return Err(error);
1060 }
1061 }
1062 };
1063 };
1064 }
1065
1066 pub fn extract_form_value<T: StreamReader>(reader: &mut T, body_buffer: &mut Vec<u8>, boundary: &String,
1067 form_part: &mut FormPart, form_part_limit: Option<&FormPartLimit>)
1068 -> Result<FormPartResult, MultipartFormDataError> {
1069 let value_end_matcher = format!("\r\n--{}", boundary);
1070 let value_end_matching_bytes = value_end_matcher.as_bytes();
1071
1072 let mut value_buffer: Vec<u8> = Vec::new();
1073 let mut bytes_written: usize = 0;
1074
1075 let mut max_value_size = None;
1076 if form_part_limit.is_some() {
1077 max_value_size = form_part_limit.unwrap().max_size;
1078 }
1079
1080 loop {
1081 let end_index = body_buffer.windows(value_end_matching_bytes.len())
1082 .position(|window| window == value_end_matching_bytes);
1083
1084 if let Some(end_index) = end_index {
1085 if end_index > 0 {
1087 let mut to_copy_bytes = &body_buffer[..end_index];
1089
1090 if to_copy_bytes.ends_with(b"\r\n") {
1091 to_copy_bytes = &to_copy_bytes[0..to_copy_bytes.len() - 2]
1092 }
1093
1094 bytes_written += to_copy_bytes.len();
1095 value_buffer.extend(to_copy_bytes);
1096
1097 *body_buffer = Vec::from(&body_buffer[end_index + value_end_matching_bytes.len()..]);
1099 }
1100
1101 if max_value_size.is_some() && max_value_size.unwrap() > bytes_written {
1103 return Err(MultipartFormDataError::MaxFieldSizeExceed(
1104 form_part.name.clone().unwrap().to_string(),
1105 "The form field value size exceeds the limit specified",
1106 ));
1107 }
1108
1109 let end_body_bytes = b"--\r\n";
1115 let next_part_bytes = b"\r\n";
1116 if body_buffer.len() < 4 {
1120 let bytes_to_read = 4 - body_buffer.len();
1122
1123 let request_new_chunk = reader.get_exact(bytes_to_read);
1124 match request_new_chunk {
1125 Ok(chunk) => {
1126 body_buffer.extend(chunk);
1127 }
1128 Err(error) => {
1129 return Err(error);
1130 }
1131 }
1132 }
1133
1134 let body_end_compare = &body_buffer[0..4];
1136 if body_end_compare == end_body_bytes {
1137 body_buffer.clear();
1139 form_part.value = Some(value_buffer);
1140 return Ok(FormPartResult::BodyCompleted);
1141 }
1142
1143 let form_part_next_compare = &body_buffer[0..2];
1145 if form_part_next_compare == next_part_bytes {
1146 *body_buffer = Vec::from(&body_buffer[2..]);
1148 form_part.value = Some(value_buffer);
1149 return Ok(FormPartResult::CheckNext);
1150 }
1151
1152 return Err(MultipartFormDataError::ParsingError("Form content did not end with \r\n"));
1154 } else {
1155 let to_copy_size = body_buffer.len() as i32 - (value_end_matching_bytes.len() as i32 + 2);
1162 if to_copy_size > 0 {
1163 bytes_written += to_copy_size as usize;
1164
1165 value_buffer.extend(&body_buffer[..to_copy_size as usize]);
1167 *body_buffer = Vec::from(&body_buffer[to_copy_size as usize..]);
1169 }
1170
1171 if form_part_limit.is_some() && (bytes_written > form_part_limit.unwrap().max_size.unwrap()) {
1172 return Err(MultipartFormDataError::MaxFieldSizeExceed(
1173 form_part.name.clone().unwrap().to_string(),
1174 "The form field value size exceeds the limit specified")
1175 );
1176 }
1177
1178 let request_new_chunk = reader.get_chunk();
1179 match request_new_chunk {
1180 Ok(chunk) => {
1181 body_buffer.extend(chunk);
1182 }
1183
1184 Err(error) => {
1185 return Err(error);
1186 }
1187 }
1188 }
1189 }
1190 }
1191}
1192
1193#[cfg(test)]
1194mod test {
1195 use std::collections::HashMap;
1196 use std::io::{Read};
1197 use rand::{Rng};
1198 use crate::headers::Headers;
1199 use crate::parser::multipart::{StreamReader};
1200 use crate::parser::multipart::{
1201 extract_form_part_body,
1202 extract_form_value,
1203 FormPart,
1204 Limits,
1205 MultipartFormDataError,
1206 parse,
1207 parse_form_part_header,
1208 };
1209
1210 struct ChunkReader {
1211 body_bytes: Vec<u8>,
1212 bytes_read: usize,
1213 }
1214
1215 impl ChunkReader {
1216 fn new(body: &str, bytes_read: usize) -> Self {
1217 let body_bytes = body.as_bytes().to_vec();
1218
1219 return ChunkReader {
1220 body_bytes,
1221 bytes_read,
1222 };
1223 }
1224
1225 fn get_bytes_left(&self) -> usize {
1226 let bytes_left: i32 = self.body_bytes.len() as i32 - self.bytes_read as i32;
1228
1229 if bytes_left > 0 {
1231 return bytes_left as usize;
1232 }
1233
1234 println!("Waiting forever...");
1235 println!("Socket connection broken.");
1236 return 0;
1237 }
1238 }
1239
1240 impl StreamReader for ChunkReader {
1241 fn get_chunk(&mut self) -> Result<Vec<u8>, MultipartFormDataError> {
1242 let bytes_left = self.get_bytes_left();
1244 if bytes_left == 0 {
1245 return Err(MultipartFormDataError::BodyReadEnd);
1246 }
1247
1248 let to_read = rand::thread_rng().gen_range(0..bytes_left + 1);
1249 let chunk = Vec::from(&self.body_bytes[self.bytes_read..&self.bytes_read + to_read]);
1250 self.bytes_read = self.bytes_read + to_read;
1251 return Ok(chunk);
1252 }
1253
1254 fn get_exact(&mut self, size: usize) -> Result<Vec<u8>, MultipartFormDataError> {
1255 let bytes_left = self.get_bytes_left();
1256 if bytes_left == 0 {
1257 println!("Waiting...");
1258 println!("Body is already read");
1259 return Err(MultipartFormDataError::BodyReadEnd);
1260 }
1261 let chunk = &self.body_bytes[self.bytes_read..self.bytes_read + size];
1262 self.bytes_read = self.bytes_read + size;
1263 return Ok(Vec::from(chunk));
1264 }
1265 }
1266
1267 const SAMPLE_BODY: &str = "----------------------------211628740782087473305609\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nJohn Doe\r\n----------------------------211628740782087473305609\r\nContent-Disposition: form-data; name=\"file\"; filename=\"a.txt\"\r\nContent-Type: text/plain\r\n\r\nhello\n\r\n----------------------------211628740782087473305609\r\nContent-Disposition: form-data; name=\"file\"; filename=\"a.txt\"\r\nContent-Type: text/plain\r\n\r\nhello\n\r\n----------------------------211628740782087473305609\r\nContent-Disposition: form-data; name=\"gender\"\r\n\r\nmale\r\n----------------------------211628740782087473305609--\r\n";
1268 const SAMPLE_BODY_2: &str = "--boundary123\r\nContent-Disposition: form-data; name=\"field1\"\r\n\r\nvalue1\r\n\r\n--boundary123\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example.txt\"\r\nContent-Type: text/plain\r\n\r\nThis is the content of the file.\r\n--boundary123\r\nContent-Disposition: form-data; name=\"field2\"\r\n\r\nvalue2\r\n--boundary123--\r\n";
1269
1270 #[test]
1271 fn test_parser() {
1272 let mut reader = ChunkReader::new(SAMPLE_BODY_2, 0);
1273 let request_chunk_result = reader.get_exact(SAMPLE_BODY_2.len());
1274 assert_eq!(true, request_chunk_result.is_ok());
1275
1276 let mut headers: Headers = HashMap::new();
1277 let content_type = vec!["multipart/form-data; boundary=boundary123".to_string()];
1279 headers.insert("Content-Type".to_string(), content_type);
1280
1281 let partial_body = request_chunk_result.unwrap();
1282 let parse_result = parse(partial_body, &headers, reader, Limits::none());
1283 match parse_result {
1284 Ok(form_parts) => {
1285 println!("Parsing success:");
1286
1287 for form_part in form_parts.iter() {
1288 println!("Name: {}", form_part.name.as_ref().unwrap());
1289 if form_part.value.as_ref().is_some() {
1290 println!("Value: {:?}", String::from_utf8(form_part.value.as_ref().unwrap().to_vec()));
1291 }
1292 }
1293 }
1294
1295 Err(error) => {
1296 println!("Error: {:?}", error);
1297 }
1298 }
1299 }
1300
1301 #[test]
1302 fn test_header_parser() {
1303 let header_sample_1 = "\r\nContent-Disposition: form-data; name=\"John Doe\"\r\n\r\n";
1304 let parsing_result = parse_form_part_header(header_sample_1.to_string());
1305 assert_eq!(true, parsing_result.is_ok());
1306 let form_part = parsing_result.unwrap();
1307 assert_eq!("John Doe", form_part.name.unwrap());
1308
1309 let header_sample_2 = "Content-Disposition: form-data; name=\"file\"; filename=\"a.txt\"\r\n\
1310 Content-Type: text/plain\r\n\r\n";
1311 let parsing_result = parse_form_part_header(header_sample_2.to_string());
1312 assert_eq!(true, parsing_result.is_ok());
1313 let form_part = parsing_result.unwrap();
1314
1315 assert_eq!(form_part.name.unwrap(), "file");
1316 assert_eq!(form_part.filename.unwrap(), "a.txt");
1317 assert_eq!(form_part.content_type.unwrap(), "text/plain");
1318 }
1319
1320 #[test]
1321 fn test_extract_file_body() {
1322 let sample_body = "John Doe\r\n\r\n----------------------------163905767229441796406063\r\nContent-Disposition...";
1323
1324 for _ in 0..10 {
1325 let mut form_part = FormPart {
1326 name: Some("file".to_string()),
1327 filename: Some("file.txt".to_string()),
1328 content_type: Some("text/html".to_string()),
1329 temp_file: None,
1330 value: None,
1331 };
1332
1333 let mut reader = ChunkReader::new(sample_body, 0);
1334 let mut body_buffer = reader.get_chunk().unwrap();
1335 let boundary = "--------------------------163905767229441796406063".to_string();
1338 let result = extract_form_part_body(&mut reader, &mut body_buffer,
1339 &boundary, &mut form_part, &Limits::none());
1340 match result {
1341 Ok(res) => {
1342 println!("{:?}", res);
1343 let mut temp_file = &form_part.temp_file.unwrap();
1344 let mut content = String::new();
1351 temp_file.read_to_string(&mut content).expect("Error reading temporary file");
1352 assert_eq!(content, "John Doe");
1353 }
1354
1355 Err(_) => {
1356 panic!("Multipart body parsing returned error.");
1357 }
1358 }
1359 }
1360 }
1361
1362 #[test]
1363 fn test_extract_form_value() {
1364 let sample_body = "John Doe\r\n----------------------------163905767229441796406063\r\nContent-Disposition";
1365 let mut reader = ChunkReader::new(sample_body, 0);
1366 let mut body_buffer = reader.get_chunk().unwrap();
1367 let boundary = "--------------------------163905767229441796406063".to_string();
1368 let mut form_part = FormPart::empty();
1369
1370 let result = extract_form_value(
1371 &mut reader,
1372 &mut body_buffer,
1373 &boundary,
1374 &mut form_part,
1375 None,
1376 );
1377
1378 assert_eq!(true, result.is_ok());
1379 assert_eq!(b"John Doe", &form_part.value.unwrap().as_slice());
1380 }
1381}