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_array = ["http://", "localhost", &request_uri.replace(&FileExt::get_path_separator(), SYMBOL.slash)];
190 let url = url_array.join(SYMBOL.empty_string);
191
192 let boxed_url_components = URL::parse(&url);
193 if boxed_url_components.is_err() {
194 let message = boxed_url_components.as_ref().err().unwrap().to_string();
195 println!("unexpected error, {}", message);
197 }
198
199 let components = boxed_url_components.unwrap();
200
201 let file_path_part = components.path.replace(SYMBOL.slash, &FileExt::get_path_separator());
202
203 let boxed_static_filepath = FileExt::get_static_filepath(&file_path_part);
204 if boxed_static_filepath.is_err() {
205 let error = Error {
206 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
207 message: boxed_static_filepath.err().unwrap()
208 };
209 eprintln!("{}", &error.message);
210 return Err(error);
211 }
212 let static_filepath = boxed_static_filepath.unwrap();
213
214 let boxed_metadata = metadata(&static_filepath);
215 if boxed_metadata.is_err() {
216 let error = Error {
217 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
218 message: boxed_metadata.err().unwrap().to_string()
219 };
220 eprintln!("{}", &error.message);
221 return Err(error);
222 }
223
224 let md = boxed_metadata.unwrap();
225 if md.is_file() {
226 let mut path = static_filepath.as_str().to_string();
227
228 let boxed_is_link = FileExt::is_symlink(&static_filepath);
229 if boxed_is_link.is_err() {
230 let error = Error {
231 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
232 message: boxed_is_link.err().unwrap()
233 };
234 eprintln!("{}", &error.message);
235 return Err(error);
236 }
237
238
239 let is_link = boxed_is_link.unwrap();
240 if is_link {
241 let boxed_points_to = FileExt::symlink_points_to(&static_filepath);
242 if boxed_points_to.is_err() {
243 let error = Error {
244 status_code_reason_phrase: STATUS_CODE_REASON_PHRASE.n500_internal_server_error,
245 message: boxed_points_to.err().unwrap()
246 };
247 eprintln!("{}", &error.message);
248 return Err(error);
249 }
250
251 let points_to = boxed_points_to.unwrap();
252 let reversed_link = &static_filepath.chars().rev().collect::<String>();
253
254 let mut symlink_directory = SYMBOL.empty_string.to_string();
255 let boxed_split = reversed_link.split_once(&FileExt::get_path_separator());
256 if boxed_split.is_some() {
257 let (_filename, path) = boxed_split.unwrap();
258 symlink_directory = path.chars().rev().collect::<String>();
259 }
260
261 let resolved_link = FileExt::resolve_symlink_path(&symlink_directory, &points_to).unwrap();
262 path = resolved_link;
263 }
264
265 let boxed_content_range_list = Range::parse_content_range(&path, md.len(), &range.value);
266 if boxed_content_range_list.is_ok() {
267 content_range_list = boxed_content_range_list.unwrap();
268 } else {
269 let error = boxed_content_range_list.err().unwrap();
270 return Err(error)
271 }
272 }
273
274 Ok(content_range_list)
275 }
276
277 pub fn _parse_multipart_body(cursor: &mut Cursor<&[u8]>, mut content_range_list: Vec<ContentRange>) -> Result<Vec<ContentRange>, String> {
278
279 let mut buffer = Range::_parse_line_as_bytes(cursor);
280 let new_line_char_found = buffer.len() != 0;
281 let mut string = Range::_convert_bytes_array_to_string(buffer);
282
283 if !new_line_char_found {
284 return Ok(content_range_list)
285 };
286
287 let mut content_range: ContentRange = ContentRange {
288 unit: Range::BYTES.to_string(),
289 range: Range { start: 0, end: 0 },
290 size: "".to_string(),
291 body: vec![],
292 content_type: "".to_string()
293 };
294
295 let content_range_is_not_parsed = content_range.body.len() == 0;
296 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
297 if string.starts_with(separator.as_str()) && content_range_is_not_parsed {
298 buffer = Range::_parse_line_as_bytes(cursor);
300 string = Range::_convert_bytes_array_to_string(buffer);
301 }
302
303 let content_type_is_not_parsed = content_range.content_type.len() == 0;
304 if string.starts_with(Header::_CONTENT_TYPE) && content_type_is_not_parsed {
305 let content_type = Response::_parse_http_response_header_string(string.as_str());
306 content_range.content_type = content_type.value.trim().to_string();
307
308 buffer = Range::_parse_line_as_bytes(cursor);
310 string = Range::_convert_bytes_array_to_string(buffer);
311 }
312
313 let content_range_is_not_parsed = content_range.size.len() == 0;
314 if string.starts_with(Header::_CONTENT_RANGE) && content_range_is_not_parsed {
315 let content_range_header = Response::_parse_http_response_header_string(string.as_str());
316
317 let boxed_result = Range::_parse_content_range_header_value(content_range_header.value);
318 if boxed_result.is_ok() {
319 let (start, end, size) = boxed_result.unwrap();
320
321 content_range.size = size.to_string();
322 content_range.range.start = start as u64;
323 content_range.range.end = end as u64;
324 } else {
325 return Err(boxed_result.err().unwrap())
326 }
327
328
329
330 buffer = Range::_parse_line_as_bytes(cursor);
332 string = Range::_convert_bytes_array_to_string(buffer);
333
334 if string.trim().len() > 0 {
335 return Err(Range::_ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY.to_string());
336 }
337
338 buffer = Range::_parse_line_as_bytes(cursor);
340 string = Range::_convert_bytes_array_to_string(buffer);
341 }
342
343 let content_range_is_parsed = content_range.size.len() != 0;
344 let content_type_is_parsed = content_range.content_type.len() != 0;
345 if content_range_is_parsed && content_type_is_parsed {
346 let mut body : Vec<u8> = vec![];
347 body = [body, string.as_bytes().to_vec()].concat();
348
349 let mut buf = Vec::from(string.as_bytes());
350 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
351 while !buf.starts_with(separator.as_bytes()) {
352 buf = vec![];
353 cursor.read_until(b'\n', &mut buf).unwrap();
354 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
355 if !buf.starts_with(separator.as_bytes()) {
356 body = [body, buf.to_vec()].concat();
357 }
358 }
359
360 let mut mutable_body : Vec<u8> = body;
361 mutable_body.pop(); mutable_body.pop(); content_range.body = mutable_body;
366
367 content_range_list.push(content_range);
368 }
369
370 let boxed_result = Range::_parse_multipart_body(cursor, content_range_list);
371 return if boxed_result.is_ok() {
372 Ok(boxed_result.unwrap())
373 } else {
374 let error = boxed_result.err().unwrap();
375 Err(error)
376 }
377
378 }
379
380 pub fn _parse_raw_content_range_header_value(unparsed_header_value: &str)-> Result<(i64, i64, i64), String> {
381 let lowercase_unparsed_header_value = unparsed_header_value.trim().to_lowercase();
382
383 let start : i64;
384 let end : i64;
385 let size : i64;
386
387
388 let boxed_split_without_bytes = lowercase_unparsed_header_value.split_once(SYMBOL.whitespace);
389 if boxed_split_without_bytes.is_none() {
390 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
391 }
392
393 let (bytes, without_bytes) = boxed_split_without_bytes.unwrap();
394 if !bytes.eq("bytes") {
395 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
396 }
397
398 let boxed_without_bytes = without_bytes.split_once(SYMBOL.hyphen);
399 if boxed_without_bytes.is_none() {
400 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
401 }
402
403 let (_start, _without_start) = boxed_without_bytes.unwrap();
404
405 let boxed_start = _start.parse::<i64>();
406 if boxed_start.is_err() {
407 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
408 }
409
410 start = boxed_start.unwrap();
411
412
413
414 let boxed_without_start = _without_start.split_once(SYMBOL.slash);
415 if boxed_without_start.is_none() {
416 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
417 }
418 let (_end, _size) = boxed_without_start.unwrap();
419
420 let boxed_end = _end.parse::<i64>();
421 if boxed_end.is_err() {
422 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
423 }
424
425 end = boxed_end.unwrap();
426
427 let boxed_size = _size.parse::<i64>();
428 if boxed_size.is_err() {
429 return Err(Range::_ERROR_UNABLE_TO_PARSE_CONTENT_RANGE.to_string())
430 }
431
432 size = boxed_size.unwrap();
433
434 Ok((start, end, size))
435 }
436
437 pub fn _parse_content_range_header_value(header_value: String) -> Result<(i64, i64, i64), String> {
438 let boxed_parse_result = Range::_parse_raw_content_range_header_value(&header_value);
439 if boxed_parse_result.is_err() {
440 return Err(boxed_parse_result.err().unwrap())
441 }
442 let (start, end, size) = boxed_parse_result.unwrap();
443
444 if start > end {
445 return Err(Range::ERROR_START_IS_AFTER_END_CONTENT_RANGE.to_string())
446 }
447
448 if start > size {
449 return Err(Range::ERROR_START_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE.to_string());
450 }
451 if end > size {
452 return Err(Range::ERROR_END_IS_BIGGER_THAN_FILESIZE_CONTENT_RANGE.to_string());
453 }
454
455 Ok((start, end, size))
456 }
457
458 pub fn _parse_line_as_bytes(cursor: &mut Cursor<&[u8]>) -> Vec<u8> {
459 let mut buffer = vec![];
460 cursor.read_until(b'\n', &mut buffer).unwrap();
461 buffer
462 }
463
464 pub fn _convert_bytes_array_to_string(buffer: Vec<u8>) -> String {
465 let buffer_as_u8_array: &[u8] = &buffer;
466 String::from_utf8(Vec::from(buffer_as_u8_array)).unwrap()
467 }
468
469 pub fn get_content_range(body: Vec<u8>, mime_type: String) -> ContentRange {
471 let length = body.len() as u64;
472 let content_range = ContentRange {
473 unit: Range::BYTES.to_string(),
474 range: Range { start: 0, end: length },
475 size: length.to_string(),
476 body,
477 content_type: mime_type
478 };
479
480 content_range
481 }
482
483 pub fn get_content_range_of_a_file(filepath: &str) -> Result<ContentRange, String> {
485 let body: Vec<u8>;
486 let boxed_file = FileExt::read_file(filepath);
487 if boxed_file.is_err() {
488 let error = boxed_file.err().unwrap();
489 return Err(error);
490 }
491
492 body = boxed_file.unwrap();
493 let mime_type = MimeType::detect_mime_type(filepath);
494 let content_range = Range::get_content_range(body, mime_type);
495 Ok(content_range)
496 }
497
498
499 pub fn parse_multipart_body(cursor: &mut Cursor<&[u8]>,
500 mut content_range_list: Vec<ContentRange>)
501 -> Result<Vec<ContentRange>, String> {
502
503 let boxed_line = Range::parse_line_as_bytes(cursor);
504 if boxed_line.is_err() {
505 let message = boxed_line.err().unwrap();
506 return Err(message);
507 }
508 let mut buffer = boxed_line.unwrap();
509
510
511 let new_line_char_found = buffer.len() != 0;
512
513
514 let boxed_line = Range::convert_bytes_array_to_string(buffer);
515 if boxed_line.is_err() {
516 let message = boxed_line.err().unwrap();
517 return Err(message);
518 }
519 let mut string = boxed_line.unwrap();
520
521 if !new_line_char_found {
522 return Ok(content_range_list)
523 };
524
525 let mut content_range: ContentRange = ContentRange {
526 unit: Range::BYTES.to_string(),
527 range: Range { start: 0, end: 0 },
528 size: "".to_string(),
529 body: vec![],
530 content_type: "".to_string()
531 };
532
533 let content_range_is_not_parsed = content_range.body.len() == 0;
534 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
535 if string.starts_with(separator.as_str()) && content_range_is_not_parsed {
536 let boxed_line = Range::parse_line_as_bytes(cursor);
538 if boxed_line.is_err() {
539 let message = boxed_line.err().unwrap();
540 return Err(message);
541 }
542 buffer = boxed_line.unwrap();
543
544 let boxed_line = Range::convert_bytes_array_to_string(buffer);
545 if boxed_line.is_err() {
546 let message = boxed_line.err().unwrap();
547 return Err(message);
548 }
549 string = boxed_line.unwrap();
550 }
551
552 let content_type_is_not_parsed = content_range.content_type.len() == 0;
553 if string.starts_with(Header::_CONTENT_TYPE) && content_type_is_not_parsed {
554 let boxed_content_type = Response::parse_http_response_header_string(string.as_str());
555 if boxed_content_type.is_err() {
556 let message = boxed_content_type.err().unwrap();
557 return Err(message);
558 }
559 let content_type = boxed_content_type.unwrap();
560
561 content_range.content_type = content_type.value.trim().to_string();
562
563 let boxed_line = Range::parse_line_as_bytes(cursor);
565 if boxed_line.is_err() {
566 let message = boxed_line.err().unwrap();
567 return Err(message);
568 }
569 buffer = boxed_line.unwrap();
570
571 let boxed_line = Range::convert_bytes_array_to_string(buffer);
572 if boxed_line.is_err() {
573 let message = boxed_line.err().unwrap();
574 return Err(message);
575 }
576 string = boxed_line.unwrap();
577 }
578
579 let content_range_is_not_parsed = content_range.size.len() == 0;
580 if string.starts_with(Header::_CONTENT_RANGE) && content_range_is_not_parsed {
581 let content_range_header = Response::_parse_http_response_header_string(string.as_str());
582
583 let boxed_result = Range::_parse_content_range_header_value(content_range_header.value);
584 if boxed_result.is_ok() {
585 let (start, end, size) = boxed_result.unwrap();
586
587 content_range.size = size.to_string();
588 content_range.range.start = start as u64;
589 content_range.range.end = end as u64;
590 } else {
591 return Err(boxed_result.err().unwrap())
592 }
593
594
595
596 let boxed_line = Range::parse_line_as_bytes(cursor);
598 if boxed_line.is_err() {
599 let message = boxed_line.err().unwrap();
600 return Err(message);
601 }
602 buffer = boxed_line.unwrap();
603
604 let boxed_line = Range::convert_bytes_array_to_string(buffer);
605 if boxed_line.is_err() {
606 let message = boxed_line.err().unwrap();
607 return Err(message);
608 }
609 string = boxed_line.unwrap();
610
611 if string.trim().len() > 0 {
612 return Err(Range::_ERROR_NO_EMPTY_LINE_BETWEEN_CONTENT_RANGE_HEADER_AND_BODY.to_string());
613 }
614
615 let boxed_line = Range::parse_line_as_bytes(cursor);
617 if boxed_line.is_err() {
618 let message = boxed_line.err().unwrap();
619 return Err(message);
620 }
621 buffer = boxed_line.unwrap();
622
623 let boxed_line = Range::convert_bytes_array_to_string(buffer);
624 if boxed_line.is_err() {
625 let message = boxed_line.err().unwrap();
626 return Err(message);
627 }
628 string = boxed_line.unwrap();
629 }
630
631 let content_range_is_parsed = content_range.size.len() != 0;
632 let content_type_is_parsed = content_range.content_type.len() != 0;
633 if content_range_is_parsed && content_type_is_parsed {
634 let mut body : Vec<u8> = vec![];
635 body = [body, string.as_bytes().to_vec()].concat();
636
637 let mut buf = Vec::from(string.as_bytes());
638 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
639 while !buf.starts_with(separator.as_bytes()) {
640 buf = vec![];
641 cursor.read_until(b'\n', &mut buf).unwrap();
642 let separator = [SYMBOL.hyphen, SYMBOL.hyphen, Range::STRING_SEPARATOR].join("");
643 if !buf.starts_with(separator.as_bytes()) {
644 body = [body, buf.to_vec()].concat();
645 }
646 }
647
648 let mut mutable_body : Vec<u8> = body;
649 mutable_body.pop(); mutable_body.pop(); content_range.body = mutable_body;
654
655 content_range_list.push(content_range);
656 }
657
658 let boxed_result = Range::_parse_multipart_body(cursor, content_range_list);
659 return if boxed_result.is_ok() {
660 Ok(boxed_result.unwrap())
661 } else {
662 let error = boxed_result.err().unwrap();
663 Err(error)
664 }
665
666 }
667
668 pub fn parse_multipart_body_with_boundary(cursor: &mut Cursor<&[u8]>,
669 mut content_range_list: Vec<ContentRange>,
670 boundary: String,
671 total_bytes: i32,
672 mut bytes_read: i32,
673 mut is_opening_boundary_read: bool)
674 -> Result<Vec<ContentRange>, String> {
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 let boxed_result = Range::parse_multipart_body_with_boundary(
846 cursor,
847 content_range_list,
848 boundary,
849 total_bytes,
850 bytes_read,
851 is_opening_boundary_read);
852 return if boxed_result.is_ok() {
853 Ok(boxed_result.unwrap())
854 } else {
855 let error = boxed_result.err().unwrap();
856 Err(error)
857 }
858
859 }
860
861 pub fn parse_line_as_bytes(cursor: &mut Cursor<&[u8]>) -> Result<Vec<u8>, String> {
862 let mut buffer = vec![];
863 let boxed_read = cursor.read_until(b'\n', &mut buffer);
864 if boxed_read.is_err() {
865 let message = boxed_read.err().unwrap().to_string();
866 return Err(message);
867 }
868 boxed_read.unwrap();
869 Ok(buffer)
870 }
871
872 pub fn convert_bytes_array_to_string(buffer: Vec<u8>) -> Result<String, String> {
873 let buffer_as_u8_array: &[u8] = &buffer;
874 let boxed_string = String::from_utf8(Vec::from(buffer_as_u8_array));
875 if boxed_string.is_err() {
876 let message = boxed_string.err().unwrap().to_string();
877 return Err(message);
878 }
879 let string = boxed_string.unwrap();
880 Ok(string)
881 }
882}
883
884