rust_web_server/range/
mod.rs

1#[cfg(test)]
2mod tests;
3
4#[cfg(test)]
5mod example;
6
7use std::io::prelude::*;
8use std::fs::{metadata};
9use std::io::{Cursor};
10use file_ext::FileExt;
11use crate::core::New;
12
13use crate::response::{Error, Response, STATUS_CODE_REASON_PHRASE};
14use crate::header::Header;
15use crate::mime_type::MimeType;
16use crate::symbol::SYMBOL;
17use crate::url::URL;
18
19#[derive(PartialEq, Eq, Clone, Debug)]
20pub struct Range {
21    pub start: u64,
22    pub end: u64,
23}
24
25#[derive(PartialEq, Eq, Clone, Debug)]
26pub struct ContentRange {
27    pub unit: String,
28    pub range: Range,
29    pub size: String,
30    pub body: Vec<u8>,
31    pub content_type: String,
32}
33
34impl New for ContentRange {
35    fn new() -> Self {
36        ContentRange {
37            unit: Range::BYTES.to_string(),
38            range: Range { start: 0, end: 0 },
39            size: "".to_string(),
40            body: vec![],
41            content_type: "".to_string()
42        }
43    }
44}
45
46impl Range {
47    pub const STRING_SEPARATOR: &'static str = "String_separator";
48    pub const BOUNDARY: &'static str = "boundary";
49    pub const BYTERANGES: &'static str = "byteranges";
50    pub const MULTIPART: &'static str = "multipart";
51    pub const BYTES: &'static str = "bytes";
52    pub const MULTIPART_BYTERANGES_CONTENT_TYPE: &'static str = "multipart/byteranges; boundary=String_separator";
53
54
55
56    pub const _ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY: &'static str = "no empty line between content range headers and body";
57    pub const _ERROR_UNABLE_TO_PARSE_CONTENT_RANGE: &'static str = "unable to parse content-range";
58
59    pub const ERROR_START_IS_AFTER_END_CONTENT_RANGE: &'static str = "start is after end in content range";
60    pub const ERROR_START_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE: &'static str = "start is bigger than filesize in content range";
61    pub const ERROR_END_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE: &'static str = "end is bigger than filesize in content range";
62    pub const ERROR_MALFORMED_RANGE_HEADER_WRONG_UNIT: &'static str = "range header malformed, most likely you have an error in unit statement";
63
64    pub const ERROR_UNABLE_TO_PARSE_RANGE_START: &'static str = "unable to parse range start";
65    pub const ERROR_UNABLE_TO_PARSE_RANGE_END: &'static str = "unable to parse range end";
66
67
68    pub fn parse_range_in_content_range(filelength: u64, range_str: &str) -> Result<Range, Error> {
69        const START_INDEX: usize = 0;
70        const END_INDEX: usize = 1;
71
72        let mut range = Range { start: 0, end: filelength };
73        let parts: Vec<&str> = range_str.split(SYMBOL.hyphen).collect();
74
75        let mut start_range_not_provided = true;
76        for (i, part) in parts.iter().enumerate() {
77
78            let num = part.trim();
79            let length = num.len();
80
81            if i == START_INDEX && length != 0 {
82                start_range_not_provided = false;
83            }
84            if i == START_INDEX && length != 0 {
85                let boxed_start  = num.parse();
86                if boxed_start.is_ok() {
87                    range.start = boxed_start.unwrap()
88                } else {
89                    let message = Range::ERROR_UNABLE_TO_PARSE_RANGE_START.to_string();
90                    let error = Error {
91                        status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
92                        message: message.to_string()
93                    };
94                    return Err(error)
95                }
96            }
97            if i == END_INDEX && length != 0 {
98                let boxed_end  = num.parse();
99                if boxed_end.is_ok() {
100                    range.end = boxed_end.unwrap()
101                } else {
102                    let message = Range::ERROR_UNABLE_TO_PARSE_RANGE_END.to_string();
103                    let error = Error {
104                        status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
105                        message: message.to_string()
106                    };
107                    return Err(error)
108                }
109            }
110            if i == END_INDEX && length != 0 && start_range_not_provided {
111                let boxed_parse = num.parse();
112                if boxed_parse.is_err() {
113                    let error = Error {
114                        status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
115                        message: Range::ERROR_UNABLE_TO_PARSE_RANGE_END.to_string()
116                    };
117                    return Err(error)
118                }
119                let num_usize : u64 = boxed_parse.unwrap();
120                range.start = filelength - num_usize;
121                range.end = filelength;
122            }
123
124            if range.end > filelength {
125                let message = Range::ERROR_END_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE.to_string();
126                let error = Error {
127                    status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
128                    message,
129                };
130                return Err(error);
131            }
132
133            if range.start > filelength {
134                let message = Range::ERROR_START_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE.to_string();
135                let error = Error {
136                    status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
137                    message,
138                };
139                return Err(error);
140            }
141
142            if range.start > range.end {
143                let message = Range::ERROR_START_IS_AFTER_END_CONTENT_RANGE.to_string();
144                let error = Error {
145                    status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
146                    message,
147                };
148                return Err(error);
149            }
150
151
152
153        }
154        Ok(range)
155    }
156
157    pub fn parse_content_range(filepath: &str, filelength: u64, raw_range_value: &str) -> Result<Vec<ContentRange>, Error> {
158        const INDEX_AFTER_UNIT_DECLARATION : usize = 1;
159        let mut content_range_list: Vec<ContentRange> = vec![];
160
161        let prefix = [Range::BYTES, SYMBOL.equals].join("");
162        if !raw_range_value.starts_with(prefix.as_str()) {
163            let message = Range::ERROR_MALFORMED_RANGE_HEADER_WRONG_UNIT.to_string();
164            let error = Error {
165                status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
166                message,
167            };
168            return Err(error);
169        }
170
171        let split_raw_range_value: Vec<&str> = raw_range_value.split(SYMBOL.equals).collect();
172        let boxed_raw_bytes = split_raw_range_value.get(INDEX_AFTER_UNIT_DECLARATION);
173        if boxed_raw_bytes.is_none() {
174            let message = Range::ERROR_UNABLE_TO_PARSE_RANGE_START.to_string();
175            let error = Error {
176                status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
177                message: message.to_string()
178            };
179            return Err(error)
180        }
181
182        let raw_bytes = boxed_raw_bytes.unwrap();
183
184        let bytes: Vec<&str> = raw_bytes.split(SYMBOL.comma).collect();
185        for byte in bytes {
186            let boxed_range = Range::parse_range_in_content_range(filelength, byte);
187            if boxed_range.is_ok() {
188                let range = boxed_range.unwrap();
189                let boxed_read = FileExt::read_file_partially(filepath, range.start, range.end);
190                if boxed_read.is_ok() {
191
192                    let content_type = MimeType::detect_mime_type(filepath);
193                    let body = boxed_read.unwrap();
194                    let content_range = ContentRange {
195                        unit: Range::BYTES.to_string(),
196                        range,
197                        size: filelength.to_string(),
198                        body,
199                        content_type,
200                    };
201                    content_range_list.push(content_range);
202                } else {
203                    let error : Error = Error {
204                        status_code_reason_phrase:  STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
205                        message: boxed_read.err().unwrap().to_string()
206                    };
207                    return Err(error)
208                }
209            } else {
210                let error : Error = boxed_range.err().unwrap();
211                return Err(error);
212            }
213        }
214        Ok(content_range_list)
215    }
216
217    pub fn get_content_range_list(request_uri: &str, range: &Header) -> Result<Vec<ContentRange>, Error> {
218        let mut content_range_list : Vec<ContentRange> = vec![];
219        let url_array = ["http://", "localhost", &request_uri.replace(&FileExt::get_path_separator(), SYMBOL.slash)];
220
221        let url = url_array.join(SYMBOL.empty_string);
222
223        let boxed_url_components = URL::parse(&url);
224        if boxed_url_components.is_err() {
225            let message = boxed_url_components.as_ref().err().unwrap().to_string();
226            // unfallable
227            println!("unexpected error, {}", message);
228        }
229
230        let components = boxed_url_components.unwrap();
231
232        let file_path_part = components.path.replace(SYMBOL.slash, &FileExt::get_path_separator());
233
234
235        let boxed_static_filepath = FileExt::get_static_filepath(&file_path_part);
236        if boxed_static_filepath.is_err() {
237            let error = Error {
238                status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
239                message: boxed_static_filepath.err().unwrap()
240            };
241            eprintln!("{}", &error.message);
242            return Err(error);
243        }
244        let static_filepath = boxed_static_filepath.unwrap();
245
246        let boxed_metadata = metadata(&static_filepath);
247        if boxed_metadata.is_err() {
248            let error = Error {
249                status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
250                message: boxed_metadata.err().unwrap().to_string()
251            };
252            eprintln!("{}", &error.message);
253            return Err(error);
254        }
255
256        let md = boxed_metadata.unwrap();
257        if md.is_file() {
258            let mut path = static_filepath.as_str().to_string();
259
260            let boxed_is_link = FileExt::is_symlink(&static_filepath);
261            if boxed_is_link.is_err() {
262                let error = Error {
263                    status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
264                    message: boxed_is_link.err().unwrap()
265                };
266                eprintln!("{}", &error.message);
267                return Err(error);
268            }
269
270
271            let is_link = boxed_is_link.unwrap();
272            if is_link {
273                let boxed_points_to = FileExt::symlink_points_to(&static_filepath);
274                if boxed_points_to.is_err() {
275                    let error = Error {
276                        status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
277                        message: boxed_points_to.err().unwrap()
278                    };
279                    eprintln!("{}", &error.message);
280                    return Err(error);
281                }
282
283                let points_to = boxed_points_to.unwrap();
284                let reversed_link = &static_filepath.chars().rev().collect::<String>();
285
286                let mut symlink_directory = SYMBOL.empty_string.to_string();
287                let boxed_split = reversed_link.split_once(&FileExt::get_path_separator());
288                if boxed_split.is_some() {
289                    let (_filename, path) = boxed_split.unwrap();
290                    symlink_directory = path.chars().rev().collect::<String>();
291                }
292
293                let resolved_link = FileExt::resolve_symlink_path(&symlink_directory, &points_to).unwrap();
294                path = resolved_link;
295            }
296
297            let boxed_content_range_list = Range::parse_content_range(&path, md.len(), &range.value);
298            if boxed_content_range_list.is_ok() {
299                content_range_list = boxed_content_range_list.unwrap();
300            } else {
301                let error = boxed_content_range_list.err().unwrap();
302                return Err(error)
303            }
304        }
305
306        Ok(content_range_list)
307    }
308
309    pub fn _parse_multipart_body(cursor: &mut Cursor<&[u8]>, mut content_range_list: Vec<ContentRange>) -> Result<Vec<ContentRange>, String> {
310
311        let mut buffer = Range::_parse_line_as_bytes(cursor);
312        let new_line_char_found = buffer.len() != 0;
313        let mut string = Range::_convert_bytes_array_to_string(buffer);
314
315        if !new_line_char_found {
316            return Ok(content_range_list)
317        };
318
319        let mut content_range: ContentRange = ContentRange {
320            unit: Range::BYTES.to_string(),
321            range: Range { start: 0, end: 0 },
322            size: "".to_string(),
323            body: vec![],
324            content_type: "".to_string()
325        };
326
327        let content_range_is_not_parsed = content_range.body.len() == 0;
328        let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
329        if string.starts_with(separator.as_str()) && content_range_is_not_parsed {
330            //read next line - Content-Type
331            buffer = Range::_parse_line_as_bytes(cursor);
332            string = Range::_convert_bytes_array_to_string(buffer);
333        }
334
335        let content_type_is_not_parsed = content_range.content_type.len() == 0;
336        if string.starts_with(Header::_CONTENT_TYPE) && content_type_is_not_parsed {
337            let content_type = Response::_parse_http_response_header_string(string.as_str());
338            content_range.content_type = content_type.value.trim().to_string();
339
340            //read next line - Content-Range
341            buffer = Range::_parse_line_as_bytes(cursor);
342            string = Range::_convert_bytes_array_to_string(buffer);
343        }
344
345        let content_range_is_not_parsed = content_range.size.len() == 0;
346        if string.starts_with(Header::_CONTENT_RANGE) && content_range_is_not_parsed {
347            let content_range_header = Response::_parse_http_response_header_string(string.as_str());
348
349            let boxed_result = Range::_parse_content_range_header_value(content_range_header.value);
350            if boxed_result.is_ok() {
351                let (start, end, size) = boxed_result.unwrap();
352
353                content_range.size = size.to_string();
354                content_range.range.start = start as u64;
355                content_range.range.end = end as u64;
356            } else {
357                return Err(boxed_result.err().unwrap())
358            }
359
360
361
362            // read next line - empty line
363            buffer = Range::_parse_line_as_bytes(cursor);
364            string = Range::_convert_bytes_array_to_string(buffer);
365
366            if string.trim().len() > 0 {
367                return Err(Range::_ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY.to_string());
368            }
369
370            // read next line - separator between content ranges
371            buffer = Range::_parse_line_as_bytes(cursor);
372            string = Range::_convert_bytes_array_to_string(buffer);
373        }
374
375        let content_range_is_parsed = content_range.size.len() != 0;
376        let content_type_is_parsed = content_range.content_type.len() != 0;
377        if content_range_is_parsed && content_type_is_parsed {
378            let mut body : Vec<u8> = vec![];
379            body = [body, string.as_bytes().to_vec()].concat();
380
381            let mut buf = Vec::from(string.as_bytes());
382            let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
383            while !buf.starts_with(separator.as_bytes()) {
384                buf = vec![];
385                cursor.read_until(b'\n', &mut buf).unwrap();
386                let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
387                if !buf.starts_with(separator.as_bytes()) {
388                    body = [body, buf.to_vec()].concat();
389                }
390            }
391
392            let mut mutable_body : Vec<u8>  = body;
393            mutable_body.pop(); // remove /r
394            mutable_body.pop(); // remove /n
395
396
397            content_range.body = mutable_body;
398
399            content_range_list.push(content_range);
400        }
401
402        let boxed_result = Range::_parse_multipart_body(cursor, content_range_list);
403        return if boxed_result.is_ok() {
404            Ok(boxed_result.unwrap())
405        } else {
406            let error = boxed_result.err().unwrap();
407            Err(error)
408        }
409
410    }
411
412    pub fn _parse_raw_content_range_header_value(unparsed_header_value: &str)-> Result<(i64, i64, i64), String> {
413        let lowercase_unparsed_header_value = unparsed_header_value.trim().to_lowercase();
414
415        let start : i64;
416        let end : i64;
417        let size : i64;
418
419
420        let boxed_split_without_bytes = lowercase_unparsed_header_value.split_once(SYMBOL.whitespace);
421        if boxed_split_without_bytes.is_none() {
422            return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
423        }
424
425        let (bytes, without_bytes) = boxed_split_without_bytes.unwrap();
426        if !bytes.eq("bytes") {
427            return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
428        }
429
430        let boxed_without_bytes = without_bytes.split_once(SYMBOL.hyphen);
431        if boxed_without_bytes.is_none() {
432            return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
433        }
434
435        let (_start, _without_start) = boxed_without_bytes.unwrap();
436
437        let boxed_start = _start.parse::<i64>();
438        if boxed_start.is_err() {
439            return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
440        }
441
442        start = boxed_start.unwrap();
443
444
445
446        let boxed_without_start = _without_start.split_once(SYMBOL.slash);
447        if boxed_without_start.is_none() {
448            return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
449        }
450        let (_end, _size) = boxed_without_start.unwrap();
451
452        let boxed_end = _end.parse::<i64>();
453        if boxed_end.is_err() {
454            return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
455        }
456
457        end = boxed_end.unwrap();
458
459        let boxed_size = _size.parse::<i64>();
460        if boxed_size.is_err() {
461            return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
462        }
463
464        size = boxed_size.unwrap();
465
466        Ok((start, end, size))
467    }
468
469    pub fn _parse_content_range_header_value(header_value: String) -> Result<(i64, i64, i64), String> {
470        let boxed_parse_result = Range::_parse_raw_content_range_header_value(&header_value);
471        if boxed_parse_result.is_err() {
472            return Err(boxed_parse_result.err().unwrap())
473        }
474        let (start, end, size) = boxed_parse_result.unwrap();
475
476        if start > end {
477            return Err(Range::ERROR_START_IS_AFTER_END_CONTENT_RANGE.to_string())
478        }
479
480        if start > size {
481            return Err(Range::ERROR_START_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE.to_string());
482        }
483        if end > size {
484            return  Err(Range::ERROR_END_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE.to_string());
485        }
486
487        Ok((start, end, size))
488    }
489
490    pub fn _parse_line_as_bytes(cursor: &mut Cursor<&[u8]>) -> Vec<u8> {
491        let mut buffer = vec![];
492        cursor.read_until(b'\n', &mut buffer).unwrap();
493        buffer
494    }
495
496    pub fn _convert_bytes_array_to_string(buffer: Vec<u8>) -> String {
497        let buffer_as_u8_array: &[u8] = &buffer;
498        String::from_utf8(Vec::from(buffer_as_u8_array)).unwrap()
499    }
500
501    pub fn get_content_range(body: Vec<u8>, mime_type: String) -> ContentRange {
502        let length = body.len() as u64;
503        let content_range = ContentRange {
504            unit: Range::BYTES.to_string(),
505            range: Range { start: 0, end: length },
506            size: length.to_string(),
507            body,
508            content_type: mime_type
509        };
510
511        content_range
512    }
513
514    pub fn get_content_range_of_a_file(filepath: &str) -> Result<ContentRange, String> {
515        let body: Vec<u8>;
516        let boxed_file = FileExt::read_file(filepath);
517        if boxed_file.is_err() {
518            let error = boxed_file.err().unwrap();
519            return Err(error);
520        }
521
522        body = boxed_file.unwrap();
523        let mime_type = MimeType::detect_mime_type(filepath);
524        let content_range = Range::get_content_range(body, mime_type);
525        Ok(content_range)
526    }
527
528    pub fn parse_multipart_body(cursor: &mut Cursor<&[u8]>,
529                                mut content_range_list: Vec<ContentRange>)
530                                -> Result<Vec<ContentRange>, String> {
531
532        let boxed_line = Range::parse_line_as_bytes(cursor);
533        if boxed_line.is_err() {
534            let message = boxed_line.err().unwrap();
535            return Err(message);
536        }
537        let mut buffer = boxed_line.unwrap();
538
539
540        let new_line_char_found = buffer.len() != 0;
541
542
543        let boxed_line = Range::convert_bytes_array_to_string(buffer);
544        if boxed_line.is_err() {
545            let message = boxed_line.err().unwrap();
546            return Err(message);
547        }
548        let mut string = boxed_line.unwrap();
549
550        if !new_line_char_found {
551            return Ok(content_range_list)
552        };
553
554        let mut content_range: ContentRange = ContentRange {
555            unit: Range::BYTES.to_string(),
556            range: Range { start: 0, end: 0 },
557            size: "".to_string(),
558            body: vec![],
559            content_type: "".to_string()
560        };
561
562        let content_range_is_not_parsed = content_range.body.len() == 0;
563        let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
564        if string.starts_with(separator.as_str()) && content_range_is_not_parsed {
565            //read next line - Content-Type
566            let boxed_line = Range::parse_line_as_bytes(cursor);
567            if boxed_line.is_err() {
568                let message = boxed_line.err().unwrap();
569                return Err(message);
570            }
571            buffer = boxed_line.unwrap();
572
573            let boxed_line = Range::convert_bytes_array_to_string(buffer);
574            if boxed_line.is_err() {
575                let message = boxed_line.err().unwrap();
576                return Err(message);
577            }
578            string = boxed_line.unwrap();
579        }
580
581        let content_type_is_not_parsed = content_range.content_type.len() == 0;
582        if string.starts_with(Header::_CONTENT_TYPE) && content_type_is_not_parsed {
583            let boxed_content_type = Response::parse_http_response_header_string(string.as_str());
584            if boxed_content_type.is_err() {
585                let message = boxed_content_type.err().unwrap();
586                return Err(message);
587            }
588            let content_type = boxed_content_type.unwrap();
589
590            content_range.content_type = content_type.value.trim().to_string();
591
592            //read next line - Content-Range
593            let boxed_line = Range::parse_line_as_bytes(cursor);
594            if boxed_line.is_err() {
595                let message = boxed_line.err().unwrap();
596                return Err(message);
597            }
598            buffer = boxed_line.unwrap();
599
600            let boxed_line = Range::convert_bytes_array_to_string(buffer);
601            if boxed_line.is_err() {
602                let message = boxed_line.err().unwrap();
603                return Err(message);
604            }
605            string = boxed_line.unwrap();
606        }
607
608        let content_range_is_not_parsed = content_range.size.len() == 0;
609        if string.starts_with(Header::_CONTENT_RANGE) && content_range_is_not_parsed {
610            let content_range_header = Response::_parse_http_response_header_string(string.as_str());
611
612            let boxed_result = Range::_parse_content_range_header_value(content_range_header.value);
613            if boxed_result.is_ok() {
614                let (start, end, size) = boxed_result.unwrap();
615
616                content_range.size = size.to_string();
617                content_range.range.start = start as u64;
618                content_range.range.end = end as u64;
619            } else {
620                return Err(boxed_result.err().unwrap())
621            }
622
623
624
625            // read next line - empty line
626            let boxed_line = Range::parse_line_as_bytes(cursor);
627            if boxed_line.is_err() {
628                let message = boxed_line.err().unwrap();
629                return Err(message);
630            }
631            buffer = boxed_line.unwrap();
632
633            let boxed_line = Range::convert_bytes_array_to_string(buffer);
634            if boxed_line.is_err() {
635                let message = boxed_line.err().unwrap();
636                return Err(message);
637            }
638            string = boxed_line.unwrap();
639
640            if string.trim().len() > 0 {
641                return Err(Range::_ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY.to_string());
642            }
643
644            // read next line - separator between content ranges
645            let boxed_line = Range::parse_line_as_bytes(cursor);
646            if boxed_line.is_err() {
647                let message = boxed_line.err().unwrap();
648                return Err(message);
649            }
650            buffer = boxed_line.unwrap();
651
652            let boxed_line = Range::convert_bytes_array_to_string(buffer);
653            if boxed_line.is_err() {
654                let message = boxed_line.err().unwrap();
655                return Err(message);
656            }
657            string = boxed_line.unwrap();
658        }
659
660        let content_range_is_parsed = content_range.size.len() != 0;
661        let content_type_is_parsed = content_range.content_type.len() != 0;
662        if content_range_is_parsed && content_type_is_parsed {
663            let mut body : Vec<u8> = vec![];
664            body = [body, string.as_bytes().to_vec()].concat();
665
666            let mut buf = Vec::from(string.as_bytes());
667            let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
668            while !buf.starts_with(separator.as_bytes()) {
669                buf = vec![];
670                cursor.read_until(b'\n', &mut buf).unwrap();
671                let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
672                if !buf.starts_with(separator.as_bytes()) {
673                    body = [body, buf.to_vec()].concat();
674                }
675            }
676
677            let mut mutable_body : Vec<u8>  = body;
678            mutable_body.pop(); // remove /r
679            mutable_body.pop(); // remove /n
680
681
682            content_range.body = mutable_body;
683
684            content_range_list.push(content_range);
685        }
686
687        let boxed_result = Range::_parse_multipart_body(cursor, content_range_list);
688        return if boxed_result.is_ok() {
689            Ok(boxed_result.unwrap())
690        } else {
691            let error = boxed_result.err().unwrap();
692            Err(error)
693        }
694
695    }
696
697    pub fn parse_line_as_bytes(cursor: &mut Cursor<&[u8]>) -> Result<Vec<u8>, String> {
698        let mut buffer = vec![];
699        let boxed_read = cursor.read_until(b'\n', &mut buffer);
700        if boxed_read.is_err() {
701            let message = boxed_read.err().unwrap().to_string();
702            return Err(message);
703        }
704        boxed_read.unwrap();
705        Ok(buffer)
706    }
707
708    pub fn convert_bytes_array_to_string(buffer: Vec<u8>) -> Result<String, String> {
709        let buffer_as_u8_array: &[u8] = &buffer;
710        let boxed_string = String::from_utf8(Vec::from(buffer_as_u8_array));
711        if boxed_string.is_err() {
712            let message = boxed_string.err().unwrap().to_string();
713            return Err(message);
714        }
715        let string = boxed_string.unwrap();
716        Ok(string)
717    }
718
719    pub fn parse_multipart_body_with_boundary(cursor: &mut Cursor<&[u8]>,
720                                              mut content_range_list: Vec<ContentRange>,
721                                              boundary: String,
722                                              total_bytes: i32,
723                                              mut bytes_read: i32,
724                                              mut is_opening_boundary_read: bool)
725                                              -> Result<Vec<ContentRange>, String> {
726
727        let mut buffer = vec![];
728        let boxed_read = cursor.read_until(b'\n', &mut buffer);
729        if boxed_read.is_err() {
730            let message = boxed_read.err().unwrap().to_string();
731            return Err(message);
732        }
733
734        let bytes_offset = boxed_read.unwrap();
735        bytes_read = bytes_read + bytes_offset as i32;
736        if bytes_read == total_bytes {
737            // end of stream
738        }
739
740
741        let new_line_char_found = buffer.len() != 0;
742
743
744        let boxed_line = Range::convert_bytes_array_to_string(buffer);
745        if boxed_line.is_err() {
746            let message = boxed_line.err().unwrap();
747            return Err(message);
748        }
749        let mut string = boxed_line.unwrap();
750
751        if !new_line_char_found {
752            return Ok(content_range_list)
753        };
754
755        let mut content_range: ContentRange = ContentRange::new();
756
757        let content_range_is_not_parsed = content_range.body.len() == 0;
758
759        if string.trim().len() != 0 && !is_opening_boundary_read && !string.contains(boundary.as_str()) {
760            return Err("Response body doesn't start with a boundary".to_string())
761        }
762
763        if string.contains(boundary.as_str()) && content_range_is_not_parsed {
764            if !is_opening_boundary_read {
765                is_opening_boundary_read = true;
766            }
767            //read next line - Content-Type
768            let boxed_line = Range::parse_line_as_bytes(cursor);
769            if boxed_line.is_err() {
770                let message = boxed_line.err().unwrap();
771                return Err(message);
772            }
773            buffer = boxed_line.unwrap();
774
775            let boxed_line = Range::convert_bytes_array_to_string(buffer);
776            if boxed_line.is_err() {
777                let message = boxed_line.err().unwrap();
778                return Err(message);
779            }
780            string = boxed_line.unwrap();
781        }
782
783        let content_type_is_not_parsed = content_range.content_type.len() == 0;
784        if string.starts_with(Header::_CONTENT_TYPE) && content_type_is_not_parsed {
785            let boxed_content_type = Response::parse_http_response_header_string(string.as_str());
786            if boxed_content_type.is_err() {
787                let message = boxed_content_type.err().unwrap();
788                return Err(message);
789            }
790            let content_type = boxed_content_type.unwrap();
791
792            content_range.content_type = content_type.value.trim().to_string();
793
794            //read next line - Content-Range
795            let boxed_line = Range::parse_line_as_bytes(cursor);
796            if boxed_line.is_err() {
797                let message = boxed_line.err().unwrap();
798                return Err(message);
799            }
800            buffer = boxed_line.unwrap();
801
802            let boxed_line = Range::convert_bytes_array_to_string(buffer);
803            if boxed_line.is_err() {
804                let message = boxed_line.err().unwrap();
805                return Err(message);
806            }
807            string = boxed_line.unwrap();
808        }
809
810        let content_range_is_not_parsed = content_range.size.len() == 0;
811        if string.starts_with(Header::_CONTENT_RANGE) && content_range_is_not_parsed {
812            let content_range_header = Response::_parse_http_response_header_string(string.as_str());
813
814            let boxed_result = Range::_parse_content_range_header_value(content_range_header.value);
815            if boxed_result.is_ok() {
816                let (start, end, size) = boxed_result.unwrap();
817
818                content_range.size = size.to_string();
819                content_range.range.start = start as u64;
820                content_range.range.end = end as u64;
821            } else {
822                return Err(boxed_result.err().unwrap())
823            }
824
825
826
827            // read next line - empty line
828            let boxed_line = Range::parse_line_as_bytes(cursor);
829            if boxed_line.is_err() {
830                let message = boxed_line.err().unwrap();
831                return Err(message);
832            }
833            buffer = boxed_line.unwrap();
834
835            let boxed_line = Range::convert_bytes_array_to_string(buffer);
836            if boxed_line.is_err() {
837                let message = boxed_line.err().unwrap();
838                return Err(message);
839            }
840            string = boxed_line.unwrap();
841
842            if string.trim().len() > 0 {
843                return Err(Range::_ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY.to_string());
844            }
845
846        }
847
848        let content_range_is_parsed = content_range.size.len() != 0;
849        let content_type_is_parsed = content_range.content_type.len() != 0;
850        if content_range_is_parsed && content_type_is_parsed {
851            let mut body : Vec<u8> = vec![];
852
853            let mut is_not_boundary = true;
854
855            while is_not_boundary {
856                let mut _bytes_offset = 0;
857                let mut buf: Vec<u8> = vec![];
858                let boxed_read = cursor.read_until(b'\n', &mut buf);
859                if boxed_read.is_err() {
860                    return Err("Unable to read from stream".to_string());
861                }
862                _bytes_offset = boxed_read.unwrap();
863                bytes_read = bytes_read + _bytes_offset as i32;
864
865
866                let boxed_line = Range::convert_bytes_array_to_string(buf.clone());
867                if boxed_line.is_err() {
868                    // non utf-8 body, continue
869                    body = [body, buf.to_vec()].concat();
870                    continue;
871                }
872
873                string = boxed_line.unwrap();
874
875                is_not_boundary = !string.contains(boundary.as_str());
876
877                if is_not_boundary {
878                    body = [body, buf.to_vec()].concat();
879                    if (bytes_read == total_bytes) || _bytes_offset == 0 {
880                        return Err("Unable to parse multipart form body, reached the end of stream and it does not contain boundary".to_string());
881                    }
882                }
883
884            }
885
886            let mut mutable_body : Vec<u8>  = body;
887            mutable_body.pop(); // remove /r
888            mutable_body.pop(); // remove /n
889
890
891            content_range.body = mutable_body;
892
893            content_range_list.push(content_range);
894        }
895
896        let boxed_result = Range::parse_multipart_body_with_boundary(
897            cursor,
898            content_range_list,
899            boundary,
900            total_bytes,
901            bytes_read,
902            is_opening_boundary_read);
903        return if boxed_result.is_ok() {
904            Ok(boxed_result.unwrap())
905        } else {
906            let error = boxed_result.err().unwrap();
907            Err(error)
908        }
909
910    }
911}
912
913