• 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 //! HTTP/1.1 request encoder implementation.
15 //!
16 //! The encoder is used to serialize the request into the specified buf in
17 //! a certain format.
18 //!
19 //! # Examples
20 //!
21 //! ```
22 //! use ylong_http::h1::RequestEncoder;
23 //! use ylong_http::request::Request;
24 //!
25 //! let request = Request::builder()
26 //!     .method("GET")
27 //!     .url("www.example.com")
28 //!     .version("HTTP/1.1")
29 //!     .header("ACCEPT", "text/html")
30 //!     .body(())
31 //!     .unwrap();
32 //!
33 //! // Gets `RequestPart`.
34 //! let (part, _) = request.into_parts();
35 //! let mut encoder = RequestEncoder::new(part);
36 //!
37 //! // We use `message` to store all the body data.
38 //! let mut message = Vec::new();
39 //! // We use `buf` to store save temporary data.
40 //! let mut buf = [0u8; 20];
41 //!
42 //! // First encoding, buf is filled.
43 //! let size = encoder.encode(&mut buf).unwrap();
44 //! assert_eq!(&buf[..size], "GET www.example.com ".as_bytes());
45 //! message.extend_from_slice(&buf[..size]);
46 //!
47 //! // Second encoding, buf is filled.
48 //! let size = encoder.encode(&mut buf).unwrap();
49 //! assert_eq!(&buf[..size], "HTTP/1.1\r\naccept:tex".as_bytes());
50 //! message.extend_from_slice(&buf[..size]);
51 //!
52 //! // Third encoding, part of buf is filled, this indicates that encoding has ended.
53 //! let size = encoder.encode(&mut buf).unwrap();
54 //! assert_eq!(&buf[..size], "t/html\r\n\r\n".as_bytes());
55 //! message.extend_from_slice(&buf[..size]);
56 //!
57 //! // We can assemble temporary data into a complete data.
58 //! let result = "GET www.example.com HTTP/1.1\r\naccept:text/html\r\n\r\n";
59 //! assert_eq!(message.as_slice(), result.as_bytes());
60 //! ```
61 
62 use std::io::Read;
63 
64 use crate::error::{ErrorKind, HttpError};
65 use crate::headers::{HeaderName, Headers, HeadersIntoIter};
66 use crate::request::method::Method;
67 use crate::request::uri::Uri;
68 use crate::request::RequestPart;
69 use crate::version::Version;
70 
71 /// A encoder that is used to encode request message in `HTTP/1.1` format.
72 ///
73 /// This encoder supports you to use the encode method multiple times to output
74 /// the result in multiple bytes slices.
75 ///
76 /// # Examples
77 ///
78 /// ```
79 /// use ylong_http::h1::RequestEncoder;
80 /// use ylong_http::request::Request;
81 ///
82 /// let request = Request::builder()
83 ///     .method("GET")
84 ///     .url("www.example.com")
85 ///     .version("HTTP/1.1")
86 ///     .header("ACCEPT", "text/html")
87 ///     .body(())
88 ///     .unwrap();
89 ///
90 /// // Gets `RequestPart`.
91 /// let (part, _) = request.into_parts();
92 /// let mut encoder = RequestEncoder::new(part);
93 ///
94 /// // We use `message` to store all the body data.
95 /// let mut message = Vec::new();
96 /// // We use `buf` to store save temporary data.
97 /// let mut buf = [0u8; 20];
98 ///
99 /// // First encoding, buf is filled.
100 /// let size = encoder.encode(&mut buf).unwrap();
101 /// assert_eq!(&buf[..size], "GET www.example.com ".as_bytes());
102 /// message.extend_from_slice(&buf[..size]);
103 ///
104 /// // Second encoding, buf is filled.
105 /// let size = encoder.encode(&mut buf).unwrap();
106 /// assert_eq!(&buf[..size], "HTTP/1.1\r\naccept:tex".as_bytes());
107 /// message.extend_from_slice(&buf[..size]);
108 ///
109 /// // Third encoding, part of buf is filled, this indicates that encoding has ended.
110 /// let size = encoder.encode(&mut buf).unwrap();
111 /// assert_eq!(&buf[..size], "t/html\r\n\r\n".as_bytes());
112 /// message.extend_from_slice(&buf[..size]);
113 ///
114 /// // We can assemble temporary data into a complete data.
115 /// let result = "GET www.example.com HTTP/1.1\r\naccept:text/html\r\n\r\n";
116 /// assert_eq!(message.as_slice(), result.as_bytes());
117 /// ```
118 pub struct RequestEncoder {
119     encode_status: EncodeState,
120     method_part: EncodeMethod,
121     method_sp_part: EncodeSp,
122     uri_part: EncodeUri,
123     uri_sp_part: EncodeSp,
124     version_part: EncodeVersion,
125     version_crlf_part: EncodeCrlf,
126     headers_part: EncodeHeader,
127     headers_crlf_part: EncodeCrlf,
128     is_proxy: bool,
129 }
130 
131 enum EncodeState {
132     // "Method" phase of encoding request-message.
133     Method,
134     // "MethodSp" phase of encoding whitespace after method.
135     MethodSp,
136     // "Uri" phase of encoding request-message.
137     Uri,
138     // "UriSp" phase of encoding whitespace after uri.
139     UriSp,
140     // "Version" phase of encoding request-message.
141     Version,
142     // "VersionCrlf" phase of encoding whitespace after version.
143     VersionCrlf,
144     // "Header" phase of encoding request-message.
145     Header,
146     // "HeaderCrlf" phase of encoding /r/n after header.
147     HeaderCrlf,
148     // "EncodeFinished" phase of finishing the encoding.
149     EncodeFinished,
150 }
151 
152 // Component encoding status.
153 enum TokenStatus<T, E> {
154     // The current component is completely encoded.
155     Complete(T),
156     // The current component is partially encoded.
157     Partial(E),
158 }
159 
160 type TokenResult<T> = Result<TokenStatus<usize, T>, HttpError>;
161 
162 impl RequestEncoder {
163     /// Creates a new `RequestEncoder` from a `RequestPart`.
164     ///
165     /// # Examples
166     ///
167     /// ```
168     /// use ylong_http::h1::RequestEncoder;
169     /// use ylong_http::request::Request;
170     ///
171     /// let request = Request::builder()
172     ///     .method("GET")
173     ///     .url("www.example.com")
174     ///     .version("HTTP/1.1")
175     ///     .header("ACCEPT", "text/html")
176     ///     .body(())
177     ///     .unwrap();
178     ///
179     /// let (part, _) = request.into_parts();
180     /// let encoder = RequestEncoder::new(part);
181     /// ```
new(part: RequestPart) -> Self182     pub fn new(part: RequestPart) -> Self {
183         Self {
184             encode_status: EncodeState::Method,
185             method_part: EncodeMethod::new(part.method),
186             method_sp_part: EncodeSp::new(),
187             uri_part: EncodeUri::new(part.uri, false),
188             uri_sp_part: EncodeSp::new(),
189             version_part: EncodeVersion::new(part.version),
190             version_crlf_part: EncodeCrlf::new(),
191             headers_part: EncodeHeader::new(part.headers),
192             headers_crlf_part: EncodeCrlf::new(),
193             is_proxy: false,
194         }
195     }
196 
197     /// Encodes `RequestPart` into target buf and returns the number of
198     /// bytes written.
199     ///
200     /// If the length of buf is not enough to write all the output results,
201     /// the state will be saved until the next call to this method.
202     ///
203     /// # Return Value
204     ///
205     /// This method may return the following results:
206     ///
207     /// - `Ok(size) && size == buf.len()`: it means that buf has been completely
208     /// filled, but the result may not be fully output. You **must** call this
209     /// method again to obtain the rest part of the result. Otherwise you may
210     /// lose some parts of the result.
211     ///
212     /// - `Ok(size) && size < buf.len()`: it indicates that the result has been
213     /// fully output.
214     ///
215     /// - `Err(e)`: it indicates that an error has occurred during encoding.
216     ///
217     /// # Examples
218     ///
219     /// ```
220     /// use ylong_http::h1::RequestEncoder;
221     /// use ylong_http::request::Request;
222     ///
223     /// let request = Request::builder()
224     ///     .method("GET")
225     ///     .url("www.example.com")
226     ///     .version("HTTP/1.1")
227     ///     .header("ACCEPT", "text/html")
228     ///     .body(())
229     ///     .unwrap();
230     ///
231     /// let (part, _) = request.into_parts();
232     /// let mut encoder = RequestEncoder::new(part);
233     ///
234     /// let mut buf = [0_u8; 10];
235     /// let mut message = Vec::new();
236     /// let mut idx = 0;
237     /// loop {
238     ///     let size = encoder.encode(&mut buf).unwrap();
239     ///     message.extend_from_slice(&buf[..size]);
240     ///     if size < buf.len() {
241     ///         break;
242     ///     }
243     /// }
244     ///
245     /// let result = "GET www.example.com HTTP/1.1\r\naccept:text/html\r\n\r\n";
246     /// assert_eq!(message.as_slice(), result.as_bytes());
247     /// ```
encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>248     pub fn encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
249         if dst.is_empty() {
250             return Err(ErrorKind::InvalidInput.into());
251         }
252         let mut count = 0;
253         while count != dst.len() {
254             count += match self.encode_status {
255                 EncodeState::Method => self.method_encode(&mut dst[count..]),
256                 EncodeState::MethodSp => self.method_sp_encode(&mut dst[count..]),
257                 EncodeState::Uri => self.uri_encode(&mut dst[count..]),
258                 EncodeState::UriSp => self.uri_sp_encode(&mut dst[count..]),
259                 EncodeState::Version => self.version_encode(&mut dst[count..]),
260                 EncodeState::VersionCrlf => self.version_crlf_encode(&mut dst[count..]),
261                 EncodeState::Header => self.header_encode(&mut dst[count..]),
262                 EncodeState::HeaderCrlf => self.header_crlf_encode(&mut dst[count..]),
263                 EncodeState::EncodeFinished => return Ok(count),
264             }?;
265         }
266         Ok(dst.len())
267     }
268 
269     /// Sets the `is_proxy` flag.
270     ///
271     /// If you enable the flag, the uri part will be encoded as a relative path
272     /// in the headline. Otherwise the uri part will be fully encoded in the
273     /// headline.
274     ///
275     /// You should use this method before the uri part being encoded.
276     ///
277     /// # Examples
278     ///
279     /// ```
280     /// use ylong_http::h1::RequestEncoder;
281     /// use ylong_http::request::Request;
282     ///
283     /// let request = Request::builder()
284     ///     .method("GET")
285     ///     .url("www.example.com")
286     ///     .version("HTTP/1.1")
287     ///     .header("ACCEPT", "text/html")
288     ///     .body(())
289     ///     .unwrap();
290     ///
291     /// let (part, _) = request.into_parts();
292     /// let mut encoder = RequestEncoder::new(part);
293     /// // After you create the request encoder, users can choose to set the proxy.
294     /// encoder.set_proxy(true);
295     ///
296     /// let mut buf = [0u8; 1024];
297     /// let size = encoder.encode(&mut buf).unwrap();
298     /// // If you set the `is_proxy` flag, the uri will be encoded as a relative path.
299     /// assert_eq!(
300     ///     &buf[..size],
301     ///     b"GET / HTTP/1.1\r\naccept:text/html\r\n\r\n".as_slice()
302     /// );
303     /// ```
set_proxy(&mut self, is_proxy: bool)304     pub fn set_proxy(&mut self, is_proxy: bool) {
305         self.is_proxy = is_proxy;
306     }
307 
method_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>308     fn method_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
309         match self.method_part.encode(dst)? {
310             TokenStatus::Complete(output_size) => {
311                 self.encode_status = EncodeState::MethodSp;
312                 Ok(output_size)
313             }
314             TokenStatus::Partial(output_size) => {
315                 self.encode_status = EncodeState::Method;
316                 Ok(output_size)
317             }
318         }
319     }
320 
method_sp_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>321     fn method_sp_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
322         match self.method_sp_part.encode(dst)? {
323             TokenStatus::Complete(output_size) => {
324                 self.uri_part.is_proxy = self.is_proxy;
325                 self.encode_status = EncodeState::Uri;
326                 Ok(output_size)
327             }
328             TokenStatus::Partial(output_size) => {
329                 self.encode_status = EncodeState::MethodSp;
330                 Ok(output_size)
331             }
332         }
333     }
334 
uri_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>335     fn uri_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
336         match self.uri_part.encode(dst)? {
337             TokenStatus::Complete(output_size) => {
338                 self.encode_status = EncodeState::UriSp;
339                 Ok(output_size)
340             }
341             TokenStatus::Partial(output_size) => {
342                 self.encode_status = EncodeState::Uri;
343                 Ok(output_size)
344             }
345         }
346     }
347 
uri_sp_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>348     fn uri_sp_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
349         match self.uri_sp_part.encode(dst)? {
350             TokenStatus::Complete(output_size) => {
351                 self.encode_status = EncodeState::Version;
352                 Ok(output_size)
353             }
354             TokenStatus::Partial(output_size) => {
355                 self.encode_status = EncodeState::UriSp;
356                 Ok(output_size)
357             }
358         }
359     }
360 
version_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>361     fn version_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
362         match self.version_part.encode(dst)? {
363             TokenStatus::Complete(output_size) => {
364                 self.encode_status = EncodeState::VersionCrlf;
365                 Ok(output_size)
366             }
367             TokenStatus::Partial(output_size) => {
368                 self.encode_status = EncodeState::Version;
369                 Ok(output_size)
370             }
371         }
372     }
373 
version_crlf_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>374     fn version_crlf_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
375         match self.version_crlf_part.encode(dst)? {
376             TokenStatus::Complete(output_size) => {
377                 self.encode_status = EncodeState::Header;
378                 Ok(output_size)
379             }
380             TokenStatus::Partial(output_size) => {
381                 self.encode_status = EncodeState::VersionCrlf;
382                 Ok(output_size)
383             }
384         }
385     }
386 
header_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>387     fn header_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
388         match self.headers_part.encode(dst)? {
389             TokenStatus::Complete(output_size) => {
390                 self.encode_status = EncodeState::HeaderCrlf;
391                 Ok(output_size)
392             }
393             TokenStatus::Partial(output_size) => {
394                 self.encode_status = EncodeState::Header;
395                 Ok(output_size)
396             }
397         }
398     }
399 
header_crlf_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError>400     fn header_crlf_encode(&mut self, dst: &mut [u8]) -> Result<usize, HttpError> {
401         match self.headers_crlf_part.encode(dst)? {
402             TokenStatus::Complete(output_size) => {
403                 self.encode_status = EncodeState::EncodeFinished;
404                 Ok(output_size)
405             }
406             TokenStatus::Partial(output_size) => {
407                 self.encode_status = EncodeState::HeaderCrlf;
408                 Ok(output_size)
409             }
410         }
411     }
412 }
413 
414 struct EncodeMethod {
415     inner: Method,
416     src_idx: usize,
417 }
418 
419 impl EncodeMethod {
new(method: Method) -> Self420     fn new(method: Method) -> Self {
421         Self {
422             inner: method,
423             src_idx: 0,
424         }
425     }
426 
encode(&mut self, buf: &mut [u8]) -> TokenResult<usize>427     fn encode(&mut self, buf: &mut [u8]) -> TokenResult<usize> {
428         let method = self.inner.as_str().as_bytes();
429         WriteData::new(method, &mut self.src_idx, buf).write()
430     }
431 }
432 
433 struct EncodeUri {
434     inner: Vec<u8>,
435     inner_proxy: Vec<u8>,
436     src_idx: usize,
437     is_proxy: bool,
438 }
439 
440 impl EncodeUri {
new(uri: Uri, is_proxy: bool) -> Self441     fn new(uri: Uri, is_proxy: bool) -> Self {
442         let mut init_proxy_uri = vec![];
443         let path = uri.path_and_query();
444         if let Some(p) = path {
445             init_proxy_uri = p.as_bytes().to_vec();
446         } else {
447             init_proxy_uri.extend_from_slice(b"/");
448         }
449         let init_uri = uri.to_string().into_bytes();
450         Self {
451             inner: init_uri,
452             inner_proxy: init_proxy_uri,
453             src_idx: 0,
454             is_proxy,
455         }
456     }
457 
encode(&mut self, buf: &mut [u8]) -> TokenResult<usize>458     fn encode(&mut self, buf: &mut [u8]) -> TokenResult<usize> {
459         let mut uri = self.inner.as_slice();
460         if self.is_proxy {
461             uri = self.inner_proxy.as_slice();
462         }
463         WriteData::new(uri, &mut self.src_idx, buf).write()
464     }
465 }
466 
467 struct EncodeVersion {
468     inner: Version,
469     src_idx: usize,
470 }
471 
472 impl EncodeVersion {
new(version: Version) -> Self473     fn new(version: Version) -> Self {
474         Self {
475             inner: version,
476             src_idx: 0,
477         }
478     }
479 
encode(&mut self, buf: &mut [u8]) -> TokenResult<usize>480     fn encode(&mut self, buf: &mut [u8]) -> TokenResult<usize> {
481         let version = self.inner.as_str().as_bytes();
482         let mut task = WriteData::new(version, &mut self.src_idx, buf);
483         task.write()
484     }
485 }
486 
487 struct EncodeHeader {
488     inner: HeadersIntoIter,
489     status: Option<HeaderStatus>,
490     name: HeaderName,
491     value: Vec<u8>,
492     name_idx: usize,
493     colon_idx: usize,
494     value_idx: usize,
495 }
496 
497 enum HeaderStatus {
498     Name,
499     Colon,
500     Value,
501     Crlf(EncodeCrlf),
502     EmptyHeader,
503 }
504 
505 impl EncodeHeader {
new(header: Headers) -> Self506     fn new(header: Headers) -> Self {
507         let mut header_iter = header.into_iter();
508         if let Some((header_name, header_value)) = header_iter.next() {
509             Self {
510                 inner: header_iter,
511                 status: Some(HeaderStatus::Name),
512                 name: header_name,
513                 value: header_value.to_str().unwrap().into_bytes(),
514                 name_idx: 0,
515                 colon_idx: 0,
516                 value_idx: 0,
517             }
518         } else {
519             Self {
520                 inner: header_iter,
521                 status: Some(HeaderStatus::EmptyHeader),
522                 name: HeaderName::from_bytes(" ".as_bytes()).unwrap(),
523                 value: vec![],
524                 name_idx: 0,
525                 colon_idx: 0,
526                 value_idx: 0,
527             }
528         }
529     }
530 
encode(&mut self, buf: &mut [u8]) -> TokenResult<usize>531     fn encode(&mut self, buf: &mut [u8]) -> TokenResult<usize> {
532         match self.status.take().unwrap() {
533             HeaderStatus::Name => {
534                 let name = self.name.as_bytes();
535                 let mut task = WriteData::new(name, &mut self.name_idx, buf);
536                 match task.write()? {
537                     TokenStatus::Complete(size) => {
538                         self.status = Some(HeaderStatus::Colon);
539                         Ok(TokenStatus::Partial(size))
540                     }
541                     TokenStatus::Partial(size) => {
542                         self.status = Some(HeaderStatus::Name);
543                         Ok(TokenStatus::Partial(size))
544                     }
545                 }
546             }
547             HeaderStatus::Colon => {
548                 let colon = ":".as_bytes();
549                 let mut task = WriteData::new(colon, &mut self.colon_idx, buf);
550                 match task.write()? {
551                     TokenStatus::Complete(size) => {
552                         self.status = Some(HeaderStatus::Value);
553                         Ok(TokenStatus::Partial(size))
554                     }
555                     TokenStatus::Partial(size) => {
556                         self.status = Some(HeaderStatus::Colon);
557                         Ok(TokenStatus::Partial(size))
558                     }
559                 }
560             }
561             HeaderStatus::Value => {
562                 let value = self.value.as_slice();
563                 let mut task = WriteData::new(value, &mut self.value_idx, buf);
564                 match task.write()? {
565                     TokenStatus::Complete(size) => {
566                         let crlf = EncodeCrlf::new();
567                         self.status = Some(HeaderStatus::Crlf(crlf));
568                         Ok(TokenStatus::Partial(size))
569                     }
570                     TokenStatus::Partial(size) => {
571                         self.status = Some(HeaderStatus::Value);
572                         Ok(TokenStatus::Partial(size))
573                     }
574                 }
575             }
576             HeaderStatus::Crlf(mut crlf) => match crlf.encode(buf)? {
577                 TokenStatus::Complete(size) => {
578                     if let Some(iter) = self.inner.next() {
579                         let (header_name, header_value) = iter;
580                         self.status = Some(HeaderStatus::Name);
581                         self.name = header_name;
582                         self.value = header_value.to_str().unwrap().into_bytes();
583                         self.name_idx = 0;
584                         self.colon_idx = 0;
585                         self.value_idx = 0;
586                         Ok(TokenStatus::Partial(size))
587                     } else {
588                         Ok(TokenStatus::Complete(size))
589                     }
590                 }
591                 TokenStatus::Partial(size) => {
592                     self.status = Some(HeaderStatus::Crlf(crlf));
593                     Ok(TokenStatus::Partial(size))
594                 }
595             },
596             HeaderStatus::EmptyHeader => Ok(TokenStatus::Complete(0)),
597         }
598     }
599 }
600 
601 struct EncodeSp {
602     src_idx: usize,
603 }
604 
605 impl EncodeSp {
new() -> Self606     fn new() -> Self {
607         Self { src_idx: 0 }
608     }
609 
encode(&mut self, buf: &mut [u8]) -> TokenResult<usize>610     fn encode(&mut self, buf: &mut [u8]) -> TokenResult<usize> {
611         let sp = " ".as_bytes();
612         let mut task = WriteData::new(sp, &mut self.src_idx, buf);
613         task.write()
614     }
615 }
616 
617 struct EncodeCrlf {
618     src_idx: usize,
619 }
620 
621 impl EncodeCrlf {
new() -> Self622     fn new() -> Self {
623         Self { src_idx: 0 }
624     }
625 
encode(&mut self, buf: &mut [u8]) -> TokenResult<usize>626     fn encode(&mut self, buf: &mut [u8]) -> TokenResult<usize> {
627         let crlf = "\r\n".as_bytes();
628         let mut task = WriteData::new(crlf, &mut self.src_idx, buf);
629         task.write()
630     }
631 }
632 
633 struct WriteData<'a> {
634     src: &'a [u8],
635     src_idx: &'a mut usize,
636     dst: &'a mut [u8],
637 }
638 
639 impl<'a> WriteData<'a> {
new(src: &'a [u8], src_idx: &'a mut usize, dst: &'a mut [u8]) -> Self640     fn new(src: &'a [u8], src_idx: &'a mut usize, dst: &'a mut [u8]) -> Self {
641         WriteData { src, src_idx, dst }
642     }
643 
write(&mut self) -> TokenResult<usize>644     fn write(&mut self) -> TokenResult<usize> {
645         let src_idx = *self.src_idx;
646         let input_len = self.src.len() - src_idx;
647         let output_len = self.dst.len();
648         let num = (&self.src[src_idx..]).read(self.dst).unwrap();
649         if output_len >= input_len {
650             return Ok(TokenStatus::Complete(num));
651         }
652         *self.src_idx += num;
653         Ok(TokenStatus::Partial(num))
654     }
655 }
656 impl Default for RequestEncoder {
default() -> Self657     fn default() -> Self {
658         RequestEncoder::new(RequestPart::default())
659     }
660 }
661 
662 #[cfg(test)]
663 mod ut_request_encoder {
664     use super::RequestEncoder;
665     use crate::request::{Request, RequestBuilder};
666 
667     /// UT test cases for `RequestEncoder::new`.
668     ///
669     /// # Brief
670     /// 1. Calls `RequestEncoder::new` to create a `RequestEncoder`.
671     #[test]
ut_request_encoder_new()672     fn ut_request_encoder_new() {
673         let request = Request::new(());
674         let (part, _) = request.into_parts();
675         let _encoder = RequestEncoder::new(part);
676         // Success if no panic.
677     }
678 
679     /// UT test cases for `RequestEncoder::encode`.
680     ///
681     /// # Brief
682     /// 1. Creates a `Request` by calling methods of `Request::builder`.
683     /// 2. Gets a request part by calling `Request::into_parts`.
684     /// 3. Creates a `RequestEncoder` by calling `RequestBuilder::new`.
685     /// 4. Calls `RequestEncoder::encode` method in a loop and collects the
686     ///    results.
687     /// 5. Checks if the test result is correct.
688     #[test]
ut_request_encoder_encode_1()689     fn ut_request_encoder_encode_1() {
690         macro_rules! encoder_test_case {
691             (
692                 Method: $method:expr,
693                 Uri: $uri:expr,
694                 Version: $version:expr,
695                 $(Header: $name:expr, $value:expr,)*
696                 RequestLine: $request_line:expr,
697             ) => {{
698                 let request = Request::builder()
699                     .method($method)
700                     .url($uri)
701                     .version($version)
702                     $(.header($name, $value))*
703                     .body(())
704                     .unwrap();
705 
706                 let (part, _) = request.into_parts();
707                 let mut encoder = RequestEncoder::new(part);
708                 let mut buf = [0u8; 5];
709                 let mut res = Vec::new();
710                 loop {
711                     let size = encoder.encode(&mut buf).unwrap();
712                     res.extend_from_slice(&buf[..size]);
713                     if size < buf.len() {
714                         break;
715                     }
716                 }
717 
718                 let str = std::str::from_utf8(res.as_slice())
719                     .expect("Cannot convert res to &str");
720 
721                 assert!(str.find($request_line).is_some());
722 
723                 $(
724                     let target_header = format!(
725                         "{}:{}\r\n",
726                         ($name).to_lowercase(),
727                         ($value).to_lowercase(),
728                     );
729                     assert!(str.find(target_header.as_str()).is_some());
730                 )*
731             }};
732         }
733 
734         // No header-lines.
735         encoder_test_case! {
736             Method: "GET",
737             Uri: "www.example.com",
738             Version: "HTTP/1.1",
739             RequestLine: "GET www.example.com HTTP/1.1\r\n",
740         }
741 
742         // 1 header-line.
743         encoder_test_case! {
744             Method: "GET",
745             Uri: "www.example.com",
746             Version: "HTTP/1.1",
747             Header: "ACCEPT", "text/html",
748             RequestLine: "GET www.example.com HTTP/1.1\r\n",
749         }
750 
751         // More than 1 header-lines.
752         encoder_test_case! {
753             Method: "GET",
754             Uri: "www.example.com",
755             Version: "HTTP/1.1",
756             Header: "ACCEPT", "text/html",
757             Header: "HOST", "127.0.0.1",
758             RequestLine: "GET www.example.com HTTP/1.1\r\n",
759         }
760     }
761 
762     /// UT test cases for `RequestEncoder::set_proxy`.
763     ///
764     /// # Brief
765     /// 1. Creates a `Request` by calling `RequestBuilder::build`.
766     /// 2. Calls set_proxy.
767     /// 3. Checks if the test result is correct.
768     #[test]
ut_request_encoder_set_proxy()769     fn ut_request_encoder_set_proxy() {
770         let request = RequestBuilder::new()
771             .method("GET")
772             .url("www.example.com")
773             .version("HTTP/1.1")
774             .body(())
775             .unwrap();
776         let (part, _) = request.into_parts();
777         let mut encoder = RequestEncoder::new(part);
778         assert!(!encoder.is_proxy);
779 
780         encoder.set_proxy(true);
781         assert!(encoder.is_proxy);
782 
783         let mut buf = [0u8; 100];
784         let size = encoder.encode(&mut buf).unwrap();
785         let res = std::str::from_utf8(&buf[..size]).unwrap();
786         assert_eq!(res, "GET / HTTP/1.1\r\n\r\n");
787     }
788 }
789