1 use super::{util, StreamDependency, StreamId};
2 use frame::{Error, Frame, Head, Kind};
3 use hpack;
4 
5 use http::{uri, HeaderMap, Method, StatusCode, Uri};
6 use http::header::{self, HeaderName, HeaderValue};
7 
8 use byteorder::{BigEndian, ByteOrder};
9 use bytes::{Bytes, BytesMut};
10 use string::String;
11 
12 use std::fmt;
13 use std::io::Cursor;
14 
15 // Minimum MAX_FRAME_SIZE is 16kb, so save some arbitrary space for frame
16 // head and other header bits.
17 const MAX_HEADER_LENGTH: usize = 1024 * 16 - 100;
18 
19 /// Header frame
20 ///
21 /// This could be either a request or a response.
22 #[derive(Eq, PartialEq)]
23 pub struct Headers {
24     /// The ID of the stream with which this frame is associated.
25     stream_id: StreamId,
26 
27     /// The stream dependency information, if any.
28     stream_dep: Option<StreamDependency>,
29 
30     /// The header block fragment
31     header_block: HeaderBlock,
32 
33     /// The associated flags
34     flags: HeadersFlag,
35 }
36 
37 #[derive(Copy, Clone, Eq, PartialEq)]
38 pub struct HeadersFlag(u8);
39 
40 #[derive(Eq, PartialEq)]
41 pub struct PushPromise {
42     /// The ID of the stream with which this frame is associated.
43     stream_id: StreamId,
44 
45     /// The ID of the stream being reserved by this PushPromise.
46     promised_id: StreamId,
47 
48     /// The header block fragment
49     header_block: HeaderBlock,
50 
51     /// The associated flags
52     flags: PushPromiseFlag,
53 }
54 
55 #[derive(Copy, Clone, Eq, PartialEq)]
56 pub struct PushPromiseFlag(u8);
57 
58 #[derive(Debug)]
59 pub struct Continuation {
60     /// Stream ID of continuation frame
61     stream_id: StreamId,
62 
63     header_block: EncodingHeaderBlock,
64 }
65 
66 // TODO: These fields shouldn't be `pub`
67 #[derive(Debug, Default, Eq, PartialEq)]
68 pub struct Pseudo {
69     // Request
70     pub method: Option<Method>,
71     pub scheme: Option<String<Bytes>>,
72     pub authority: Option<String<Bytes>>,
73     pub path: Option<String<Bytes>>,
74 
75     // Response
76     pub status: Option<StatusCode>,
77 }
78 
79 #[derive(Debug)]
80 pub struct Iter {
81     /// Pseudo headers
82     pseudo: Option<Pseudo>,
83 
84     /// Header fields
85     fields: header::IntoIter<HeaderValue>,
86 }
87 
88 #[derive(Debug, PartialEq, Eq)]
89 struct HeaderBlock {
90     /// The decoded header fields
91     fields: HeaderMap,
92 
93     /// Set to true if decoding went over the max header list size.
94     is_over_size: bool,
95 
96     /// Pseudo headers, these are broken out as they must be sent as part of the
97     /// headers frame.
98     pseudo: Pseudo,
99 }
100 
101 #[derive(Debug)]
102 struct EncodingHeaderBlock {
103     /// Argument to pass to the HPACK encoder to resume encoding
104     hpack: Option<hpack::EncodeState>,
105 
106     /// remaining headers to encode
107     headers: Iter,
108 }
109 
110 const END_STREAM: u8 = 0x1;
111 const END_HEADERS: u8 = 0x4;
112 const PADDED: u8 = 0x8;
113 const PRIORITY: u8 = 0x20;
114 const ALL: u8 = END_STREAM | END_HEADERS | PADDED | PRIORITY;
115 
116 // ===== impl Headers =====
117 
118 impl Headers {
119     /// Create a new HEADERS frame
new(stream_id: StreamId, pseudo: Pseudo, fields: HeaderMap) -> Self120     pub fn new(stream_id: StreamId, pseudo: Pseudo, fields: HeaderMap) -> Self {
121         Headers {
122             stream_id: stream_id,
123             stream_dep: None,
124             header_block: HeaderBlock {
125                 fields: fields,
126                 is_over_size: false,
127                 pseudo: pseudo,
128             },
129             flags: HeadersFlag::default(),
130         }
131     }
132 
trailers(stream_id: StreamId, fields: HeaderMap) -> Self133     pub fn trailers(stream_id: StreamId, fields: HeaderMap) -> Self {
134         let mut flags = HeadersFlag::default();
135         flags.set_end_stream();
136 
137         Headers {
138             stream_id,
139             stream_dep: None,
140             header_block: HeaderBlock {
141                 fields: fields,
142                 is_over_size: false,
143                 pseudo: Pseudo::default(),
144             },
145             flags: flags,
146         }
147     }
148 
149     /// Loads the header frame but doesn't actually do HPACK decoding.
150     ///
151     /// HPACK decoding is done in the `load_hpack` step.
load(head: Head, mut src: BytesMut) -> Result<(Self, BytesMut), Error>152     pub fn load(head: Head, mut src: BytesMut) -> Result<(Self, BytesMut), Error> {
153         let flags = HeadersFlag(head.flag());
154         let mut pad = 0;
155 
156         trace!("loading headers; flags={:?}", flags);
157 
158         // Read the padding length
159         if flags.is_padded() {
160             if src.len() < 1 {
161                 return Err(Error::MalformedMessage);
162             }
163             pad = src[0] as usize;
164 
165             // Drop the padding
166             let _ = src.split_to(1);
167         }
168 
169         // Read the stream dependency
170         let stream_dep = if flags.is_priority() {
171             if src.len() < 5 {
172                 return Err(Error::MalformedMessage);
173             }
174             let stream_dep = StreamDependency::load(&src[..5])?;
175 
176             if stream_dep.dependency_id() == head.stream_id() {
177                 return Err(Error::InvalidDependencyId);
178             }
179 
180             // Drop the next 5 bytes
181             let _ = src.split_to(5);
182 
183             Some(stream_dep)
184         } else {
185             None
186         };
187 
188         if pad > 0 {
189             if pad > src.len() {
190                 return Err(Error::TooMuchPadding);
191             }
192 
193             let len = src.len() - pad;
194             src.truncate(len);
195         }
196 
197         let headers = Headers {
198             stream_id: head.stream_id(),
199             stream_dep: stream_dep,
200             header_block: HeaderBlock {
201                 fields: HeaderMap::new(),
202                 is_over_size: false,
203                 pseudo: Pseudo::default(),
204             },
205             flags: flags,
206         };
207 
208         Ok((headers, src))
209     }
210 
load_hpack(&mut self, src: &mut BytesMut, max_header_list_size: usize, decoder: &mut hpack::Decoder) -> Result<(), Error>211     pub fn load_hpack(&mut self, src: &mut BytesMut, max_header_list_size: usize, decoder: &mut hpack::Decoder) -> Result<(), Error> {
212         self.header_block.load(src, max_header_list_size, decoder)
213     }
214 
stream_id(&self) -> StreamId215     pub fn stream_id(&self) -> StreamId {
216         self.stream_id
217     }
218 
is_end_headers(&self) -> bool219     pub fn is_end_headers(&self) -> bool {
220         self.flags.is_end_headers()
221     }
222 
set_end_headers(&mut self)223     pub fn set_end_headers(&mut self) {
224         self.flags.set_end_headers();
225     }
226 
is_end_stream(&self) -> bool227     pub fn is_end_stream(&self) -> bool {
228         self.flags.is_end_stream()
229     }
230 
set_end_stream(&mut self)231     pub fn set_end_stream(&mut self) {
232         self.flags.set_end_stream()
233     }
234 
is_over_size(&self) -> bool235     pub fn is_over_size(&self) -> bool {
236         self.header_block.is_over_size
237     }
238 
has_too_big_field(&self) -> bool239     pub(crate) fn has_too_big_field(&self) -> bool {
240         self.header_block.has_too_big_field()
241     }
242 
into_parts(self) -> (Pseudo, HeaderMap)243     pub fn into_parts(self) -> (Pseudo, HeaderMap) {
244         (self.header_block.pseudo, self.header_block.fields)
245     }
246 
247     #[cfg(feature = "unstable")]
pseudo_mut(&mut self) -> &mut Pseudo248     pub fn pseudo_mut(&mut self) -> &mut Pseudo {
249         &mut self.header_block.pseudo
250     }
251 
fields(&self) -> &HeaderMap252     pub fn fields(&self) -> &HeaderMap {
253         &self.header_block.fields
254     }
255 
into_fields(self) -> HeaderMap256     pub fn into_fields(self) -> HeaderMap {
257         self.header_block.fields
258     }
259 
encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut) -> Option<Continuation>260     pub fn encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut) -> Option<Continuation> {
261         // At this point, the `is_end_headers` flag should always be set
262         debug_assert!(self.flags.is_end_headers());
263 
264         // Get the HEADERS frame head
265         let head = self.head();
266 
267         self.header_block.into_encoding()
268             .encode(&head, encoder, dst, |_| {
269             })
270     }
271 
head(&self) -> Head272     fn head(&self) -> Head {
273         Head::new(Kind::Headers, self.flags.into(), self.stream_id)
274     }
275 }
276 
277 impl<T> From<Headers> for Frame<T> {
from(src: Headers) -> Self278     fn from(src: Headers) -> Self {
279         Frame::Headers(src)
280     }
281 }
282 
283 impl fmt::Debug for Headers {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result284     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
285         let mut builder = f.debug_struct("Headers");
286         builder
287             .field("stream_id", &self.stream_id)
288             .field("flags", &self.flags);
289 
290         if let Some(ref dep) = self.stream_dep {
291             builder.field("stream_dep", dep);
292         }
293 
294         // `fields` and `pseudo` purposefully not included
295         builder.finish()
296     }
297 }
298 
299 // ===== impl PushPromise =====
300 
301 impl PushPromise {
302     /// Loads the push promise frame but doesn't actually do HPACK decoding.
303     ///
304     /// HPACK decoding is done in the `load_hpack` step.
load(head: Head, mut src: BytesMut) -> Result<(Self, BytesMut), Error>305     pub fn load(head: Head, mut src: BytesMut) -> Result<(Self, BytesMut), Error> {
306         let flags = PushPromiseFlag(head.flag());
307         let mut pad = 0;
308 
309         // Read the padding length
310         if flags.is_padded() {
311             if src.len() < 1 {
312                 return Err(Error::MalformedMessage);
313             }
314 
315             // TODO: Ensure payload is sized correctly
316             pad = src[0] as usize;
317 
318             // Drop the padding
319             let _ = src.split_to(1);
320         }
321 
322         if src.len() < 5 {
323             return Err(Error::MalformedMessage);
324         }
325 
326         let (promised_id, _) = StreamId::parse(&src[..4]);
327         // Drop promised_id bytes
328         let _ = src.split_to(4);
329 
330         if pad > 0 {
331             if pad > src.len() {
332                 return Err(Error::TooMuchPadding);
333             }
334 
335             let len = src.len() - pad;
336             src.truncate(len);
337         }
338 
339         let frame = PushPromise {
340             flags: flags,
341             header_block: HeaderBlock {
342                 fields: HeaderMap::new(),
343                 is_over_size: false,
344                 pseudo: Pseudo::default(),
345             },
346             promised_id: promised_id,
347             stream_id: head.stream_id(),
348         };
349         Ok((frame, src))
350     }
351 
load_hpack(&mut self, src: &mut BytesMut, max_header_list_size: usize, decoder: &mut hpack::Decoder) -> Result<(), Error>352     pub fn load_hpack(&mut self, src: &mut BytesMut, max_header_list_size: usize, decoder: &mut hpack::Decoder) -> Result<(), Error> {
353         self.header_block.load(src, max_header_list_size, decoder)
354     }
355 
stream_id(&self) -> StreamId356     pub fn stream_id(&self) -> StreamId {
357         self.stream_id
358     }
359 
promised_id(&self) -> StreamId360     pub fn promised_id(&self) -> StreamId {
361         self.promised_id
362     }
363 
is_end_headers(&self) -> bool364     pub fn is_end_headers(&self) -> bool {
365         self.flags.is_end_headers()
366     }
367 
set_end_headers(&mut self)368     pub fn set_end_headers(&mut self) {
369         self.flags.set_end_headers();
370     }
371 
is_over_size(&self) -> bool372     pub fn is_over_size(&self) -> bool {
373         self.header_block.is_over_size
374     }
375 
encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut) -> Option<Continuation>376     pub fn encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut) -> Option<Continuation> {
377         use bytes::BufMut;
378 
379         // At this point, the `is_end_headers` flag should always be set
380         debug_assert!(self.flags.is_end_headers());
381 
382         let head = self.head();
383         let promised_id = self.promised_id;
384 
385         self.header_block.into_encoding()
386             .encode(&head, encoder, dst, |dst| {
387                 dst.put_u32_be(promised_id.into());
388             })
389     }
390 
head(&self) -> Head391     fn head(&self) -> Head {
392         Head::new(Kind::PushPromise, self.flags.into(), self.stream_id)
393     }
394 }
395 
396 impl PushPromise {
397     /// Consume `self`, returning the parts of the frame
into_parts(self) -> (Pseudo, HeaderMap)398     pub fn into_parts(self) -> (Pseudo, HeaderMap) {
399         (self.header_block.pseudo, self.header_block.fields)
400     }
401 }
402 
403 #[cfg(feature = "unstable")]
404 impl PushPromise {
new( stream_id: StreamId, promised_id: StreamId, pseudo: Pseudo, fields: HeaderMap, ) -> Self405     pub fn new(
406         stream_id: StreamId,
407         promised_id: StreamId,
408         pseudo: Pseudo,
409         fields: HeaderMap,
410     ) -> Self {
411         PushPromise {
412             flags: PushPromiseFlag::default(),
413             header_block: HeaderBlock {
414                 fields,
415                 is_over_size: false,
416                 pseudo,
417             },
418             promised_id,
419             stream_id,
420         }
421     }
422 
fields(&self) -> &HeaderMap423     pub fn fields(&self) -> &HeaderMap {
424         &self.header_block.fields
425     }
426 
into_fields(self) -> HeaderMap427     pub fn into_fields(self) -> HeaderMap {
428         self.header_block.fields
429     }
430 }
431 
432 impl<T> From<PushPromise> for Frame<T> {
from(src: PushPromise) -> Self433     fn from(src: PushPromise) -> Self {
434         Frame::PushPromise(src)
435     }
436 }
437 
438 impl fmt::Debug for PushPromise {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result439     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440         f.debug_struct("PushPromise")
441             .field("stream_id", &self.stream_id)
442             .field("promised_id", &self.promised_id)
443             .field("flags", &self.flags)
444             // `fields` and `pseudo` purposefully not included
445             .finish()
446     }
447 }
448 
449 // ===== impl Continuation =====
450 
451 impl Continuation {
head(&self) -> Head452     fn head(&self) -> Head {
453         Head::new(Kind::Continuation, END_HEADERS, self.stream_id)
454     }
455 
encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut) -> Option<Continuation>456     pub fn encode(self, encoder: &mut hpack::Encoder, dst: &mut BytesMut) -> Option<Continuation> {
457         // Get the CONTINUATION frame head
458         let head = self.head();
459 
460         self.header_block
461             .encode(&head, encoder, dst, |_| {
462             })
463     }
464 }
465 
466 // ===== impl Pseudo =====
467 
468 impl Pseudo {
request(method: Method, uri: Uri) -> Self469     pub fn request(method: Method, uri: Uri) -> Self {
470         let parts = uri::Parts::from(uri);
471 
472         let mut path = parts
473             .path_and_query
474             .map(|v| v.into())
475             .unwrap_or_else(|| Bytes::new());
476 
477         if path.is_empty() && method != Method::OPTIONS {
478             path = Bytes::from_static(b"/");
479         }
480 
481         let mut pseudo = Pseudo {
482             method: Some(method),
483             scheme: None,
484             authority: None,
485             path: Some(to_string(path)),
486             status: None,
487         };
488 
489         // If the URI includes a scheme component, add it to the pseudo headers
490         //
491         // TODO: Scheme must be set...
492         if let Some(scheme) = parts.scheme {
493             pseudo.set_scheme(scheme);
494         }
495 
496         // If the URI includes an authority component, add it to the pseudo
497         // headers
498         if let Some(authority) = parts.authority {
499             pseudo.set_authority(to_string(authority.into()));
500         }
501 
502         pseudo
503     }
504 
response(status: StatusCode) -> Self505     pub fn response(status: StatusCode) -> Self {
506         Pseudo {
507             method: None,
508             scheme: None,
509             authority: None,
510             path: None,
511             status: Some(status),
512         }
513     }
514 
set_scheme(&mut self, scheme: uri::Scheme)515     pub fn set_scheme(&mut self, scheme: uri::Scheme) {
516         self.scheme = Some(to_string(scheme.into()));
517     }
518 
set_authority(&mut self, authority: String<Bytes>)519     pub fn set_authority(&mut self, authority: String<Bytes>) {
520         self.authority = Some(authority);
521     }
522 }
523 
to_string(src: Bytes) -> String<Bytes>524 fn to_string(src: Bytes) -> String<Bytes> {
525     unsafe { String::from_utf8_unchecked(src) }
526 }
527 
528 // ===== impl EncodingHeaderBlock =====
529 
530 impl EncodingHeaderBlock {
encode<F>(mut self, head: &Head, encoder: &mut hpack::Encoder, dst: &mut BytesMut, f: F) -> Option<Continuation> where F: FnOnce(&mut BytesMut),531     fn encode<F>(mut self,
532                  head: &Head,
533                  encoder: &mut hpack::Encoder,
534                  dst: &mut BytesMut,
535                  f: F)
536         -> Option<Continuation>
537     where F: FnOnce(&mut BytesMut),
538     {
539         let head_pos = dst.len();
540 
541         // At this point, we don't know how big the h2 frame will be.
542         // So, we write the head with length 0, then write the body, and
543         // finally write the length once we know the size.
544         head.encode(0, dst);
545 
546         let payload_pos = dst.len();
547 
548         f(dst);
549 
550         // Now, encode the header payload
551         let continuation = match encoder.encode(self.hpack, &mut self.headers, dst) {
552             hpack::Encode::Full => None,
553             hpack::Encode::Partial(state) => Some(Continuation {
554                 stream_id: head.stream_id(),
555                 header_block: EncodingHeaderBlock {
556                     hpack: Some(state),
557                     headers: self.headers,
558                 },
559             }),
560         };
561 
562         // Compute the header block length
563         let payload_len = (dst.len() - payload_pos) as u64;
564 
565         // Write the frame length
566         BigEndian::write_uint(&mut dst[head_pos..head_pos + 3], payload_len, 3);
567 
568         if continuation.is_some() {
569             // There will be continuation frames, so the `is_end_headers` flag
570             // must be unset
571             debug_assert!(dst[head_pos + 4] & END_HEADERS == END_HEADERS);
572 
573             dst[head_pos + 4] -= END_HEADERS;
574         }
575 
576         continuation
577     }
578 }
579 
580 // ===== impl Iter =====
581 
582 impl Iterator for Iter {
583     type Item = hpack::Header<Option<HeaderName>>;
584 
next(&mut self) -> Option<Self::Item>585     fn next(&mut self) -> Option<Self::Item> {
586         use hpack::Header::*;
587 
588         if let Some(ref mut pseudo) = self.pseudo {
589             if let Some(method) = pseudo.method.take() {
590                 return Some(Method(method));
591             }
592 
593             if let Some(scheme) = pseudo.scheme.take() {
594                 return Some(Scheme(scheme));
595             }
596 
597             if let Some(authority) = pseudo.authority.take() {
598                 return Some(Authority(authority));
599             }
600 
601             if let Some(path) = pseudo.path.take() {
602                 return Some(Path(path));
603             }
604 
605             if let Some(status) = pseudo.status.take() {
606                 return Some(Status(status));
607             }
608         }
609 
610         self.pseudo = None;
611 
612         self.fields.next().map(|(name, value)| {
613             Field {
614                 name: name,
615                 value: value,
616             }
617         })
618     }
619 }
620 
621 // ===== impl HeadersFlag =====
622 
623 impl HeadersFlag {
empty() -> HeadersFlag624     pub fn empty() -> HeadersFlag {
625         HeadersFlag(0)
626     }
627 
load(bits: u8) -> HeadersFlag628     pub fn load(bits: u8) -> HeadersFlag {
629         HeadersFlag(bits & ALL)
630     }
631 
is_end_stream(&self) -> bool632     pub fn is_end_stream(&self) -> bool {
633         self.0 & END_STREAM == END_STREAM
634     }
635 
set_end_stream(&mut self)636     pub fn set_end_stream(&mut self) {
637         self.0 |= END_STREAM;
638     }
639 
is_end_headers(&self) -> bool640     pub fn is_end_headers(&self) -> bool {
641         self.0 & END_HEADERS == END_HEADERS
642     }
643 
set_end_headers(&mut self)644     pub fn set_end_headers(&mut self) {
645         self.0 |= END_HEADERS;
646     }
647 
is_padded(&self) -> bool648     pub fn is_padded(&self) -> bool {
649         self.0 & PADDED == PADDED
650     }
651 
is_priority(&self) -> bool652     pub fn is_priority(&self) -> bool {
653         self.0 & PRIORITY == PRIORITY
654     }
655 }
656 
657 impl Default for HeadersFlag {
658     /// Returns a `HeadersFlag` value with `END_HEADERS` set.
default() -> Self659     fn default() -> Self {
660         HeadersFlag(END_HEADERS)
661     }
662 }
663 
664 impl From<HeadersFlag> for u8 {
from(src: HeadersFlag) -> u8665     fn from(src: HeadersFlag) -> u8 {
666         src.0
667     }
668 }
669 
670 impl fmt::Debug for HeadersFlag {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result671     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
672         util::debug_flags(fmt, self.0)
673             .flag_if(self.is_end_headers(), "END_HEADERS")
674             .flag_if(self.is_end_stream(), "END_STREAM")
675             .flag_if(self.is_padded(), "PADDED")
676             .flag_if(self.is_priority(), "PRIORITY")
677             .finish()
678     }
679 }
680 
681 // ===== impl PushPromiseFlag =====
682 
683 impl PushPromiseFlag {
empty() -> PushPromiseFlag684     pub fn empty() -> PushPromiseFlag {
685         PushPromiseFlag(0)
686     }
687 
load(bits: u8) -> PushPromiseFlag688     pub fn load(bits: u8) -> PushPromiseFlag {
689         PushPromiseFlag(bits & ALL)
690     }
691 
is_end_headers(&self) -> bool692     pub fn is_end_headers(&self) -> bool {
693         self.0 & END_HEADERS == END_HEADERS
694     }
695 
set_end_headers(&mut self)696     pub fn set_end_headers(&mut self) {
697         self.0 |= END_HEADERS;
698     }
699 
is_padded(&self) -> bool700     pub fn is_padded(&self) -> bool {
701         self.0 & PADDED == PADDED
702     }
703 }
704 
705 impl Default for PushPromiseFlag {
706     /// Returns a `PushPromiseFlag` value with `END_HEADERS` set.
default() -> Self707     fn default() -> Self {
708         PushPromiseFlag(END_HEADERS)
709     }
710 }
711 
712 impl From<PushPromiseFlag> for u8 {
from(src: PushPromiseFlag) -> u8713     fn from(src: PushPromiseFlag) -> u8 {
714         src.0
715     }
716 }
717 
718 impl fmt::Debug for PushPromiseFlag {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result719     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
720         util::debug_flags(fmt, self.0)
721             .flag_if(self.is_end_headers(), "END_HEADERS")
722             .flag_if(self.is_padded(), "PADDED")
723             .finish()
724     }
725 }
726 
727 // ===== HeaderBlock =====
728 
729 
730 impl HeaderBlock {
load(&mut self, src: &mut BytesMut, max_header_list_size: usize, decoder: &mut hpack::Decoder) -> Result<(), Error>731     fn load(&mut self, src: &mut BytesMut, max_header_list_size: usize, decoder: &mut hpack::Decoder) -> Result<(), Error> {
732         let mut reg = !self.fields.is_empty();
733         let mut malformed = false;
734         let mut headers_size = self.calculate_header_list_size();
735 
736         macro_rules! set_pseudo {
737             ($field:ident, $val:expr) => {{
738                 if reg {
739                     trace!("load_hpack; header malformed -- pseudo not at head of block");
740                     malformed = true;
741                 } else if self.pseudo.$field.is_some() {
742                     trace!("load_hpack; header malformed -- repeated pseudo");
743                     malformed = true;
744                 } else {
745                     let __val = $val;
746                     headers_size += decoded_header_size(stringify!($ident).len() + 1, __val.as_str().len());
747                     if headers_size < max_header_list_size {
748                         self.pseudo.$field = Some(__val);
749                     } else if !self.is_over_size {
750                         trace!("load_hpack; header list size over max");
751                         self.is_over_size = true;
752                     }
753                 }
754             }}
755         }
756 
757         let mut cursor = Cursor::new(src);
758 
759         // If the header frame is malformed, we still have to continue decoding
760         // the headers. A malformed header frame is a stream level error, but
761         // the hpack state is connection level. In order to maintain correct
762         // state for other streams, the hpack decoding process must complete.
763         let res = decoder.decode(&mut cursor, |header| {
764             use hpack::Header::*;
765 
766             match header {
767                 Field {
768                     name,
769                     value,
770                 } => {
771                     // Connection level header fields are not supported and must
772                     // result in a protocol error.
773 
774                     if name == header::CONNECTION
775                         || name == header::TRANSFER_ENCODING
776                         || name == header::UPGRADE
777                         || name == "keep-alive"
778                         || name == "proxy-connection"
779                     {
780                         trace!("load_hpack; connection level header");
781                         malformed = true;
782                     } else if name == header::TE && value != "trailers" {
783                         trace!("load_hpack; TE header not set to trailers; val={:?}", value);
784                         malformed = true;
785                     } else {
786                         reg = true;
787 
788                         headers_size += decoded_header_size(name.as_str().len(), value.len());
789                         if headers_size < max_header_list_size {
790                             self.fields.append(name, value);
791                         } else if !self.is_over_size {
792                             trace!("load_hpack; header list size over max");
793                             self.is_over_size = true;
794                         }
795                     }
796                 },
797                 Authority(v) => set_pseudo!(authority, v),
798                 Method(v) => set_pseudo!(method, v),
799                 Scheme(v) => set_pseudo!(scheme, v),
800                 Path(v) => set_pseudo!(path, v),
801                 Status(v) => set_pseudo!(status, v),
802             }
803         });
804 
805         if let Err(e) = res {
806             trace!("hpack decoding error; err={:?}", e);
807             return Err(e.into());
808         }
809 
810         if malformed {
811             trace!("malformed message");
812             return Err(Error::MalformedMessage.into());
813         }
814 
815         Ok(())
816     }
817 
into_encoding(self) -> EncodingHeaderBlock818     fn into_encoding(self) -> EncodingHeaderBlock {
819         EncodingHeaderBlock {
820             hpack: None,
821             headers: Iter {
822                 pseudo: Some(self.pseudo),
823                 fields: self.fields.into_iter(),
824             },
825         }
826     }
827 
828     /// Calculates the size of the currently decoded header list.
829     ///
830     /// According to http://httpwg.org/specs/rfc7540.html#SETTINGS_MAX_HEADER_LIST_SIZE
831     ///
832     /// > The value is based on the uncompressed size of header fields,
833     /// > including the length of the name and value in octets plus an
834     /// > overhead of 32 octets for each header field.
calculate_header_list_size(&self) -> usize835     fn calculate_header_list_size(&self) -> usize {
836         macro_rules! pseudo_size {
837             ($name:ident) => ({
838                 self.pseudo
839                     .$name
840                     .as_ref()
841                     .map(|m| decoded_header_size(stringify!($name).len() + 1, m.as_str().len()))
842                     .unwrap_or(0)
843             });
844         }
845 
846         pseudo_size!(method) +
847         pseudo_size!(scheme) +
848         pseudo_size!(status) +
849         pseudo_size!(authority) +
850         pseudo_size!(path) +
851         self.fields.iter()
852             .map(|(name, value)| decoded_header_size(name.as_str().len(), value.len()))
853             .sum::<usize>()
854     }
855 
856     /// Iterate over all pseudos and headers to see if any individual pair
857     /// would be too large to encode.
has_too_big_field(&self) -> bool858     pub(crate) fn has_too_big_field(&self) -> bool {
859         macro_rules! pseudo_size {
860             ($name:ident) => ({
861                 self.pseudo
862                     .$name
863                     .as_ref()
864                     .map(|m| decoded_header_size(stringify!($name).len() + 1, m.as_str().len()))
865                     .unwrap_or(0)
866             });
867         }
868 
869         if pseudo_size!(method) > MAX_HEADER_LENGTH {
870             return true;
871         }
872 
873         if pseudo_size!(scheme) > MAX_HEADER_LENGTH {
874             return true;
875         }
876 
877         if pseudo_size!(authority) > MAX_HEADER_LENGTH {
878             return true;
879         }
880 
881         if pseudo_size!(path) > MAX_HEADER_LENGTH {
882             return true;
883         }
884 
885         // skip :status, its never going to be too big
886 
887         for (name, value) in &self.fields {
888             if decoded_header_size(name.as_str().len(), value.len()) > MAX_HEADER_LENGTH {
889                 return true;
890             }
891         }
892 
893         false
894     }
895 }
896 
decoded_header_size(name: usize, value: usize) -> usize897 fn decoded_header_size(name: usize, value: usize) -> usize {
898     name + value + 32
899 }
900 
901 // Stupid hack to make the set_pseudo! macro happy, since all other values
902 // have a method `as_str` except for `String<Bytes>`.
903 trait AsStr {
as_str(&self) -> &str904     fn as_str(&self) -> &str;
905 }
906 
907 impl AsStr for String<Bytes> {
as_str(&self) -> &str908     fn as_str(&self) -> &str {
909         self
910     }
911 }
912