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