work
This commit is contained in:
		| @@ -4,11 +4,13 @@ use tower::http::{HeaderName, Str}; | |||||||
| use bytes::{Buf, Bytes}; | use bytes::{Buf, Bytes}; | ||||||
|  |  | ||||||
| use std::io::Cursor; | use std::io::Cursor; | ||||||
|  | use std::collections::VecDeque; | ||||||
|  |  | ||||||
| /// Decodes headers using HPACK | /// Decodes headers using HPACK | ||||||
| pub struct Decoder { | pub struct Decoder { | ||||||
|     // Protocol indicated that the max table size will update |     // Protocol indicated that the max table size will update | ||||||
|     max_size_update: Option<usize>, |     max_size_update: Option<usize>, | ||||||
|  |     table: Table, | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Represents all errors that can be encountered while performing the decoding | /// Represents all errors that can be encountered while performing the decoding | ||||||
| @@ -112,6 +114,12 @@ enum Representation { | |||||||
|     SizeUpdate, |     SizeUpdate, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | struct Table { | ||||||
|  |     entries: VecDeque<Entry>, | ||||||
|  |     size: usize, | ||||||
|  |     max_size: usize, | ||||||
|  | } | ||||||
|  |  | ||||||
| // ===== impl Decoder ===== | // ===== impl Decoder ===== | ||||||
|  |  | ||||||
| impl Decoder { | impl Decoder { | ||||||
| @@ -119,6 +127,7 @@ impl Decoder { | |||||||
|     pub fn new() -> Decoder { |     pub fn new() -> Decoder { | ||||||
|         Decoder { |         Decoder { | ||||||
|             max_size_update: None, |             max_size_update: None, | ||||||
|  |             table: Table::new(4_096), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -193,8 +202,6 @@ impl Representation { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| // ===== Utils ===== |  | ||||||
|  |  | ||||||
| fn decode_int<B: Buf>(buf: &mut B, prefix_size: u8) -> Result<usize, DecoderError> { | fn decode_int<B: Buf>(buf: &mut B, prefix_size: u8) -> Result<usize, DecoderError> { | ||||||
|     // The octet limit is chosen such that the maximum allowed *value* can |     // The octet limit is chosen such that the maximum allowed *value* can | ||||||
|     // never overflow an unsigned 32-bit integer. The maximum value of any |     // never overflow an unsigned 32-bit integer. The maximum value of any | ||||||
| @@ -257,3 +264,37 @@ fn decode_int<B: Buf>(buf: &mut B, prefix_size: u8) -> Result<usize, DecoderErro | |||||||
| fn peek_u8<B: Buf>(buf: &mut B) -> u8 { | fn peek_u8<B: Buf>(buf: &mut B) -> u8 { | ||||||
|     buf.bytes()[0] |     buf.bytes()[0] | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ===== impl Table ===== | ||||||
|  |  | ||||||
|  | impl Table { | ||||||
|  |     fn new(max_size: usize) -> Table { | ||||||
|  |         Table { | ||||||
|  |             entries: VecDeque::new(), | ||||||
|  |             size: 0, | ||||||
|  |             max_size: max_size, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn max_size(&self) -> usize { | ||||||
|  |         self.max_size | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn insert(&mut self, entry: Entry) { | ||||||
|  |         let len = entry.len(); | ||||||
|  |  | ||||||
|  |         debug_assert!(len <= self.max_size); | ||||||
|  |  | ||||||
|  |         while self.size + len > self.max_size { | ||||||
|  |             let last = self.entries.pop_back() | ||||||
|  |                 .expect("size of table != 0, but no headers left!"); | ||||||
|  |  | ||||||
|  |             self.size -= last.len(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         self.size += len; | ||||||
|  |  | ||||||
|  |         // Track the entry | ||||||
|  |         self.entries.push_front(entry); | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								src/hpack/entry.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/hpack/entry.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | use tower::http::{HeaderName, Method, StatusCode, Str}; | ||||||
|  |  | ||||||
|  | /// HPack table entry | ||||||
|  | pub enum Entry { | ||||||
|  |     Header { | ||||||
|  |         name: HeaderName, | ||||||
|  |         value: Str, | ||||||
|  |     }, | ||||||
|  |     Authority(Str), | ||||||
|  |     Method(Method), | ||||||
|  |     Scheme(Str), | ||||||
|  |     Path(Str), | ||||||
|  |     Status(StatusCode), | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl Entry { | ||||||
|  |     pub fn len(&self) -> usize { | ||||||
|  |         match *self { | ||||||
|  |             Entry::Header { ref name, ref value } => { | ||||||
|  |                 let n: &str = name.as_ref(); | ||||||
|  |                 32 + n.len() + value.len() | ||||||
|  |             } | ||||||
|  |             Entry::Authority(ref v) => { | ||||||
|  |                 32 + 10 + v.len() | ||||||
|  |             } | ||||||
|  |             Entry::Method(ref v) => { | ||||||
|  |                 32 + 7 + v.as_ref().len() | ||||||
|  |             } | ||||||
|  |             Entry::Scheme(ref v) => { | ||||||
|  |                 32 + 7 + v.len() | ||||||
|  |             } | ||||||
|  |             Entry::Path(ref v) => { | ||||||
|  |                 32 + 5 + v.len() | ||||||
|  |             } | ||||||
|  |             Entry::Status(ref v) => { | ||||||
|  |                 32 + 7 + 3 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,7 +1,9 @@ | |||||||
| mod encoder; | mod encoder; | ||||||
| mod decoder; | mod decoder; | ||||||
| mod table; | mod entry; | ||||||
|  | // mod table; | ||||||
|  |  | ||||||
| pub use self::encoder::Encoder; | pub use self::encoder::Encoder; | ||||||
|  | pub use self::entry::Entry; | ||||||
| pub use self::decoder::Decoder; | pub use self::decoder::Decoder; | ||||||
| pub use self::table::Entry; | // pub use self::table::Entry; | ||||||
|   | |||||||
| @@ -1,19 +1,8 @@ | |||||||
|  | use hpack::Entry; | ||||||
|  |  | ||||||
| use tower::http::{HeaderName, StatusCode, Method, Str}; | use tower::http::{HeaderName, StatusCode, Method, Str}; | ||||||
| use std::collections::VecDeque; | use std::collections::VecDeque; | ||||||
|  |  | ||||||
| /// HPack table entry |  | ||||||
| pub enum Entry { |  | ||||||
|     Header { |  | ||||||
|         name: HeaderName, |  | ||||||
|         value: Str, |  | ||||||
|     }, |  | ||||||
|     Authority(Str), |  | ||||||
|     Method(Method), |  | ||||||
|     Scheme(Str), |  | ||||||
|     Path(Str), |  | ||||||
|     Status(StatusCode), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// Get an entry from the static table | /// Get an entry from the static table | ||||||
| pub fn get_static(idx: usize) -> Entry { | pub fn get_static(idx: usize) -> Entry { | ||||||
|     use tower::http::StandardHeader::*; |     use tower::http::StandardHeader::*; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user