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