• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //! Tests nested `MimeMulti`, for its building and synchronous encoding.
15 
16 use ylong_http::body::{sync_impl, MimeMulti, MimeMultiEncoder, MimePart};
17 
18 // A multi example in [`RFC2049`]
19 // [`RFC2049`]: https://www.rfc-editor.org/rfc/rfc2049
20 //
21 // MIME-Version: 1.0
22 // From: Nathaniel Borenstein <nsb@nsb.fv.com>
23 // To: Ned Freed <ned@innosoft.com>
24 // Date: Fri, 07 Oct 1994 16:15:05 -0700 (PDT)
25 // Subject: A multipart example
26 // Content-Type: multipart/mixed;
27 //               boundary=unique-boundary-1
28 //
29 // This is the preamble area of a multipart message.
30 // Mail readers that understand multipart format
31 // should ignore this preamble.
32 //
33 // If you are reading this text, you might want to
34 // consider changing to a mail reader that understands
35 // how to properly display multipart messages.
36 //
37 // --unique-boundary-1
38 //
39 //   ... Some text appears here ...
40 //
41 // [Note that the blank between the boundary and the start
42 //  of the text in this part means no header fields were
43 //  given and this is text in the US-ASCII character set.
44 //  It could have been done with explicit typing as in the
45 //  next part.]
46 //
47 // --unique-boundary-1
48 // Content-type: text/plain; charset=US-ASCII
49 //
50 // This could have been part of the previous part, but
51 // illustrates explicit versus implicit typing of body
52 // parts.
53 //
54 // --unique-boundary-1
55 // Content-Type: multipart/parallel; boundary=unique-boundary-2
56 //
57 // --unique-boundary-2
58 // Content-Type: audio/basic
59 // Content-Transfer-Encoding: base64
60 //
61 //   ... base64-encoded 8000 Hz single-channel
62 //       mu-law-format audio data goes here ...
63 //
64 // --unique-boundary-2
65 // Content-Type: image/jpeg
66 // Content-Transfer-Encoding: base64
67 //
68 //   ... base64-encoded image data goes here ...
69 //
70 // --unique-boundary-2--
71 //
72 // --unique-boundary-1
73 // Content-type: text/enriched
74 //
75 // This is <bold><italic>enriched.</italic></bold>
76 // <smaller>as defined in RFC 1896</smaller>
77 //
78 // Isn't it
79 // <bigger><bigger>cool?</bigger></bigger>
80 //
81 // --unique-boundary-1
82 // Content-Type: message/rfc822
83 //
84 // From: (mailbox in US-ASCII)
85 // To: (address in US-ASCII)
86 // Subject: (subject in US-ASCII)
87 // Content-Type: Text/plain; charset=ISO-8859-1
88 // Content-Transfer-Encoding: Quoted-printable
89 //
90 //   ... Additional text in ISO-8859-1 goes here ...
91 //
92 // --unique-boundary-1--
93 
main()94 fn main() {
95     let body_text1 = "\
96         This could have been part of the previous part, but \
97         illustrates explicit versus implicit typing of body parts.\r\n"
98         .as_bytes();
99     let body_text2 = "\
100         ... base64-encoded 8000 Hz single-channel \
101         mu-law-format audio data goes here ...\r\n"
102         .as_bytes();
103     let body_text3 = "... base64-encoded image data goes here ...\r\n".as_bytes();
104 
105     let body_text4 = "\
106 This is <bold><italic>enriched.</italic></bold>
107 <smaller>as defined in RFC 1896</smaller>
108 
109 Isn't it
110 <bigger><bigger>cool?</bigger></bigger>
111 "
112     .as_bytes();
113 
114     let body_text5 = "\
115 From: (mailbox in US-ASCII)
116 To: (address in US-ASCII)
117 Subject: (subject in US-ASCII)
118 Content-Type: Text/plain; charset=ISO-8859-1
119 Content-Transfer-Encoding: Quoted-printable
120 
121 ... Additional text in ISO-8859-1 goes here ...
122 "
123     .as_bytes();
124 
125     let multi = MimeMulti::builder()
126         .set_content_type(b"multipart/mixed", b"unique-boundary-1".to_vec())
127         .add_part(
128             MimePart::builder()
129                 .body_from_bytes("... Some text appears here ...\r\n".as_bytes())
130                 .build()
131                 .unwrap(),
132         )
133         .add_part(
134             MimePart::builder()
135                 .header("Content-type", "text/plain; charset=US-ASCII")
136                 .body_from_bytes(body_text1)
137                 .build()
138                 .unwrap(),
139         )
140         .add_multi(
141             MimeMulti::builder()
142                 .set_content_type(b"multipart/parallel", b"unique-boundary-2".to_vec())
143                 .add_part(
144                     MimePart::builder()
145                         .header("Content-type", "audio/basic")
146                         .header("Content-Transfer-Encoding", "base64")
147                         .body_from_bytes(body_text2)
148                         .build()
149                         .unwrap(),
150                 )
151                 .add_part(
152                     MimePart::builder()
153                         .header("Content-type", "image/jpeg")
154                         .header("Content-Transfer-Encoding", "base64")
155                         .body_from_bytes(body_text3)
156                         .build()
157                         .unwrap(),
158                 )
159                 .build()
160                 .unwrap(),
161         )
162         .add_part(
163             MimePart::builder()
164                 .header("Content-type", "text/enriched")
165                 .body_from_reader(body_text4)
166                 .build()
167                 .unwrap(),
168         )
169         .add_part(
170             MimePart::builder()
171                 .header("Content-type", "message/rfc822")
172                 .body_from_reader(body_text5)
173                 .build()
174                 .unwrap(),
175         )
176         .build()
177         .unwrap();
178 
179     let mut multi_encoder = MimeMultiEncoder::from_multi(multi);
180     let mut buf = vec![0u8; 50];
181     let mut v_size = vec![];
182     let mut v_str = vec![];
183 
184     loop {
185         let len = sync_impl::Body::data(&mut multi_encoder, &mut buf).unwrap();
186         if len == 0 {
187             break;
188         }
189         v_size.push(len);
190         v_str.extend_from_slice(&buf[..len]);
191     }
192     assert_eq!(
193         v_size,
194         vec![
195             50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
196             35
197         ]
198     );
199     // Headers is a HashMap, so that sequence of iter is different.
200     println!("{}", core::str::from_utf8(&v_str).unwrap());
201 }
202