1use std::{cmp, collections::VecDeque, io::Cursor, str::Utf8Error};
2
3use ntex_bytes::{Buf, ByteString, Bytes, BytesMut};
4use ntex_http::{Method, StatusCode, compat, header};
5
6use super::{Header, huffman};
7
8#[derive(Debug)]
10pub struct Decoder {
11 max_size_update: Option<usize>,
13 last_max_update: usize,
14 table: Table,
15 buffer: BytesMut,
16}
17
18#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
21pub enum DecoderError {
22 #[error("InvalidRepresentation")]
23 InvalidRepresentation,
24 #[error("InvalidIntegerPrefix")]
25 InvalidIntegerPrefix,
26 #[error("InvalidTableIndex")]
27 InvalidTableIndex,
28 #[error("InvalidHuffmanCode")]
29 InvalidHuffmanCode,
30 #[error("InvalidUtf8")]
31 InvalidUtf8,
32 #[error("InvalidStatusCode")]
33 InvalidStatusCode,
34 #[error("InvalidPseudoheader")]
35 InvalidPseudoheader,
36 #[error("InvalidMaxDynamicSize")]
37 InvalidMaxDynamicSize,
38 #[error("IntegerOverflow")]
39 IntegerOverflow,
40 #[error("{0}")]
41 NeedMore(NeedMore),
42}
43
44#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
45pub enum NeedMore {
46 #[error("Unexpected end of stream")]
47 UnexpectedEndOfStream,
48 #[error("Integer underflow")]
49 IntegerUnderflow,
50 #[error("String underflow")]
51 StringUnderflow,
52}
53
54enum Representation {
55 Indexed,
69
70 LiteralWithIndexing,
89
90 LiteralWithoutIndexing,
109
110 LiteralNeverIndexed,
128
129 SizeUpdate,
143}
144
145#[derive(Debug)]
146struct Table {
147 entries: VecDeque<Header>,
148 size: usize,
149 max_size: usize,
150}
151
152struct StringMarker {
153 offset: usize,
154 len: usize,
155 string: Option<Bytes>,
156}
157
158impl Decoder {
161 pub fn new(size: usize) -> Decoder {
163 Decoder {
164 max_size_update: None,
165 last_max_update: size,
166 table: Table::new(size),
167 buffer: BytesMut::with_capacity(4096),
168 }
169 }
170
171 #[allow(dead_code)]
173 pub fn queue_size_update(&mut self, size: usize) {
174 let size = match self.max_size_update {
175 Some(v) => cmp::max(v, size),
176 None => size,
177 };
178
179 self.max_size_update = Some(size);
180 }
181
182 pub fn decode<F>(
184 &mut self,
185 src: &mut Cursor<&mut BytesMut>,
186 mut f: F,
187 ) -> Result<(), DecoderError>
188 where
189 F: FnMut(Header),
190 {
191 use self::Representation::*;
192
193 let mut can_resize = true;
194
195 if let Some(size) = self.max_size_update.take() {
196 self.last_max_update = size;
197 }
198
199 while let Some(ty) = peek_u8(src) {
200 match Representation::load(ty)? {
204 Indexed => {
205 can_resize = false;
207 let entry = self.decode_indexed(src)?;
208 consume(src);
209 f(entry);
210 }
211 LiteralWithIndexing => {
212 can_resize = false;
214 let entry = self.decode_literal(src, true)?;
215
216 self.table.insert(entry.clone());
218 consume(src);
219
220 f(entry);
221 }
222 LiteralWithoutIndexing => {
223 can_resize = false;
225 let entry = self.decode_literal(src, false)?;
226 consume(src);
227 f(entry);
228 }
229 LiteralNeverIndexed => {
230 can_resize = false;
232 let entry = self.decode_literal(src, false)?;
233 consume(src);
234
235 f(entry);
238 }
239 SizeUpdate => {
240 if !can_resize {
242 return Err(DecoderError::InvalidMaxDynamicSize);
243 }
244
245 self.process_size_update(src)?;
247 consume(src);
248 }
249 }
250 }
251
252 Ok(())
253 }
254
255 fn process_size_update(&mut self, buf: &mut Cursor<&mut BytesMut>) -> Result<(), DecoderError> {
256 let new_size = decode_int(buf, 5)?;
257
258 if new_size > self.last_max_update {
259 return Err(DecoderError::InvalidMaxDynamicSize);
260 }
261
262 log::debug!(
263 "Decoder changed max table size, from {} to {}",
264 self.table.size(),
265 new_size,
266 );
267
268 self.table.set_max_size(new_size);
269
270 Ok(())
271 }
272
273 fn decode_indexed(&self, buf: &mut Cursor<&mut BytesMut>) -> Result<Header, DecoderError> {
274 let index = decode_int(buf, 7)?;
275 self.table.get(index)
276 }
277
278 fn decode_literal(
279 &mut self,
280 buf: &mut Cursor<&mut BytesMut>,
281 index: bool,
282 ) -> Result<Header, DecoderError> {
283 let prefix = if index { 6 } else { 4 };
284
285 let table_idx = decode_int(buf, prefix)?;
287
288 if table_idx == 0 {
290 let old_pos = buf.position();
291 let name_marker = self.try_decode_string(buf)?;
292 let value_marker = self.try_decode_string(buf)?;
293 buf.set_position(old_pos);
294 let name = name_marker.consume(buf);
296 let value = value_marker.consume(buf);
297 Header::new(name, value)
298 } else {
299 let e = self.table.get(table_idx)?;
300 let value = self.decode_string(buf)?;
301
302 e.name().into_entry(value)
303 }
304 }
305
306 fn try_decode_string(
307 &mut self,
308 buf: &mut Cursor<&mut BytesMut>,
309 ) -> Result<StringMarker, DecoderError> {
310 let old_pos = buf.position();
311 const HUFF_FLAG: u8 = 0b1000_0000;
312
313 let huff = match peek_u8(buf) {
315 Some(hdr) => (hdr & HUFF_FLAG) == HUFF_FLAG,
316 None => return Err(DecoderError::NeedMore(NeedMore::UnexpectedEndOfStream)),
317 };
318
319 let len = decode_int(buf, 7)?;
321
322 if len > buf.remaining() {
323 log::trace!("decode_string underflow {:?} {:?}", len, buf.remaining());
324 return Err(DecoderError::NeedMore(NeedMore::StringUnderflow));
325 }
326
327 let offset = (buf.position() - old_pos) as usize;
328 if huff {
329 let ret = {
330 let raw = &buf.chunk()[..len];
331 huffman::decode(raw, &mut self.buffer).map(|buf| StringMarker {
332 offset,
333 len,
334 string: Some(BytesMut::freeze(buf)),
335 })
336 };
337
338 buf.advance(len);
339 ret
340 } else {
341 buf.advance(len);
342 Ok(StringMarker {
343 offset,
344 len,
345 string: None,
346 })
347 }
348 }
349
350 fn decode_string(&mut self, buf: &mut Cursor<&mut BytesMut>) -> Result<Bytes, DecoderError> {
351 let old_pos = buf.position();
352 let marker = self.try_decode_string(buf)?;
353 buf.set_position(old_pos);
354 Ok(marker.consume(buf))
355 }
356}
357
358impl Default for Decoder {
359 fn default() -> Decoder {
360 Decoder::new(4096)
361 }
362}
363
364impl Representation {
367 pub fn load(byte: u8) -> Result<Representation, DecoderError> {
368 const INDEXED: u8 = 0b1000_0000;
369 const LITERAL_WITH_INDEXING: u8 = 0b0100_0000;
370 const LITERAL_WITHOUT_INDEXING: u8 = 0b1111_0000;
371 const LITERAL_NEVER_INDEXED: u8 = 0b0001_0000;
372 const SIZE_UPDATE_MASK: u8 = 0b1110_0000;
373 const SIZE_UPDATE: u8 = 0b0010_0000;
374
375 if byte & INDEXED == INDEXED {
378 Ok(Representation::Indexed)
379 } else if byte & LITERAL_WITH_INDEXING == LITERAL_WITH_INDEXING {
380 Ok(Representation::LiteralWithIndexing)
381 } else if byte & LITERAL_WITHOUT_INDEXING == 0 {
382 Ok(Representation::LiteralWithoutIndexing)
383 } else if byte & LITERAL_WITHOUT_INDEXING == LITERAL_NEVER_INDEXED {
384 Ok(Representation::LiteralNeverIndexed)
385 } else if byte & SIZE_UPDATE_MASK == SIZE_UPDATE {
386 Ok(Representation::SizeUpdate)
387 } else {
388 Err(DecoderError::InvalidRepresentation)
389 }
390 }
391}
392
393fn decode_int<B: Buf>(buf: &mut B, prefix_size: u8) -> Result<usize, DecoderError> {
394 const MAX_BYTES: usize = 5;
398 const VARINT_MASK: u8 = 0b0111_1111;
399 const VARINT_FLAG: u8 = 0b1000_0000;
400
401 if !(1..=8).contains(&prefix_size) {
402 return Err(DecoderError::InvalidIntegerPrefix);
403 }
404
405 if !buf.has_remaining() {
406 return Err(DecoderError::NeedMore(NeedMore::IntegerUnderflow));
407 }
408
409 let mask = if prefix_size == 8 {
410 0xFF
411 } else {
412 (1u8 << prefix_size).wrapping_sub(1)
413 };
414
415 let mut ret = (buf.get_u8() & mask) as usize;
416
417 if ret < mask as usize {
418 return Ok(ret);
420 }
421
422 let mut bytes = 1;
427
428 let mut shift = 0;
431
432 while buf.has_remaining() {
433 let b = buf.get_u8();
434
435 bytes += 1;
436 ret += ((b & VARINT_MASK) as usize) << shift;
437 shift += 7;
438
439 if b & VARINT_FLAG == 0 {
440 return Ok(ret);
441 }
442
443 if bytes == MAX_BYTES {
444 return Err(DecoderError::IntegerOverflow);
446 }
447 }
448
449 Err(DecoderError::NeedMore(NeedMore::IntegerUnderflow))
450}
451
452fn peek_u8<B: Buf>(buf: &B) -> Option<u8> {
453 if buf.has_remaining() {
454 Some(buf.chunk()[0])
455 } else {
456 None
457 }
458}
459
460fn take(buf: &mut Cursor<&mut BytesMut>, n: usize) -> Bytes {
461 let pos = buf.position() as usize;
462 let mut head = buf.get_mut().split_to(pos + n);
463 buf.set_position(0);
464 head.advance(pos);
465 head.freeze()
466}
467
468impl StringMarker {
469 fn consume(self, buf: &mut Cursor<&mut BytesMut>) -> Bytes {
470 buf.advance(self.offset);
471 match self.string {
472 Some(string) => {
473 buf.advance(self.len);
474 string
475 }
476 None => take(buf, self.len),
477 }
478 }
479}
480
481fn consume(buf: &mut Cursor<&mut BytesMut>) {
482 take(buf, 0);
486}
487
488impl Table {
491 fn new(max_size: usize) -> Table {
492 Table {
493 entries: VecDeque::new(),
494 size: 0,
495 max_size,
496 }
497 }
498
499 fn size(&self) -> usize {
500 self.size
501 }
502
503 pub fn get(&self, index: usize) -> Result<Header, DecoderError> {
512 if index == 0 {
513 return Err(DecoderError::InvalidTableIndex);
514 }
515
516 if index <= 61 {
517 return Ok(get_static(index));
518 }
519
520 match self.entries.get(index - 62) {
522 Some(e) => Ok(e.clone()),
523 None => Err(DecoderError::InvalidTableIndex),
524 }
525 }
526
527 fn insert(&mut self, entry: Header) {
528 let len = entry.len();
529
530 self.reserve(len);
531
532 if self.size + len <= self.max_size {
533 self.size += len;
534
535 self.entries.push_front(entry);
537 }
538 }
539
540 fn set_max_size(&mut self, size: usize) {
541 self.max_size = size;
542 self.consolidate();
544 }
545
546 fn reserve(&mut self, size: usize) {
547 while self.size + size > self.max_size {
548 match self.entries.pop_back() {
549 Some(last) => {
550 self.size -= last.len();
551 }
552 None => return,
553 }
554 }
555 }
556
557 fn consolidate(&mut self) {
558 while self.size > self.max_size {
559 {
560 let last = match self.entries.back() {
561 Some(x) => x,
562 None => {
563 panic!("Size of table != 0, but no headers left!");
566 }
567 };
568
569 self.size -= last.len();
570 }
571
572 self.entries.pop_back();
573 }
574 }
575}
576
577impl From<Utf8Error> for DecoderError {
580 fn from(_: Utf8Error) -> DecoderError {
581 DecoderError::InvalidUtf8
582 }
583}
584
585impl From<()> for DecoderError {
586 fn from(_: ()) -> DecoderError {
587 DecoderError::InvalidUtf8
588 }
589}
590
591impl From<header::InvalidHeaderValue> for DecoderError {
592 fn from(_: header::InvalidHeaderValue) -> DecoderError {
593 DecoderError::InvalidUtf8
594 }
595}
596
597impl From<header::InvalidHeaderName> for DecoderError {
598 fn from(_: header::InvalidHeaderName) -> DecoderError {
599 DecoderError::InvalidUtf8
600 }
601}
602
603impl From<compat::InvalidMethod> for DecoderError {
604 fn from(_: compat::InvalidMethod) -> DecoderError {
605 DecoderError::InvalidUtf8
606 }
607}
608
609impl From<compat::InvalidStatusCode> for DecoderError {
610 fn from(_: compat::InvalidStatusCode) -> DecoderError {
611 DecoderError::InvalidUtf8
613 }
614}
615
616pub fn get_static(idx: usize) -> Header {
618 use ntex_http::header::HeaderValue;
619
620 match idx {
621 1 => Header::Authority(ByteString::from_static("")),
622 2 => Header::Method(Method::GET),
623 3 => Header::Method(Method::POST),
624 4 => Header::Path(ByteString::from_static("/")),
625 5 => Header::Path(ByteString::from_static("/index.html")),
626 6 => Header::Scheme(ByteString::from_static("http")),
627 7 => Header::Scheme(ByteString::from_static("https")),
628 8 => Header::Status(StatusCode::OK),
629 9 => Header::Status(StatusCode::NO_CONTENT),
630 10 => Header::Status(StatusCode::PARTIAL_CONTENT),
631 11 => Header::Status(StatusCode::NOT_MODIFIED),
632 12 => Header::Status(StatusCode::BAD_REQUEST),
633 13 => Header::Status(StatusCode::NOT_FOUND),
634 14 => Header::Status(StatusCode::INTERNAL_SERVER_ERROR),
635 15 => Header::Field {
636 name: header::ACCEPT_CHARSET,
637 value: HeaderValue::from_static(""),
638 },
639 16 => Header::Field {
640 name: header::ACCEPT_ENCODING,
641 value: HeaderValue::from_static("gzip, deflate"),
642 },
643 17 => Header::Field {
644 name: header::ACCEPT_LANGUAGE,
645 value: HeaderValue::from_static(""),
646 },
647 18 => Header::Field {
648 name: header::ACCEPT_RANGES,
649 value: HeaderValue::from_static(""),
650 },
651 19 => Header::Field {
652 name: header::ACCEPT,
653 value: HeaderValue::from_static(""),
654 },
655 20 => Header::Field {
656 name: header::ACCESS_CONTROL_ALLOW_ORIGIN,
657 value: HeaderValue::from_static(""),
658 },
659 21 => Header::Field {
660 name: header::AGE,
661 value: HeaderValue::from_static(""),
662 },
663 22 => Header::Field {
664 name: header::ALLOW,
665 value: HeaderValue::from_static(""),
666 },
667 23 => Header::Field {
668 name: header::AUTHORIZATION,
669 value: HeaderValue::from_static(""),
670 },
671 24 => Header::Field {
672 name: header::CACHE_CONTROL,
673 value: HeaderValue::from_static(""),
674 },
675 25 => Header::Field {
676 name: header::CONTENT_DISPOSITION,
677 value: HeaderValue::from_static(""),
678 },
679 26 => Header::Field {
680 name: header::CONTENT_ENCODING,
681 value: HeaderValue::from_static(""),
682 },
683 27 => Header::Field {
684 name: header::CONTENT_LANGUAGE,
685 value: HeaderValue::from_static(""),
686 },
687 28 => Header::Field {
688 name: header::CONTENT_LENGTH,
689 value: HeaderValue::from_static(""),
690 },
691 29 => Header::Field {
692 name: header::CONTENT_LOCATION,
693 value: HeaderValue::from_static(""),
694 },
695 30 => Header::Field {
696 name: header::CONTENT_RANGE,
697 value: HeaderValue::from_static(""),
698 },
699 31 => Header::Field {
700 name: header::CONTENT_TYPE,
701 value: HeaderValue::from_static(""),
702 },
703 32 => Header::Field {
704 name: header::COOKIE,
705 value: HeaderValue::from_static(""),
706 },
707 33 => Header::Field {
708 name: header::DATE,
709 value: HeaderValue::from_static(""),
710 },
711 34 => Header::Field {
712 name: header::ETAG,
713 value: HeaderValue::from_static(""),
714 },
715 35 => Header::Field {
716 name: header::EXPECT,
717 value: HeaderValue::from_static(""),
718 },
719 36 => Header::Field {
720 name: header::EXPIRES,
721 value: HeaderValue::from_static(""),
722 },
723 37 => Header::Field {
724 name: header::FROM,
725 value: HeaderValue::from_static(""),
726 },
727 38 => Header::Field {
728 name: header::HOST,
729 value: HeaderValue::from_static(""),
730 },
731 39 => Header::Field {
732 name: header::IF_MATCH,
733 value: HeaderValue::from_static(""),
734 },
735 40 => Header::Field {
736 name: header::IF_MODIFIED_SINCE,
737 value: HeaderValue::from_static(""),
738 },
739 41 => Header::Field {
740 name: header::IF_NONE_MATCH,
741 value: HeaderValue::from_static(""),
742 },
743 42 => Header::Field {
744 name: header::IF_RANGE,
745 value: HeaderValue::from_static(""),
746 },
747 43 => Header::Field {
748 name: header::IF_UNMODIFIED_SINCE,
749 value: HeaderValue::from_static(""),
750 },
751 44 => Header::Field {
752 name: header::LAST_MODIFIED,
753 value: HeaderValue::from_static(""),
754 },
755 45 => Header::Field {
756 name: header::LINK,
757 value: HeaderValue::from_static(""),
758 },
759 46 => Header::Field {
760 name: header::LOCATION,
761 value: HeaderValue::from_static(""),
762 },
763 47 => Header::Field {
764 name: header::MAX_FORWARDS,
765 value: HeaderValue::from_static(""),
766 },
767 48 => Header::Field {
768 name: header::PROXY_AUTHENTICATE,
769 value: HeaderValue::from_static(""),
770 },
771 49 => Header::Field {
772 name: header::PROXY_AUTHORIZATION,
773 value: HeaderValue::from_static(""),
774 },
775 50 => Header::Field {
776 name: header::RANGE,
777 value: HeaderValue::from_static(""),
778 },
779 51 => Header::Field {
780 name: header::REFERER,
781 value: HeaderValue::from_static(""),
782 },
783 52 => Header::Field {
784 name: header::REFRESH,
785 value: HeaderValue::from_static(""),
786 },
787 53 => Header::Field {
788 name: header::RETRY_AFTER,
789 value: HeaderValue::from_static(""),
790 },
791 54 => Header::Field {
792 name: header::SERVER,
793 value: HeaderValue::from_static(""),
794 },
795 55 => Header::Field {
796 name: header::SET_COOKIE,
797 value: HeaderValue::from_static(""),
798 },
799 56 => Header::Field {
800 name: header::STRICT_TRANSPORT_SECURITY,
801 value: HeaderValue::from_static(""),
802 },
803 57 => Header::Field {
804 name: header::TRANSFER_ENCODING,
805 value: HeaderValue::from_static(""),
806 },
807 58 => Header::Field {
808 name: header::USER_AGENT,
809 value: HeaderValue::from_static(""),
810 },
811 59 => Header::Field {
812 name: header::VARY,
813 value: HeaderValue::from_static(""),
814 },
815 60 => Header::Field {
816 name: header::VIA,
817 value: HeaderValue::from_static(""),
818 },
819 61 => Header::Field {
820 name: header::WWW_AUTHENTICATE,
821 value: HeaderValue::from_static(""),
822 },
823 _ => unreachable!(),
824 }
825}
826
827#[cfg(test)]
828mod test {
829 use super::*;
830
831 #[test]
832 fn test_peek_u8() {
833 let b = 0xff;
834 let mut buf = Cursor::new(vec![b]);
835 assert_eq!(peek_u8(&buf), Some(b));
836 assert_eq!(buf.get_u8(), b);
837 assert_eq!(peek_u8(&buf), None);
838 }
839
840 #[test]
841 fn test_decode_string_empty() {
842 let mut de = Decoder::new(0);
843 let mut buf = BytesMut::new();
844 let err = de.decode_string(&mut Cursor::new(&mut buf)).unwrap_err();
845 assert_eq!(err, DecoderError::NeedMore(NeedMore::UnexpectedEndOfStream));
846 }
847
848 #[test]
849 #[allow(clippy::unit_cmp, clippy::let_unit_value)]
850 fn test_decode_empty() {
851 let mut de = Decoder::new(0);
852 let mut buf = BytesMut::new();
853 let empty = de.decode(&mut Cursor::new(&mut buf), |_| {}).unwrap();
854 assert_eq!(empty, ());
855 }
856
857 #[test]
858 fn test_decode_indexed_larger_than_table() {
859 let mut de = Decoder::new(0);
860
861 let mut buf = BytesMut::new();
862 buf.extend(&[0b01000000, 0x80 | 2]);
863 buf.extend(huff_encode(b"foo"));
864 buf.extend(&[0x80 | 3]);
865 buf.extend(huff_encode(b"bar"));
866
867 let mut res = vec![];
868 de.decode(&mut Cursor::new(&mut buf), |h| {
869 res.push(h);
870 })
871 .unwrap();
872
873 assert_eq!(res.len(), 1);
874 assert_eq!(de.table.size(), 0);
875
876 match res[0] {
877 Header::Field {
878 ref name,
879 ref value,
880 } => {
881 assert_eq!(name, "foo");
882 assert_eq!(value, "bar");
883 }
884 _ => panic!(),
885 }
886 }
887
888 fn huff_encode(src: &[u8]) -> BytesMut {
889 let mut buf = BytesMut::new();
890 huffman::encode(src, &mut buf);
891 buf
892 }
893
894 #[test]
895 fn test_decode_continuation_header_with_non_huff_encoded_name() {
896 let mut de = Decoder::new(0);
897 let value = huff_encode(b"bar");
898 let mut buf = BytesMut::new();
899 buf.extend(&[0b01000000, 3]);
901 buf.extend(b"foo");
902 buf.extend(&[0x80 | 3]);
904 buf.extend(&value[0..1]);
905
906 let mut res = vec![];
907 let e = de
908 .decode(&mut Cursor::new(&mut buf), |h| {
909 res.push(h);
910 })
911 .unwrap_err();
912 assert_eq!(e, DecoderError::NeedMore(NeedMore::StringUnderflow));
914
915 buf.extend(&value[1..]);
917 de.decode(&mut Cursor::new(&mut buf), |h| {
918 res.push(h);
919 })
920 .unwrap();
921
922 assert_eq!(res.len(), 1);
923 assert_eq!(de.table.size(), 0);
924
925 match res[0] {
926 Header::Field {
927 ref name,
928 ref value,
929 } => {
930 assert_eq!(name, "foo");
931 assert_eq!(value, "bar");
932 }
933 _ => panic!(),
934 }
935 }
936}