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::cmp::Ordering; 15 16 use crate::h2::error::ErrorCode; 17 use crate::h2::hpack::integer::IntegerDecoder; 18 use crate::h2::hpack::representation::{Name, PrefixBit, Representation}; 19 use crate::h2::H2Error; 20 use crate::huffman::HuffmanDecoder; 21 22 /// Decoder implementation for decoding representation. Every time users call 23 /// `decode`, the `ReprDecoder` will try to decode a `Repr`. If `buf` has been 24 /// fully decoded and users continue to call `decode`, it will return `None`. 25 /// Users need to save intermediate results in time. 26 pub(crate) struct ReprDecoder<'a> { 27 /// `buf` represents the byte stream to be decoded. 28 buf: &'a [u8], 29 /// `state` represents the remaining state after the last call to `decode`. 30 state: Option<ReprDecodeState>, 31 } 32 33 impl<'a> ReprDecoder<'a> { 34 /// Creates a new `ReprDecoder` whose `state` is `None`. new(buf: &'a [u8]) -> Self35 pub(crate) fn new(buf: &'a [u8]) -> Self { 36 Self { buf, state: None } 37 } 38 39 /// Loads state from a holder. load(&mut self, holder: &mut ReprDecStateHolder)40 pub(crate) fn load(&mut self, holder: &mut ReprDecStateHolder) { 41 self.state = holder.state.take(); 42 } 43 44 /// Decodes `self.buf`. Every time users call `decode`, it will try to 45 /// decode a `Representation`. decode(&mut self) -> Result<Option<Representation>, H2Error>46 pub(crate) fn decode(&mut self) -> Result<Option<Representation>, H2Error> { 47 // If buf is empty, leave the state unchanged. 48 if self.buf.is_empty() { 49 return Ok(None); 50 } 51 52 // If `self.state` is `None`, start decoding from the `Index` state. 53 match self 54 .state 55 .take() 56 .unwrap_or_else(|| ReprDecodeState::Index(Index::new())) 57 .decode(&mut self.buf) 58 { 59 // If `buf` is not enough to continue decoding a complete 60 // `Representation`, `Ok(None)` will be returned. Users need to call 61 // `save` to save the current state to a `ReprDecStateHolder`. 62 DecResult::NeedMore(state) => { 63 self.state = Some(state); 64 Ok(None) 65 } 66 // If a `Representation` is decoded, return it. 67 DecResult::Decoded(repr) => Ok(Some(repr)), 68 DecResult::Error(error) => Err(error), 69 } 70 } 71 72 /// Saves current state to a `ReprDecStateHolder`. save(self, holder: &mut ReprDecStateHolder)73 pub(crate) fn save(self, holder: &mut ReprDecStateHolder) { 74 holder.state = self.state 75 } 76 } 77 78 /// `ReprDecStateHolder` is used to hold the intermediate `DecodeState`. 79 pub(crate) struct ReprDecStateHolder { 80 state: Option<ReprDecodeState>, 81 } 82 83 impl ReprDecStateHolder { new() -> Self84 pub(crate) fn new() -> Self { 85 Self { state: None } 86 } 87 is_empty(&self) -> bool88 pub(crate) fn is_empty(&self) -> bool { 89 self.state.is_none() 90 } 91 } 92 93 macro_rules! state_def { 94 ($name: ident, $decoded: ty, $($state: ident),* $(,)?) => { 95 pub(crate) enum $name { 96 $( 97 $state($state), 98 )* 99 } 100 101 impl $name { 102 fn decode(self, buf: &mut &[u8]) -> DecResult<$decoded, $name> { 103 match self { 104 $( 105 Self::$state(state) => state.decode(buf), 106 )* 107 } 108 } 109 } 110 111 $( 112 impl From<$state> for $name { 113 fn from(s: $state) -> Self { 114 Self::$state(s) 115 } 116 } 117 )* 118 } 119 } 120 121 // `Repr` decoding state diagram: 122 // 123 // ┌ `Index` ─ `IndexInner` ┬ `FirstByte` 124 // │ └ `TrailingBytes` 125 // │ 126 // `ReprDecodeState` ┼ `NameString` ┐ ┌ `LengthFirstByte` 127 // │ ├ `LiteralString` ┼ `LengthTrailingBytes` 128 // └ `ValueString` ┘ ├ `AsciiStringBytes` 129 // └ `HuffmanStringBytes` 130 131 // `ReprDecodeState` contains 3 states: `Index`, `NameString` and `ValueString`. 132 state_def!( 133 ReprDecodeState, 134 Representation, 135 Index, 136 NameString, 137 ValueString 138 ); 139 140 // `IndexInner` contains 2 states: `FirstByte` and `TrailingBytes`. 141 state_def!(IndexInner, (PrefixBit, usize), FirstByte, TrailingBytes); 142 143 // `LiteralString` contains 4 states: `LengthFirstByte`, `LengthTrailingBytes`, 144 // `AsciiStringBytes` and `HuffmanStringBytes` 145 state_def!( 146 LiteralString, 147 Vec<u8>, 148 LengthFirstByte, 149 LengthTrailingBytes, 150 AsciiStringBytes, 151 HuffmanStringBytes, 152 ); 153 154 /// `Index` is responsible for decoding the starting index part. 155 pub(crate) struct Index { 156 inner: IndexInner, 157 } 158 159 impl Index { new() -> Self160 fn new() -> Self { 161 Self::from_inner(FirstByte.into()) 162 } 163 from_inner(inner: IndexInner) -> Self164 fn from_inner(inner: IndexInner) -> Self { 165 Self { inner } 166 } 167 decode(self, buf: &mut &[u8]) -> DecResult<Representation, ReprDecodeState>168 fn decode(self, buf: &mut &[u8]) -> DecResult<Representation, ReprDecodeState> { 169 match self.inner.decode(buf) { 170 // RFC7541-6.1: The index value of 0 is not used. It MUST be treated 171 // as a decoding error if found in an indexed header field representation. 172 DecResult::Decoded((PrefixBit::INDEXED, 0)) => { 173 H2Error::ConnectionError(ErrorCode::CompressionError).into() 174 } 175 DecResult::Decoded((PrefixBit::INDEXED, index)) => { 176 DecResult::Decoded(Representation::Indexed { index }) 177 } 178 DecResult::Decoded((PrefixBit::SIZE_UPDATE, max_size)) => { 179 DecResult::Decoded(Representation::SizeUpdate { max_size }) 180 } 181 DecResult::Decoded((repr, 0)) => NameString::new(repr).decode(buf), 182 DecResult::Decoded((repr, index)) => { 183 ValueString::new(repr, Name::Index(index)).decode(buf) 184 } 185 DecResult::NeedMore(inner) => DecResult::NeedMore(Index::from_inner(inner).into()), 186 DecResult::Error(e) => e.into(), 187 } 188 } 189 } 190 191 /// `NameString` is responsible for decoding the name string part. 192 pub(crate) struct NameString { 193 repr: PrefixBit, 194 inner: LiteralString, 195 } 196 197 impl NameString { new(repr: PrefixBit) -> Self198 fn new(repr: PrefixBit) -> Self { 199 Self::from_inner(repr, LengthFirstByte.into()) 200 } 201 from_inner(repr: PrefixBit, inner: LiteralString) -> Self202 fn from_inner(repr: PrefixBit, inner: LiteralString) -> Self { 203 Self { repr, inner } 204 } 205 decode(self, buf: &mut &[u8]) -> DecResult<Representation, ReprDecodeState>206 fn decode(self, buf: &mut &[u8]) -> DecResult<Representation, ReprDecodeState> { 207 match self.inner.decode(buf) { 208 DecResult::Decoded(octets) => { 209 ValueString::new(self.repr, Name::Literal(octets)).decode(buf) 210 } 211 DecResult::NeedMore(inner) => { 212 DecResult::NeedMore(Self::from_inner(self.repr, inner).into()) 213 } 214 DecResult::Error(e) => e.into(), 215 } 216 } 217 } 218 219 /// `ValueString` is responsible for decoding the value string part. 220 pub(crate) struct ValueString { 221 repr: PrefixBit, 222 name: Name, 223 inner: LiteralString, 224 } 225 226 impl ValueString { new(repr: PrefixBit, name: Name) -> Self227 fn new(repr: PrefixBit, name: Name) -> Self { 228 Self::from_inner(repr, name, LengthFirstByte.into()) 229 } 230 from_inner(repr: PrefixBit, name: Name, inner: LiteralString) -> Self231 fn from_inner(repr: PrefixBit, name: Name, inner: LiteralString) -> Self { 232 Self { repr, name, inner } 233 } 234 decode(self, buf: &mut &[u8]) -> DecResult<Representation, ReprDecodeState>235 fn decode(self, buf: &mut &[u8]) -> DecResult<Representation, ReprDecodeState> { 236 match (self.repr, self.inner.decode(buf)) { 237 (PrefixBit::LITERAL_WITH_INDEXING, DecResult::Decoded(value)) => { 238 DecResult::Decoded(Representation::LiteralWithIndexing { 239 name: self.name, 240 value, 241 }) 242 } 243 (PrefixBit::LITERAL_WITHOUT_INDEXING, DecResult::Decoded(value)) => { 244 DecResult::Decoded(Representation::LiteralWithoutIndexing { 245 name: self.name, 246 value, 247 }) 248 } 249 (_, DecResult::Decoded(value)) => { 250 DecResult::Decoded(Representation::LiteralNeverIndexed { 251 name: self.name, 252 value, 253 }) 254 } 255 (_, DecResult::NeedMore(inner)) => { 256 DecResult::NeedMore(Self::from_inner(self.repr, self.name, inner).into()) 257 } 258 (_, DecResult::Error(e)) => e.into(), 259 } 260 } 261 } 262 263 /// `FirstByte` is responsible for decoding the first byte of the index of 264 /// `Representation`. 265 /// 266 /// # Binary Format 267 /// ```text 268 /// Bytes list: 269 /// +--------+----------------------+ 270 /// | Prefix | Index | 271 /// +--------+----------------------+ 272 /// | (trailing bytes)... | 273 /// +--------+----------------------+ 274 /// ``` 275 pub(crate) struct FirstByte; 276 277 impl FirstByte { decode(self, buf: &mut &[u8]) -> DecResult<(PrefixBit, usize), IndexInner>278 fn decode(self, buf: &mut &[u8]) -> DecResult<(PrefixBit, usize), IndexInner> { 279 // If `buf` has been completely decoded here, return the current state. 280 if buf.is_empty() { 281 return DecResult::NeedMore(self.into()); 282 } 283 284 // Decodes `Prefix`. 285 let byte = buf[0]; 286 let repr = PrefixBit::from_u8(byte); 287 let mask = repr.prefix_index_mask(); 288 289 // Moves the pointer of `buf` backward. 290 *buf = &buf[1..]; 291 match IntegerDecoder::first_byte(byte, mask.0) { 292 Ok(idx) => DecResult::Decoded((repr, idx)), 293 Err(int) => TrailingBytes::new(repr, int).decode(buf), 294 } 295 } 296 } 297 298 /// `TrailingBytes` is responsible for decoding the trailing bytes of the index 299 /// of `Representation`. 300 /// 301 /// # Binary Format 302 /// ```text 303 /// Bytes list: 304 /// +--------+----------------------+ 305 /// | Prefix | Index | 306 /// +---+----+----------------------+ 307 /// | 1 | Index | 308 /// +---+----+----------------------+ 309 /// | ... | 310 /// +---+----+----------------------+ 311 /// | 0 | Index | 312 /// +---+----+----------------------+ 313 /// | (trailing bytes)... | 314 /// +--------+----------------------+ 315 /// ``` 316 pub(crate) struct TrailingBytes { 317 repr: PrefixBit, 318 index: IntegerDecoder, 319 } 320 321 impl TrailingBytes { new(repr: PrefixBit, index: IntegerDecoder) -> Self322 fn new(repr: PrefixBit, index: IntegerDecoder) -> Self { 323 Self { repr, index } 324 } 325 decode(mut self, buf: &mut &[u8]) -> DecResult<(PrefixBit, usize), IndexInner>326 fn decode(mut self, buf: &mut &[u8]) -> DecResult<(PrefixBit, usize), IndexInner> { 327 loop { 328 // If `buf` has been completely decoded here, return the current state. 329 if buf.is_empty() { 330 return DecResult::NeedMore(self.into()); 331 } 332 333 let byte = buf[0]; 334 *buf = &buf[1..]; 335 // Updates trailing bytes until we get the index. 336 match self.index.next_byte(byte) { 337 Ok(None) => {} 338 Ok(Some(index)) => return DecResult::Decoded((self.repr, index)), 339 Err(e) => return e.into(), 340 } 341 } 342 } 343 } 344 345 /// `LengthFirstByte` is responsible for decoding the first byte of the 346 /// length in `Representation`. 347 /// 348 /// # Binary Format 349 /// ```text 350 /// Bytes list: 351 /// +---+---------------------------+ 352 /// | H | Length | 353 /// +---+---------------------------+ 354 /// | (trailing bytes)... | 355 /// +--------+----------------------+ 356 /// ``` 357 pub(crate) struct LengthFirstByte; 358 359 impl LengthFirstByte { decode(self, buf: &mut &[u8]) -> DecResult<Vec<u8>, LiteralString>360 fn decode(self, buf: &mut &[u8]) -> DecResult<Vec<u8>, LiteralString> { 361 if buf.is_empty() { 362 return DecResult::NeedMore(self.into()); 363 } 364 365 let byte = buf[0]; 366 *buf = &buf[1..]; 367 match ( 368 IntegerDecoder::first_byte(byte, 0x7f), 369 (byte & 0x80) == 0x80, 370 ) { 371 (Ok(len), true) => HuffmanStringBytes::new(len).decode(buf), 372 (Ok(len), false) => AsciiStringBytes::new(len).decode(buf), 373 (Err(int), huffman) => LengthTrailingBytes::new(huffman, int).decode(buf), 374 } 375 } 376 } 377 378 /// `LengthTrailingBytes` is responsible for decoding the trailing bytes of the 379 /// length in `Representation`. 380 /// 381 /// # Binary Format 382 /// ```text 383 /// Bytes list: 384 /// +---+---------------------------+ 385 /// | H | Length | 386 /// +---+---------------------------+ 387 /// | 1 | Length | 388 /// +---+----+----------------------+ 389 /// | ... | 390 /// +---+----+----------------------+ 391 /// | 0 | Length | 392 /// +---+----+----------------------+ 393 /// | (trailing bytes)... | 394 /// +--------+----------------------+ 395 /// ``` 396 pub(crate) struct LengthTrailingBytes { 397 is_huffman: bool, 398 length: IntegerDecoder, 399 } 400 401 impl LengthTrailingBytes { new(is_huffman: bool, length: IntegerDecoder) -> Self402 fn new(is_huffman: bool, length: IntegerDecoder) -> Self { 403 Self { is_huffman, length } 404 } 405 decode(mut self, buf: &mut &[u8]) -> DecResult<Vec<u8>, LiteralString>406 fn decode(mut self, buf: &mut &[u8]) -> DecResult<Vec<u8>, LiteralString> { 407 loop { 408 if buf.is_empty() { 409 return DecResult::NeedMore(self.into()); 410 } 411 412 let byte = buf[0]; 413 *buf = &buf[1..]; 414 match (self.length.next_byte(byte), self.is_huffman) { 415 (Ok(None), _) => {} 416 (Err(e), _) => return e.into(), 417 (Ok(Some(length)), true) => return HuffmanStringBytes::new(length).decode(buf), 418 (Ok(Some(length)), false) => return AsciiStringBytes::new(length).decode(buf), 419 } 420 } 421 } 422 } 423 424 /// `AsciiStringBytes` is responsible for decoding the ascii string of the 425 /// literal octets of `Representation`. 426 /// 427 /// # Binary Format 428 /// ```text 429 /// Bytes list: 430 /// +-------------------------------+ 431 /// | String | 432 /// +-------------------------------+ 433 /// | (trailing bytes)... | 434 /// +--------+----------------------+ 435 /// ``` 436 pub(crate) struct AsciiStringBytes { 437 octets: Vec<u8>, 438 length: usize, 439 } 440 441 impl AsciiStringBytes { new(length: usize) -> Self442 fn new(length: usize) -> Self { 443 Self { 444 octets: Vec::new(), 445 length, 446 } 447 } 448 decode(mut self, buf: &mut &[u8]) -> DecResult<Vec<u8>, LiteralString>449 fn decode(mut self, buf: &mut &[u8]) -> DecResult<Vec<u8>, LiteralString> { 450 match (buf.len() + self.octets.len()).cmp(&self.length) { 451 Ordering::Greater | Ordering::Equal => { 452 let pos = self.length - self.octets.len(); 453 self.octets.extend_from_slice(&buf[..pos]); 454 *buf = &buf[pos..]; 455 DecResult::Decoded(self.octets) 456 } 457 Ordering::Less => { 458 self.octets.extend_from_slice(buf); 459 *buf = &buf[buf.len()..]; 460 DecResult::NeedMore(self.into()) 461 } 462 } 463 } 464 } 465 466 /// `HuffmanStringBytes` is responsible for decoding the huffman string of the 467 /// literal octets of `Representation`. 468 /// 469 /// # Binary Format 470 /// ```text 471 /// Bytes list: 472 /// +-------------------------------+ 473 /// | String | 474 /// +-------------------------------+ 475 /// | (trailing bytes)... | 476 /// +--------+----------------------+ 477 /// ``` 478 pub(crate) struct HuffmanStringBytes { 479 huffman: HuffmanDecoder, 480 read: usize, 481 length: usize, 482 } 483 484 impl HuffmanStringBytes { new(length: usize) -> Self485 fn new(length: usize) -> Self { 486 Self { 487 huffman: HuffmanDecoder::new(), 488 read: 0, 489 length, 490 } 491 } 492 decode(mut self, buf: &mut &[u8]) -> DecResult<Vec<u8>, LiteralString>493 fn decode(mut self, buf: &mut &[u8]) -> DecResult<Vec<u8>, LiteralString> { 494 match (buf.len() + self.read).cmp(&self.length) { 495 Ordering::Greater | Ordering::Equal => { 496 let pos = self.length - self.read; 497 if self.huffman.decode(&buf[..pos]).is_err() { 498 return H2Error::ConnectionError(ErrorCode::CompressionError).into(); 499 } 500 *buf = &buf[pos..]; 501 match self.huffman.finish() { 502 Ok(vec) => DecResult::Decoded(vec), 503 Err(_) => H2Error::ConnectionError(ErrorCode::CompressionError).into(), 504 } 505 } 506 Ordering::Less => { 507 if self.huffman.decode(buf).is_err() { 508 return H2Error::ConnectionError(ErrorCode::CompressionError).into(); 509 } 510 self.read += buf.len(); 511 *buf = &buf[buf.len()..]; 512 DecResult::NeedMore(self.into()) 513 } 514 } 515 } 516 } 517 518 /// Finish state, generate `Representation` by name and value. 519 pub(crate) struct Finish { 520 repr: PrefixBit, 521 name: Name, 522 value: Vec<u8>, 523 } 524 525 impl Finish { new(repr: PrefixBit, name: Name, value: Vec<u8>) -> Self526 fn new(repr: PrefixBit, name: Name, value: Vec<u8>) -> Self { 527 Self { repr, name, value } 528 } 529 decode(self) -> DecResult<Representation, ReprDecodeState>530 fn decode(self) -> DecResult<Representation, ReprDecodeState> { 531 DecResult::Decoded(match self.repr { 532 PrefixBit::LITERAL_WITH_INDEXING => Representation::LiteralWithIndexing { 533 name: self.name, 534 value: self.value, 535 }, 536 PrefixBit::LITERAL_WITHOUT_INDEXING => Representation::LiteralWithoutIndexing { 537 name: self.name, 538 value: self.value, 539 }, 540 _ => Representation::LiteralNeverIndexed { 541 name: self.name, 542 value: self.value, 543 }, 544 }) 545 } 546 } 547 548 /// Decoder's possible returns during the decoding process. 549 enum DecResult<D, S> { 550 /// Decoder has got a `D`. Users can continue to call `encode` to try to 551 /// get the next `D`. 552 Decoded(D), 553 554 /// Decoder needs more bytes to decode to get a `D`. Returns the current 555 /// decoding state `S`. 556 NeedMore(S), 557 558 /// Errors that may occur when decoding. 559 Error(H2Error), 560 } 561 562 impl<D, S> From<H2Error> for DecResult<D, S> { from(e: H2Error) -> Self563 fn from(e: H2Error) -> Self { 564 DecResult::Error(e) 565 } 566 } 567 568 #[cfg(test)] 569 mod ut_repr_decoder { 570 use super::*; 571 use crate::util::test_util::decode; 572 573 /// UT test cases for `ReprDecoder`. 574 /// 575 /// # Brief 576 /// 1. Creates a `ReprDecoder`. 577 /// 2. Calls `ReprDecoder::decode()` function, passing in the specified 578 /// parameters. 579 /// 3. Checks if the test results are correct. 580 #[test] ut_repr_decoder()581 fn ut_repr_decoder() { 582 rfc7541_test_cases(); 583 584 macro_rules! inner_test_case { 585 ($decoder: expr, $pat: ident => $name: expr) => { 586 match $decoder.decode() { 587 Ok(Some(Representation::$pat { index })) => assert_eq!($name, index), 588 _ => panic!("ReprDecoder::decode() failed!"), 589 } 590 }; 591 ($decoder: expr, $pat: ident, $kind: ident => $name: expr, $value: expr) => { 592 match $decoder.decode() { 593 Ok(Some(Representation::$pat { 594 name: Name::$kind(n), 595 value: v, 596 })) => { 597 assert_eq!($name, n); 598 assert_eq!($value, v); 599 } 600 _ => panic!("ReprDecoder::decode() failed!"), 601 } 602 }; 603 } 604 605 macro_rules! repr_test_case { 606 ($octets: literal, $({ $pat: ident $(, $kind: ident)? => $first: expr $(, $second: expr)?} $(,)?)*) => { 607 let slice = decode($octets).unwrap(); 608 let mut decoder = ReprDecoder::new(&slice); 609 $( 610 inner_test_case!(decoder, $pat $(, $kind)? => $first $(, $second)?); 611 )* 612 } 613 } 614 615 /// The following test cases are from RFC7541. 616 fn rfc7541_test_cases() { 617 // C.2.1. Literal Header Field with Indexing 618 repr_test_case!( 619 "400a637573746f6d2d6b65790d637573746f6d2d686561646572", 620 { LiteralWithIndexing, Literal => b"custom-key".to_vec(), b"custom-header".to_vec() } 621 ); 622 623 // C.2.2. Literal Header Field without Indexing 624 repr_test_case!( 625 "040c2f73616d706c652f70617468", 626 { LiteralWithoutIndexing, Index => 4, b"/sample/path".to_vec() } 627 ); 628 629 // C.2.3. Literal Header Field Never Indexed 630 repr_test_case!( 631 "100870617373776f726406736563726574", 632 { LiteralNeverIndexed, Literal => b"password".to_vec(), b"secret".to_vec() } 633 ); 634 635 // C.2.4. Indexed Header Field 636 repr_test_case!( 637 "82", 638 { Indexed => 2 } 639 ); 640 641 // C.3.1. First Request 642 repr_test_case!( 643 "828684410f7777772e6578616d706c652e636f6d", 644 { Indexed => 2 }, 645 { Indexed => 6 }, 646 { Indexed => 4 }, 647 { LiteralWithIndexing, Index => 1, b"www.example.com".to_vec() } 648 ); 649 650 // C.3.2. Second Request 651 repr_test_case!( 652 "828684be58086e6f2d6361636865", 653 { Indexed => 2 }, 654 { Indexed => 6 }, 655 { Indexed => 4 }, 656 { Indexed => 62 }, 657 { LiteralWithIndexing, Index => 24, b"no-cache".to_vec() } 658 ); 659 660 // C.3.3. Third Request 661 repr_test_case!( 662 "828785bf400a637573746f6d2d6b65790c637573746f6d2d76616c7565", 663 { Indexed => 2 }, 664 { Indexed => 7 }, 665 { Indexed => 5 }, 666 { Indexed => 63 }, 667 { LiteralWithIndexing, Literal => b"custom-key".to_vec(), b"custom-value".to_vec() } 668 ); 669 670 // C.4.1. First Request 671 repr_test_case!( 672 "828684418cf1e3c2e5f23a6ba0ab90f4ff", 673 { Indexed => 2 }, 674 { Indexed => 6 }, 675 { Indexed => 4 }, 676 { LiteralWithIndexing, Index => 1, b"www.example.com".to_vec() } 677 ); 678 679 // C.4.2. Second Request 680 repr_test_case!( 681 "828684be5886a8eb10649cbf", 682 { Indexed => 2 }, 683 { Indexed => 6 }, 684 { Indexed => 4 }, 685 { Indexed => 62 }, 686 { LiteralWithIndexing, Index => 24, b"no-cache".to_vec() } 687 ); 688 689 // C.4.3. Third Request 690 repr_test_case!( 691 "828785bf408825a849e95ba97d7f8925a849e95bb8e8b4bf", 692 { Indexed => 2 }, 693 { Indexed => 7 }, 694 { Indexed => 5 }, 695 { Indexed => 63 }, 696 { LiteralWithIndexing, Literal => b"custom-key".to_vec(), b"custom-value".to_vec() } 697 ); 698 699 // C.5.1. First Response 700 repr_test_case!( 701 "4803333032580770726976617465611d\ 702 4d6f6e2c203231204f63742032303133\ 703 2032303a31333a323120474d546e1768\ 704 747470733a2f2f7777772e6578616d70\ 705 6c652e636f6d", 706 { LiteralWithIndexing, Index => 8, b"302".to_vec() }, 707 { LiteralWithIndexing, Index => 24, b"private".to_vec() }, 708 { LiteralWithIndexing, Index => 33, b"Mon, 21 Oct 2013 20:13:21 GMT".to_vec() }, 709 { LiteralWithIndexing, Index => 46, b"https://www.example.com".to_vec() } 710 ); 711 712 // C.5.2. Second Response 713 repr_test_case!( 714 "4803333037c1c0bf", 715 { LiteralWithIndexing, Index => 8, b"307".to_vec() }, 716 { Indexed => 65 }, 717 { Indexed => 64 }, 718 { Indexed => 63 } 719 ); 720 721 // C.5.3. Third Response 722 repr_test_case!( 723 "88c1611d4d6f6e2c203231204f637420\ 724 323031332032303a31333a323220474d\ 725 54c05a04677a69707738666f6f3d4153\ 726 444a4b48514b425a584f5157454f5049\ 727 5541585157454f49553b206d61782d61\ 728 67653d333630303b2076657273696f6e\ 729 3d31", 730 { Indexed => 8 }, 731 { Indexed => 65 }, 732 { LiteralWithIndexing, Index => 33, b"Mon, 21 Oct 2013 20:13:22 GMT".to_vec() }, 733 { Indexed => 64 }, 734 { LiteralWithIndexing, Index => 26, b"gzip".to_vec() }, 735 { LiteralWithIndexing, Index => 55, b"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1".to_vec() } 736 ); 737 738 // C.6.1. First Response 739 repr_test_case!( 740 "488264025885aec3771a4b6196d07abe\ 741 941054d444a8200595040b8166e082a6\ 742 2d1bff6e919d29ad171863c78f0b97c8\ 743 e9ae82ae43d3", 744 { LiteralWithIndexing, Index => 8, b"302".to_vec() }, 745 { LiteralWithIndexing, Index => 24, b"private".to_vec() }, 746 { LiteralWithIndexing, Index => 33, b"Mon, 21 Oct 2013 20:13:21 GMT".to_vec() }, 747 { LiteralWithIndexing, Index => 46, b"https://www.example.com".to_vec() } 748 ); 749 750 // C.6.2. Second Response 751 repr_test_case!( 752 "4883640effc1c0bf", 753 { LiteralWithIndexing, Index => 8, b"307".to_vec() }, 754 { Indexed => 65 }, 755 { Indexed => 64 }, 756 { Indexed => 63 } 757 ); 758 759 // C.6.3. Third Response 760 repr_test_case!( 761 "88c16196d07abe941054d444a8200595\ 762 040b8166e084a62d1bffc05a839bd9ab\ 763 77ad94e7821dd7f2e6c7b335dfdfcd5b\ 764 3960d5af27087f3672c1ab270fb5291f\ 765 9587316065c003ed4ee5b1063d5007", 766 { Indexed => 8 }, 767 { Indexed => 65 }, 768 { LiteralWithIndexing, Index => 33, b"Mon, 21 Oct 2013 20:13:22 GMT".to_vec() }, 769 { Indexed => 64 }, 770 { LiteralWithIndexing, Index => 26, b"gzip".to_vec() }, 771 { LiteralWithIndexing, Index => 55, b"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1".to_vec() } 772 ); 773 } 774 } 775 776 /// UT test cases for `Finish::decode`. 777 /// 778 /// # Brief 779 /// 1. Creates a `Finish` instance. 780 /// 2. Calls `Finish::decode` to decode. 781 /// 3. Checks the results. 782 #[test] ut_finish_decode()783 fn ut_finish_decode() { 784 // Case 1: Testing LiteralWithIndexing 785 let name = Name::Literal("test_name".as_bytes().to_vec()); 786 let value = vec![0u8, 1u8, 2u8]; 787 let finish = Finish::new(PrefixBit::LITERAL_WITH_INDEXING, name, value); 788 match finish.decode() { 789 DecResult::Decoded(repr) => match repr { 790 Representation::LiteralWithIndexing { name: _, value: _ } => {} 791 _ => panic!("Expected LiteralWithIndexing"), 792 }, 793 _ => panic!("Decode failed"), 794 } 795 796 // Case 2: Testing LiteralWithoutIndexing 797 let name = Name::Literal("test_name".as_bytes().to_vec()); 798 let value = vec![0u8, 1u8, 2u8]; 799 let finish = Finish::new(PrefixBit::LITERAL_WITHOUT_INDEXING, name, value); 800 match finish.decode() { 801 DecResult::Decoded(repr) => match repr { 802 Representation::LiteralWithoutIndexing { name: _, value: _ } => {} 803 _ => panic!("Expected LiteralWithoutIndexing"), 804 }, 805 _ => panic!("Decode failed"), 806 } 807 808 // Case 3: Testing LiteralNeverIndexed 809 let name = Name::Literal("test_name".as_bytes().to_vec()); 810 let value = vec![0u8, 1u8, 2u8]; 811 let finish = Finish::new(PrefixBit::LITERAL_NEVER_INDEXED, name, value); 812 match finish.decode() { 813 DecResult::Decoded(repr) => match repr { 814 Representation::LiteralNeverIndexed { name: _, value: _ } => {} 815 _ => panic!("Expected LiteralNeverIndexed"), 816 }, 817 _ => panic!("Decode failed"), 818 } 819 820 // Case 4: Testing Indexed 821 let name = Name::Literal("test_name".as_bytes().to_vec()); 822 let value = vec![0u8, 1u8, 2u8]; 823 let finish = Finish::new(PrefixBit::INDEXED, name, value); 824 match finish.decode() { 825 DecResult::Decoded(repr) => match repr { 826 Representation::LiteralNeverIndexed { name: _, value: _ } => {} 827 _ => panic!("Expected LiteralNeverIndexed for PrefixBit::INDEXED"), 828 }, 829 _ => panic!("Decode failed"), 830 } 831 832 // Case 5: Testing SizeUpdate 833 let name = Name::Literal("test_name".as_bytes().to_vec()); 834 let value = vec![0u8, 1u8, 2u8]; 835 let finish = Finish::new(PrefixBit::SIZE_UPDATE, name, value); 836 match finish.decode() { 837 DecResult::Decoded(repr) => match repr { 838 Representation::LiteralNeverIndexed { name: _, value: _ } => {} 839 _ => panic!("Expected LiteralNeverIndexed for PrefixBit::SIZE_UPDATE"), 840 }, 841 _ => panic!("Decode failed"), 842 } 843 } 844 } 845