• 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 use core::convert::Infallible;
15 use core::ops::{Deref, DerefMut};
16 use core::pin::Pin;
17 use core::str::from_utf8_unchecked;
18 use core::task::{Context, Poll};
19 use std::any::Any;
20 use std::collections::HashMap;
21 use std::convert::{TryFrom, TryInto};
22 use std::future::Future;
23 use std::io::{Error, Read};
24 
25 use super::origin::{FromAsyncReader, FromBytes, FromReader};
26 use super::{async_impl, sync_impl};
27 use crate::body::origin::FromAsyncBody;
28 use crate::error::{ErrorKind, HttpError};
29 use crate::headers::{Header, HeaderName, HeaderValue, Headers};
30 use crate::{AsyncRead, AsyncReadExt, ReadBuf};
31 
32 /// A chunk body is used to encode body to send message by chunk in `HTTP/1.1`
33 /// format.
34 ///
35 /// This chunk body encoder supports you to use the chunk encode method multiple
36 /// times to output the result in multiple bytes slices.
37 ///
38 /// # Examples
39 ///
40 /// ```
41 /// use ylong_http::body::sync_impl::Body;
42 /// use ylong_http::body::ChunkBody;
43 ///
44 /// let content = "aaaaa bbbbb ccccc ddddd";
45 /// // Gets `ChunkBody`
46 /// let mut task = ChunkBody::from_bytes(content.as_bytes());
47 /// let mut user_slice = [0_u8; 10];
48 /// let mut output_vec = vec![];
49 ///
50 /// // First encoding, user_slice is filled.
51 /// let size = task.data(user_slice.as_mut_slice()).unwrap();
52 /// assert_eq!(&user_slice[..size], "17\r\naaaaa ".as_bytes());
53 /// output_vec.extend_from_slice(user_slice.as_mut_slice());
54 ///
55 /// // Second encoding, user_slice is filled.
56 /// let size = task.data(user_slice.as_mut_slice()).unwrap();
57 /// assert_eq!(&user_slice[..size], "bbbbb cccc".as_bytes());
58 /// output_vec.extend_from_slice(user_slice.as_mut_slice());
59 ///
60 /// // Third encoding, user_slice is filled.
61 /// let size = task.data(user_slice.as_mut_slice()).unwrap();
62 /// assert_eq!(&user_slice[..size], "c ddddd\r\n0".as_bytes());
63 /// output_vec.extend_from_slice(user_slice.as_mut_slice());
64 ///
65 /// // Fourth encoding, part of user_slice is filled, this indicates that encoding has ended.
66 /// let size = task.data(user_slice.as_mut_slice()).unwrap();
67 /// assert_eq!(&user_slice[..size], "\r\n\r\n".as_bytes());
68 /// output_vec.extend_from_slice(&user_slice[..size]);
69 ///
70 /// // We can assemble temporary data into a complete data.
71 /// let result = "17\r\naaaaa bbbbb ccccc ddddd\r\n0\r\n\r\n";
72 /// assert_eq!(output_vec.as_slice(), result.as_bytes());
73 /// ```
74 pub struct ChunkBody<T> {
75     from: T,
76     trailer_value: Vec<u8>,
77     chunk_data: ChunkData,
78     data_status: DataState,
79     encode_status: EncodeStatus,
80     trailer: EncodeTrailer,
81 }
82 
83 const CHUNK_SIZE: usize = 1024;
84 
85 struct StatusVar {
86     cnt: usize,
87     data_status: DataState,
88 }
89 
90 // Data encoding status
91 enum DataState {
92     // Data encode is processing
93     Partial,
94     // Data encode is completed
95     Complete,
96     // Data encode is finished and return result
97     Finish,
98 }
99 
100 // Component encoding status
101 enum TokenStatus<T, E> {
102     // The current component is completely encoded.
103     Complete(T),
104     // The current component is partially encoded.
105     Partial(E),
106 }
107 
108 type Token<T> = TokenStatus<usize, T>;
109 
110 impl<'a> ChunkBody<FromBytes<'a>> {
111     /// Creates a new `ChunkBody` by `bytes`.
112     ///
113     /// # Examples
114     ///
115     /// ```
116     /// use ylong_http::body::ChunkBody;
117     ///
118     /// let task = ChunkBody::from_bytes("".as_bytes());
119     /// ```
from_bytes(bytes: &'a [u8]) -> Self120     pub fn from_bytes(bytes: &'a [u8]) -> Self {
121         ChunkBody {
122             from: FromBytes::new(bytes),
123             trailer_value: vec![],
124             chunk_data: ChunkData::new(vec![]),
125             data_status: DataState::Partial,
126             encode_status: EncodeStatus::new(),
127             trailer: EncodeTrailer::new(),
128         }
129     }
130 
chunk_encode(&mut self, src: &[u8], dst: &mut [u8]) -> usize131     fn chunk_encode(&mut self, src: &[u8], dst: &mut [u8]) -> usize {
132         self.encode_status.chunk_last = self.chunk_data.chunk_last;
133         let (output_size, var) = self.encode_status.encode(src, dst);
134 
135         if let Some(v) = var {
136             self.chunk_data.chunk_count = v.cnt;
137             self.data_status = v.data_status;
138         }
139         output_size
140     }
141 }
142 
143 impl<T: Read> ChunkBody<FromReader<T>> {
144     /// Creates a new `ChunkBody` by `reader`.
145     ///
146     /// # Examples
147     ///
148     /// ```
149     /// use ylong_http::body::ChunkBody;
150     ///
151     /// let task = ChunkBody::from_reader("".as_bytes());
152     /// ```
from_reader(reader: T) -> Self153     pub fn from_reader(reader: T) -> Self {
154         ChunkBody {
155             from: FromReader::new(reader),
156             trailer_value: vec![],
157             chunk_data: ChunkData::new(vec![0; CHUNK_SIZE]),
158             data_status: DataState::Partial,
159             encode_status: EncodeStatus::new(),
160             trailer: EncodeTrailer::new(),
161         }
162     }
163 
chunk_encode(&mut self, dst: &mut [u8]) -> usize164     fn chunk_encode(&mut self, dst: &mut [u8]) -> usize {
165         self.chunk_encode_reader(dst)
166     }
167 }
168 
169 impl<T: AsyncRead + Unpin + Send + Sync> ChunkBody<FromAsyncReader<T>> {
170     /// Creates a new `ChunkBody` by `async reader`.
171     ///
172     /// # Examples
173     ///
174     /// ```
175     /// use ylong_http::body::ChunkBody;
176     ///
177     /// let task = ChunkBody::from_async_reader("".as_bytes());
178     /// ```
from_async_reader(reader: T) -> Self179     pub fn from_async_reader(reader: T) -> Self {
180         ChunkBody {
181             from: FromAsyncReader::new(reader),
182             trailer_value: vec![],
183             chunk_data: ChunkData::new(vec![0; CHUNK_SIZE]),
184             data_status: DataState::Partial,
185             encode_status: EncodeStatus::new(),
186             trailer: EncodeTrailer::new(),
187         }
188     }
189 
chunk_encode(&mut self, dst: &mut [u8]) -> usize190     fn chunk_encode(&mut self, dst: &mut [u8]) -> usize {
191         self.chunk_encode_reader(dst)
192     }
193 }
194 
195 impl<T: async_impl::Body + Unpin> ChunkBody<FromAsyncBody<T>> {
196     /// Creates a new `ChunkBody` by `async body`.
197     ///
198     /// # Examples
199     ///
200     /// ```
201     /// use ylong_http::body::ChunkBody;
202     ///
203     /// let task = ChunkBody::from_async_body("".as_bytes());
204     /// ```
from_async_body(body: T) -> Self205     pub fn from_async_body(body: T) -> Self {
206         ChunkBody {
207             from: FromAsyncBody::new(body),
208             trailer_value: vec![],
209             chunk_data: ChunkData::new(vec![0; CHUNK_SIZE]),
210             data_status: DataState::Partial,
211             encode_status: EncodeStatus::new(),
212             trailer: EncodeTrailer::new(),
213         }
214     }
215 
chunk_encode(&mut self, dst: &mut [u8]) -> usize216     fn chunk_encode(&mut self, dst: &mut [u8]) -> usize {
217         self.chunk_encode_reader(dst)
218     }
219 }
220 
221 impl<'a> sync_impl::Body for ChunkBody<FromBytes<'a>> {
222     type Error = Infallible;
223 
data(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>224     fn data(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
225         let mut count = 0;
226         while count != buf.len() {
227             let encode_size = match self.data_status {
228                 DataState::Partial => self.bytes_encode(&mut buf[count..]),
229                 DataState::Complete => self.trailer_encode(&mut buf[count..]),
230                 DataState::Finish => return Ok(count),
231             };
232             count += encode_size;
233         }
234         Ok(buf.len())
235     }
236 }
237 
238 impl<T: Read> sync_impl::Body for ChunkBody<FromReader<T>> {
239     type Error = Error;
240 
data(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>241     fn data(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
242         let mut count = 0;
243         while count != buf.len() {
244             let encode_size = match self.data_status {
245                 DataState::Partial => {
246                     if !self.encode_status.get_flag() {
247                         self.encode_status.set_flag(true);
248                         self.encode_status.set_chunk_idx(0);
249                         self.chunk_data.chunk_last =
250                             (*self.from).read(&mut self.chunk_data.chunk_buf).unwrap();
251                     }
252                     self.chunk_encode(&mut buf[count..])
253                 }
254                 DataState::Complete => self.trailer_encode(&mut buf[count..]),
255                 DataState::Finish => {
256                     return Ok(count);
257                 }
258             };
259             count += encode_size;
260         }
261         Ok(buf.len())
262     }
263 }
264 
265 impl<'c> async_impl::Body for ChunkBody<FromBytes<'c>> {
266     type Error = Error;
267 
poll_data( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize, Self::Error>>268     fn poll_data(
269         mut self: Pin<&mut Self>,
270         _cx: &mut Context<'_>,
271         buf: &mut [u8],
272     ) -> Poll<Result<usize, Self::Error>> {
273         let mut count = 0;
274         while count != buf.len() {
275             let encode_size: Poll<usize> = match self.data_status {
276                 DataState::Partial => Poll::Ready(self.bytes_encode(&mut buf[count..])),
277                 DataState::Complete => Poll::Ready(self.trailer_encode(&mut buf[count..])),
278                 DataState::Finish => return Poll::Ready(Ok(count)),
279             };
280             match encode_size {
281                 Poll::Ready(size) => {
282                     count += size;
283                 }
284                 Poll::Pending => return Poll::Pending,
285             }
286         }
287         Poll::Ready(Ok(buf.len()))
288     }
289 }
290 
291 impl<T: AsyncRead + Unpin + Send + Sync> async_impl::Body for ChunkBody<FromAsyncReader<T>> {
292     type Error = Error;
293 
poll_data( self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize, Self::Error>>294     fn poll_data(
295         self: Pin<&mut Self>,
296         _cx: &mut Context<'_>,
297         buf: &mut [u8],
298     ) -> Poll<Result<usize, Self::Error>> {
299         let chunk_body = self.get_mut();
300         let mut count = 0;
301         while count != buf.len() {
302             let encode_size = match chunk_body.data_status {
303                 DataState::Partial => {
304                     if !chunk_body.encode_status.get_flag() {
305                         let mut read_buf = ReadBuf::new(&mut chunk_body.chunk_data.chunk_buf);
306 
307                         match Pin::new(&mut *chunk_body.from).poll_read(_cx, &mut read_buf) {
308                             Poll::Ready(Ok(())) => {
309                                 let size = read_buf.filled().len();
310                                 chunk_body.encode_status.set_flag(true);
311                                 // chunk idx reset zero
312                                 chunk_body.encode_status.set_chunk_idx(0);
313                                 chunk_body.chunk_data.chunk_last = size;
314                                 let data_size = chunk_body.chunk_encode(&mut buf[count..]);
315                                 Poll::Ready(data_size)
316                             }
317                             Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
318                             Poll::Pending => Poll::Pending,
319                         }
320                     } else {
321                         Poll::Ready(chunk_body.chunk_encode(&mut buf[count..]))
322                     }
323                 }
324                 DataState::Complete => Poll::Ready(chunk_body.trailer_encode(&mut buf[count..])),
325                 DataState::Finish => {
326                     return Poll::Ready(Ok(count));
327                 }
328             };
329 
330             match encode_size {
331                 Poll::Ready(size) => {
332                     count += size;
333                 }
334                 Poll::Pending => {
335                     if count != 0 {
336                         return Poll::Ready(Ok(count));
337                     }
338                     return Poll::Pending;
339                 }
340             }
341         }
342         Poll::Ready(Ok(buf.len()))
343     }
344 }
345 
346 impl<T: async_impl::Body> async_impl::Body for ChunkBody<FromAsyncBody<T>> {
347     type Error = T::Error;
348 
poll_data( self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize, Self::Error>>349     fn poll_data(
350         self: Pin<&mut Self>,
351         _cx: &mut Context<'_>,
352         buf: &mut [u8],
353     ) -> Poll<Result<usize, Self::Error>> {
354         let chunk_body = self.get_mut();
355         let mut count = 0;
356         while count != buf.len() {
357             let encode_size = match chunk_body.data_status {
358                 DataState::Partial => {
359                     if !chunk_body.encode_status.get_flag() {
360                         match Pin::new(&mut *chunk_body.from)
361                             .poll_data(_cx, &mut chunk_body.chunk_data.chunk_buf)
362                         {
363                             Poll::Ready(Ok(size)) => {
364                                 chunk_body.encode_status.set_flag(true);
365                                 // chunk idx reset zero
366                                 chunk_body.encode_status.set_chunk_idx(0);
367                                 chunk_body.chunk_data.chunk_last = size;
368                                 let data_size = chunk_body.chunk_encode(&mut buf[count..]);
369                                 Poll::Ready(data_size)
370                             }
371                             Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
372                             Poll::Pending => Poll::Pending,
373                         }
374                     } else {
375                         Poll::Ready(chunk_body.chunk_encode(&mut buf[count..]))
376                     }
377                 }
378                 DataState::Complete => Poll::Ready(chunk_body.trailer_encode(&mut buf[count..])),
379                 DataState::Finish => {
380                     return Poll::Ready(Ok(count));
381                 }
382             };
383 
384             match encode_size {
385                 Poll::Ready(size) => {
386                     count += size;
387                 }
388                 Poll::Pending => {
389                     if count != 0 {
390                         return Poll::Ready(Ok(count));
391                     }
392                     return Poll::Pending;
393                 }
394             }
395         }
396         Poll::Ready(Ok(buf.len()))
397     }
398 }
399 
400 impl<'a> ChunkBody<FromBytes<'a>> {
bytes_encode(&mut self, dst: &mut [u8]) -> usize401     fn bytes_encode(&mut self, dst: &mut [u8]) -> usize {
402         if !self.encode_status.get_flag() {
403             self.encode_status.set_flag(true);
404             self.encode_status.set_chunk_idx(0);
405             let data_left = self.from.len() - self.chunk_data.chunk_count * CHUNK_SIZE;
406             self.chunk_data.chunk_last = if data_left < CHUNK_SIZE {
407                 data_left
408             } else {
409                 CHUNK_SIZE
410             };
411         }
412         let src = &self.from[self.chunk_data.chunk_count * CHUNK_SIZE
413             ..(self.chunk_data.chunk_count * CHUNK_SIZE + self.chunk_data.chunk_last)];
414         self.chunk_encode(src, dst)
415     }
416 }
417 
418 impl<T> ChunkBody<T> {
419     /// Creates a new `Trailer` by `set_trailer`.
420     ///
421     /// # Examples
422     ///
423     /// ```
424     /// use ylong_http::body::ChunkBody;
425     /// use ylong_http::headers::Headers;
426     ///
427     /// let mut headers = Headers::new();
428     /// let _ = headers.insert("accept", "text/html");
429     /// let mut task = ChunkBody::from_bytes("".as_bytes()).set_trailer(headers);
430     /// ```
set_trailer(mut self, trailer_headers: Headers) -> Self431     pub fn set_trailer(mut self, trailer_headers: Headers) -> Self {
432         let mut trailer_vec = vec![];
433         for (name, value) in trailer_headers.into_iter() {
434             // Operate on each `HeaderName` and `HeaderValue` pair.
435             trailer_vec.extend_from_slice(name.as_bytes());
436             trailer_vec.extend_from_slice(b":");
437             // to_string will not return err, so can use unwrap directly
438             trailer_vec.extend_from_slice(value.to_str().unwrap().as_bytes());
439             trailer_vec.extend_from_slice(b"\r\n");
440         }
441         self.trailer_value = trailer_vec;
442         self
443     }
chunk_encode_reader(&mut self, dst: &mut [u8]) -> usize444     fn chunk_encode_reader(&mut self, dst: &mut [u8]) -> usize {
445         self.encode_status.chunk_last = self.chunk_data.chunk_last;
446         let (output_size, var) = self.encode_status.encode(
447             &self.chunk_data.chunk_buf[..self.chunk_data.chunk_last],
448             dst,
449         );
450         if let Some(v) = var {
451             self.chunk_data.chunk_count = v.cnt;
452             self.data_status = v.data_status;
453         }
454         output_size
455     }
456 
trailer_encode(&mut self, dst: &mut [u8]) -> usize457     fn trailer_encode(&mut self, dst: &mut [u8]) -> usize {
458         let mut src = b"0\r\n".to_vec();
459         if self.trailer_value.is_empty() {
460             src.extend_from_slice(b"\r\n");
461         } else {
462             src.extend_from_slice(self.trailer_value.as_slice());
463             src.extend_from_slice(b"\r\n");
464         };
465         match self.trailer.encode(src.as_slice(), dst) {
466             TokenStatus::Complete(output_size) => {
467                 self.data_status = DataState::Finish;
468                 output_size
469             }
470             TokenStatus::Partial(output_size) => output_size,
471         }
472     }
473 }
474 
475 struct ChunkData {
476     chunk_buf: Vec<u8>,
477     chunk_count: usize,
478     chunk_last: usize,
479 }
480 
481 impl ChunkData {
new(buf: Vec<u8>) -> Self482     fn new(buf: Vec<u8>) -> Self {
483         ChunkData {
484             chunk_buf: buf,
485             chunk_count: 0,
486             chunk_last: 0,
487         }
488     }
489 }
490 
491 struct EncodeStatus {
492     chunk_size: usize,
493     chunk_last: usize,
494     chunk_idx: usize,
495     read_flag: bool,
496     src_idx: usize,
497     chunk_status: ChunkState,
498     meta_crlf: EncodeCrlf,
499     data_crlf: EncodeCrlf,
500     finish_crlf: EncodeCrlf,
501     hex: EncodeHex,
502     hex_last: EncodeHex,
503 }
504 
505 impl EncodeStatus {
new() -> Self506     fn new() -> Self {
507         EncodeStatus {
508             chunk_size: CHUNK_SIZE,
509             chunk_last: 0,
510             chunk_idx: 0,
511             read_flag: false,
512             src_idx: 0,
513             chunk_status: ChunkState::MetaSize,
514             meta_crlf: EncodeCrlf::new(),
515             data_crlf: EncodeCrlf::new(),
516             finish_crlf: EncodeCrlf::new(),
517             hex: EncodeHex::new(format!("{CHUNK_SIZE:x}")),
518             hex_last: EncodeHex::new("".to_string()),
519         }
520     }
521 
encode(&mut self, src: &[u8], dst: &mut [u8]) -> (usize, Option<StatusVar>)522     fn encode(&mut self, src: &[u8], dst: &mut [u8]) -> (usize, Option<StatusVar>) {
523         match self.chunk_status {
524             ChunkState::MetaSize => (self.meta_size_encode(dst), None),
525             ChunkState::MetaExt => (0, None),
526             ChunkState::MetaCrlf => (self.meta_crlf_encode(dst), None),
527             ChunkState::Data => {
528                 if self.chunk_last != CHUNK_SIZE {
529                     self.tail_encode(src, dst)
530                 } else {
531                     self.data_encode(src, dst)
532                 }
533             }
534             ChunkState::DataCrlf => (self.data_crlf_encode(dst), None),
535             ChunkState::Finish => self.finish_encode(dst),
536         }
537     }
538 
meta_size_encode(&mut self, dst: &mut [u8]) -> usize539     fn meta_size_encode(&mut self, dst: &mut [u8]) -> usize {
540         if self.chunk_last == CHUNK_SIZE {
541             match self.hex.encode(dst) {
542                 TokenStatus::Complete(output_size) => {
543                     self.chunk_status = ChunkState::MetaCrlf;
544                     self.hex.src_idx = 0;
545                     output_size
546                 }
547                 TokenStatus::Partial(output_size) => output_size,
548             }
549         } else {
550             self.hex_last = EncodeHex::new(format!("{last:x}", last = self.chunk_last));
551             match self.hex_last.encode(dst) {
552                 TokenStatus::Complete(output_size) => {
553                     self.chunk_status = ChunkState::MetaCrlf;
554                     self.hex_last.src_idx = 0;
555                     output_size
556                 }
557                 TokenStatus::Partial(output_size) => output_size,
558             }
559         }
560     }
561 
meta_crlf_encode(&mut self, dst: &mut [u8]) -> usize562     fn meta_crlf_encode(&mut self, dst: &mut [u8]) -> usize {
563         match self.meta_crlf.encode(dst) {
564             TokenStatus::Complete(output_size) => {
565                 self.chunk_status = ChunkState::Data;
566                 self.meta_crlf.src_idx = 0;
567                 output_size
568             }
569             TokenStatus::Partial(output_size) => output_size,
570         }
571     }
572 
data_crlf_encode(&mut self, dst: &mut [u8]) -> usize573     fn data_crlf_encode(&mut self, dst: &mut [u8]) -> usize {
574         match self.data_crlf.encode(dst) {
575             TokenStatus::Complete(output_size) => {
576                 self.chunk_status = ChunkState::MetaSize;
577                 self.data_crlf.src_idx = 0;
578                 output_size
579             }
580             TokenStatus::Partial(output_size) => output_size,
581         }
582     }
583 
finish_encode(&mut self, dst: &mut [u8]) -> (usize, Option<StatusVar>)584     fn finish_encode(&mut self, dst: &mut [u8]) -> (usize, Option<StatusVar>) {
585         match self.finish_crlf.encode(dst) {
586             TokenStatus::Complete(output_size) => {
587                 self.meta_crlf.src_idx = 0;
588                 let var = StatusVar {
589                     cnt: 0,
590                     data_status: DataState::Complete,
591                 };
592                 (output_size, Some(var))
593             }
594             TokenStatus::Partial(output_size) => (output_size, None),
595         }
596     }
597 
data_encode(&mut self, src: &[u8], dst: &mut [u8]) -> (usize, Option<StatusVar>)598     fn data_encode(&mut self, src: &[u8], dst: &mut [u8]) -> (usize, Option<StatusVar>) {
599         let mut task = WriteData::new(src, &mut self.chunk_idx, dst);
600 
601         match task.write() {
602             TokenStatus::Complete(output_size) => {
603                 self.chunk_status = ChunkState::DataCrlf;
604                 self.read_flag = false;
605                 let var = StatusVar {
606                     cnt: 1,
607                     data_status: DataState::Partial,
608                 };
609                 (output_size, Some(var))
610             }
611             TokenStatus::Partial(output_size) => (output_size, None),
612         }
613     }
614 
tail_encode(&mut self, src: &[u8], dst: &mut [u8]) -> (usize, Option<StatusVar>)615     fn tail_encode(&mut self, src: &[u8], dst: &mut [u8]) -> (usize, Option<StatusVar>) {
616         let mut task = WriteData::new(src, &mut self.chunk_idx, dst);
617         match task.write() {
618             TokenStatus::Complete(output_size) => {
619                 self.chunk_status = ChunkState::Finish;
620                 self.read_flag = false;
621                 let var = StatusVar {
622                     cnt: 0,
623                     data_status: DataState::Partial,
624                 };
625                 (output_size, Some(var))
626             }
627             TokenStatus::Partial(output_size) => (output_size, None),
628         }
629     }
630 
get_flag(&mut self) -> bool631     fn get_flag(&mut self) -> bool {
632         self.read_flag
633     }
634 
set_flag(&mut self, flag: bool)635     fn set_flag(&mut self, flag: bool) {
636         self.read_flag = flag;
637     }
638 
set_chunk_idx(&mut self, num: usize)639     fn set_chunk_idx(&mut self, num: usize) {
640         self.chunk_idx = num;
641     }
642 }
643 
644 struct EncodeHex {
645     inner: String,
646     src_idx: usize,
647 }
648 
649 impl EncodeHex {
new(hex: String) -> Self650     fn new(hex: String) -> Self {
651         Self {
652             inner: hex,
653             src_idx: 0,
654         }
655     }
656 
encode(&mut self, buf: &mut [u8]) -> Token<usize>657     fn encode(&mut self, buf: &mut [u8]) -> Token<usize> {
658         let hex = self.inner.as_bytes();
659         let mut task = WriteData::new(hex, &mut self.src_idx, buf);
660         task.write()
661     }
662 }
663 
664 struct EncodeCrlf {
665     src_idx: usize,
666 }
667 
668 impl EncodeCrlf {
new() -> Self669     fn new() -> Self {
670         Self { src_idx: 0 }
671     }
672 
encode(&mut self, buf: &mut [u8]) -> Token<usize>673     fn encode(&mut self, buf: &mut [u8]) -> Token<usize> {
674         let crlf = "\r\n".as_bytes();
675         let mut task = WriteData::new(crlf, &mut self.src_idx, buf);
676         task.write()
677     }
678 }
679 
680 struct EncodeTrailer {
681     src_idx: usize,
682 }
683 
684 impl EncodeTrailer {
new() -> Self685     fn new() -> Self {
686         Self { src_idx: 0 }
687     }
688 
encode(&mut self, src: &[u8], buf: &mut [u8]) -> Token<usize>689     fn encode(&mut self, src: &[u8], buf: &mut [u8]) -> Token<usize> {
690         let mut task = WriteData::new(src, &mut self.src_idx, buf);
691         task.write()
692     }
693 }
694 
695 struct WriteData<'a> {
696     src: &'a [u8],
697     src_idx: &'a mut usize,
698     dst: &'a mut [u8],
699 }
700 
701 impl<'a> WriteData<'a> {
new(src: &'a [u8], src_idx: &'a mut usize, dst: &'a mut [u8]) -> Self702     fn new(src: &'a [u8], src_idx: &'a mut usize, dst: &'a mut [u8]) -> Self {
703         WriteData { src, src_idx, dst }
704     }
705 
write(&mut self) -> Token<usize>706     fn write(&mut self) -> Token<usize> {
707         let src_idx = *self.src_idx;
708         let input_len = self.src.len() - src_idx;
709         let output_len = self.dst.len();
710         let num = std::io::Read::read(&mut &self.src[src_idx..], self.dst).unwrap();
711         if output_len >= input_len {
712             *self.src_idx += num;
713             return TokenStatus::Complete(num);
714         }
715         *self.src_idx += num;
716         TokenStatus::Partial(num)
717     }
718 }
719 
720 // Stage of decode chunks, The elements of the chunk-body are as follows:
721 // |========================================================================
722 // | chunked-body   = *chunk                                               |
723 // |                    last-chunk                                         |
724 // |                    trailer-section                                    |
725 // |                    CRLF                                               |
726 // |                                                                       |
727 // |   chunk          = chunk-size [ chunk-ext ] CRLF                      |
728 // |                    chunk-data CRLF                                    |
729 // |   chunk-size     = 1*HEXDIG                                           |
730 // |   last-chunk     = 1*("0") [ chunk-ext ] CRLF                         |
731 // |                                                                       |
732 // |   chunk-data     = 1*OCTET ; a sequence of chunk-size octets          |
733 // |                                                                       |
734 // |   chunk-ext      = *( BWS ";" BWS chunk-ext-name                      |
735 // |                       [ BWS "=" BWS chunk-ext-val ] )                 |
736 // |                                                                       |
737 // |   chunk-ext-name = token                                              |
738 // |   chunk-ext-val  = token / quoted-string                              |
739 // |========================================================================
740 enum Stage {
741     Size,
742     Extension,
743     SizeEnd,
744     Data,
745     DataEnd,
746     TrailerCrlf,
747     TrailerData,
748     TrailerEndCrlf,
749 }
750 
751 /// Chunk-ext part of a chunk,
752 /// Currently, the `ChunkBodyDecoder` does not decode the chunk-ext part.
753 /// Therefore, the chunk-ext key-value pair cannot be inserted or extracted.
754 #[derive(Debug, Default, Eq, PartialEq)]
755 pub struct ChunkExt {
756     map: HashMap<String, String>,
757 }
758 
759 impl ChunkExt {
760     /// Constructor of `ChunkExt`
new() -> Self761     pub fn new() -> Self {
762         ChunkExt {
763             map: HashMap::new(),
764         }
765     }
766 }
767 
768 /// Decode state of the chunk buffer.
769 /// When chunks in the buffer end in different elements, `ChunkBodyDecoder`
770 /// returns different `ChunkState`, as shown in the following figure:
771 /// > ```trust
772 /// > Meta:     `chunk-size [ chunk-ext ] CRLF`
773 /// > Partial:  `chunk-size [ chunk-ext ] CRLF chunk-data`
774 /// > Complete: `chunk-size [ chunk-ext ] CRLF chunk-data CRLF`
775 /// > ```
776 #[derive(Debug, Eq, PartialEq)]
777 pub enum ChunkState {
778     /// State of `chunk-size`
779     MetaSize,
780     /// State of `chunk-ext`
781     MetaExt,
782     /// CRLF
783     MetaCrlf,
784     /// State of `chunk-data`
785     Data,
786     /// CRLF
787     DataCrlf,
788     /// End
789     Finish,
790 }
791 
792 /// Decode result of the chunk buffer, contains all chunks in a buffer.
793 #[derive(Debug, Eq, PartialEq)]
794 pub struct Chunks<'a> {
795     chunks: Vec<Chunk<'a>>,
796 }
797 
798 /// An iterator of `Chunks`.
799 pub struct ChunksIter<'a> {
800     iter: core::slice::Iter<'a, Chunk<'a>>,
801 }
802 
803 /// An iterator that moves out of a `Chunks`.
804 pub struct ChunksIntoIter<'a> {
805     into_iter: std::vec::IntoIter<Chunk<'a>>,
806 }
807 
808 impl ChunksIter<'_> {
new<'a>(iter: core::slice::Iter<'a, Chunk<'a>>) -> ChunksIter<'a>809     fn new<'a>(iter: core::slice::Iter<'a, Chunk<'a>>) -> ChunksIter<'a> {
810         ChunksIter { iter }
811     }
812 }
813 
814 impl<'a> Deref for ChunksIter<'a> {
815     type Target = core::slice::Iter<'a, Chunk<'a>>;
816 
deref(&self) -> &Self::Target817     fn deref(&self) -> &Self::Target {
818         &self.iter
819     }
820 }
821 
822 impl<'a> DerefMut for ChunksIter<'a> {
deref_mut(&mut self) -> &mut Self::Target823     fn deref_mut(&mut self) -> &mut Self::Target {
824         &mut self.iter
825     }
826 }
827 
828 impl ChunksIntoIter<'_> {
new(into_iter: std::vec::IntoIter<Chunk>) -> ChunksIntoIter829     fn new(into_iter: std::vec::IntoIter<Chunk>) -> ChunksIntoIter {
830         ChunksIntoIter { into_iter }
831     }
832 }
833 
834 impl<'a> Iterator for ChunksIntoIter<'a> {
835     type Item = Chunk<'a>;
836 
next(&mut self) -> Option<Self::Item>837     fn next(&mut self) -> Option<Self::Item> {
838         self.into_iter.next()
839     }
840 }
841 
842 impl<'a> Deref for ChunksIntoIter<'a> {
843     type Target = std::vec::IntoIter<Chunk<'a>>;
844 
deref(&self) -> &Self::Target845     fn deref(&self) -> &Self::Target {
846         &self.into_iter
847     }
848 }
849 
850 impl<'b> Chunks<'b> {
851     /// Returns an `ChunksIter`
iter(&self) -> ChunksIter852     pub fn iter(&self) -> ChunksIter {
853         ChunksIter::new(self.chunks.iter())
854     }
855 
new() -> Self856     fn new() -> Self {
857         Chunks { chunks: vec![] }
858     }
859 
push<'a: 'b>(&mut self, chunk: Chunk<'a>)860     fn push<'a: 'b>(&mut self, chunk: Chunk<'a>) {
861         self.chunks.push(chunk)
862     }
863 }
864 
865 impl<'a> IntoIterator for Chunks<'a> {
866     type Item = Chunk<'a>;
867     type IntoIter = ChunksIntoIter<'a>;
868 
into_iter(self) -> Self::IntoIter869     fn into_iter(self) -> Self::IntoIter {
870         ChunksIntoIter::new(self.chunks.into_iter())
871     }
872 }
873 
874 /// Chunk instance, Indicates a chunk.
875 /// After a decode, the `ChunkBodyDecoder` returns a `Chunk` regardless of
876 /// whether a chunk is completely decoded. The decode status is recorded by the
877 /// `state` variable.
878 #[derive(Debug, Eq, PartialEq)]
879 pub struct Chunk<'a> {
880     id: usize,
881     state: ChunkState,
882     size: usize,
883     extension: ChunkExt,
884     data: &'a [u8],
885     trailer: Option<&'a [u8]>,
886 }
887 
888 impl Chunk<'_> {
set_id(&mut self, id: usize)889     fn set_id(&mut self, id: usize) {
890         self.id = id;
891     }
892 
is_complete(&self) -> bool893     fn is_complete(&self) -> bool {
894         matches!(self.state, ChunkState::Finish)
895     }
896 
897     /// Get the id of chunk-data.
id(&self) -> usize898     pub fn id(&self) -> usize {
899         self.id
900     }
901 
902     /// Get the immutable reference of a state.
state(&self) -> &ChunkState903     pub fn state(&self) -> &ChunkState {
904         &self.state
905     }
906 
907     /// Get the size of chunk-data,
908     /// If the size part of a chunk is not completely decoded, the value of size
909     /// is 0.
size(&self) -> usize910     pub fn size(&self) -> usize {
911         self.size
912     }
913 
914     /// Get the immutable reference of chunk-ext.
915     /// Currently, only one empty ChunkExt is contained.
extension(&self) -> &ChunkExt916     pub fn extension(&self) -> &ChunkExt {
917         &self.extension
918     }
919 
920     /// Get the chunk-data.
921     /// When the state is partial, only partial data is returned.
data(&self) -> &[u8]922     pub fn data(&self) -> &[u8] {
923         self.data
924     }
925     /// Get the trailer.
trailer(&self) -> Option<&[u8]>926     pub fn trailer(&self) -> Option<&[u8]> {
927         self.trailer
928     }
929 }
930 
931 /// Chunk decoder.
932 /// The decoder decode only all chunks and last-chunk in chunk-body and does not
933 /// decode subsequent trailer-section. The decoder maintains a state saving
934 /// decode phase. When a chunk is not completely decoded or a decoding exception
935 /// occurs, the state is not reset.
936 pub struct ChunkBodyDecoder {
937     chunk_num: usize,
938     total_size: usize,
939     rest_size: usize,
940     hex_count: i64,
941     trailer: Vec<u8>,
942     cr_meet: bool,
943     chunk_flag: bool,
944     is_last_chunk: bool,
945     is_chunk_trailer: bool,
946     is_trailer: bool,
947     is_trailer_crlf: bool,
948     stage: Stage,
949 }
950 
951 impl Default for ChunkBodyDecoder {
default() -> Self952     fn default() -> Self {
953         Self::new()
954     }
955 }
956 
957 impl ChunkBodyDecoder {
958     /// Constructor of `ChunkBodyDecoder` bytes decoder.
959     /// Initial stage is `Size`
new() -> ChunkBodyDecoder960     pub fn new() -> ChunkBodyDecoder {
961         ChunkBodyDecoder {
962             chunk_num: 0,
963             total_size: 0,
964             rest_size: 0,
965             hex_count: 0,
966             trailer: vec![],
967             cr_meet: false,
968             chunk_flag: false,
969             is_last_chunk: false,
970             is_chunk_trailer: false,
971             is_trailer: false,
972             is_trailer_crlf: false,
973             stage: Stage::Size,
974         }
975     }
976 
977     /// Initial trailer settings for check whether body contain trailer.
contains_trailer(mut self, contain_trailer: bool) -> Self978     pub fn contains_trailer(mut self, contain_trailer: bool) -> Self {
979         self.is_trailer = contain_trailer;
980         self
981     }
982 
merge_trailer(&mut self, chunk: &Chunk)983     fn merge_trailer(&mut self, chunk: &Chunk) {
984         if chunk.state() == &ChunkState::Finish || chunk.state() == &ChunkState::DataCrlf {
985             self.trailer.extend_from_slice(chunk.trailer().unwrap());
986             if !self.trailer.is_empty() {
987                 self.trailer.extend_from_slice(b"\r\n");
988             }
989         } else {
990             self.trailer.extend_from_slice(chunk.trailer().unwrap());
991         }
992     }
993     /// Decode interface of the chunk decoder.
994     /// It transfers a u8 slice pointing to the chunk data and returns the data
995     /// of a chunk and the remaining data. When the data in the u8 slice is
996     /// not completely decoded for a chunk, An empty u8 slice is returned
997     /// for the remaining data.
998     ///
999     /// # Examples
1000     ///
1001     /// ```
1002     /// use ylong_http::body::{Chunk, ChunkBodyDecoder, ChunkExt, ChunkState};
1003     /// let mut decoder = ChunkBodyDecoder::new();
1004     /// let chunk_body_bytes = "\
1005     ///             5\r\n\
1006     ///             hello\r\n\
1007     ///             000; message = last\r\n\
1008     ///             \r\n\
1009     ///             "
1010     /// .as_bytes();
1011     /// let (chunks, rest) = decoder.decode(chunk_body_bytes).unwrap();
1012     /// assert_eq!(chunks.iter().len(), 2);
1013     /// let chunk = chunks.iter().next().unwrap();
1014     /// assert_eq!(
1015     ///     (
1016     ///         chunk.id(),
1017     ///         chunk.state(),
1018     ///         chunk.size(),
1019     ///         chunk.extension(),
1020     ///         chunk.data()
1021     ///     ),
1022     ///     (
1023     ///         0,
1024     ///         &ChunkState::Finish,
1025     ///         5,
1026     ///         &ChunkExt::new(),
1027     ///         "hello".as_bytes()
1028     ///     )
1029     /// );
1030     /// ```
decode<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunks<'a>, &'a [u8]), HttpError>1031     pub fn decode<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunks<'a>, &'a [u8]), HttpError> {
1032         let mut results = Chunks::new();
1033         let mut remains = buf;
1034         loop {
1035             let (mut chunk, rest) = match self.stage {
1036                 Stage::Size => self.decode_size(remains),
1037                 Stage::Extension => self.skip_extension(remains),
1038                 Stage::SizeEnd => self.skip_crlf(remains),
1039                 Stage::Data => self.decode_data(remains),
1040                 Stage::DataEnd => self.skip_last_crlf(&remains[..0], remains),
1041                 Stage::TrailerCrlf => self.skip_trailer_crlf(remains),
1042                 Stage::TrailerData => self.decode_trailer_data(remains),
1043                 Stage::TrailerEndCrlf => self.skip_trailer_last_crlf(&remains[..0], remains),
1044             }?;
1045 
1046             chunk.set_id(self.chunk_num);
1047 
1048             if chunk.trailer.is_some() {
1049                 self.merge_trailer(&chunk);
1050             }
1051 
1052             remains = rest;
1053             match (chunk.is_complete(), self.is_last_chunk) {
1054                 (false, _) => {
1055                     if self.is_chunk_trailer
1056                         && (chunk.state == ChunkState::Data || chunk.state == ChunkState::DataCrlf)
1057                     {
1058                         results.push(chunk);
1059                         self.chunk_num += 1;
1060                         if remains.is_empty() {
1061                             break;
1062                         }
1063                     } else {
1064                         results.push(chunk);
1065                         break;
1066                     }
1067                 }
1068                 (true, true) => {
1069                     results.push(chunk);
1070                     self.is_last_chunk = false;
1071                     self.chunk_num = 0;
1072                     break;
1073                 }
1074                 (true, false) => {
1075                     results.push(chunk);
1076                     self.chunk_num += 1;
1077                     if remains.is_empty() {
1078                         break;
1079                     }
1080                 }
1081             }
1082         }
1083         Ok((results, remains))
1084     }
1085 
1086     /// Get trailer headers.
get_trailer(&self) -> Result<Option<Headers>, HttpError>1087     pub fn get_trailer(&self) -> Result<Option<Headers>, HttpError> {
1088         if self.trailer.is_empty() {
1089             return Ok(None);
1090         }
1091 
1092         let mut colon = 0;
1093         let mut lf = 0;
1094         let mut trailer_header_name = HeaderName::from_bytes(b"")?;
1095         let mut trailer_headers = Headers::new();
1096         for (i, b) in self.trailer.iter().enumerate() {
1097             if *b == b' ' {
1098                 continue;
1099             }
1100 
1101             if *b == b':' {
1102                 colon = i;
1103                 if lf == 0 {
1104                     let trailer_name = &self.trailer[..colon];
1105                     trailer_header_name = HeaderName::from_bytes(trailer_name)?;
1106                 } else {
1107                     let trailer_name = &self.trailer[lf + 1..colon];
1108                     trailer_header_name = HeaderName::from_bytes(trailer_name)?;
1109                 }
1110                 continue;
1111             }
1112 
1113             if *b == b'\n' {
1114                 if &self.trailer[i - 2..i - 1] == "\n".as_bytes() {
1115                     break;
1116                 }
1117                 lf = i;
1118                 let trailer_value = &self.trailer[colon + 1..lf - 1];
1119                 let trailer_header_value = HeaderValue::from_bytes(trailer_value)?;
1120                 let _ = trailer_headers.insert::<HeaderName, HeaderValue>(
1121                     trailer_header_name.clone(),
1122                     trailer_header_value.clone(),
1123                 )?;
1124             }
1125         }
1126 
1127         Ok(Some(trailer_headers))
1128     }
1129 
hex_to_decimal(mut count: i64, num: i64) -> Result<i64, HttpError>1130     fn hex_to_decimal(mut count: i64, num: i64) -> Result<i64, HttpError> {
1131         count = count
1132             .checked_mul(16)
1133             .ok_or_else(|| HttpError::from(ErrorKind::InvalidInput))?;
1134         count
1135             .checked_add(num)
1136             .ok_or_else(|| HttpError::from(ErrorKind::InvalidInput))
1137     }
1138 
decode_size<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError>1139     fn decode_size<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError> {
1140         self.stage = Stage::Size;
1141         if buf.is_empty() {
1142             return Ok((
1143                 Chunk {
1144                     id: 0,
1145                     state: ChunkState::MetaSize,
1146                     size: self.total_size,
1147                     extension: ChunkExt::new(),
1148                     data: &buf[..0],
1149                     trailer: None,
1150                 },
1151                 buf,
1152             ));
1153         }
1154         self.chunk_flag = false;
1155         for (i, &b) in buf.iter().enumerate() {
1156             match b {
1157                 b'0' => {
1158                     if buf.len() <= i + 1 {
1159                         self.hex_count = Self::hex_to_decimal(self.hex_count, 0_i64)?;
1160                         continue;
1161                     }
1162                     if buf[i + 1] != b';' && buf[i + 1] != b' ' && buf[i + 1] != b'\r' {
1163                         self.hex_count = Self::hex_to_decimal(self.hex_count, 0_i64)?;
1164                         continue;
1165                     }
1166                     if self.is_trailer && !self.chunk_flag {
1167                         self.is_chunk_trailer = true;
1168                         return self.skip_extension(&buf[i..]);
1169                     } else {
1170                         self.hex_count = Self::hex_to_decimal(self.hex_count, 0_i64)?;
1171                         continue;
1172                     }
1173                 }
1174                 b'1'..=b'9' => {
1175                     self.hex_count = Self::hex_to_decimal(self.hex_count, b as i64 - '0' as i64)?;
1176                     self.chunk_flag = true;
1177                     continue;
1178                 }
1179 
1180                 b'a'..=b'f' => {
1181                     self.hex_count =
1182                         Self::hex_to_decimal(self.hex_count, b as i64 - 'a' as i64 + 10i64)?;
1183                     self.chunk_flag = true;
1184                     continue;
1185                 }
1186                 b'A'..=b'F' => {
1187                     self.hex_count =
1188                         Self::hex_to_decimal(self.hex_count, b as i64 - 'A' as i64 + 10i64)?;
1189                     self.chunk_flag = true;
1190                     continue;
1191                 }
1192                 b' ' | b'\t' | b';' | b'\r' | b'\n' => {
1193                     if self.is_chunk_trailer {
1194                         return self.skip_trailer_crlf(&buf[i..]);
1195                     } else {
1196                         self.total_size = self.hex_count as usize;
1197                         self.hex_count = 0;
1198                         // Decode to the last chunk
1199                         return if self.total_size == 0 {
1200                             self.is_last_chunk = true;
1201                             self.skip_extension(&buf[i..])
1202                         } else {
1203                             self.rest_size = self.total_size;
1204                             self.skip_extension(&buf[i..])
1205                         };
1206                     }
1207                 }
1208                 _ => return Err(ErrorKind::InvalidInput.into()),
1209             }
1210         }
1211         Ok((
1212             Chunk {
1213                 id: 0,
1214                 state: ChunkState::MetaSize,
1215                 size: self.total_size,
1216                 extension: ChunkExt::new(),
1217                 data: &buf[..0],
1218                 trailer: None,
1219             },
1220             &buf[buf.len()..],
1221         ))
1222     }
1223 
skip_extension<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError>1224     fn skip_extension<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError> {
1225         self.stage = Stage::Extension;
1226         if self.is_chunk_trailer {
1227             for (i, &b) in buf.iter().enumerate() {
1228                 match b {
1229                     b'\r' => {
1230                         if self.cr_meet {
1231                             return Err(ErrorKind::InvalidInput.into());
1232                         }
1233                         self.cr_meet = true;
1234                         return self.skip_trailer_crlf(&buf[i + 1..]);
1235                     }
1236                     b'\n' => {
1237                         if !self.cr_meet {
1238                             return Err(ErrorKind::InvalidInput.into());
1239                         }
1240                         self.cr_meet = false;
1241 
1242                         return self.skip_trailer_crlf(&buf[i..]);
1243                     }
1244                     _ => {}
1245                 }
1246             }
1247             Ok((
1248                 Chunk {
1249                     id: 0,
1250                     state: ChunkState::MetaExt,
1251                     size: self.total_size,
1252                     extension: ChunkExt::new(),
1253                     data: &buf[..0],
1254                     trailer: Some(&buf[..0]),
1255                 },
1256                 &buf[buf.len()..],
1257             ))
1258         } else {
1259             for (i, &b) in buf.iter().enumerate() {
1260                 match b {
1261                     b'\r' => {
1262                         if self.cr_meet {
1263                             return Err(ErrorKind::InvalidInput.into());
1264                         }
1265                         self.cr_meet = true;
1266                         return self.skip_crlf(&buf[i + 1..]);
1267                     }
1268                     b'\n' => {
1269                         if !self.cr_meet {
1270                             return Err(ErrorKind::InvalidInput.into());
1271                         }
1272                         self.cr_meet = false;
1273                         return self.skip_crlf(&buf[i..]);
1274                     }
1275                     _ => {}
1276                 }
1277             }
1278             Ok((
1279                 Chunk {
1280                     id: 0,
1281                     state: ChunkState::MetaExt,
1282                     size: self.total_size,
1283                     extension: ChunkExt::new(),
1284                     data: &buf[..0],
1285                     trailer: None,
1286                 },
1287                 &buf[buf.len()..],
1288             ))
1289         }
1290     }
1291 
skip_crlf<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError>1292     fn skip_crlf<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError> {
1293         self.stage = Stage::SizeEnd;
1294         for (i, &b) in buf.iter().enumerate() {
1295             match b {
1296                 b'\r' => {
1297                     if self.cr_meet {
1298                         // TODO Check whether the state machine needs to be reused after the parsing
1299                         // fails and whether the state machine status needs to be adjusted.
1300                         return Err(ErrorKind::InvalidInput.into());
1301                     }
1302                     self.cr_meet = true;
1303                 }
1304                 b'\n' => {
1305                     if !self.cr_meet {
1306                         return Err(ErrorKind::InvalidInput.into());
1307                     }
1308                     self.cr_meet = false;
1309                     return self.decode_data(&buf[i + 1..]);
1310                 }
1311                 _ => return Err(ErrorKind::InvalidInput.into()),
1312             }
1313         }
1314         Ok((
1315             Chunk {
1316                 id: 0,
1317                 state: ChunkState::MetaCrlf,
1318                 size: self.total_size,
1319                 extension: ChunkExt::new(),
1320                 data: &buf[..0],
1321                 trailer: None,
1322             },
1323             &buf[buf.len()..],
1324         ))
1325     }
1326 
skip_trailer_crlf<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError>1327     fn skip_trailer_crlf<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError> {
1328         self.stage = Stage::TrailerCrlf;
1329         for (i, &b) in buf.iter().enumerate() {
1330             match b {
1331                 b'\r' => {
1332                     if self.cr_meet {
1333                         return Err(ErrorKind::InvalidInput.into());
1334                     }
1335                     self.cr_meet = true;
1336                 }
1337                 b'\n' => {
1338                     if !self.cr_meet {
1339                         return Err(ErrorKind::InvalidInput.into());
1340                     }
1341                     self.cr_meet = false;
1342                     self.is_trailer_crlf = true;
1343                     return self.decode_trailer_data(&buf[i + 1..]);
1344                 }
1345                 _ => return Err(ErrorKind::InvalidInput.into()),
1346             }
1347         }
1348         Ok((
1349             Chunk {
1350                 id: 0,
1351                 state: ChunkState::MetaCrlf,
1352                 size: self.total_size,
1353                 extension: ChunkExt::new(),
1354                 data: &buf[..0],
1355                 trailer: Some(&buf[..0]),
1356             },
1357             &buf[buf.len()..],
1358         ))
1359     }
1360 
decode_trailer_data<'a>( &mut self, buf: &'a [u8], ) -> Result<(Chunk<'a>, &'a [u8]), HttpError>1361     fn decode_trailer_data<'a>(
1362         &mut self,
1363         buf: &'a [u8],
1364     ) -> Result<(Chunk<'a>, &'a [u8]), HttpError> {
1365         self.stage = Stage::TrailerData;
1366         if buf.is_empty() {
1367             return Ok((
1368                 Chunk {
1369                     id: 0,
1370                     state: ChunkState::Data,
1371                     size: 0,
1372                     extension: ChunkExt::new(),
1373                     data: &buf[..0],
1374                     trailer: Some(&buf[..0]),
1375                 },
1376                 &buf[buf.len()..],
1377             ));
1378         }
1379 
1380         if buf[0] == b'\r' && self.is_trailer_crlf {
1381             self.is_last_chunk = true;
1382         }
1383 
1384         for (i, &b) in buf.iter().enumerate() {
1385             match b {
1386                 b'\r' => {
1387                     if self.cr_meet {
1388                         return Err(ErrorKind::InvalidInput.into());
1389                     }
1390                     self.cr_meet = true;
1391                     return self.skip_trailer_last_crlf(&buf[..i], &buf[i + 1..]);
1392                 }
1393                 b'\n' => {
1394                     if !self.cr_meet {
1395                         return Err(ErrorKind::InvalidInput.into());
1396                     }
1397                     self.cr_meet = false;
1398                     return self.skip_trailer_last_crlf(&buf[..i], &buf[i..]);
1399                 }
1400                 _ => {}
1401             }
1402         }
1403         self.is_trailer_crlf = false;
1404         Ok((
1405             Chunk {
1406                 id: 0,
1407                 state: ChunkState::Data,
1408                 size: 0,
1409                 extension: ChunkExt::new(),
1410                 data: &buf[..0],
1411                 trailer: Some(buf),
1412             },
1413             &buf[buf.len()..],
1414         ))
1415     }
1416 
decode_data<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError>1417     fn decode_data<'a>(&mut self, buf: &'a [u8]) -> Result<(Chunk<'a>, &'a [u8]), HttpError> {
1418         self.stage = Stage::Data;
1419         if buf.is_empty() {
1420             return Ok((
1421                 Chunk {
1422                     id: 0,
1423                     state: ChunkState::Data,
1424                     size: self.total_size,
1425                     extension: ChunkExt::new(),
1426                     data: &buf[..0],
1427                     trailer: None,
1428                 },
1429                 &buf[buf.len()..],
1430             ));
1431         }
1432 
1433         let rest = self.rest_size;
1434         if buf.len() >= rest {
1435             self.rest_size = 0;
1436             self.cr_meet = false;
1437             self.skip_last_crlf(&buf[..rest], &buf[rest..])
1438         } else {
1439             self.rest_size -= buf.len();
1440             Ok((
1441                 Chunk {
1442                     id: 0,
1443                     state: ChunkState::Data,
1444                     size: self.total_size,
1445                     extension: ChunkExt::new(),
1446                     data: buf,
1447                     trailer: None,
1448                 },
1449                 &buf[buf.len()..],
1450             ))
1451         }
1452     }
1453 
skip_trailer_last_crlf<'a>( &mut self, data: &'a [u8], buf: &'a [u8], ) -> Result<(Chunk<'a>, &'a [u8]), HttpError>1454     fn skip_trailer_last_crlf<'a>(
1455         &mut self,
1456         data: &'a [u8],
1457         buf: &'a [u8],
1458     ) -> Result<(Chunk<'a>, &'a [u8]), HttpError> {
1459         self.stage = Stage::TrailerEndCrlf;
1460         for (i, &b) in buf.iter().enumerate() {
1461             match b {
1462                 b'\r' => {
1463                     if self.cr_meet {
1464                         return Err(ErrorKind::InvalidInput.into());
1465                     }
1466                     self.cr_meet = true;
1467                 }
1468                 b'\n' => {
1469                     if !self.cr_meet {
1470                         return Err(ErrorKind::InvalidInput.into());
1471                     }
1472                     self.cr_meet = false;
1473                     return if self.is_last_chunk {
1474                         self.stage = Stage::TrailerEndCrlf;
1475                         Ok((
1476                             Chunk {
1477                                 id: 0,
1478                                 state: ChunkState::Finish,
1479                                 size: 0,
1480                                 extension: ChunkExt::new(),
1481                                 data: &buf[..0],
1482                                 trailer: Some(&buf[..0]),
1483                             },
1484                             &buf[i + 1..],
1485                         ))
1486                     } else {
1487                         self.cr_meet = false;
1488                         self.is_trailer_crlf = true;
1489                         self.stage = Stage::TrailerData;
1490                         let complete_chunk = Chunk {
1491                             id: 0,
1492                             state: ChunkState::DataCrlf,
1493                             size: 0,
1494                             extension: ChunkExt::new(),
1495                             data: &data[..0],
1496                             trailer: Some(data),
1497                         };
1498                         return Ok((complete_chunk, &buf[i + 1..]));
1499                     };
1500                 }
1501                 _ => return Err(ErrorKind::InvalidInput.into()),
1502             }
1503         }
1504 
1505         Ok((
1506             Chunk {
1507                 id: 0,
1508                 state: ChunkState::DataCrlf,
1509                 size: 0,
1510                 extension: ChunkExt::new(),
1511                 data: &data[..0],
1512                 trailer: Some(data),
1513             },
1514             &buf[buf.len()..],
1515         ))
1516     }
1517 
skip_last_crlf<'a>( &mut self, data: &'a [u8], buf: &'a [u8], ) -> Result<(Chunk<'a>, &'a [u8]), HttpError>1518     fn skip_last_crlf<'a>(
1519         &mut self,
1520         data: &'a [u8],
1521         buf: &'a [u8],
1522     ) -> Result<(Chunk<'a>, &'a [u8]), HttpError> {
1523         self.stage = Stage::DataEnd;
1524         for (i, &b) in buf.iter().enumerate() {
1525             match b {
1526                 b'\r' => {
1527                     if self.cr_meet {
1528                         return Err(ErrorKind::InvalidInput.into());
1529                     }
1530                     self.cr_meet = true;
1531                 }
1532                 b'\n' => {
1533                     if !self.cr_meet {
1534                         return Err(ErrorKind::InvalidInput.into());
1535                     }
1536                     self.cr_meet = false;
1537                     self.stage = Stage::Size;
1538                     let complete_chunk = Chunk {
1539                         id: 0,
1540                         state: ChunkState::Finish,
1541                         size: self.total_size,
1542                         extension: ChunkExt::new(),
1543                         data,
1544                         trailer: None,
1545                     };
1546                     self.total_size = 0;
1547                     return Ok((complete_chunk, &buf[i + 1..]));
1548                 }
1549                 _ => return Err(ErrorKind::InvalidInput.into()),
1550             }
1551         }
1552         Ok((
1553             Chunk {
1554                 id: 0,
1555                 state: ChunkState::DataCrlf,
1556                 size: self.total_size,
1557                 extension: ChunkExt::new(),
1558                 data,
1559                 trailer: None,
1560             },
1561             &buf[buf.len()..],
1562         ))
1563     }
1564 }
1565 
1566 #[cfg(test)]
1567 mod ut_chunk {
1568     use crate::body::chunk::ChunkBody;
1569     use crate::body::sync_impl::Body;
1570     use crate::body::{async_impl, Chunk, ChunkBodyDecoder, ChunkExt, ChunkState, Chunks};
1571     use crate::error::ErrorKind;
1572     use crate::headers::Headers;
1573 
data_message() -> Vec<u8>1574     fn data_message() -> Vec<u8> {
1575         let mut vec = Vec::new();
1576         for i in 0..=10 {
1577             vec.extend_from_slice(&[i % 10; 100]);
1578         }
1579         vec
1580     }
1581 
res_message() -> Vec<u8>1582     fn res_message() -> Vec<u8> {
1583         let mut res = b"400\r\n".to_vec();
1584         for i in 0..=9 {
1585             res.extend_from_slice(&[i % 10; 100]);
1586         }
1587         res.extend_from_slice(&[0; 24]);
1588         res.extend_from_slice(b"\r\n4c\r\n");
1589         res.extend_from_slice(&[0; 76]);
1590         res.extend_from_slice(b"\r\n0\r\n\r\n");
1591         res
1592     }
res_trailer_message() -> Vec<u8>1593     fn res_trailer_message() -> Vec<u8> {
1594         let mut res = b"400\r\n".to_vec();
1595         for i in 0..=9 {
1596             res.extend_from_slice(&[i % 10; 100]);
1597         }
1598         res.extend_from_slice(&[0; 24]);
1599         res.extend_from_slice(b"\r\n4c\r\n");
1600         res.extend_from_slice(&[0; 76]);
1601         res.extend_from_slice(b"\r\n0\r\n");
1602         res.extend_from_slice(b"accept:text/html\r\n");
1603         res.extend_from_slice(b"\r\n");
1604         res
1605     }
1606 
1607     /// UT test cases for `ChunkBody::set_trailer`.
1608     ///
1609     /// # Brief
1610     /// 1. Creates a `ChunkBody` by calling `ChunkBody::set_trailer`.
1611     /// 2. Encodes chunk body by calling `ChunkBody::data`
1612     /// 3. Checks if the test result is correct.
1613     #[test]
ut_chunk_body_encode_trailer_0()1614     fn ut_chunk_body_encode_trailer_0() {
1615         let mut headers = Headers::new();
1616         let _ = headers.insert("accept", "text/html");
1617         let content = data_message();
1618         let mut task = ChunkBody::from_bytes(content.as_slice()).set_trailer(headers);
1619         let mut user_slice = [0_u8; 20];
1620         let mut output_vec = vec![];
1621         let mut size = user_slice.len();
1622         while size == user_slice.len() {
1623             size = task.data(user_slice.as_mut_slice()).unwrap();
1624             output_vec.extend_from_slice(&user_slice[..size]);
1625         }
1626         assert_eq!(output_vec, res_trailer_message());
1627     }
1628 
1629     /// UT test cases for `ChunkBody::data`.
1630     ///
1631     /// # Brief
1632     /// 1. Creates a `ChunkBody` by calling `ChunkBody::from_bytes`.
1633     /// 2. Encodes chunk body by calling `ChunkBody::data`
1634     /// 3. Checks if the test result is correct.
1635     #[test]
ut_chunk_body_encode_0()1636     fn ut_chunk_body_encode_0() {
1637         let content = data_message();
1638         let mut task = ChunkBody::from_bytes(content.as_slice());
1639         let mut user_slice = [0_u8; 20];
1640         let mut output_vec = vec![];
1641 
1642         let mut size = user_slice.len();
1643         while size == user_slice.len() {
1644             size = task.data(user_slice.as_mut_slice()).unwrap();
1645             output_vec.extend_from_slice(&user_slice[..size]);
1646         }
1647         assert_eq!(output_vec, res_message());
1648     }
1649 
1650     /// UT test cases for `ChunkBody::data`.
1651     ///
1652     /// # Brief
1653     /// 1. Creates a `ChunkBody` by calling `ChunkBody::from_reader`.
1654     /// 2. Encodes chunk body by calling `ChunkBody::data`
1655     /// 3. Checks if the test result is correct.
1656     #[test]
ut_chunk_body_encode_1()1657     fn ut_chunk_body_encode_1() {
1658         let content = data_message();
1659         let mut task = ChunkBody::from_reader(content.as_slice());
1660         let mut user_slice = [0_u8; 20];
1661         let mut output_vec = vec![];
1662 
1663         let mut size = user_slice.len();
1664         while size == user_slice.len() {
1665             size = task.data(user_slice.as_mut_slice()).unwrap();
1666             output_vec.extend_from_slice(&user_slice[..size]);
1667         }
1668         assert_eq!(output_vec, res_message());
1669     }
1670 
1671     /// UT test cases for `ChunkBody::data` in async condition.
1672     ///
1673     /// # Brief
1674     /// 1. Creates a `ChunkBody` by calling `ChunkBody::from_bytes`.
1675     /// 2. Encodes chunk body by calling `async_impl::Body::data`
1676     /// 3. Checks if the test result is correct.
1677     #[cfg(feature = "ylong_base")]
1678     #[test]
ut_asnyc_chunk_body_encode_0()1679     fn ut_asnyc_chunk_body_encode_0() {
1680         let handle = ylong_runtime::spawn(async move {
1681             asnyc_chunk_body_encode_0().await;
1682         });
1683         ylong_runtime::block_on(handle).unwrap();
1684     }
1685 
1686     #[cfg(feature = "ylong_base")]
asnyc_chunk_body_encode_0()1687     async fn asnyc_chunk_body_encode_0() {
1688         let content = data_message();
1689         let mut task = ChunkBody::from_bytes(content.as_slice());
1690         let mut user_slice = [0_u8; 20];
1691         let mut output_vec = vec![];
1692 
1693         let mut size = user_slice.len();
1694         while size == user_slice.len() {
1695             size = async_impl::Body::data(&mut task, user_slice.as_mut_slice())
1696                 .await
1697                 .unwrap();
1698             output_vec.extend_from_slice(&user_slice[..size]);
1699         }
1700         assert_eq!(output_vec, res_message());
1701     }
1702 
1703     /// UT test cases for `ChunkBody::data` in async condition.
1704     ///
1705     /// # Brief
1706     /// 1. Creates a `ChunkBody` by calling `ChunkBody::from_async_reader`.
1707     /// 2. Encodes chunk body by calling `async_impl::Body::data`
1708     /// 3. Checks if the test result is correct.
1709     #[cfg(feature = "ylong_base")]
1710     #[test]
ut_asnyc_chunk_body_encode_1()1711     fn ut_asnyc_chunk_body_encode_1() {
1712         let handle = ylong_runtime::spawn(async move {
1713             asnyc_chunk_body_encode_1().await;
1714         });
1715         ylong_runtime::block_on(handle).unwrap();
1716     }
1717 
1718     #[cfg(feature = "ylong_base")]
asnyc_chunk_body_encode_1()1719     async fn asnyc_chunk_body_encode_1() {
1720         let content = data_message();
1721         let mut task = ChunkBody::from_async_reader(content.as_slice());
1722         let mut user_slice = [0_u8; 1024];
1723         let mut output_vec = vec![];
1724 
1725         let mut size = user_slice.len();
1726         while size == user_slice.len() {
1727             size = async_impl::Body::data(&mut task, user_slice.as_mut_slice())
1728                 .await
1729                 .unwrap();
1730             output_vec.extend_from_slice(&user_slice[..size]);
1731         }
1732         assert_eq!(output_vec, res_message());
1733     }
1734 
1735     /// UT test cases for `ChunkBodyDecoder::decode`.
1736     ///
1737     /// # Brief
1738     /// 1. Creates a `ChunkBodyDecoder` by calling `ChunkBodyDecoder::new`.
1739     /// 2. Decodes chunk body by calling `ChunkBodyDecoder::decode`
1740     /// 3. Checks if the test result is correct.
1741     #[test]
ut_chunk_body_decode_0()1742     fn ut_chunk_body_decode_0() {
1743         let mut decoder = ChunkBodyDecoder::new().contains_trailer(true);
1744         let chunk_body_bytes = "\
1745             5\r\n\
1746             hello\r\n\
1747             C ; type = text ;end = !\r\n\
1748             hello world!\r\n\
1749             000; message = last\r\n\
1750             Trailer: value\r\n\
1751             another-trainer: another-value\r\n\
1752             \r\n\
1753             "
1754         .as_bytes();
1755         // 5
1756         let res = decoder.decode(&chunk_body_bytes[..1]);
1757         let mut chunks = Chunks::new();
1758         chunks.push(Chunk {
1759             id: 0,
1760             state: ChunkState::MetaSize,
1761             size: 0,
1762             extension: ChunkExt::new(),
1763             data: &[] as &[u8],
1764             trailer: None,
1765         });
1766         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1767         // 5\r
1768         let res = decoder.decode(&chunk_body_bytes[1..2]);
1769         let mut chunks = Chunks::new();
1770         chunks.push(Chunk {
1771             id: 0,
1772             state: ChunkState::MetaCrlf,
1773             size: 5,
1774             extension: ChunkExt::new(),
1775             data: &[] as &[u8],
1776             trailer: None,
1777         });
1778         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1779         // 5\r
1780         let res = decoder.decode(&chunk_body_bytes[2..2]);
1781         let mut chunks = Chunks::new();
1782         chunks.push(Chunk {
1783             id: 0,
1784             state: ChunkState::MetaCrlf,
1785             size: 5,
1786             extension: ChunkExt::new(),
1787             data: &[] as &[u8],
1788             trailer: None,
1789         });
1790         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1791         // 5\r\n
1792         let res = decoder.decode(&chunk_body_bytes[2..3]);
1793         let mut chunks = Chunks::new();
1794         chunks.push(Chunk {
1795             id: 0,
1796             state: ChunkState::Data,
1797             size: 5,
1798             extension: ChunkExt::new(),
1799             data: &[] as &[u8],
1800             trailer: None,
1801         });
1802         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1803 
1804         // 5\r\nhe
1805         let res = decoder.decode(&chunk_body_bytes[3..5]);
1806         let mut chunks = Chunks::new();
1807         chunks.push(Chunk {
1808             id: 0,
1809             state: ChunkState::Data,
1810             size: 5,
1811             extension: ChunkExt::new(),
1812             data: "he".as_bytes(),
1813             trailer: None,
1814         });
1815         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1816 
1817         // 5\r\nhello\r
1818         let res = decoder.decode(&chunk_body_bytes[5..9]);
1819         let mut chunks = Chunks::new();
1820         chunks.push(Chunk {
1821             id: 0,
1822             state: ChunkState::DataCrlf,
1823             size: 5,
1824             extension: ChunkExt::new(),
1825             data: "llo".as_bytes(),
1826             trailer: None,
1827         });
1828         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1829 
1830         // 5\r\nhello\r
1831         let res = decoder.decode(&chunk_body_bytes[9..9]);
1832         let mut chunks = Chunks::new();
1833         chunks.push(Chunk {
1834             id: 0,
1835             state: ChunkState::DataCrlf,
1836             size: 5,
1837             extension: ChunkExt::new(),
1838             data: &[] as &[u8],
1839             trailer: None,
1840         });
1841         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1842 
1843         // 5\r\nhello\r\n
1844         let res = decoder.decode(&chunk_body_bytes[9..10]);
1845         let mut chunks = Chunks::new();
1846         chunks.push(Chunk {
1847             id: 0,
1848             state: ChunkState::Finish,
1849             size: 5,
1850             extension: ChunkExt::new(),
1851             data: &[] as &[u8],
1852             trailer: None,
1853         });
1854         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1855 
1856         // 5\r\nhello\r\nC ;
1857         let res = decoder.decode(&chunk_body_bytes[10..13]);
1858         let mut chunks = Chunks::new();
1859         chunks.push(Chunk {
1860             id: 1,
1861             state: ChunkState::MetaExt,
1862             size: 12,
1863             extension: ChunkExt::new(),
1864             data: &[] as &[u8],
1865             trailer: None,
1866         });
1867         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1868 
1869         // 5\r\nhello\r\nC ; type = text ;
1870         let res = decoder.decode(&chunk_body_bytes[13..27]);
1871         let mut chunks = Chunks::new();
1872         chunks.push(Chunk {
1873             id: 1,
1874             state: ChunkState::MetaExt,
1875             size: 12,
1876             extension: ChunkExt::new(),
1877             data: &[] as &[u8],
1878             trailer: None,
1879         });
1880         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1881 
1882         // 5\r\nhello\r\nC ; type = text ;end = !\r\n
1883         let res = decoder.decode(&chunk_body_bytes[27..36]);
1884         let mut chunks = Chunks::new();
1885         chunks.push(Chunk {
1886             id: 1,
1887             state: ChunkState::Data,
1888             size: 12,
1889             extension: ChunkExt::new(),
1890             data: &[] as &[u8],
1891             trailer: None,
1892         });
1893         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1894 
1895         // 5\r\nhello\r\nC ; type = text ;end = !\r\nhello world!\r\n
1896         let res = decoder.decode(&chunk_body_bytes[36..50]);
1897         let mut chunks = Chunks::new();
1898         chunks.push(Chunk {
1899             id: 1,
1900             state: ChunkState::Finish,
1901             size: 12,
1902             extension: ChunkExt::new(),
1903             data: "hello world!".as_bytes(),
1904             trailer: None,
1905         });
1906         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1907 
1908         // 5\r\nhello\r\nC ; type = text ;end = !\r\nhello world!\r\n0
1909         let res = decoder.decode(&chunk_body_bytes[50..51]);
1910         let mut chunks = Chunks::new();
1911         chunks.push(Chunk {
1912             id: 2,
1913             state: ChunkState::MetaSize,
1914             size: 0,
1915             extension: ChunkExt::new(),
1916             data: &[] as &[u8],
1917             trailer: None,
1918         });
1919         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1920 
1921         // 5\r\nhello\r\nC ; type = text ;end = !\r\nhello world!\r\n000;
1922         let res = decoder.decode(&chunk_body_bytes[51..54]);
1923         let mut chunks = Chunks::new();
1924         chunks.push(Chunk {
1925             id: 2,
1926             state: ChunkState::MetaExt,
1927             size: 0,
1928             extension: ChunkExt::new(),
1929             data: &[] as &[u8],
1930             trailer: Some(&[] as &[u8]),
1931         });
1932         assert_eq!(res, Ok((chunks, &[] as &[u8],)));
1933 
1934         // 5\r\nhello\r\nC ; type = text ;end = !\r\nhello world!\r\n000; message =
1935         // last\r\n
1936         let res = decoder.decode(&chunk_body_bytes[54..71]);
1937         let mut chunks = Chunks::new();
1938         chunks.push(Chunk {
1939             id: 2,
1940             state: ChunkState::Data,
1941             size: 0,
1942             extension: ChunkExt::new(),
1943             data: &[] as &[u8],
1944             trailer: Some(&[] as &[u8]),
1945         });
1946         assert_eq!(res, Ok((chunks, &[] as &[u8])));
1947         // 5\r\nhello\r\nC ; type = text ;end = !\r\nhello world!\r\n000; message =
1948         // last\r\nTrailer: value\r\n
1949         let res = decoder.decode(&chunk_body_bytes[71..87]);
1950         let mut chunks = Chunks::new();
1951         chunks.push(Chunk {
1952             id: 3,
1953             state: ChunkState::DataCrlf,
1954             size: 0,
1955             extension: ChunkExt::new(),
1956             data: &[] as &[u8],
1957             trailer: Some("Trailer: value".as_bytes()),
1958         });
1959         assert_eq!(res, Ok((chunks, &[] as &[u8])));
1960         // 5\r\nhello\r\nC ; type = text ;end = !\r\nhello world!\r\n000;
1961         // message = last\r\nTrailer: value\r\n\another-trainer: another-value\r\n\
1962         let res = decoder.decode(&chunk_body_bytes[87..119]);
1963         let mut chunks = Chunks::new();
1964         chunks.push(Chunk {
1965             id: 4,
1966             state: ChunkState::DataCrlf,
1967             size: 0,
1968             extension: ChunkExt::new(),
1969             data: &[] as &[u8],
1970             trailer: Some("another-trainer: another-value".as_bytes()),
1971         });
1972         assert_eq!(res, Ok((chunks, &[] as &[u8])));
1973         // 5\r\nhello\r\nC ; type = text ;end = !\r\nhello world!\r\n000;
1974         // message = last\r\nTrailer: value\r\n\another-trainer: another-value\r\n\r\n\
1975         let res = decoder.decode(&chunk_body_bytes[119..121]);
1976         let mut chunks = Chunks::new();
1977         chunks.push(Chunk {
1978             id: 5,
1979             state: ChunkState::Finish,
1980             size: 0,
1981             extension: ChunkExt::new(),
1982             data: &[] as &[u8],
1983             trailer: Some(&[] as &[u8]),
1984         });
1985         assert_eq!(res, Ok((chunks, &[] as &[u8])));
1986     }
1987 
1988     /// UT test cases for `ChunkBodyDecoder::decode`.
1989     ///
1990     /// # Brief
1991     /// 1. Creates a `ChunkBodyDecoder` by calling `ChunkBodyDecoder::new`.
1992     /// 2. Decodes chunk body by calling `ChunkBodyDecoder::decode`
1993     /// 3. Checks if the test result is correct.
1994     #[test]
ut_chunk_body_decode_1()1995     fn ut_chunk_body_decode_1() {
1996         let mut decoder = ChunkBodyDecoder::new();
1997         let chunk_body_bytes = "\
1998             5\r\n\
1999             hello\r\n\
2000             C ; type = text ;end = !\r\n\
2001             hello world!\r\n\
2002             000; message = last\r\n\
2003             \r\n\
2004             "
2005         .as_bytes();
2006 
2007         // 5
2008         let (chunks, remaining) = decoder.decode(chunk_body_bytes).unwrap();
2009         let mut iter = chunks.iter();
2010         let chunk = Chunk {
2011             id: 0,
2012             state: ChunkState::Finish,
2013             size: 5,
2014             extension: ChunkExt::new(),
2015             data: "hello".as_bytes(),
2016             trailer: None,
2017         };
2018         assert_eq!(iter.next(), Some(&chunk));
2019         let chunk = Chunk {
2020             id: 1,
2021             state: ChunkState::Finish,
2022             size: 12,
2023             extension: ChunkExt::new(),
2024             data: "hello world!".as_bytes(),
2025             trailer: None,
2026         };
2027         assert_eq!(iter.next(), Some(&chunk));
2028         let chunk = Chunk {
2029             id: 2,
2030             state: ChunkState::Finish,
2031             size: 0,
2032             extension: ChunkExt::new(),
2033             data: &[] as &[u8],
2034             trailer: None,
2035         };
2036         assert_eq!(iter.next(), Some(&chunk));
2037         assert_eq!(iter.next(), None);
2038         assert_eq!(remaining, "".as_bytes());
2039     }
2040 
2041     /// UT test cases for `ChunkBodyDecoder::decode`.
2042     ///
2043     /// # Brief
2044     /// 1. Creates a `ChunkBodyDecoder` by calling `ChunkBodyDecoder::new`.
2045     /// 2. Decodes chunk body by calling `ChunkBodyDecoder::decode`
2046     /// 3. Checks if the test result is correct.
2047     #[test]
ut_chunk_body_decode_2()2048     fn ut_chunk_body_decode_2() {
2049         let mut decoder = ChunkBodyDecoder::new();
2050         let chunk_body_bytes = "\
2051             5\r\n\
2052             hello\r\n\
2053             C ; type = text ;end = !\r\n\
2054             hello world!\r\n\
2055             000; message = last\r\n\
2056             \r\n\
2057             "
2058         .as_bytes();
2059 
2060         // 5
2061         let (chunks, remaining) = decoder.decode(chunk_body_bytes).unwrap();
2062         let mut iter = chunks.into_iter();
2063         let chunk = Chunk {
2064             id: 0,
2065             state: ChunkState::Finish,
2066             size: 5,
2067             extension: ChunkExt::new(),
2068             data: "hello".as_bytes(),
2069             trailer: None,
2070         };
2071         assert_eq!(iter.next(), Some(chunk));
2072         let chunk = Chunk {
2073             id: 1,
2074             state: ChunkState::Finish,
2075             size: 12,
2076             extension: ChunkExt::new(),
2077             data: "hello world!".as_bytes(),
2078             trailer: None,
2079         };
2080         assert_eq!(iter.next(), Some(chunk));
2081         let chunk = Chunk {
2082             id: 2,
2083             state: ChunkState::Finish,
2084             size: 0,
2085             extension: ChunkExt::new(),
2086             data: &[] as &[u8],
2087             trailer: None,
2088         };
2089         assert_eq!(iter.next(), Some(chunk));
2090         assert_eq!(iter.next(), None);
2091         assert_eq!(remaining, "".as_bytes());
2092     }
2093 
2094     /// UT test cases for `ChunkBodyDecoder::decode`.
2095     ///
2096     /// # Brief
2097     /// 1. Creates a `ChunkBodyDecoder` by calling `ChunkBodyDecoder::new`.
2098     /// 2. Decodes chunk body by calling `ChunkBodyDecoder::decode`
2099     /// 3. Checks if the test result is correct.
2100     #[test]
ut_chunk_body_decode_3()2101     fn ut_chunk_body_decode_3() {
2102         let chunk_body_bytes = "\
2103             5 ; type = text ;end = !\r\n\
2104             hello world!\r\n\
2105             000; message = last\r\n\
2106             \r\n\
2107             "
2108         .as_bytes();
2109         let mut decoder = ChunkBodyDecoder::new();
2110 
2111         // 5
2112         let res = decoder.decode(chunk_body_bytes);
2113         assert_eq!(res, Err(ErrorKind::InvalidInput.into()));
2114     }
2115 
2116     /// UT test cases for `ChunkBodyDecoder::decode`.
2117     ///
2118     /// # Brief
2119     /// 1. Creates a `ChunkBodyDecoder` by calling `ChunkBodyDecoder::new`.
2120     /// 2. Decodes chunk body by calling `ChunkBodyDecoder::decode`
2121     /// 3. Checks if the test result is correct.
2122     #[test]
ut_chunk_body_decode_4()2123     fn ut_chunk_body_decode_4() {
2124         let chunk_body_bytes = "\
2125             C ; type = text ;end = !\r\r\n\
2126             hello world!\r\n\
2127             000; message = last\r\n\
2128             Trailer: value\r\n\
2129             another-trainer: another-value\r\n\
2130             \r\n\
2131             "
2132         .as_bytes();
2133         let mut decoder = ChunkBodyDecoder::new();
2134 
2135         // 5
2136         let res = decoder.decode(chunk_body_bytes);
2137         assert_eq!(res, Err(ErrorKind::InvalidInput.into()));
2138     }
2139 
2140     /// UT test cases for `ChunkBodyDecoder::decode`.
2141     ///
2142     /// # Brief
2143     /// 1. Creates a `ChunkBodyDecoder` by calling `ChunkBodyDecoder::new`.
2144     /// 2. Decodes chunk body by calling `ChunkBodyDecoder::decode`
2145     /// 3. Checks if the test result is correct.
2146     #[test]
ut_chunk_body_decode_5()2147     fn ut_chunk_body_decode_5() {
2148         let chunk_body_bytes = " C ; type = text ;end = !\r\n\
2149             hello world!\r\n\
2150             000; message = last\r\n\
2151             Trailer: value\r\n\
2152             another-trainer: another-value\r\n\
2153             \r\n\
2154             "
2155         .as_bytes();
2156         let mut decoder = ChunkBodyDecoder::new();
2157         // 5
2158         let res = decoder.decode(chunk_body_bytes);
2159         assert_eq!(res, Err(ErrorKind::InvalidInput.into()));
2160     }
2161 
2162     /// UT test cases for `ChunkBodyDecoder::decode`.
2163     ///
2164     /// # Brief
2165     /// 1. Creates a `ChunkBodyDecoder` by calling `ChunkBodyDecoder::new`.
2166     /// 2. Decodes chunk body by calling `ChunkBodyDecoder::decode`
2167     /// 3. Checks if the test result is correct.
2168     #[test]
ut_chunk_body_decode_6()2169     fn ut_chunk_body_decode_6() {
2170         let mut decoder = ChunkBodyDecoder::new();
2171         let chunk_body_bytes = "\
2172             5\r\n\
2173             hello\r\n\
2174             C ; type = text ;end = !\r\n\
2175             hello world!\r\n\
2176             000; message = last\r\n\
2177             \r\n\
2178             "
2179         .as_bytes();
2180 
2181         // 5
2182         let (chunks, _) = decoder.decode(chunk_body_bytes).unwrap();
2183         assert_eq!(chunks.iter().len(), 3);
2184         let chunk = chunks.iter().next().unwrap();
2185         assert_eq!(
2186             (
2187                 chunk.id(),
2188                 chunk.state(),
2189                 chunk.size(),
2190                 chunk.extension(),
2191                 chunk.data()
2192             ),
2193             (
2194                 0,
2195                 &ChunkState::Finish,
2196                 5,
2197                 &ChunkExt::new(),
2198                 "hello".as_bytes()
2199             )
2200         );
2201     }
2202 
2203     /// UT test cases for `ChunkBodyDecoder::decode`.
2204     ///
2205     /// # Brief
2206     /// 1. Creates a `ChunkBodyDecoder` by calling `ChunkBodyDecoder::new`.
2207     /// 2. Decodes chunk body by calling `ChunkBodyDecoder::decode`
2208     /// 3. Checks if the test result is correct.
2209     #[test]
ut_chunk_body_decode_7()2210     fn ut_chunk_body_decode_7() {
2211         let mut decoder = ChunkBodyDecoder::new().contains_trailer(true);
2212         let buf = b"010\r\nAAAAAAAAAAAAAAAA\r\n0\r\ntrailer:value\r\n\r\n";
2213         let res = decoder.decode(&buf[0..23]); // 010\r\nAAAAAAAAAAAAAAAA\r\n
2214         let mut chunks = Chunks::new();
2215         chunks.push(Chunk {
2216             id: 0,
2217             state: ChunkState::Finish,
2218             size: 16,
2219             extension: ChunkExt::new(),
2220             data: "AAAAAAAAAAAAAAAA".as_bytes(),
2221             trailer: None,
2222         });
2223         assert_eq!(res, Ok((chunks, &[] as &[u8])));
2224 
2225         let res = decoder.decode(&buf[23..39]); // 0\r\ntrailer:value
2226         let mut chunks = Chunks::new();
2227         chunks.push(Chunk {
2228             id: 1,
2229             state: ChunkState::Data,
2230             size: 0,
2231             extension: ChunkExt::new(),
2232             data: &[] as &[u8],
2233             trailer: Some("trailer:value".as_bytes()),
2234         });
2235         assert_eq!(res, Ok((chunks, &[] as &[u8])));
2236 
2237         let res = decoder.decode(&buf[39..41]); //\r\n
2238         let mut chunks = Chunks::new();
2239         chunks.push(Chunk {
2240             id: 2,
2241             state: ChunkState::DataCrlf,
2242             size: 0,
2243             extension: ChunkExt::new(),
2244             data: &[] as &[u8],
2245             trailer: Some(&[] as &[u8]),
2246         });
2247         assert_eq!(res, Ok((chunks, &[] as &[u8])));
2248 
2249         let res = decoder.decode(&buf[41..]); //\r\n
2250         let mut chunks = Chunks::new();
2251         chunks.push(Chunk {
2252             id: 3,
2253             state: ChunkState::Finish,
2254             size: 0,
2255             extension: ChunkExt::new(),
2256             data: &[] as &[u8],
2257             trailer: Some(&[] as &[u8]),
2258         });
2259         assert_eq!(res, Ok((chunks, &[] as &[u8])));
2260 
2261         let trailer_headers = decoder.get_trailer().unwrap().unwrap();
2262         let value = trailer_headers.get("trailer");
2263         assert_eq!(value.unwrap().to_str().unwrap(), "value");
2264     }
2265 }
2266