Accept HPACK literals greater than max size (#244)
The spec specifically allows accepting HPACK literals with indexing when the HPACK literal is greater than the max table size. In this case, the literal is not inserted in the table. Fixes #243
This commit is contained in:
		| @@ -482,11 +482,13 @@ impl Table { | |||||||
|  |  | ||||||
|         self.reserve(len); |         self.reserve(len); | ||||||
|  |  | ||||||
|  |         if self.size + len <= self.max_size { | ||||||
|             self.size += len; |             self.size += len; | ||||||
|  |  | ||||||
|             // Track the entry |             // Track the entry | ||||||
|             self.entries.push_front(entry); |             self.entries.push_front(entry); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fn set_max_size(&mut self, size: usize) { |     fn set_max_size(&mut self, size: usize) { | ||||||
|         self.max_size = size; |         self.max_size = size; | ||||||
| @@ -495,15 +497,14 @@ impl Table { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn reserve(&mut self, size: usize) { |     fn reserve(&mut self, size: usize) { | ||||||
|         debug_assert!(size <= self.max_size); |  | ||||||
|  |  | ||||||
|         while self.size + size > self.max_size { |         while self.size + size > self.max_size { | ||||||
|             let last = self.entries |             match self.entries.pop_back() { | ||||||
|                 .pop_back() |                 Some(last) => { | ||||||
|                 .expect("size of table != 0, but no headers left!"); |  | ||||||
|  |  | ||||||
|                     self.size -= last.len(); |                     self.size -= last.len(); | ||||||
|                 } |                 } | ||||||
|  |                 None => return, | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn consolidate(&mut self) { |     fn consolidate(&mut self) { | ||||||
| @@ -785,6 +786,11 @@ fn from_static(s: &'static str) -> String<Bytes> { | |||||||
|     unsafe { String::from_utf8_unchecked(Bytes::from_static(s.as_bytes())) } |     unsafe { String::from_utf8_unchecked(Bytes::from_static(s.as_bytes())) } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(test)] | ||||||
|  | mod test { | ||||||
|  |     use super::*; | ||||||
|  |     use hpack::Header; | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_peek_u8() { |     fn test_peek_u8() { | ||||||
|         let b = 0xff; |         let b = 0xff; | ||||||
| @@ -809,3 +815,38 @@ fn test_decode_empty() { | |||||||
|         let empty = de.decode(&mut Cursor::new(&mut buf), |_| {}).unwrap(); |         let empty = de.decode(&mut Cursor::new(&mut buf), |_| {}).unwrap(); | ||||||
|         assert_eq!(empty, ()); |         assert_eq!(empty, ()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_decode_indexed_larger_than_table() { | ||||||
|  |         let mut de = Decoder::new(0); | ||||||
|  |  | ||||||
|  |         let mut buf = vec![0b01000000, 0x80 | 2]; | ||||||
|  |         buf.extend(huff_encode(b"foo")); | ||||||
|  |         buf.extend(&[0x80 | 3]); | ||||||
|  |         buf.extend(huff_encode(b"bar")); | ||||||
|  |  | ||||||
|  |         let mut buf = buf.into(); | ||||||
|  |  | ||||||
|  |         let mut res = vec![]; | ||||||
|  |         let _ = de.decode(&mut Cursor::new(&mut buf), |h| { | ||||||
|  |             res.push(h); | ||||||
|  |         }).unwrap(); | ||||||
|  |  | ||||||
|  |         assert_eq!(res.len(), 1); | ||||||
|  |         assert_eq!(de.table.size(), 0); | ||||||
|  |  | ||||||
|  |         match res[0] { | ||||||
|  |             Header::Field { ref name, ref value } => { | ||||||
|  |                 assert_eq!(name, "foo"); | ||||||
|  |                 assert_eq!(value, "bar"); | ||||||
|  |             } | ||||||
|  |             _ => panic!(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn huff_encode(src: &[u8]) -> BytesMut { | ||||||
|  |         let mut buf = BytesMut::new(); | ||||||
|  |         huffman::encode(src, &mut buf).unwrap(); | ||||||
|  |         buf | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user