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