1 use super::{header::BytesStr, huffman, Header};
2 use crate::frame;
3 
4 use bytes::{Buf, Bytes, BytesMut};
5 use http::header;
6 use http::method::{self, Method};
7 use http::status::{self, StatusCode};
8 
9 use std::cmp;
10 use std::collections::VecDeque;
11 use std::io::Cursor;
12 use std::str::Utf8Error;
13 
14 /// Decodes headers using HPACK
15 #[derive(Debug)]
16 pub struct Decoder {
17     // Protocol indicated that the max table size will update
18     max_size_update: Option<usize>,
19     last_max_update: usize,
20     table: Table,
21     buffer: BytesMut,
22 }
23 
24 /// Represents all errors that can be encountered while performing the decoding
25 /// of an HPACK header set.
26 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
27 pub enum DecoderError {
28     InvalidRepresentation,
29     InvalidIntegerPrefix,
30     InvalidTableIndex,
31     InvalidHuffmanCode,
32     InvalidUtf8,
33     InvalidStatusCode,
34     InvalidPseudoheader,
35     InvalidMaxDynamicSize,
36     IntegerOverflow,
37     NeedMore(NeedMore),
38 }
39 
40 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
41 pub enum NeedMore {
42     UnexpectedEndOfStream,
43     IntegerUnderflow,
44     StringUnderflow,
45 }
46 
47 enum Representation {
48     /// Indexed header field representation
49     ///
50     /// An indexed header field representation identifies an entry in either the
51     /// static table or the dynamic table (see Section 2.3).
52     ///
53     /// # Header encoding
54     ///
55     /// ```text
56     ///   0   1   2   3   4   5   6   7
57     /// +---+---+---+---+---+---+---+---+
58     /// | 1 |        Index (7+)         |
59     /// +---+---------------------------+
60     /// ```
61     Indexed,
62 
63     /// Literal Header Field with Incremental Indexing
64     ///
65     /// A literal header field with incremental indexing representation results
66     /// in appending a header field to the decoded header list and inserting it
67     /// as a new entry into the dynamic table.
68     ///
69     /// # Header encoding
70     ///
71     /// ```text
72     ///   0   1   2   3   4   5   6   7
73     /// +---+---+---+---+---+---+---+---+
74     /// | 0 | 1 |      Index (6+)       |
75     /// +---+---+-----------------------+
76     /// | H |     Value Length (7+)     |
77     /// +---+---------------------------+
78     /// | Value String (Length octets)  |
79     /// +-------------------------------+
80     /// ```
81     LiteralWithIndexing,
82 
83     /// Literal Header Field without Indexing
84     ///
85     /// A literal header field without indexing representation results in
86     /// appending a header field to the decoded header list without altering the
87     /// dynamic table.
88     ///
89     /// # Header encoding
90     ///
91     /// ```text
92     ///   0   1   2   3   4   5   6   7
93     /// +---+---+---+---+---+---+---+---+
94     /// | 0 | 0 | 0 | 0 |  Index (4+)   |
95     /// +---+---+-----------------------+
96     /// | H |     Value Length (7+)     |
97     /// +---+---------------------------+
98     /// | Value String (Length octets)  |
99     /// +-------------------------------+
100     /// ```
101     LiteralWithoutIndexing,
102 
103     /// Literal Header Field Never Indexed
104     ///
105     /// A literal header field never-indexed representation results in appending
106     /// a header field to the decoded header list without altering the dynamic
107     /// table. Intermediaries MUST use the same representation for encoding this
108     /// header field.
109     ///
110     /// ```text
111     ///   0   1   2   3   4   5   6   7
112     /// +---+---+---+---+---+---+---+---+
113     /// | 0 | 0 | 0 | 1 |  Index (4+)   |
114     /// +---+---+-----------------------+
115     /// | H |     Value Length (7+)     |
116     /// +---+---------------------------+
117     /// | Value String (Length octets)  |
118     /// +-------------------------------+
119     /// ```
120     LiteralNeverIndexed,
121 
122     /// Dynamic Table Size Update
123     ///
124     /// A dynamic table size update signals a change to the size of the dynamic
125     /// table.
126     ///
127     /// # Header encoding
128     ///
129     /// ```text
130     ///   0   1   2   3   4   5   6   7
131     /// +---+---+---+---+---+---+---+---+
132     /// | 0 | 0 | 1 |   Max size (5+)   |
133     /// +---+---------------------------+
134     /// ```
135     SizeUpdate,
136 }
137 
138 #[derive(Debug)]
139 struct Table {
140     entries: VecDeque<Header>,
141     size: usize,
142     max_size: usize,
143 }
144 
145 struct StringMarker {
146     offset: usize,
147     len: usize,
148     string: Option<Bytes>,
149 }
150 
151 // ===== impl Decoder =====
152 
153 impl Decoder {
154     /// Creates a new `Decoder` with all settings set to default values.
new(size: usize) -> Decoder155     pub fn new(size: usize) -> Decoder {
156         Decoder {
157             max_size_update: None,
158             last_max_update: size,
159             table: Table::new(size),
160             buffer: BytesMut::with_capacity(4096),
161         }
162     }
163 
164     /// Queues a potential size update
165     #[allow(dead_code)]
queue_size_update(&mut self, size: usize)166     pub fn queue_size_update(&mut self, size: usize) {
167         let size = match self.max_size_update {
168             Some(v) => cmp::max(v, size),
169             None => size,
170         };
171 
172         self.max_size_update = Some(size);
173     }
174 
175     /// Decodes the headers found in the given buffer.
decode<F>( &mut self, src: &mut Cursor<&mut BytesMut>, mut f: F, ) -> Result<(), DecoderError> where F: FnMut(Header),176     pub fn decode<F>(
177         &mut self,
178         src: &mut Cursor<&mut BytesMut>,
179         mut f: F,
180     ) -> Result<(), DecoderError>
181     where
182         F: FnMut(Header),
183     {
184         use self::Representation::*;
185 
186         let mut can_resize = true;
187 
188         if let Some(size) = self.max_size_update.take() {
189             self.last_max_update = size;
190         }
191 
192         let span = tracing::trace_span!("hpack::decode");
193         let _e = span.enter();
194 
195         tracing::trace!("decode");
196 
197         while let Some(ty) = peek_u8(src) {
198             // At this point we are always at the beginning of the next block
199             // within the HPACK data. The type of the block can always be
200             // determined from the first byte.
201             match Representation::load(ty)? {
202                 Indexed => {
203                     tracing::trace!(rem = src.remaining(), kind = %"Indexed");
204                     can_resize = false;
205                     let entry = self.decode_indexed(src)?;
206                     consume(src);
207                     f(entry);
208                 }
209                 LiteralWithIndexing => {
210                     tracing::trace!(rem = src.remaining(), kind = %"LiteralWithIndexing");
211                     can_resize = false;
212                     let entry = self.decode_literal(src, true)?;
213 
214                     // Insert the header into the table
215                     self.table.insert(entry.clone());
216                     consume(src);
217 
218                     f(entry);
219                 }
220                 LiteralWithoutIndexing => {
221                     tracing::trace!(rem = src.remaining(), kind = %"LiteralWithoutIndexing");
222                     can_resize = false;
223                     let entry = self.decode_literal(src, false)?;
224                     consume(src);
225                     f(entry);
226                 }
227                 LiteralNeverIndexed => {
228                     tracing::trace!(rem = src.remaining(), kind = %"LiteralNeverIndexed");
229                     can_resize = false;
230                     let entry = self.decode_literal(src, false)?;
231                     consume(src);
232 
233                     // TODO: Track that this should never be indexed
234 
235                     f(entry);
236                 }
237                 SizeUpdate => {
238                     tracing::trace!(rem = src.remaining(), kind = %"SizeUpdate");
239                     if !can_resize {
240                         return Err(DecoderError::InvalidMaxDynamicSize);
241                     }
242 
243                     // Handle the dynamic table size update
244                     self.process_size_update(src)?;
245                     consume(src);
246                 }
247             }
248         }
249 
250         Ok(())
251     }
252 
process_size_update(&mut self, buf: &mut Cursor<&mut BytesMut>) -> Result<(), DecoderError>253     fn process_size_update(&mut self, buf: &mut Cursor<&mut BytesMut>) -> Result<(), DecoderError> {
254         let new_size = decode_int(buf, 5)?;
255 
256         if new_size > self.last_max_update {
257             return Err(DecoderError::InvalidMaxDynamicSize);
258         }
259 
260         tracing::debug!(
261             from = self.table.size(),
262             to = new_size,
263             "Decoder changed max table size"
264         );
265 
266         self.table.set_max_size(new_size);
267 
268         Ok(())
269     }
270 
decode_indexed(&self, buf: &mut Cursor<&mut BytesMut>) -> Result<Header, DecoderError>271     fn decode_indexed(&self, buf: &mut Cursor<&mut BytesMut>) -> Result<Header, DecoderError> {
272         let index = decode_int(buf, 7)?;
273         self.table.get(index)
274     }
275 
decode_literal( &mut self, buf: &mut Cursor<&mut BytesMut>, index: bool, ) -> Result<Header, DecoderError>276     fn decode_literal(
277         &mut self,
278         buf: &mut Cursor<&mut BytesMut>,
279         index: bool,
280     ) -> Result<Header, DecoderError> {
281         let prefix = if index { 6 } else { 4 };
282 
283         // Extract the table index for the name, or 0 if not indexed
284         let table_idx = decode_int(buf, prefix)?;
285 
286         // First, read the header name
287         if table_idx == 0 {
288             let old_pos = buf.position();
289             let name_marker = self.try_decode_string(buf)?;
290             let value_marker = self.try_decode_string(buf)?;
291             buf.set_position(old_pos);
292             // Read the name as a literal
293             let name = name_marker.consume(buf);
294             let value = value_marker.consume(buf);
295             Header::new(name, value)
296         } else {
297             let e = self.table.get(table_idx)?;
298             let value = self.decode_string(buf)?;
299 
300             e.name().into_entry(value)
301         }
302     }
303 
try_decode_string( &mut self, buf: &mut Cursor<&mut BytesMut>, ) -> Result<StringMarker, DecoderError>304     fn try_decode_string(
305         &mut self,
306         buf: &mut Cursor<&mut BytesMut>,
307     ) -> Result<StringMarker, DecoderError> {
308         let old_pos = buf.position();
309         const HUFF_FLAG: u8 = 0b1000_0000;
310 
311         // The first bit in the first byte contains the huffman encoded flag.
312         let huff = match peek_u8(buf) {
313             Some(hdr) => (hdr & HUFF_FLAG) == HUFF_FLAG,
314             None => return Err(DecoderError::NeedMore(NeedMore::UnexpectedEndOfStream)),
315         };
316 
317         // Decode the string length using 7 bit prefix
318         let len = decode_int(buf, 7)?;
319 
320         if len > buf.remaining() {
321             tracing::trace!(len, remaining = buf.remaining(), "decode_string underflow",);
322             return Err(DecoderError::NeedMore(NeedMore::StringUnderflow));
323         }
324 
325         let offset = (buf.position() - old_pos) as usize;
326         if huff {
327             let ret = {
328                 let raw = &buf.chunk()[..len];
329                 huffman::decode(raw, &mut self.buffer).map(|buf| StringMarker {
330                     offset,
331                     len,
332                     string: Some(BytesMut::freeze(buf)),
333                 })
334             };
335 
336             buf.advance(len);
337             ret
338         } else {
339             buf.advance(len);
340             Ok(StringMarker {
341                 offset,
342                 len,
343                 string: None,
344             })
345         }
346     }
347 
decode_string(&mut self, buf: &mut Cursor<&mut BytesMut>) -> Result<Bytes, DecoderError>348     fn decode_string(&mut self, buf: &mut Cursor<&mut BytesMut>) -> Result<Bytes, DecoderError> {
349         let old_pos = buf.position();
350         let marker = self.try_decode_string(buf)?;
351         buf.set_position(old_pos);
352         Ok(marker.consume(buf))
353     }
354 }
355 
356 impl Default for Decoder {
default() -> Decoder357     fn default() -> Decoder {
358         Decoder::new(4096)
359     }
360 }
361 
362 // ===== impl Representation =====
363 
364 impl Representation {
load(byte: u8) -> Result<Representation, DecoderError>365     pub fn load(byte: u8) -> Result<Representation, DecoderError> {
366         const INDEXED: u8 = 0b1000_0000;
367         const LITERAL_WITH_INDEXING: u8 = 0b0100_0000;
368         const LITERAL_WITHOUT_INDEXING: u8 = 0b1111_0000;
369         const LITERAL_NEVER_INDEXED: u8 = 0b0001_0000;
370         const SIZE_UPDATE_MASK: u8 = 0b1110_0000;
371         const SIZE_UPDATE: u8 = 0b0010_0000;
372 
373         // TODO: What did I even write here?
374 
375         if byte & INDEXED == INDEXED {
376             Ok(Representation::Indexed)
377         } else if byte & LITERAL_WITH_INDEXING == LITERAL_WITH_INDEXING {
378             Ok(Representation::LiteralWithIndexing)
379         } else if byte & LITERAL_WITHOUT_INDEXING == 0 {
380             Ok(Representation::LiteralWithoutIndexing)
381         } else if byte & LITERAL_WITHOUT_INDEXING == LITERAL_NEVER_INDEXED {
382             Ok(Representation::LiteralNeverIndexed)
383         } else if byte & SIZE_UPDATE_MASK == SIZE_UPDATE {
384             Ok(Representation::SizeUpdate)
385         } else {
386             Err(DecoderError::InvalidRepresentation)
387         }
388     }
389 }
390 
decode_int<B: Buf>(buf: &mut B, prefix_size: u8) -> Result<usize, DecoderError>391 fn decode_int<B: Buf>(buf: &mut B, prefix_size: u8) -> Result<usize, DecoderError> {
392     // The octet limit is chosen such that the maximum allowed *value* can
393     // never overflow an unsigned 32-bit integer. The maximum value of any
394     // integer that can be encoded with 5 octets is ~2^28
395     const MAX_BYTES: usize = 5;
396     const VARINT_MASK: u8 = 0b0111_1111;
397     const VARINT_FLAG: u8 = 0b1000_0000;
398 
399     if prefix_size < 1 || prefix_size > 8 {
400         return Err(DecoderError::InvalidIntegerPrefix);
401     }
402 
403     if !buf.has_remaining() {
404         return Err(DecoderError::NeedMore(NeedMore::IntegerUnderflow));
405     }
406 
407     let mask = if prefix_size == 8 {
408         0xFF
409     } else {
410         (1u8 << prefix_size).wrapping_sub(1)
411     };
412 
413     let mut ret = (buf.get_u8() & mask) as usize;
414 
415     if ret < mask as usize {
416         // Value fits in the prefix bits
417         return Ok(ret);
418     }
419 
420     // The int did not fit in the prefix bits, so continue reading.
421     //
422     // The total number of bytes used to represent the int. The first byte was
423     // the prefix, so start at 1.
424     let mut bytes = 1;
425 
426     // The rest of the int is stored as a varint -- 7 bits for the value and 1
427     // bit to indicate if it is the last byte.
428     let mut shift = 0;
429 
430     while buf.has_remaining() {
431         let b = buf.get_u8();
432 
433         bytes += 1;
434         ret += ((b & VARINT_MASK) as usize) << shift;
435         shift += 7;
436 
437         if b & VARINT_FLAG == 0 {
438             return Ok(ret);
439         }
440 
441         if bytes == MAX_BYTES {
442             // The spec requires that this situation is an error
443             return Err(DecoderError::IntegerOverflow);
444         }
445     }
446 
447     Err(DecoderError::NeedMore(NeedMore::IntegerUnderflow))
448 }
449 
peek_u8<B: Buf>(buf: &B) -> Option<u8>450 fn peek_u8<B: Buf>(buf: &B) -> Option<u8> {
451     if buf.has_remaining() {
452         Some(buf.chunk()[0])
453     } else {
454         None
455     }
456 }
457 
take(buf: &mut Cursor<&mut BytesMut>, n: usize) -> Bytes458 fn take(buf: &mut Cursor<&mut BytesMut>, n: usize) -> Bytes {
459     let pos = buf.position() as usize;
460     let mut head = buf.get_mut().split_to(pos + n);
461     buf.set_position(0);
462     head.advance(pos);
463     head.freeze()
464 }
465 
466 impl StringMarker {
consume(self, buf: &mut Cursor<&mut BytesMut>) -> Bytes467     fn consume(self, buf: &mut Cursor<&mut BytesMut>) -> Bytes {
468         buf.advance(self.offset);
469         match self.string {
470             Some(string) => {
471                 buf.advance(self.len);
472                 string
473             }
474             None => take(buf, self.len),
475         }
476     }
477 }
478 
consume(buf: &mut Cursor<&mut BytesMut>)479 fn consume(buf: &mut Cursor<&mut BytesMut>) {
480     // remove bytes from the internal BytesMut when they have been successfully
481     // decoded. This is a more permanent cursor position, which will be
482     // used to resume if decoding was only partial.
483     take(buf, 0);
484 }
485 
486 // ===== impl Table =====
487 
488 impl Table {
new(max_size: usize) -> Table489     fn new(max_size: usize) -> Table {
490         Table {
491             entries: VecDeque::new(),
492             size: 0,
493             max_size,
494         }
495     }
496 
size(&self) -> usize497     fn size(&self) -> usize {
498         self.size
499     }
500 
501     /// Returns the entry located at the given index.
502     ///
503     /// The table is 1-indexed and constructed in such a way that the first
504     /// entries belong to the static table, followed by entries in the dynamic
505     /// table. They are merged into a single index address space, though.
506     ///
507     /// This is according to the [HPACK spec, section 2.3.3.]
508     /// (http://http2.github.io/http2-spec/compression.html#index.address.space)
get(&self, index: usize) -> Result<Header, DecoderError>509     pub fn get(&self, index: usize) -> Result<Header, DecoderError> {
510         if index == 0 {
511             return Err(DecoderError::InvalidTableIndex);
512         }
513 
514         if index <= 61 {
515             return Ok(get_static(index));
516         }
517 
518         // Convert the index for lookup in the entries structure.
519         match self.entries.get(index - 62) {
520             Some(e) => Ok(e.clone()),
521             None => Err(DecoderError::InvalidTableIndex),
522         }
523     }
524 
insert(&mut self, entry: Header)525     fn insert(&mut self, entry: Header) {
526         let len = entry.len();
527 
528         self.reserve(len);
529 
530         if self.size + len <= self.max_size {
531             self.size += len;
532 
533             // Track the entry
534             self.entries.push_front(entry);
535         }
536     }
537 
set_max_size(&mut self, size: usize)538     fn set_max_size(&mut self, size: usize) {
539         self.max_size = size;
540         // Make the table size fit within the new constraints.
541         self.consolidate();
542     }
543 
reserve(&mut self, size: usize)544     fn reserve(&mut self, size: usize) {
545         while self.size + size > self.max_size {
546             match self.entries.pop_back() {
547                 Some(last) => {
548                     self.size -= last.len();
549                 }
550                 None => return,
551             }
552         }
553     }
554 
consolidate(&mut self)555     fn consolidate(&mut self) {
556         while self.size > self.max_size {
557             {
558                 let last = match self.entries.back() {
559                     Some(x) => x,
560                     None => {
561                         // Can never happen as the size of the table must reach
562                         // 0 by the time we've exhausted all elements.
563                         panic!("Size of table != 0, but no headers left!");
564                     }
565                 };
566 
567                 self.size -= last.len();
568             }
569 
570             self.entries.pop_back();
571         }
572     }
573 }
574 
575 // ===== impl DecoderError =====
576 
577 impl From<Utf8Error> for DecoderError {
from(_: Utf8Error) -> DecoderError578     fn from(_: Utf8Error) -> DecoderError {
579         // TODO: Better error?
580         DecoderError::InvalidUtf8
581     }
582 }
583 
584 impl From<header::InvalidHeaderValue> for DecoderError {
from(_: header::InvalidHeaderValue) -> DecoderError585     fn from(_: header::InvalidHeaderValue) -> DecoderError {
586         // TODO: Better error?
587         DecoderError::InvalidUtf8
588     }
589 }
590 
591 impl From<header::InvalidHeaderName> for DecoderError {
from(_: header::InvalidHeaderName) -> DecoderError592     fn from(_: header::InvalidHeaderName) -> DecoderError {
593         // TODO: Better error
594         DecoderError::InvalidUtf8
595     }
596 }
597 
598 impl From<method::InvalidMethod> for DecoderError {
from(_: method::InvalidMethod) -> DecoderError599     fn from(_: method::InvalidMethod) -> DecoderError {
600         // TODO: Better error
601         DecoderError::InvalidUtf8
602     }
603 }
604 
605 impl From<status::InvalidStatusCode> for DecoderError {
from(_: status::InvalidStatusCode) -> DecoderError606     fn from(_: status::InvalidStatusCode) -> DecoderError {
607         // TODO: Better error
608         DecoderError::InvalidUtf8
609     }
610 }
611 
612 impl From<DecoderError> for frame::Error {
from(src: DecoderError) -> Self613     fn from(src: DecoderError) -> Self {
614         frame::Error::Hpack(src)
615     }
616 }
617 
618 /// Get an entry from the static table
get_static(idx: usize) -> Header619 pub fn get_static(idx: usize) -> Header {
620     use http::header::HeaderValue;
621 
622     match idx {
623         1 => Header::Authority(BytesStr::from_static("")),
624         2 => Header::Method(Method::GET),
625         3 => Header::Method(Method::POST),
626         4 => Header::Path(BytesStr::from_static("/")),
627         5 => Header::Path(BytesStr::from_static("/index.html")),
628         6 => Header::Scheme(BytesStr::from_static("http")),
629         7 => Header::Scheme(BytesStr::from_static("https")),
630         8 => Header::Status(StatusCode::OK),
631         9 => Header::Status(StatusCode::NO_CONTENT),
632         10 => Header::Status(StatusCode::PARTIAL_CONTENT),
633         11 => Header::Status(StatusCode::NOT_MODIFIED),
634         12 => Header::Status(StatusCode::BAD_REQUEST),
635         13 => Header::Status(StatusCode::NOT_FOUND),
636         14 => Header::Status(StatusCode::INTERNAL_SERVER_ERROR),
637         15 => Header::Field {
638             name: header::ACCEPT_CHARSET,
639             value: HeaderValue::from_static(""),
640         },
641         16 => Header::Field {
642             name: header::ACCEPT_ENCODING,
643             value: HeaderValue::from_static("gzip, deflate"),
644         },
645         17 => Header::Field {
646             name: header::ACCEPT_LANGUAGE,
647             value: HeaderValue::from_static(""),
648         },
649         18 => Header::Field {
650             name: header::ACCEPT_RANGES,
651             value: HeaderValue::from_static(""),
652         },
653         19 => Header::Field {
654             name: header::ACCEPT,
655             value: HeaderValue::from_static(""),
656         },
657         20 => Header::Field {
658             name: header::ACCESS_CONTROL_ALLOW_ORIGIN,
659             value: HeaderValue::from_static(""),
660         },
661         21 => Header::Field {
662             name: header::AGE,
663             value: HeaderValue::from_static(""),
664         },
665         22 => Header::Field {
666             name: header::ALLOW,
667             value: HeaderValue::from_static(""),
668         },
669         23 => Header::Field {
670             name: header::AUTHORIZATION,
671             value: HeaderValue::from_static(""),
672         },
673         24 => Header::Field {
674             name: header::CACHE_CONTROL,
675             value: HeaderValue::from_static(""),
676         },
677         25 => Header::Field {
678             name: header::CONTENT_DISPOSITION,
679             value: HeaderValue::from_static(""),
680         },
681         26 => Header::Field {
682             name: header::CONTENT_ENCODING,
683             value: HeaderValue::from_static(""),
684         },
685         27 => Header::Field {
686             name: header::CONTENT_LANGUAGE,
687             value: HeaderValue::from_static(""),
688         },
689         28 => Header::Field {
690             name: header::CONTENT_LENGTH,
691             value: HeaderValue::from_static(""),
692         },
693         29 => Header::Field {
694             name: header::CONTENT_LOCATION,
695             value: HeaderValue::from_static(""),
696         },
697         30 => Header::Field {
698             name: header::CONTENT_RANGE,
699             value: HeaderValue::from_static(""),
700         },
701         31 => Header::Field {
702             name: header::CONTENT_TYPE,
703             value: HeaderValue::from_static(""),
704         },
705         32 => Header::Field {
706             name: header::COOKIE,
707             value: HeaderValue::from_static(""),
708         },
709         33 => Header::Field {
710             name: header::DATE,
711             value: HeaderValue::from_static(""),
712         },
713         34 => Header::Field {
714             name: header::ETAG,
715             value: HeaderValue::from_static(""),
716         },
717         35 => Header::Field {
718             name: header::EXPECT,
719             value: HeaderValue::from_static(""),
720         },
721         36 => Header::Field {
722             name: header::EXPIRES,
723             value: HeaderValue::from_static(""),
724         },
725         37 => Header::Field {
726             name: header::FROM,
727             value: HeaderValue::from_static(""),
728         },
729         38 => Header::Field {
730             name: header::HOST,
731             value: HeaderValue::from_static(""),
732         },
733         39 => Header::Field {
734             name: header::IF_MATCH,
735             value: HeaderValue::from_static(""),
736         },
737         40 => Header::Field {
738             name: header::IF_MODIFIED_SINCE,
739             value: HeaderValue::from_static(""),
740         },
741         41 => Header::Field {
742             name: header::IF_NONE_MATCH,
743             value: HeaderValue::from_static(""),
744         },
745         42 => Header::Field {
746             name: header::IF_RANGE,
747             value: HeaderValue::from_static(""),
748         },
749         43 => Header::Field {
750             name: header::IF_UNMODIFIED_SINCE,
751             value: HeaderValue::from_static(""),
752         },
753         44 => Header::Field {
754             name: header::LAST_MODIFIED,
755             value: HeaderValue::from_static(""),
756         },
757         45 => Header::Field {
758             name: header::LINK,
759             value: HeaderValue::from_static(""),
760         },
761         46 => Header::Field {
762             name: header::LOCATION,
763             value: HeaderValue::from_static(""),
764         },
765         47 => Header::Field {
766             name: header::MAX_FORWARDS,
767             value: HeaderValue::from_static(""),
768         },
769         48 => Header::Field {
770             name: header::PROXY_AUTHENTICATE,
771             value: HeaderValue::from_static(""),
772         },
773         49 => Header::Field {
774             name: header::PROXY_AUTHORIZATION,
775             value: HeaderValue::from_static(""),
776         },
777         50 => Header::Field {
778             name: header::RANGE,
779             value: HeaderValue::from_static(""),
780         },
781         51 => Header::Field {
782             name: header::REFERER,
783             value: HeaderValue::from_static(""),
784         },
785         52 => Header::Field {
786             name: header::REFRESH,
787             value: HeaderValue::from_static(""),
788         },
789         53 => Header::Field {
790             name: header::RETRY_AFTER,
791             value: HeaderValue::from_static(""),
792         },
793         54 => Header::Field {
794             name: header::SERVER,
795             value: HeaderValue::from_static(""),
796         },
797         55 => Header::Field {
798             name: header::SET_COOKIE,
799             value: HeaderValue::from_static(""),
800         },
801         56 => Header::Field {
802             name: header::STRICT_TRANSPORT_SECURITY,
803             value: HeaderValue::from_static(""),
804         },
805         57 => Header::Field {
806             name: header::TRANSFER_ENCODING,
807             value: HeaderValue::from_static(""),
808         },
809         58 => Header::Field {
810             name: header::USER_AGENT,
811             value: HeaderValue::from_static(""),
812         },
813         59 => Header::Field {
814             name: header::VARY,
815             value: HeaderValue::from_static(""),
816         },
817         60 => Header::Field {
818             name: header::VIA,
819             value: HeaderValue::from_static(""),
820         },
821         61 => Header::Field {
822             name: header::WWW_AUTHENTICATE,
823             value: HeaderValue::from_static(""),
824         },
825         _ => unreachable!(),
826     }
827 }
828 
829 #[cfg(test)]
830 mod test {
831     use super::*;
832 
833     #[test]
test_peek_u8()834     fn test_peek_u8() {
835         let b = 0xff;
836         let mut buf = Cursor::new(vec![b]);
837         assert_eq!(peek_u8(&buf), Some(b));
838         assert_eq!(buf.get_u8(), b);
839         assert_eq!(peek_u8(&buf), None);
840     }
841 
842     #[test]
test_decode_string_empty()843     fn test_decode_string_empty() {
844         let mut de = Decoder::new(0);
845         let mut buf = BytesMut::new();
846         let err = de.decode_string(&mut Cursor::new(&mut buf)).unwrap_err();
847         assert_eq!(err, DecoderError::NeedMore(NeedMore::UnexpectedEndOfStream));
848     }
849 
850     #[test]
test_decode_empty()851     fn test_decode_empty() {
852         let mut de = Decoder::new(0);
853         let mut buf = BytesMut::new();
854         let _: () = de.decode(&mut Cursor::new(&mut buf), |_| {}).unwrap();
855     }
856 
857     #[test]
test_decode_indexed_larger_than_table()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 
huff_encode(src: &[u8]) -> BytesMut888     fn huff_encode(src: &[u8]) -> BytesMut {
889         let mut buf = BytesMut::new();
890         huffman::encode(src, &mut buf);
891         buf
892     }
893 
894     #[test]
test_decode_continuation_header_with_non_huff_encoded_name()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         // header name is non_huff encoded
900         buf.extend([0b01000000, 3]);
901         buf.extend(b"foo");
902         // header value is partial
903         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         // decode error because the header value is partial
913         assert_eq!(e, DecoderError::NeedMore(NeedMore::StringUnderflow));
914 
915         // extend buf with the remaining header value
916         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 }
937