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