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