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