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