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