1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use core::mem::take; 15 16 use crate::body::mime::common::{ 17 get_content_type_boundary, get_crlf_contain, trim_back_lwsp_if_end_with_lf, XPart, 18 }; 19 use crate::body::mime::decode::BoundaryTag; 20 use crate::body::mime::{DecodeHeaders, MimeMulti, MimePartDecoder}; 21 use crate::body::TokenStatus; 22 use crate::error::{ErrorKind, HttpError}; 23 use crate::headers::Headers; 24 25 type ByteVec<'a> = Result<TokenStatus<(Vec<u8>, &'a [u8]), &'a [u8]>, HttpError>; 26 27 // TODO: Increases compatibility for preamble and epilogue. 28 29 /// `MimeMultiDecoder` can create a [`MimeMulti`] according to a serialized 30 /// data. 31 /// 32 /// [`MimeMulti`]: MimeMulti 33 /// 34 /// # Examples 35 /// 36 /// ``` 37 /// use ylong_http::body::{MimeMulti, MimeMultiDecoder, MimePart, TokenStatus}; 38 /// 39 /// let buf = b"--abc\r\nkey1:value1\r\n\r\n1111\r\n--abc--\r\nabcd"; 40 /// let mut decoder = MimeMultiDecoder::new(); 41 /// let (elem, rest) = decoder.decode(buf).unwrap(); 42 /// assert!(elem.is_complete()); 43 /// let multi1 = MimeMulti::builder() 44 /// .set_boundary(b"abc".to_vec()) 45 /// .add_part( 46 /// MimePart::builder() 47 /// .header("key1", "value1") 48 /// .body_from_owned(b"1111".to_vec()) 49 /// .build() 50 /// .unwrap(), 51 /// ) 52 /// .build() 53 /// .unwrap(); 54 /// if let TokenStatus::Complete(multi) = elem { 55 /// assert_eq!(multi.boundary(), multi1.boundary()); 56 /// assert_eq!(multi.headers(), multi1.headers()); 57 /// assert_eq!(multi, multi1); 58 /// } 59 /// assert_eq!(rest, b"abcd"); 60 /// ``` 61 #[derive(Debug, Default, PartialEq)] 62 pub struct MimeMultiDecoder { 63 // stack of stage 64 stages: Vec<MultiStage>, 65 // stack of multi 66 multis: Vec<MimeMulti<'static>>, 67 } 68 69 impl MimeMultiDecoder { 70 /// Creates a new `MimeMultiDecoder`. 71 /// 72 /// # Examples 73 /// 74 /// ``` 75 /// use ylong_http::body::MimeMultiDecoder; 76 /// 77 /// let mut decoder = MimeMultiDecoder::new(); 78 /// ``` new() -> Self79 pub fn new() -> Self { 80 let mut decoder = MimeMultiDecoder { 81 stages: vec![], 82 multis: vec![], 83 }; 84 let multi = MimeMulti::new(); 85 decoder.multis.push(multi); 86 let data = DecodeData::new(); 87 decoder.stages.push(MultiStage::Multi(data)); 88 decoder 89 } 90 91 /// Inputs datas, gets a [`MimeMulti`]. 92 /// 93 /// [`MimeMulti`]: MimeMulti 94 /// 95 /// # Examples 96 /// 97 /// ``` 98 /// use ylong_http::body::{MimeMulti, MimeMultiDecoder, MimePart, TokenStatus}; 99 /// 100 /// let buf = b"--abc\r\n\r\n--abc--\r\nabcd"; 101 /// let mut decoder = MimeMultiDecoder::new(); 102 /// let (elem, rest) = decoder.decode(buf).unwrap(); 103 /// assert!(elem.is_complete()); 104 /// let multi1 = MimeMulti::builder() 105 /// .set_boundary(b"abc".to_vec()) 106 /// .add_part(MimePart::builder().build().unwrap()) 107 /// .build() 108 /// .unwrap(); 109 /// if let TokenStatus::Complete(multi) = elem { 110 /// assert_eq!(multi.boundary(), multi1.boundary()); 111 /// assert_eq!(multi, multi1); 112 /// } 113 /// assert_eq!(rest, b"abcd"); 114 /// ``` decode<'a>( &mut self, buf: &'a [u8], ) -> Result<(TokenStatus<MimeMulti, ()>, &'a [u8]), HttpError>115 pub fn decode<'a>( 116 &mut self, 117 buf: &'a [u8], 118 ) -> Result<(TokenStatus<MimeMulti, ()>, &'a [u8]), HttpError> { 119 if buf.is_empty() { 120 return Err(ErrorKind::InvalidInput.into()); 121 } 122 123 let mut results = TokenStatus::Partial(()); 124 let mut remains = buf; 125 126 while let Some(stage) = self.stages.pop() { 127 let rest = match stage { 128 MultiStage::Unknown(headers_decoder) => { 129 self.unknown_decode(headers_decoder, remains) 130 } 131 MultiStage::Part(part_decoder) => self.part_decode(part_decoder, remains), 132 MultiStage::Multi(data) => self.multi_decode(data, remains), 133 MultiStage::End => { 134 results = match self.multis.pop() { 135 Some(multi) => TokenStatus::Complete(multi), 136 None => return Err(ErrorKind::InvalidInput.into()), 137 }; 138 break; 139 } 140 }?; 141 remains = rest; 142 // at least has the outermost multi stage, unless is replaced by 143 // MultiStage::End, so the last stage can uncheck. 144 if remains.is_empty() && !self.last_stage()?.is_end() { 145 break; 146 } 147 } 148 149 Ok((results, remains)) 150 } 151 unknown_decode<'a>( &mut self, mut headers_decoder: DecodeHeaders, buf: &'a [u8], ) -> Result<&'a [u8], HttpError>152 fn unknown_decode<'a>( 153 &mut self, 154 mut headers_decoder: DecodeHeaders, 155 buf: &'a [u8], 156 ) -> Result<&'a [u8], HttpError> { 157 let (elem, rest) = headers_decoder.decode(buf)?; 158 match elem { 159 TokenStatus::Partial(_) => self.stages.push(MultiStage::Unknown(headers_decoder)), 160 TokenStatus::Complete(headers) => { 161 match get_content_type_boundary(&headers) { 162 // is multi 163 Some(boundary) => self.push_new_multi_stage(headers, boundary), 164 // is part 165 None => self.push_new_part_stage(headers)?, 166 } 167 } 168 } 169 Ok(rest) 170 } 171 push_new_unknown_stage(&mut self)172 fn push_new_unknown_stage(&mut self) { 173 let headers_decoder = DecodeHeaders::new(); 174 self.stages.push(MultiStage::Unknown(headers_decoder)); 175 } 176 push_new_multi_stage(&mut self, headers: Headers, boundary: Vec<u8>)177 fn push_new_multi_stage(&mut self, headers: Headers, boundary: Vec<u8>) { 178 // push a new Multi stage 179 let data = DecodeData::new_as_part(boundary.clone()); 180 self.stages.push(MultiStage::Multi(data)); 181 182 // push a new multi struct 183 let mut multi = MimeMulti::new(); 184 multi.set_headers(headers); 185 multi.set_boundary(boundary); 186 self.multis.push(multi); 187 } 188 push_new_part_stage(&mut self, headers: Headers) -> Result<(), HttpError>189 fn push_new_part_stage(&mut self, headers: Headers) -> Result<(), HttpError> { 190 let mut decoder = MimePartDecoder::new(); 191 // at least has the outermost multi, so the last multi can uncheck. 192 decoder.init_from_multi(headers, self.last_multi()?.boundary.clone()); 193 self.stages.push(MultiStage::Part(decoder)); 194 Ok(()) 195 } 196 part_decode<'a>( &mut self, mut part_decoder: MimePartDecoder, buf: &'a [u8], ) -> Result<&'a [u8], HttpError>197 fn part_decode<'a>( 198 &mut self, 199 mut part_decoder: MimePartDecoder, 200 buf: &'a [u8], 201 ) -> Result<&'a [u8], HttpError> { 202 let (elem, rest) = part_decoder.decode(buf)?; 203 match elem { 204 TokenStatus::Partial(_) => { 205 // push self 206 self.stages.push(MultiStage::Part(part_decoder)); 207 } 208 TokenStatus::Complete(part) => { 209 // at least has the outermost multi, so the last multi can uncheck. 210 self.last_multi_mut()?.add_part(part); 211 // now temp multi is end 212 if part_decoder.is_last_part() { 213 self.temp_multi_end(true)?; 214 } else { 215 self.push_new_unknown_stage(); 216 } 217 } 218 } 219 Ok(rest) 220 } 221 multi_decode<'a>(&mut self, data: DecodeData, buf: &'a [u8]) -> Result<&'a [u8], HttpError>222 fn multi_decode<'a>(&mut self, data: DecodeData, buf: &'a [u8]) -> Result<&'a [u8], HttpError> { 223 match data.is_finish_first_boundary { 224 true => self.middle_or_end_boundary_decode(data, buf), 225 false => self.first_boundary_decode(data, buf), 226 } 227 } 228 229 /// find middle or end boundary for inner and outer multi middle_or_end_boundary_decode<'a>( &mut self, mut data: DecodeData, buf: &'a [u8], ) -> Result<&'a [u8], HttpError>230 fn middle_or_end_boundary_decode<'a>( 231 &mut self, 232 mut data: DecodeData, 233 buf: &'a [u8], 234 ) -> Result<&'a [u8], HttpError> { 235 match data.middle_or_end_boundary(buf) { 236 TokenStatus::Partial(rest) => { 237 self.stages.push(MultiStage::Multi(data)); 238 Ok(rest) 239 } 240 TokenStatus::Complete(rest) => match data.tag { 241 BoundaryTag::Middle => { 242 self.stages.push(MultiStage::Multi(data)); 243 self.push_new_unknown_stage(); 244 Ok(rest) 245 } 246 BoundaryTag::End => { 247 self.temp_multi_end(false)?; 248 Ok(rest) 249 } 250 // ensure not in this arm 251 _ => Ok(rest), 252 }, 253 } 254 } 255 first_boundary_decode<'a>( &mut self, data: DecodeData, buf: &'a [u8], ) -> Result<&'a [u8], HttpError>256 fn first_boundary_decode<'a>( 257 &mut self, 258 data: DecodeData, 259 buf: &'a [u8], 260 ) -> Result<&'a [u8], HttpError> { 261 match data.is_outermost { 262 true => self.outermost_first_boundary_decode(data, buf), 263 false => self.inner_first_boundary_decode(data, buf), 264 } 265 } 266 267 /// for outermost multi outermost_first_boundary_decode<'a>( &mut self, mut data: DecodeData, buf: &'a [u8], ) -> Result<&'a [u8], HttpError>268 fn outermost_first_boundary_decode<'a>( 269 &mut self, 270 mut data: DecodeData, 271 buf: &'a [u8], 272 ) -> Result<&'a [u8], HttpError> { 273 match data.outermost_first_boundary(buf)? { 274 TokenStatus::Partial(rest) => { 275 // push self 276 self.stages.push(MultiStage::Multi(data)); 277 Ok(rest) 278 } 279 TokenStatus::Complete((boundary, rest)) => { 280 match self.multis.first_mut() { 281 Some(multi) => { 282 multi.set_boundary(boundary); 283 // push self 284 self.stages.push(MultiStage::Multi(data)); 285 self.push_new_unknown_stage(); 286 Ok(rest) 287 } 288 None => Err(ErrorKind::InvalidInput.into()), 289 } 290 } 291 } 292 } 293 294 /// for inner multi inner_first_boundary_decode<'a>( &mut self, mut data: DecodeData, buf: &'a [u8], ) -> Result<&'a [u8], HttpError>295 fn inner_first_boundary_decode<'a>( 296 &mut self, 297 mut data: DecodeData, 298 buf: &'a [u8], 299 ) -> Result<&'a [u8], HttpError> { 300 let rest = match data.inner_first_boundary(buf)? { 301 TokenStatus::Partial(rest) => rest, 302 TokenStatus::Complete(rest) => rest, 303 }; 304 // push self 305 self.stages.push(MultiStage::Multi(data)); 306 self.push_new_unknown_stage(); 307 Ok(rest) 308 } 309 310 // when the last multi is end. temp_multi_end(&mut self, by_part: bool) -> Result<(), HttpError>311 fn temp_multi_end(&mut self, by_part: bool) -> Result<(), HttpError> { 312 if self.multis.len() == 1 { 313 self.stages = vec![MultiStage::End]; 314 return Ok(()); 315 } 316 317 if by_part { 318 // pop the nearly Multi stage 319 self.stages_pop()?; 320 } 321 let multi = self.multis_pop()?; 322 // at least has the outermost multi, so the last multi can uncheck. 323 self.last_multi_mut()?.add_multi(multi); 324 Ok(()) 325 } 326 multis_pop(&mut self) -> Result<MimeMulti<'static>, HttpError>327 fn multis_pop(&mut self) -> Result<MimeMulti<'static>, HttpError> { 328 match self.multis.pop() { 329 Some(multi) => Ok(multi), 330 None => Err(ErrorKind::InvalidInput.into()), 331 } 332 } 333 stages_pop(&mut self) -> Result<MultiStage, HttpError>334 fn stages_pop(&mut self) -> Result<MultiStage, HttpError> { 335 match self.stages.pop() { 336 Some(stage) => Ok(stage), 337 None => Err(ErrorKind::InvalidInput.into()), 338 } 339 } 340 last_multi(&self) -> Result<&MimeMulti<'static>, HttpError>341 fn last_multi(&self) -> Result<&MimeMulti<'static>, HttpError> { 342 match self.multis.last() { 343 Some(multi) => Ok(multi), 344 None => Err(ErrorKind::InvalidInput.into()), 345 } 346 } 347 last_multi_mut(&mut self) -> Result<&mut MimeMulti<'static>, HttpError>348 fn last_multi_mut(&mut self) -> Result<&mut MimeMulti<'static>, HttpError> { 349 match self.multis.last_mut() { 350 Some(multi) => Ok(multi), 351 None => Err(ErrorKind::InvalidInput.into()), 352 } 353 } 354 last_stage(&self) -> Result<&MultiStage, HttpError>355 fn last_stage(&self) -> Result<&MultiStage, HttpError> { 356 match self.stages.last() { 357 Some(stage) => Ok(stage), 358 None => Err(ErrorKind::InvalidInput.into()), 359 } 360 } 361 } 362 363 #[derive(Debug, PartialEq)] 364 enum MultiStage { 365 Unknown(DecodeHeaders), 366 Part(MimePartDecoder), 367 Multi(DecodeData), 368 End, 369 } 370 371 impl MultiStage { is_end(&self) -> bool372 fn is_end(&self) -> bool { 373 matches!(self, MultiStage::End) 374 } 375 } 376 377 #[derive(Debug, PartialEq)] 378 struct DecodeData { 379 // whether read first boundary completely 380 is_finish_first_boundary: bool, 381 // whether is outermost multi 382 is_outermost: bool, 383 boundary: Vec<u8>, 384 // 1 is middle part; 2 is end part 385 tag: BoundaryTag, 386 // src which is need to encode 387 src: Vec<u8>, 388 src_idx: usize, 389 } 390 391 impl DecodeData { 392 /// is outermost multi new() -> Self393 fn new() -> Self { 394 Self { 395 is_finish_first_boundary: false, 396 is_outermost: true, 397 boundary: vec![], 398 tag: BoundaryTag::Init, 399 src: vec![], 400 src_idx: 0, 401 } 402 } 403 404 /// is a part of multi new_as_part(boundary: Vec<u8>) -> Self405 fn new_as_part(boundary: Vec<u8>) -> Self { 406 Self { 407 is_finish_first_boundary: false, 408 is_outermost: false, 409 boundary, 410 tag: BoundaryTag::Init, 411 src: vec![], 412 src_idx: 0, 413 } 414 } 415 set_boundary(&mut self, boundary: Vec<u8>)416 fn set_boundary(&mut self, boundary: Vec<u8>) { 417 self.boundary = boundary; 418 } 419 420 /// finds the first boundary of the outermost multi outermost_first_boundary<'a>(&mut self, buf: &'a [u8]) -> ByteVec<'a>421 fn outermost_first_boundary<'a>(&mut self, buf: &'a [u8]) -> ByteVec<'a> { 422 match get_crlf_contain(buf) { 423 TokenStatus::Partial(unparsed) => { 424 self.src.extend_from_slice(unparsed); 425 Ok(TokenStatus::Partial(&[])) 426 } 427 TokenStatus::Complete((src, unparsed)) => { 428 // clone in this. 429 self.src.extend_from_slice(src); 430 // safety: use for trim. 431 let s = unsafe { std::str::from_utf8_unchecked(&self.src).trim() }; 432 // implies s >= 2 433 if let Some(s) = s.strip_prefix("--") { 434 let boundary = s.as_bytes().to_vec(); 435 self.set_boundary(boundary.clone()); 436 self.when_is_first_boundary(); 437 return Ok(TokenStatus::Complete((boundary, unparsed))); 438 } 439 440 // is not end; need to find next '\n' 441 self.src = vec![]; 442 self.src_idx = 0; 443 Ok(TokenStatus::Partial(&[])) 444 } 445 } 446 } 447 448 /// use to inner multi inner_first_boundary<'a>( &mut self, buf: &'a [u8], ) -> Result<TokenStatus<&'a [u8], &'a [u8]>, HttpError>449 fn inner_first_boundary<'a>( 450 &mut self, 451 buf: &'a [u8], 452 ) -> Result<TokenStatus<&'a [u8], &'a [u8]>, HttpError> { 453 match get_crlf_contain(buf) { 454 TokenStatus::Partial(unparsed) => { 455 self.src.extend_from_slice(unparsed); 456 Ok(TokenStatus::Partial(&[])) 457 } 458 TokenStatus::Complete((src, unparsed)) => { 459 // clone in this. 460 self.src.extend_from_slice(src); 461 let line = &self.src[self.src_idx..]; 462 let trim_line = trim_back_lwsp_if_end_with_lf(line); 463 464 // checks whether is first boundary 465 let mut deriv_boundary = b"--".to_vec(); 466 deriv_boundary.extend_from_slice(&self.boundary); 467 if trim_line == deriv_boundary { 468 self.when_is_first_boundary(); 469 return Ok(TokenStatus::Complete(unparsed)); 470 } 471 472 // is not end 473 self.src_idx = self.src.len(); 474 Ok(TokenStatus::Partial(unparsed)) 475 } 476 } 477 } 478 when_is_first_boundary(&mut self)479 fn when_is_first_boundary(&mut self) { 480 self.is_finish_first_boundary = true; 481 self.tag = BoundaryTag::First; 482 self.src_init(); 483 } 484 src_init(&mut self)485 fn src_init(&mut self) { 486 // init 487 self.src = vec![]; 488 self.src_idx = 0; 489 } 490 491 /// use to all multi middle_or_end_boundary<'a>(&mut self, buf: &'a [u8]) -> TokenStatus<&'a [u8], &'a [u8]>492 fn middle_or_end_boundary<'a>(&mut self, buf: &'a [u8]) -> TokenStatus<&'a [u8], &'a [u8]> { 493 match get_crlf_contain(buf) { 494 TokenStatus::Partial(unparsed) => { 495 self.src.extend_from_slice(unparsed); 496 TokenStatus::Partial(&[]) 497 } 498 TokenStatus::Complete((src, unparsed)) => { 499 // clone in this. 500 self.src.extend_from_slice(src); 501 let line = &self.src[self.src_idx..]; 502 let trim_line = trim_back_lwsp_if_end_with_lf(line); 503 504 // checks whether is middle boundary 505 let mut deriv_boundary = b"--".to_vec(); 506 deriv_boundary.extend_from_slice(&self.boundary); 507 if trim_line == deriv_boundary { 508 self.tag = BoundaryTag::Middle; 509 self.src_init(); 510 return TokenStatus::Complete(unparsed); 511 } 512 // checks whether is end boundary 513 deriv_boundary.extend_from_slice(b"--"); 514 if trim_line == deriv_boundary { 515 self.tag = BoundaryTag::End; 516 self.src_init(); 517 return TokenStatus::Complete(unparsed); 518 } 519 520 // is not end 521 self.src_idx = self.src.len(); 522 TokenStatus::Partial(unparsed) 523 } 524 } 525 } 526 } 527 528 #[cfg(test)] 529 mod ut_mime_multi_decoder { 530 use crate::body::{MimeMulti, MimeMultiDecoder, MimePart, TokenStatus}; 531 532 /// UT test cases for `MimeMultiDecoder::decode`. 533 /// 534 /// # Brief 535 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 536 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 537 /// 3. The `MimeMulti` is composed of a part. 538 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 539 /// 5. Checks whether the result is correct. 540 #[test] ut_mime_multi_decoder_new()541 fn ut_mime_multi_decoder_new() { 542 let buf = b"--abc\r\n\r\n--abc--\r\nabcd"; 543 let mut decoder = MimeMultiDecoder::new(); 544 let (elem, rest) = decoder.decode(buf).unwrap(); 545 assert!(elem.is_complete()); 546 let multi1 = MimeMulti::builder() 547 .set_boundary(b"abc".to_vec()) 548 .add_part(MimePart::builder().build().unwrap()) 549 .build() 550 .unwrap(); 551 if let TokenStatus::Complete(multi) = elem { 552 assert_eq!(multi.boundary(), multi1.boundary()); 553 assert_eq!(multi, multi1); 554 } 555 assert_eq!(rest, b"abcd"); 556 } 557 558 /// UT test cases for `MimeMultiDecoder::decode`. 559 /// 560 /// # Brief 561 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 562 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 563 /// 3. The `MimeMulti` is composed of a part. 564 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 565 /// 5. Checks whether the result is correct. 566 #[test] ut_mime_multi_decoder_one_part()567 fn ut_mime_multi_decoder_one_part() { 568 let buf = b"--abc\r\nkey1:value1\r\n\r\n1111\r\n--abc--\r\nabcd"; 569 let mut decoder = MimeMultiDecoder::new(); 570 let (elem, rest) = decoder.decode(buf).unwrap(); 571 assert!(elem.is_complete()); 572 let multi1 = MimeMulti::builder() 573 .set_boundary(b"abc".to_vec()) 574 .add_part( 575 MimePart::builder() 576 .header("key1", "value1") 577 .body_from_owned(b"1111".to_vec()) 578 .build() 579 .unwrap(), 580 ) 581 .build() 582 .unwrap(); 583 if let TokenStatus::Complete(multi) = elem { 584 assert_eq!(multi.boundary(), multi1.boundary()); 585 assert_eq!(multi.headers(), multi1.headers()); 586 assert_eq!(multi, multi1); 587 } 588 assert_eq!(rest, b"abcd"); 589 } 590 591 /// UT test cases for `MimeMultiDecoder::decode`. 592 /// 593 /// # Brief 594 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 595 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 596 /// 3. The `MimeMulti` is composed of a part. 597 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 598 /// 5. Checks whether the result is correct. 599 #[test] ut_mime_multi_decoder_one_part_no_headers()600 fn ut_mime_multi_decoder_one_part_no_headers() { 601 let buf = b"--abc\r\n\r\n112233\r\n--abc--\r\nabcd"; 602 let mut decoder = MimeMultiDecoder::new(); 603 let (elem, rest) = decoder.decode(buf).unwrap(); 604 assert!(elem.is_complete()); 605 let multi1 = MimeMulti::builder() 606 .set_boundary(b"abc".to_vec()) 607 .add_part( 608 MimePart::builder() 609 .body_from_owned(b"112233".to_vec()) 610 .build() 611 .unwrap(), 612 ) 613 .build() 614 .unwrap(); 615 if let TokenStatus::Complete(multi) = elem { 616 assert_eq!(multi.boundary(), multi1.boundary()); 617 assert_eq!(multi.headers(), multi1.headers()); 618 assert_eq!(multi, multi1); 619 } 620 assert_eq!(rest, b"abcd"); 621 } 622 623 /// UT test cases for `MimeMultiDecoder::decode`. 624 /// 625 /// # Brief 626 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 627 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 628 /// 3. The `MimeMulti` is composed of a part. 629 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 630 /// 5. Checks whether the result is correct. 631 #[test] ut_mime_multi_decoder_one_part_no_body()632 fn ut_mime_multi_decoder_one_part_no_body() { 633 let buf = b"--abc\r\nkey1:value1\r\n\r\n--abc--\r\nabcd"; 634 let mut decoder = MimeMultiDecoder::new(); 635 let (elem, rest) = decoder.decode(buf).unwrap(); 636 assert!(elem.is_complete()); 637 let multi1 = MimeMulti::builder() 638 .set_boundary(b"abc".to_vec()) 639 .add_part( 640 MimePart::builder() 641 .header("key1", "value1") 642 .build() 643 .unwrap(), 644 ) 645 .build() 646 .unwrap(); 647 if let TokenStatus::Complete(multi) = elem { 648 assert_eq!(multi.boundary(), multi1.boundary()); 649 assert_eq!(multi.headers(), multi1.headers()); 650 assert_eq!(multi, multi1); 651 } 652 assert_eq!(rest, b"abcd"); 653 } 654 655 /// UT test cases for `MimeMultiDecoder::decode`. 656 /// 657 /// # Brief 658 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 659 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 660 /// 3. The `MimeMulti` is composed of several parts. 661 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 662 /// 5. Checks whether the result is correct. 663 #[test] ut_mime_multi_decoder_several_parts()664 fn ut_mime_multi_decoder_several_parts() { 665 let buf = 666 b"---\r\nkey1:value1\r\n\r\n1111\r\n---\r\nkey2: value2\r\n\r\n2222\r\n-----\r\nabcd"; 667 let mut decoder = MimeMultiDecoder::new(); 668 let (elem, rest) = decoder.decode(buf).unwrap(); 669 assert!(elem.is_complete()); 670 let multi1 = MimeMulti::builder() 671 .set_boundary(b"-".to_vec()) 672 .add_part( 673 MimePart::builder() 674 .header("key1", "value1") 675 .body_from_owned(b"1111".to_vec()) 676 .build() 677 .unwrap(), 678 ) 679 .add_part( 680 MimePart::builder() 681 .header("key2", "value2") 682 .body_from_owned(b"2222".to_vec()) 683 .build() 684 .unwrap(), 685 ) 686 .build() 687 .unwrap(); 688 if let TokenStatus::Complete(multi) = elem { 689 assert_eq!(multi, multi1); 690 } 691 assert_eq!(rest, b"abcd"); 692 } 693 694 /// UT test cases for `MimeMultiDecoder::decode`. 695 /// 696 /// # Brief 697 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 698 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 699 /// 3. The `MimeMulti` is composed of several parts, and the boundary has 700 /// LWSP chars. 701 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 702 /// 5. Checks whether the result is correct. 703 #[test] ut_mime_multi_decoder_several_parts_has_lwsp()704 fn ut_mime_multi_decoder_several_parts_has_lwsp() { 705 let buf = 706 b"--- \r\nkey1:value1\r\n\r\n1111\r\n--- \r\nkey2: value2\r\n\r\n2222\r\n----- \r\nabcd"; 707 let mut decoder = MimeMultiDecoder::new(); 708 let (elem, rest) = decoder.decode(buf).unwrap(); 709 assert!(elem.is_complete()); 710 let multi1 = MimeMulti::builder() 711 .set_boundary(b"-".to_vec()) 712 .add_part( 713 MimePart::builder() 714 .header("key1", "value1") 715 .body_from_owned(b"1111".to_vec()) 716 .build() 717 .unwrap(), 718 ) 719 .add_part( 720 MimePart::builder() 721 .header("key2", "value2") 722 .body_from_owned(b"2222".to_vec()) 723 .build() 724 .unwrap(), 725 ) 726 .build() 727 .unwrap(); 728 if let TokenStatus::Complete(multi) = elem { 729 assert_eq!(multi, multi1); 730 } 731 assert_eq!(rest, b"abcd"); 732 } 733 734 /// UT test cases for `MimeMultiDecoder::decode`. 735 /// 736 /// # Brief 737 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 738 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 739 /// 3. The `MimeMulti` is nesting. 740 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 741 /// 5. Checks whether the result is correct. 742 #[test] ut_mime_multi_decoder_nest()743 fn ut_mime_multi_decoder_nest() { 744 let buf = "\ 745 --abc\r\nContent-Type:multipart/mix; boundary=aaa\r\n\r\n\ 746 --aaa\r\nkey1:value1\r\n\r\n1111\r\n--aaa--\r\n\r\n--abc--\r\nabcd" 747 .as_bytes(); 748 let mut decoder = MimeMultiDecoder::new(); 749 let (elem, rest) = decoder.decode(buf).unwrap(); 750 assert!(elem.is_complete()); 751 let multi1 = MimeMulti::builder() 752 .set_boundary(b"abc".to_vec()) 753 .add_multi( 754 MimeMulti::builder() 755 .set_content_type(b"multipart/mix", b"aaa".to_vec()) 756 .add_part( 757 MimePart::builder() 758 .header("key1", "value1") 759 .body_from_owned(b"1111".to_vec()) 760 .build() 761 .unwrap(), 762 ) 763 .build() 764 .unwrap(), 765 ) 766 .build() 767 .unwrap(); 768 if let TokenStatus::Complete(multi) = elem { 769 assert_eq!(multi, multi1); 770 } 771 assert_eq!(rest, b"abcd"); 772 } 773 774 /// UT test cases for `MimeMultiDecoder::decode`. 775 /// 776 /// # Brief 777 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 778 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 779 /// 3. The `MimeMulti` is nesting. 780 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 781 /// 5. Checks whether the result is correct. 782 #[test] ut_mime_multi_decoder_nest2()783 fn ut_mime_multi_decoder_nest2() { 784 let buf = "\ 785 --abc\r\nContent-Type:multipart/mix; boundary=aaa\r\n\r\n--aaa\r\nkey1:\ 786 value1\r\n\r\n1111\r\n--aaa--\r\n\r\n--abc\r\nkey2:value2\r\n\r\n2222\r\n--\ 787 abc--\r\nabcd" 788 .as_bytes(); 789 let mut decoder = MimeMultiDecoder::new(); 790 let (elem, rest) = decoder.decode(buf).unwrap(); 791 assert!(elem.is_complete()); 792 let multi1 = MimeMulti::builder() 793 .set_boundary(b"abc".to_vec()) 794 .add_multi( 795 MimeMulti::builder() 796 .set_content_type(b"multipart/mix", b"aaa".to_vec()) 797 .add_part( 798 MimePart::builder() 799 .header("key1", "value1") 800 .body_from_owned(b"1111".to_vec()) 801 .build() 802 .unwrap(), 803 ) 804 .build() 805 .unwrap(), 806 ) 807 .add_part( 808 MimePart::builder() 809 .header("key2", "value2") 810 .body_from_owned(b"2222".to_vec()) 811 .build() 812 .unwrap(), 813 ) 814 .build() 815 .unwrap(); 816 if let TokenStatus::Complete(multi) = elem { 817 assert_eq!(multi, multi1); 818 } 819 assert_eq!(rest, b"abcd"); 820 } 821 822 /// UT test cases for `MimeMultiDecoder::decode`. 823 /// 824 /// # Brief 825 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 826 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 827 /// 3. The `MimeMulti` is nesting. 828 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 829 /// 5. Checks whether the result is correct. 830 #[test] ut_mime_multi_decoder_nest3()831 fn ut_mime_multi_decoder_nest3() { 832 let buf = "\ 833 --abc\r\nkey2:value2\r\n\r\n2222\r\n--abc\r\nContent-Type:multipart/mix; \ 834 boundary=aaa\r\n\r\n--aaa\r\nkey1:value1\r\n\r\n1111\r\n--aaa--\r\n\r\n\ 835 --abc--\r\nabcd" 836 .as_bytes(); 837 let mut decoder = MimeMultiDecoder::new(); 838 let (elem, rest) = decoder.decode(buf).unwrap(); 839 assert!(elem.is_complete()); 840 let multi1 = MimeMulti::builder() 841 .set_boundary(b"abc".to_vec()) 842 .add_part( 843 MimePart::builder() 844 .header("key2", "value2") 845 .body_from_owned(b"2222".to_vec()) 846 .build() 847 .unwrap(), 848 ) 849 .add_multi( 850 MimeMulti::builder() 851 .set_content_type(b"multipart/mix", b"aaa".to_vec()) 852 .add_part( 853 MimePart::builder() 854 .header("key1", "value1") 855 .body_from_owned(b"1111".to_vec()) 856 .build() 857 .unwrap(), 858 ) 859 .build() 860 .unwrap(), 861 ) 862 .build() 863 .unwrap(); 864 if let TokenStatus::Complete(multi) = elem { 865 assert_eq!(multi, multi1); 866 } 867 assert_eq!(rest, b"abcd"); 868 } 869 870 /// UT test cases for `MimeMultiDecoder::decode`. 871 /// 872 /// # Brief 873 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 874 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 875 /// 3. The `MimeMulti` is nesting. 876 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 877 /// 5. Checks whether the result is correct. 878 #[test] ut_mime_multi_decoder_nest4()879 fn ut_mime_multi_decoder_nest4() { 880 let buf = "\ 881 --abc\r\nkey2:value2\r\n\r\n2222\r\n--abc\r\nContent-Type:multipart/mix; \ 882 boundary=aaa\r\n\r\n--aaa\r\nkey1:value1\r\n\r\n1111\r\n--aaa\r\nkey3:value3\ 883 \r\n\r\n--aaa--\r\n\r\n--abc--\r\nabcd" 884 .as_bytes(); 885 let mut decoder = MimeMultiDecoder::new(); 886 let (elem, rest) = decoder.decode(buf).unwrap(); 887 assert!(elem.is_complete()); 888 let multi1 = MimeMulti::builder() 889 .set_boundary(b"abc".to_vec()) 890 .add_part( 891 MimePart::builder() 892 .header("key2", "value2") 893 .body_from_owned(b"2222".to_vec()) 894 .build() 895 .unwrap(), 896 ) 897 .add_multi( 898 MimeMulti::builder() 899 .set_content_type(b"multipart/mix", b"aaa".to_vec()) 900 .add_part( 901 MimePart::builder() 902 .header("key1", "value1") 903 .body_from_owned(b"1111".to_vec()) 904 .build() 905 .unwrap(), 906 ) 907 .add_part( 908 MimePart::builder() 909 .header("key3", "value3") 910 .build() 911 .unwrap(), 912 ) 913 .build() 914 .unwrap(), 915 ) 916 .build() 917 .unwrap(); 918 if let TokenStatus::Complete(multi) = elem { 919 assert_eq!(multi, multi1); 920 } 921 assert_eq!(rest, b"abcd"); 922 } 923 924 /// UT test cases for `MimeMultiDecoder::decode`. 925 /// 926 /// # Brief 927 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 928 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 929 /// 3. The decode bytes are divided into several executions. 930 /// 4. Creates a `MimeMulti` and sets the same parameters to compare. 931 /// 5. Checks whether the result is correct. 932 #[test] ut_mime_multi_decoder_times()933 fn ut_mime_multi_decoder_times() { 934 let buf = 935 b"---\r\nkey1:value1\r\n\r\n1111\r\n---\r\nkey2: value2\r\n\r\n2222\r\n-----\r\nabcd"; 936 let mut decoder = MimeMultiDecoder::new(); 937 938 //--- 939 let (elem, rest) = decoder.decode(&buf[..3]).unwrap(); 940 assert!(!elem.is_complete()); 941 assert_eq!(rest, b""); 942 943 //\r\nkey1:value1 944 let (elem, rest) = decoder.decode(&buf[3..16]).unwrap(); 945 assert!(!elem.is_complete()); 946 assert_eq!(rest, b""); 947 948 //\r\n\r\n1111\r\n---\r\n 949 let (elem, rest) = decoder.decode(&buf[16..31]).unwrap(); 950 assert!(!elem.is_complete()); 951 assert_eq!(rest, b""); 952 953 // key2: value2\r\n\r\n2222\r\n-----\r\n 954 let (elem, rest) = decoder.decode(&buf[31..60]).unwrap(); 955 assert!(elem.is_complete()); 956 let multi1 = MimeMulti::builder() 957 .set_boundary(b"-".to_vec()) 958 .add_part( 959 MimePart::builder() 960 .header("key1", "value1") 961 .body_from_owned(b"1111".to_vec()) 962 .build() 963 .unwrap(), 964 ) 965 .add_part( 966 MimePart::builder() 967 .header("key2", "value2") 968 .body_from_owned(b"2222".to_vec()) 969 .build() 970 .unwrap(), 971 ) 972 .build() 973 .unwrap(); 974 if let TokenStatus::Complete(multi) = elem { 975 assert_eq!(multi, multi1); 976 } 977 assert_eq!(rest, b""); 978 979 // abcd 980 let (_elem, rest) = decoder.decode(&buf[60..]).unwrap(); 981 assert_eq!(rest, b"abcd"); 982 } 983 984 /// UT test cases for `MimeMultiDecoder::decode`. 985 /// 986 /// # Brief 987 /// 1. Creates a `MimeMultiDecoder` by `MimeMultiDecoder::new`. 988 /// 2. Uses `MimeMultiDecoder::decode` to decode `MimeMulti`. 989 /// 3. Uses wrong input. 990 /// 4. Checks whether the result is correct. 991 #[test] ut_mime_multi_decoder_err()992 fn ut_mime_multi_decoder_err() { 993 let mut buf = b"--abc\r\n\r\n--abc--\r\nabcd".to_vec(); 994 buf.insert(7, 200); 995 let mut decoder = MimeMultiDecoder::new(); 996 let res = decoder.decode(&buf); 997 assert!(res.is_err()); 998 } 999 } 1000