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