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