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 bytes: Vec<&str> = raw_bytes.split(SYMBOL.comma).collect();
154 for byte in bytes {
155 let boxed_range = Range::parse_range_in_content_range(filelength, byte);
156 if boxed_range.is_ok() {
157 let range = boxed_range.unwrap();
158 let boxed_read = FileExt::read_file_partially(filepath, range.start, range.end);
159 if boxed_read.is_ok() {
160
161 let content_type = MimeType::detect_mime_type(filepath);
162 let body = boxed_read.unwrap();
163 let content_range = ContentRange {
164 unit: Range::BYTES.to_string(),
165 range,
166 size: filelength.to_string(),
167 body,
168 content_type,
169 };
170 content_range_list.push(content_range);
171 } else {
172 let error : Error = Error {
173 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n416_range_not_satisfiable,
174 message: boxed_read.err().unwrap().to_string()
175 };
176 return Err(error)
177 }
178 } else {
179 let error : Error = boxed_range.err().unwrap();
180 return Err(error);
181 }
182 }
183 Ok(content_range_list)
184 }
185
186 pub fn get_content_range_list(request_uri: &str, range: &Header) -> Result<Vec<ContentRange>, Error> {
187 let mut content_range_list : Vec<ContentRange> = vec![];
188
189 let url = request_uri.replace(&FileExt::get_path_separator(), SYMBOL.slash).to_string();
190
191 let boxed_url_components = URL::parse_request_target(&url);
192 if boxed_url_components.is_err() {
193 let message = boxed_url_components.as_ref().err().unwrap().to_string();
194 println!("unexpected error, {}", message);
196 }
197
198 let components = boxed_url_components.unwrap();
199
200 let file_path_part = components.path.replace(SYMBOL.slash, &FileExt::get_path_separator());
201
202 let boxed_static_filepath = crate::app::controller::static_resource::static_fs_path(&file_path_part);
203 if boxed_static_filepath.is_err() {
204 let error = Error {
205 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
206 message: boxed_static_filepath.err().unwrap()
207 };
208 eprintln!("{}", &error.message);
209 return Err(error);
210 }
211 let static_filepath = boxed_static_filepath.unwrap();
212
213 let boxed_metadata = metadata(&static_filepath);
214 if boxed_metadata.is_err() {
215 let error = Error {
216 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
217 message: boxed_metadata.err().unwrap().to_string()
218 };
219 eprintln!("{}", &error.message);
220 return Err(error);
221 }
222
223 let md = boxed_metadata.unwrap();
224 if md.is_file() {
225 let mut path = static_filepath.as_str().to_string();
226
227 let boxed_is_link = FileExt::is_symlink(&static_filepath);
228 if boxed_is_link.is_err() {
229 let error = Error {
230 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
231 message: boxed_is_link.err().unwrap()
232 };
233 eprintln!("{}", &error.message);
234 return Err(error);
235 }
236
237
238 let is_link = boxed_is_link.unwrap();
239 if is_link {
240 let boxed_points_to = FileExt::symlink_points_to(&static_filepath);
241 if boxed_points_to.is_err() {
242 let error = Error {
243 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
244 message: boxed_points_to.err().unwrap()
245 };
246 eprintln!("{}", &error.message);
247 return Err(error);
248 }
249
250 let points_to = boxed_points_to.unwrap();
251 let reversed_link = &static_filepath.chars().rev().collect::<String>();
252
253 let mut symlink_directory = SYMBOL.empty_string.to_string();
254 let boxed_split = reversed_link.split_once(&FileExt::get_path_separator());
255 if boxed_split.is_some() {
256 let (_filename, path) = boxed_split.unwrap();
257 symlink_directory = path.chars().rev().collect::<String>();
258 }
259
260 let resolved_link = FileExt::resolve_symlink_path(&symlink_directory, &points_to).unwrap();
261 path = resolved_link;
262 }
263
264 let boxed_content_range_list = Range::parse_content_range(&path, md.len(), &range.value);
265 if boxed_content_range_list.is_ok() {
266 content_range_list = boxed_content_range_list.unwrap();
267 } else {
268 let error = boxed_content_range_list.err().unwrap();
269 return Err(error)
270 }
271 }
272
273 Ok(content_range_list)
274 }
275
276 pub fn _parse_multipart_body(cursor: &mut Cursor<&[u8]>, mut content_range_list: Vec<ContentRange>) -> Result<Vec<ContentRange>, String> {
277 loop {
281
282 let mut buffer = Range::_parse_line_as_bytes(cursor);
283 let new_line_char_found = buffer.len() != 0;
284 let mut string = Range::_convert_bytes_array_to_string(buffer);
285
286 if !new_line_char_found {
287 return Ok(content_range_list)
288 };
289
290 let mut content_range: ContentRange = ContentRange {
291 unit: Range::BYTES.to_string(),
292 range: Range { start: 0, end: 0 },
293 size: "".to_string(),
294 body: vec![],
295 content_type: "".to_string()
296 };
297
298 let content_range_is_not_parsed = content_range.body.len() == 0;
299 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
300 if string.starts_with(separator.as_str()) && content_range_is_not_parsed {
301 buffer = Range::_parse_line_as_bytes(cursor);
303 string = Range::_convert_bytes_array_to_string(buffer);
304 }
305
306 let content_type_is_not_parsed = content_range.content_type.len() == 0;
307 if string.starts_with(Header::_CONTENT_TYPE) && content_type_is_not_parsed {
308 let content_type = Response::_parse_http_response_header_string(string.as_str());
309 content_range.content_type = content_type.value.trim().to_string();
310
311 buffer = Range::_parse_line_as_bytes(cursor);
313 string = Range::_convert_bytes_array_to_string(buffer);
314 }
315
316 let content_range_is_not_parsed = content_range.size.len() == 0;
317 if string.starts_with(Header::_CONTENT_RANGE) && content_range_is_not_parsed {
318 let content_range_header = Response::_parse_http_response_header_string(string.as_str());
319
320 let boxed_result = Range::_parse_content_range_header_value(content_range_header.value);
321 if boxed_result.is_ok() {
322 let (start, end, size) = boxed_result.unwrap();
323
324 content_range.size = size.to_string();
325 content_range.range.start = start as u64;
326 content_range.range.end = end as u64;
327 } else {
328 return Err(boxed_result.err().unwrap())
329 }
330
331
332
333 buffer = Range::_parse_line_as_bytes(cursor);
335 string = Range::_convert_bytes_array_to_string(buffer);
336
337 if string.trim().len() > 0 {
338 return Err(Range::_ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY.to_string());
339 }
340
341 buffer = Range::_parse_line_as_bytes(cursor);
343 string = Range::_convert_bytes_array_to_string(buffer);
344 }
345
346 let content_range_is_parsed = content_range.size.len() != 0;
347 let content_type_is_parsed = content_range.content_type.len() != 0;
348 if content_range_is_parsed && content_type_is_parsed {
349 let mut body : Vec<u8> = vec![];
350 body = [body, string.as_bytes().to_vec()].concat();
351
352 let mut buf = Vec::from(string.as_bytes());
353 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
354 while !buf.starts_with(separator.as_bytes()) {
355 buf = vec![];
356 cursor.read_until(b'\n', &mut buf).unwrap();
357 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
358 if !buf.starts_with(separator.as_bytes()) {
359 body = [body, buf.to_vec()].concat();
360 }
361 }
362
363 let mut mutable_body : Vec<u8> = body;
364 mutable_body.pop(); mutable_body.pop(); content_range.body = mutable_body;
369
370 content_range_list.push(content_range);
371 }
372
373 }
374 }
375
376 pub fn _parse_raw_content_range_header_value(unparsed_header_value: &str)-> Result<(i64, i64, i64), String> {
377 let lowercase_unparsed_header_value = unparsed_header_value.trim().to_lowercase();
378
379 let start : i64;
380 let end : i64;
381 let size : i64;
382
383
384 let boxed_split_without_bytes = lowercase_unparsed_header_value.split_once(SYMBOL.whitespace);
385 if boxed_split_without_bytes.is_none() {
386 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
387 }
388
389 let (bytes, without_bytes) = boxed_split_without_bytes.unwrap();
390 if !bytes.eq("bytes") {
391 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
392 }
393
394 let boxed_without_bytes = without_bytes.split_once(SYMBOL.hyphen);
395 if boxed_without_bytes.is_none() {
396 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
397 }
398
399 let (_start, _without_start) = boxed_without_bytes.unwrap();
400
401 let boxed_start = _start.parse::<i64>();
402 if boxed_start.is_err() {
403 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
404 }
405
406 start = boxed_start.unwrap();
407
408
409
410 let boxed_without_start = _without_start.split_once(SYMBOL.slash);
411 if boxed_without_start.is_none() {
412 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
413 }
414 let (_end, _size) = boxed_without_start.unwrap();
415
416 let boxed_end = _end.parse::<i64>();
417 if boxed_end.is_err() {
418 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
419 }
420
421 end = boxed_end.unwrap();
422
423 let boxed_size = _size.parse::<i64>();
424 if boxed_size.is_err() {
425 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
426 }
427
428 size = boxed_size.unwrap();
429
430 Ok((start, end, size))
431 }
432
433 pub fn _parse_content_range_header_value(header_value: String) -> Result<(i64, i64, i64), String> {
434 let boxed_parse_result = Range::_parse_raw_content_range_header_value(&header_value);
435 if boxed_parse_result.is_err() {
436 return Err(boxed_parse_result.err().unwrap())
437 }
438 let (start, end, size) = boxed_parse_result.unwrap();
439
440 if start > end {
441 return Err(Range::ERROR_START_IS_AFTER_END_CONTENT_RANGE.to_string())
442 }
443
444 if start > size {
445 return Err(Range::ERROR_START_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE.to_string());
446 }
447 if end > size {
448 return Err(Range::ERROR_END_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE.to_string());
449 }
450
451 Ok((start, end, size))
452 }
453
454 pub fn _parse_line_as_bytes(cursor: &mut Cursor<&[u8]>) -> Vec<u8> {
455 let mut buffer = vec![];
456 cursor.read_until(b'\n', &mut buffer).unwrap();
457 buffer
458 }
459
460 pub fn _convert_bytes_array_to_string(buffer: Vec<u8>) -> String {
461 let buffer_as_u8_array: &[u8] = &buffer;
462 String::from_utf8(Vec::from(buffer_as_u8_array)).unwrap()
463 }
464
465 pub fn get_content_range(body: Vec<u8>, mime_type: String) -> ContentRange {
467 let length = body.len() as u64;
468 let content_range = ContentRange {
469 unit: Range::BYTES.to_string(),
470 range: Range { start: 0, end: length },
471 size: length.to_string(),
472 body,
473 content_type: mime_type
474 };
475
476 content_range
477 }
478
479 pub fn get_content_range_of_a_file(filepath: &str) -> Result<ContentRange, String> {
481 let body: Vec<u8>;
482 let boxed_file = FileExt::read_file(filepath);
483 if boxed_file.is_err() {
484 let error = boxed_file.err().unwrap();
485 return Err(error);
486 }
487
488 body = boxed_file.unwrap();
489 let mime_type = MimeType::detect_mime_type(filepath);
490 let content_range = Range::get_content_range(body, mime_type);
491 Ok(content_range)
492 }
493
494
495 pub fn parse_multipart_body(cursor: &mut Cursor<&[u8]>,
496 mut content_range_list: Vec<ContentRange>)
497 -> Result<Vec<ContentRange>, String> {
498
499 let boxed_line = Range::parse_line_as_bytes(cursor);
500 if boxed_line.is_err() {
501 let message = boxed_line.err().unwrap();
502 return Err(message);
503 }
504 let mut buffer = boxed_line.unwrap();
505
506
507 let new_line_char_found = buffer.len() != 0;
508
509
510 let boxed_line = Range::convert_bytes_array_to_string(buffer);
511 if boxed_line.is_err() {
512 let message = boxed_line.err().unwrap();
513 return Err(message);
514 }
515 let mut string = boxed_line.unwrap();
516
517 if !new_line_char_found {
518 return Ok(content_range_list)
519 };
520
521 let mut content_range: ContentRange = ContentRange {
522 unit: Range::BYTES.to_string(),
523 range: Range { start: 0, end: 0 },
524 size: "".to_string(),
525 body: vec![],
526 content_type: "".to_string()
527 };
528
529 let content_range_is_not_parsed = content_range.body.len() == 0;
530 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
531 if string.starts_with(separator.as_str()) && content_range_is_not_parsed {
532 let boxed_line = Range::parse_line_as_bytes(cursor);
534 if boxed_line.is_err() {
535 let message = boxed_line.err().unwrap();
536 return Err(message);
537 }
538 buffer = boxed_line.unwrap();
539
540 let boxed_line = Range::convert_bytes_array_to_string(buffer);
541 if boxed_line.is_err() {
542 let message = boxed_line.err().unwrap();
543 return Err(message);
544 }
545 string = boxed_line.unwrap();
546 }
547
548 let content_type_is_not_parsed = content_range.content_type.len() == 0;
549 if string.starts_with(Header::_CONTENT_TYPE) && content_type_is_not_parsed {
550 let boxed_content_type = Response::parse_http_response_header_string(string.as_str());
551 if boxed_content_type.is_err() {
552 let message = boxed_content_type.err().unwrap();
553 return Err(message);
554 }
555 let content_type = boxed_content_type.unwrap();
556
557 content_range.content_type = content_type.value.trim().to_string();
558
559 let boxed_line = Range::parse_line_as_bytes(cursor);
561 if boxed_line.is_err() {
562 let message = boxed_line.err().unwrap();
563 return Err(message);
564 }
565 buffer = boxed_line.unwrap();
566
567 let boxed_line = Range::convert_bytes_array_to_string(buffer);
568 if boxed_line.is_err() {
569 let message = boxed_line.err().unwrap();
570 return Err(message);
571 }
572 string = boxed_line.unwrap();
573 }
574
575 let content_range_is_not_parsed = content_range.size.len() == 0;
576 if string.starts_with(Header::_CONTENT_RANGE) && content_range_is_not_parsed {
577 let content_range_header = Response::_parse_http_response_header_string(string.as_str());
578
579 let boxed_result = Range::_parse_content_range_header_value(content_range_header.value);
580 if boxed_result.is_ok() {
581 let (start, end, size) = boxed_result.unwrap();
582
583 content_range.size = size.to_string();
584 content_range.range.start = start as u64;
585 content_range.range.end = end as u64;
586 } else {
587 return Err(boxed_result.err().unwrap())
588 }
589
590
591
592 let boxed_line = Range::parse_line_as_bytes(cursor);
594 if boxed_line.is_err() {
595 let message = boxed_line.err().unwrap();
596 return Err(message);
597 }
598 buffer = boxed_line.unwrap();
599
600 let boxed_line = Range::convert_bytes_array_to_string(buffer);
601 if boxed_line.is_err() {
602 let message = boxed_line.err().unwrap();
603 return Err(message);
604 }
605 string = boxed_line.unwrap();
606
607 if string.trim().len() > 0 {
608 return Err(Range::_ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY.to_string());
609 }
610
611 let boxed_line = Range::parse_line_as_bytes(cursor);
613 if boxed_line.is_err() {
614 let message = boxed_line.err().unwrap();
615 return Err(message);
616 }
617 buffer = boxed_line.unwrap();
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 string = boxed_line.unwrap();
625 }
626
627 let content_range_is_parsed = content_range.size.len() != 0;
628 let content_type_is_parsed = content_range.content_type.len() != 0;
629 if content_range_is_parsed && content_type_is_parsed {
630 let mut body : Vec<u8> = vec![];
631 body = [body, string.as_bytes().to_vec()].concat();
632
633 let mut buf = Vec::from(string.as_bytes());
634 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
635 while !buf.starts_with(separator.as_bytes()) {
636 buf = vec![];
637 cursor.read_until(b'\n', &mut buf).unwrap();
638 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
639 if !buf.starts_with(separator.as_bytes()) {
640 body = [body, buf.to_vec()].concat();
641 }
642 }
643
644 let mut mutable_body : Vec<u8> = body;
645 mutable_body.pop(); mutable_body.pop(); content_range.body = mutable_body;
650
651 content_range_list.push(content_range);
652 }
653
654 let boxed_result = Range::_parse_multipart_body(cursor, content_range_list);
655 return if boxed_result.is_ok() {
656 Ok(boxed_result.unwrap())
657 } else {
658 let error = boxed_result.err().unwrap();
659 Err(error)
660 }
661
662 }
663
664 pub fn parse_multipart_body_with_boundary(cursor: &mut Cursor<&[u8]>,
665 mut content_range_list: Vec<ContentRange>,
666 boundary: String,
667 total_bytes: i32,
668 mut bytes_read: i32,
669 mut is_opening_boundary_read: bool)
670 -> Result<Vec<ContentRange>, String> {
671 loop {
675
676 let mut buffer = vec![];
677 let boxed_read = cursor.read_until(b'\n', &mut buffer);
678 if boxed_read.is_err() {
679 let message = boxed_read.err().unwrap().to_string();
680 return Err(message);
681 }
682
683 let bytes_offset = boxed_read.unwrap();
684 bytes_read = bytes_read + bytes_offset as i32;
685 if bytes_read == total_bytes {
686 }
688
689
690 let new_line_char_found = buffer.len() != 0;
691
692
693 let boxed_line = Range::convert_bytes_array_to_string(buffer);
694 if boxed_line.is_err() {
695 let message = boxed_line.err().unwrap();
696 return Err(message);
697 }
698 let mut string = boxed_line.unwrap();
699
700 if !new_line_char_found {
701 return Ok(content_range_list)
702 };
703
704 let mut content_range: ContentRange = ContentRange::new();
705
706 let content_range_is_not_parsed = content_range.body.len() == 0;
707
708 if string.trim().len() != 0 && !is_opening_boundary_read && !string.contains(boundary.as_str()) {
709 return Err("Response body doesn't start with a boundary".to_string())
710 }
711
712 if string.contains(boundary.as_str()) && content_range_is_not_parsed {
713 if !is_opening_boundary_read {
714 is_opening_boundary_read = true;
715 }
716 let boxed_line = Range::parse_line_as_bytes(cursor);
718 if boxed_line.is_err() {
719 let message = boxed_line.err().unwrap();
720 return Err(message);
721 }
722 buffer = boxed_line.unwrap();
723
724 let boxed_line = Range::convert_bytes_array_to_string(buffer);
725 if boxed_line.is_err() {
726 let message = boxed_line.err().unwrap();
727 return Err(message);
728 }
729 string = boxed_line.unwrap();
730 }
731
732 let content_type_is_not_parsed = content_range.content_type.len() == 0;
733 if string.starts_with(Header::_CONTENT_TYPE) && content_type_is_not_parsed {
734 let boxed_content_type = Response::parse_http_response_header_string(string.as_str());
735 if boxed_content_type.is_err() {
736 let message = boxed_content_type.err().unwrap();
737 return Err(message);
738 }
739 let content_type = boxed_content_type.unwrap();
740
741 content_range.content_type = content_type.value.trim().to_string();
742
743 let boxed_line = Range::parse_line_as_bytes(cursor);
745 if boxed_line.is_err() {
746 let message = boxed_line.err().unwrap();
747 return Err(message);
748 }
749 buffer = boxed_line.unwrap();
750
751 let boxed_line = Range::convert_bytes_array_to_string(buffer);
752 if boxed_line.is_err() {
753 let message = boxed_line.err().unwrap();
754 return Err(message);
755 }
756 string = boxed_line.unwrap();
757 }
758
759 let content_range_is_not_parsed = content_range.size.len() == 0;
760 if string.starts_with(Header::_CONTENT_RANGE) && content_range_is_not_parsed {
761 let content_range_header = Response::_parse_http_response_header_string(string.as_str());
762
763 let boxed_result = Range::_parse_content_range_header_value(content_range_header.value);
764 if boxed_result.is_ok() {
765 let (start, end, size) = boxed_result.unwrap();
766
767 content_range.size = size.to_string();
768 content_range.range.start = start as u64;
769 content_range.range.end = end as u64;
770 } else {
771 return Err(boxed_result.err().unwrap())
772 }
773
774
775
776 let boxed_line = Range::parse_line_as_bytes(cursor);
778 if boxed_line.is_err() {
779 let message = boxed_line.err().unwrap();
780 return Err(message);
781 }
782 buffer = boxed_line.unwrap();
783
784 let boxed_line = Range::convert_bytes_array_to_string(buffer);
785 if boxed_line.is_err() {
786 let message = boxed_line.err().unwrap();
787 return Err(message);
788 }
789 string = boxed_line.unwrap();
790
791 if string.trim().len() > 0 {
792 return Err(Range::_ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY.to_string());
793 }
794
795 }
796
797 let content_range_is_parsed = content_range.size.len() != 0;
798 let content_type_is_parsed = content_range.content_type.len() != 0;
799 if content_range_is_parsed && content_type_is_parsed {
800 let mut body : Vec<u8> = vec![];
801
802 let mut is_not_boundary = true;
803
804 while is_not_boundary {
805 let mut _bytes_offset = 0;
806 let mut buf: Vec<u8> = vec![];
807 let boxed_read = cursor.read_until(b'\n', &mut buf);
808 if boxed_read.is_err() {
809 return Err("Unable to read from stream".to_string());
810 }
811 _bytes_offset = boxed_read.unwrap();
812 bytes_read = bytes_read + _bytes_offset as i32;
813
814
815 let boxed_line = Range::convert_bytes_array_to_string(buf.clone());
816 if boxed_line.is_err() {
817 body = [body, buf.to_vec()].concat();
819 continue;
820 }
821
822 string = boxed_line.unwrap();
823
824 is_not_boundary = !string.contains(boundary.as_str());
825
826 if is_not_boundary {
827 body = [body, buf.to_vec()].concat();
828 if (bytes_read == total_bytes) || _bytes_offset == 0 {
829 return Err("Unable to parse multipart form body, reached the end of stream and it does not contain boundary".to_string());
830 }
831 }
832
833 }
834
835 let mut mutable_body : Vec<u8> = body;
836 mutable_body.pop(); mutable_body.pop(); content_range.body = mutable_body;
841
842 content_range_list.push(content_range);
843 }
844
845 }
846 }
847
848 pub fn parse_line_as_bytes(cursor: &mut Cursor<&[u8]>) -> Result<Vec<u8>, String> {
849 let mut buffer = vec![];
850 let boxed_read = cursor.read_until(b'\n', &mut buffer);
851 if boxed_read.is_err() {
852 let message = boxed_read.err().unwrap().to_string();
853 return Err(message);
854 }
855 boxed_read.unwrap();
856 Ok(buffer)
857 }
858
859 pub fn convert_bytes_array_to_string(buffer: Vec<u8>) -> Result<String, String> {
860 let buffer_as_u8_array: &[u8] = &buffer;
861 let boxed_string = String::from_utf8(Vec::from(buffer_as_u8_array));
862 if boxed_string.is_err() {
863 let message = boxed_string.err().unwrap().to_string();
864 return Err(message);
865 }
866 let string = boxed_string.unwrap();
867 Ok(string)
868 }
869}
870
871