chore: cargo fmt, clippy

This commit is contained in:
Gurwinder Singh
2019-08-17 09:07:32 +05:30
committed by Sean McArthur
parent e72d6dc189
commit f46840f3fa
43 changed files with 785 additions and 870 deletions

View File

@@ -168,7 +168,11 @@ impl Decoder {
}
/// Decodes the headers found in the given buffer.
pub fn decode<F>(&mut self, src: &mut Cursor<&mut BytesMut>, mut f: F) -> Result<(), DecoderError>
pub fn decode<F>(
&mut self,
src: &mut Cursor<&mut BytesMut>,
mut f: F,
) -> Result<(), DecoderError>
where
F: FnMut(Header),
{
@@ -193,7 +197,7 @@ impl Decoder {
let entry = self.decode_indexed(src)?;
consume(src);
f(entry);
},
}
LiteralWithIndexing => {
log::trace!(" LiteralWithIndexing; rem={:?}", src.remaining());
can_resize = false;
@@ -204,14 +208,14 @@ impl Decoder {
consume(src);
f(entry);
},
}
LiteralWithoutIndexing => {
log::trace!(" LiteralWithoutIndexing; rem={:?}", src.remaining());
can_resize = false;
let entry = self.decode_literal(src, false)?;
consume(src);
f(entry);
},
}
LiteralNeverIndexed => {
log::trace!(" LiteralNeverIndexed; rem={:?}", src.remaining());
can_resize = false;
@@ -221,7 +225,7 @@ impl Decoder {
// TODO: Track that this should never be indexed
f(entry);
},
}
SizeUpdate => {
log::trace!(" SizeUpdate; rem={:?}", src.remaining());
if !can_resize {
@@ -231,7 +235,7 @@ impl Decoder {
// Handle the dynamic table size update
self.process_size_update(src)?;
consume(src);
},
}
}
}
@@ -287,7 +291,7 @@ impl Decoder {
}
fn decode_string(&mut self, buf: &mut Cursor<&mut BytesMut>) -> Result<Bytes, DecoderError> {
const HUFF_FLAG: u8 = 0b10000000;
const HUFF_FLAG: u8 = 0b1000_0000;
// The first bit in the first byte contains the huffman encoded flag.
let huff = match peek_u8(buf) {
@@ -331,12 +335,12 @@ impl Default for Decoder {
impl Representation {
pub fn load(byte: u8) -> Result<Representation, DecoderError> {
const INDEXED: u8 = 0b10000000;
const LITERAL_WITH_INDEXING: u8 = 0b01000000;
const LITERAL_WITHOUT_INDEXING: u8 = 0b11110000;
const LITERAL_NEVER_INDEXED: u8 = 0b00010000;
const SIZE_UPDATE_MASK: u8 = 0b11100000;
const SIZE_UPDATE: u8 = 0b00100000;
const INDEXED: u8 = 0b1000_0000;
const LITERAL_WITH_INDEXING: u8 = 0b0100_0000;
const LITERAL_WITHOUT_INDEXING: u8 = 0b1111_0000;
const LITERAL_NEVER_INDEXED: u8 = 0b0001_0000;
const SIZE_UPDATE_MASK: u8 = 0b1110_0000;
const SIZE_UPDATE: u8 = 0b0010_0000;
// TODO: What did I even write here?
@@ -361,8 +365,8 @@ fn decode_int<B: Buf>(buf: &mut B, prefix_size: u8) -> Result<usize, DecoderErro
// never overflow an unsigned 32-bit integer. The maximum value of any
// integer that can be encoded with 5 octets is ~2^28
const MAX_BYTES: usize = 5;
const VARINT_MASK: u8 = 0b01111111;
const VARINT_FLAG: u8 = 0b10000000;
const VARINT_MASK: u8 = 0b0111_1111;
const VARINT_FLAG: u8 = 0b1000_0000;
if prefix_size < 1 || prefix_size > 8 {
return Err(DecoderError::InvalidIntegerPrefix);
@@ -445,7 +449,7 @@ impl Table {
Table {
entries: VecDeque::new(),
size: 0,
max_size: max_size,
max_size,
}
}
@@ -516,7 +520,7 @@ impl Table {
// Can never happen as the size of the table must reach
// 0 by the time we've exhausted all elements.
panic!("Size of table != 0, but no headers left!");
},
}
};
self.size -= last.len();
@@ -827,15 +831,20 @@ mod test {
let mut buf = buf.into();
let mut res = vec![];
let _ = de.decode(&mut Cursor::new(&mut buf), |h| {
res.push(h);
}).unwrap();
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 } => {
Header::Field {
ref name,
ref value,
} => {
assert_eq!(name, "foo");
assert_eq!(value, "bar");
}

View File

@@ -1,5 +1,5 @@
use super::{huffman, Header};
use super::table::{Index, Table};
use super::{huffman, Header};
use bytes::{BufMut, BytesMut};
use http::header::{HeaderName, HeaderValue};
@@ -47,27 +47,31 @@ impl Encoder {
#[allow(dead_code)]
pub fn update_max_size(&mut self, val: usize) {
match self.size_update {
Some(SizeUpdate::One(old)) => if val > old {
if old > self.table.max_size() {
Some(SizeUpdate::One(old)) => {
if val > old {
if old > self.table.max_size() {
self.size_update = Some(SizeUpdate::One(val));
} else {
self.size_update = Some(SizeUpdate::Two(old, val));
}
} else {
self.size_update = Some(SizeUpdate::One(val));
}
}
Some(SizeUpdate::Two(min, _)) => {
if val < min {
self.size_update = Some(SizeUpdate::One(val));
} else {
self.size_update = Some(SizeUpdate::Two(old, val));
self.size_update = Some(SizeUpdate::Two(min, val));
}
} else {
self.size_update = Some(SizeUpdate::One(val));
},
Some(SizeUpdate::Two(min, _)) => if val < min {
self.size_update = Some(SizeUpdate::One(val));
} else {
self.size_update = Some(SizeUpdate::Two(min, val));
},
}
None => {
if val != self.table.max_size() {
// Don't bother writing a frame if the value already matches
// the table's max size.
self.size_update = Some(SizeUpdate::One(val));
}
},
}
}
}
@@ -120,14 +124,11 @@ impl Encoder {
if res.is_err() {
dst.truncate(len);
return Encode::Partial(EncodeState {
index: index,
value: None,
});
return Encode::Partial(EncodeState { index, value: None });
}
last_index = Some(index);
},
}
// The header does not have an associated name. This means that
// the name is the same as the previously yielded header. In
// which case, we skip table lookup and just use the same index
@@ -148,7 +149,7 @@ impl Encoder {
value: Some(value),
});
}
},
}
};
}
@@ -160,14 +161,14 @@ impl Encoder {
Some(SizeUpdate::One(val)) => {
self.table.resize(val);
encode_size_update(val, dst)?;
},
}
Some(SizeUpdate::Two(min, max)) => {
self.table.resize(min);
self.table.resize(max);
encode_size_update(min, dst)?;
encode_size_update(max, dst)?;
},
None => {},
}
None => {}
}
Ok(())
@@ -177,12 +178,12 @@ impl Encoder {
match *index {
Index::Indexed(idx, _) => {
encode_int(idx, 7, 0x80, dst)?;
},
}
Index::Name(idx, _) => {
let header = self.table.resolve(&index);
encode_not_indexed(idx, header.value_slice(), header.is_sensitive(), dst)?;
},
}
Index::Inserted(_) => {
let header = self.table.resolve(&index);
@@ -192,19 +193,19 @@ impl Encoder {
return Err(EncoderError::BufferOverflow);
}
dst.put_u8(0b01000000);
dst.put_u8(0b0100_0000);
encode_str(header.name().as_slice(), dst)?;
encode_str(header.value_slice(), dst)?;
},
}
Index::InsertedValue(idx, _) => {
let header = self.table.resolve(&index);
assert!(!header.is_sensitive());
encode_int(idx, 6, 0b01000000, dst)?;
encode_int(idx, 6, 0b0100_0000, dst)?;
encode_str(header.value_slice(), dst)?;
},
}
Index::NotIndexed(_) => {
let header = self.table.resolve(&index);
@@ -214,7 +215,7 @@ impl Encoder {
header.is_sensitive(),
dst,
)?;
},
}
}
Ok(())
@@ -227,14 +228,14 @@ impl Encoder {
dst: &mut BytesMut,
) -> Result<(), EncoderError> {
match *last {
Index::Indexed(..) |
Index::Name(..) |
Index::Inserted(..) |
Index::InsertedValue(..) => {
Index::Indexed(..)
| Index::Name(..)
| Index::Inserted(..)
| Index::InsertedValue(..) => {
let idx = self.table.resolve_idx(last);
encode_not_indexed(idx, value.as_ref(), value.is_sensitive(), dst)?;
},
}
Index::NotIndexed(_) => {
let last = self.table.resolve(last);
@@ -244,7 +245,7 @@ impl Encoder {
value.is_sensitive(),
dst,
)?;
},
}
}
Ok(())
@@ -258,7 +259,7 @@ impl Default for Encoder {
}
fn encode_size_update<B: BufMut>(val: usize, dst: &mut B) -> Result<(), EncoderError> {
encode_int(val, 5, 0b00100000, dst)
encode_int(val, 5, 0b0010_0000, dst)
}
fn encode_not_indexed(
@@ -305,7 +306,7 @@ fn encode_str(val: &[u8], dst: &mut BytesMut) -> Result<(), EncoderError> {
return Err(EncoderError::BufferOverflow);
}
if val.len() != 0 {
if !val.is_empty() {
let idx = dst.len();
// Push a placeholder byte for the length header
@@ -378,7 +379,7 @@ fn encode_int<B: BufMut>(
value -= low;
if value > 0x0fffffff {
if value > 0x0fff_ffff {
panic!("value out of range");
}
@@ -390,10 +391,10 @@ fn encode_int<B: BufMut>(
return Err(EncoderError::BufferOverflow);
}
dst.put_u8(0b10000000 | value as u8);
dst.put_u8(0b1000_0000 | value as u8);
rem -= 1;
value = value >> 7;
value >>= 7;
}
if rem == 0 {
@@ -560,7 +561,7 @@ mod test {
let header = Header::Field {
name: Some(name),
value: value,
value,
};
// Now, try to encode the sensitive header
@@ -580,7 +581,7 @@ mod test {
let header = Header::Field {
name: Some(name),
value: value,
value,
};
let mut encoder = Encoder::default();
@@ -604,7 +605,7 @@ mod test {
let header = Header::Field {
name: Some(name),
value: value,
value,
};
let res = encode(&mut encoder, vec![header]);
@@ -808,7 +809,8 @@ mod test {
name: None,
value: HeaderValue::from_bytes(b"sup").unwrap(),
},
].into_iter();
]
.into_iter();
let resume = match encoder.encode(None, &mut input, &mut dst) {
Encode::Partial(r) => r,
@@ -823,7 +825,7 @@ mod test {
dst.clear();
match encoder.encode(Some(resume), &mut input, &mut dst) {
Encode::Full => {},
Encode::Full => {}
unexpected => panic!("resume returned unexpected: {:?}", unexpected),
}
@@ -856,7 +858,7 @@ mod test {
Header::Field {
name: Some(name),
value: value,
value,
}
}

View File

@@ -1,8 +1,8 @@
use super::{DecoderError, NeedMore};
use bytes::Bytes;
use http::{Method, StatusCode};
use http::header::{HeaderName, HeaderValue};
use http::{Method, StatusCode};
use string::{String, TryFrom};
/// HTTP/2.0 Header
@@ -41,14 +41,8 @@ impl Header<Option<HeaderName>> {
Field {
name: Some(n),
value,
} => Field {
name: n,
value: value,
},
Field {
name: None,
value,
} => return Err(value),
} => Field { name: n, value },
Field { name: None, value } => return Err(value),
Authority(v) => Authority(v),
Method(v) => Method(v),
Scheme(v) => Scheme(v),
@@ -60,7 +54,7 @@ impl Header<Option<HeaderName>> {
impl Header {
pub fn new(name: Bytes, value: Bytes) -> Result<Header, DecoderError> {
if name.len() == 0 {
if name.is_empty() {
return Err(DecoderError::NeedMore(NeedMore::UnexpectedEndOfStream));
}
if name[0] == b':' {
@@ -68,23 +62,23 @@ impl Header {
b"authority" => {
let value = String::try_from(value)?;
Ok(Header::Authority(value))
},
}
b"method" => {
let method = Method::from_bytes(&value)?;
Ok(Header::Method(method))
},
}
b"scheme" => {
let value = String::try_from(value)?;
Ok(Header::Scheme(value))
},
}
b"path" => {
let value = String::try_from(value)?;
Ok(Header::Path(value))
},
}
b"status" => {
let status = StatusCode::from_bytes(&value)?;
Ok(Header::Status(status))
},
}
_ => Err(DecoderError::InvalidPseudoheader),
}
} else {
@@ -92,10 +86,7 @@ impl Header {
let name = HeaderName::from_lowercase(&name)?;
let value = HeaderValue::from_bytes(&value)?;
Ok(Header::Field {
name: name,
value: value,
})
Ok(Header::Field { name, value })
}
}
@@ -116,9 +107,7 @@ impl Header {
/// Returns the header name
pub fn name(&self) -> Name {
match *self {
Header::Field {
ref name, ..
} => Name::Field(name),
Header::Field { ref name, .. } => Name::Field(name),
Header::Authority(..) => Name::Authority,
Header::Method(..) => Name::Method,
Header::Scheme(..) => Name::Scheme,
@@ -129,9 +118,7 @@ impl Header {
pub fn value_slice(&self) -> &[u8] {
match *self {
Header::Field {
ref value, ..
} => value.as_ref(),
Header::Field { ref value, .. } => value.as_ref(),
Header::Authority(ref v) => v.as_ref(),
Header::Method(ref v) => v.as_ref().as_ref(),
Header::Scheme(ref v) => v.as_ref(),
@@ -142,17 +129,13 @@ impl Header {
pub fn value_eq(&self, other: &Header) -> bool {
match *self {
Header::Field {
ref value, ..
} => {
Header::Field { ref value, .. } => {
let a = value;
match *other {
Header::Field {
ref value, ..
} => a == value,
Header::Field { ref value, .. } => a == value,
_ => false,
}
},
}
Header::Authority(ref a) => match *other {
Header::Authority(ref b) => a == b,
_ => false,
@@ -178,9 +161,7 @@ impl Header {
pub fn is_sensitive(&self) -> bool {
match *self {
Header::Field {
ref value, ..
} => value.is_sensitive(),
Header::Field { ref value, .. } => value.is_sensitive(),
// TODO: Technically these other header values can be sensitive too.
_ => false,
}
@@ -190,18 +171,16 @@ impl Header {
use http::header;
match *self {
Header::Field {
ref name, ..
} => match *name {
header::AGE |
header::AUTHORIZATION |
header::CONTENT_LENGTH |
header::ETAG |
header::IF_MODIFIED_SINCE |
header::IF_NONE_MATCH |
header::LOCATION |
header::COOKIE |
header::SET_COOKIE => true,
Header::Field { ref name, .. } => match *name {
header::AGE
| header::AUTHORIZATION
| header::CONTENT_LENGTH
| header::ETAG
| header::IF_MODIFIED_SINCE
| header::IF_NONE_MATCH
| header::LOCATION
| header::COOKIE
| header::SET_COOKIE => true,
_ => false,
},
Header::Path(..) => true,
@@ -214,10 +193,7 @@ impl Header {
impl From<Header> for Header<Option<HeaderName>> {
fn from(src: Header) -> Self {
match src {
Header::Field {
name,
value,
} => Header::Field {
Header::Field { name, value } => Header::Field {
name: Some(name),
value,
},
@@ -247,7 +223,7 @@ impl<'a> Name<'a> {
// TODO: better error handling
Err(_) => Err(DecoderError::InvalidStatusCode),
}
},
}
}
}

View File

@@ -3,37 +3,37 @@
// (num-bits, bits)
pub const ENCODE_TABLE: [(usize, u64); 257] = [
(13, 0x1ff8),
(23, 0x7fffd8),
(28, 0xfffffe2),
(28, 0xfffffe3),
(28, 0xfffffe4),
(28, 0xfffffe5),
(28, 0xfffffe6),
(28, 0xfffffe7),
(28, 0xfffffe8),
(24, 0xffffea),
(30, 0x3ffffffc),
(28, 0xfffffe9),
(28, 0xfffffea),
(30, 0x3ffffffd),
(28, 0xfffffeb),
(28, 0xfffffec),
(28, 0xfffffed),
(28, 0xfffffee),
(28, 0xfffffef),
(28, 0xffffff0),
(28, 0xffffff1),
(28, 0xffffff2),
(30, 0x3ffffffe),
(28, 0xffffff3),
(28, 0xffffff4),
(28, 0xffffff5),
(28, 0xffffff6),
(28, 0xffffff7),
(28, 0xffffff8),
(28, 0xffffff9),
(28, 0xffffffa),
(28, 0xffffffb),
(23, 0x007f_ffd8),
(28, 0x0fff_ffe2),
(28, 0x0fff_ffe3),
(28, 0x0fff_ffe4),
(28, 0x0fff_ffe5),
(28, 0x0fff_ffe6),
(28, 0x0fff_ffe7),
(28, 0x0fff_ffe8),
(24, 0x00ff_ffea),
(30, 0x3fff_fffc),
(28, 0x0fff_ffe9),
(28, 0x0fff_ffea),
(30, 0x3fff_fffd),
(28, 0x0fff_ffeb),
(28, 0x0fff_ffec),
(28, 0x0fff_ffed),
(28, 0x0fff_ffee),
(28, 0x0fff_ffef),
(28, 0x0fff_fff0),
(28, 0x0fff_fff1),
(28, 0x0fff_fff2),
(30, 0x3fff_fffe),
(28, 0x0fff_fff3),
(28, 0x0fff_fff4),
(28, 0x0fff_fff5),
(28, 0x0fff_fff6),
(28, 0x0fff_fff7),
(28, 0x0fff_fff8),
(28, 0x0fff_fff9),
(28, 0x0fff_fffa),
(28, 0x0fff_fffb),
(6, 0x14),
(10, 0x3f8),
(10, 0x3f9),
@@ -129,136 +129,136 @@ pub const ENCODE_TABLE: [(usize, u64); 257] = [
(11, 0x7fc),
(14, 0x3ffd),
(13, 0x1ffd),
(28, 0xffffffc),
(28, 0x0fff_fffc),
(20, 0xfffe6),
(22, 0x3fffd2),
(22, 0x003f_ffd2),
(20, 0xfffe7),
(20, 0xfffe8),
(22, 0x3fffd3),
(22, 0x3fffd4),
(22, 0x3fffd5),
(23, 0x7fffd9),
(22, 0x3fffd6),
(23, 0x7fffda),
(23, 0x7fffdb),
(23, 0x7fffdc),
(23, 0x7fffdd),
(23, 0x7fffde),
(24, 0xffffeb),
(23, 0x7fffdf),
(24, 0xffffec),
(24, 0xffffed),
(22, 0x3fffd7),
(23, 0x7fffe0),
(24, 0xffffee),
(23, 0x7fffe1),
(23, 0x7fffe2),
(23, 0x7fffe3),
(23, 0x7fffe4),
(21, 0x1fffdc),
(22, 0x3fffd8),
(23, 0x7fffe5),
(22, 0x3fffd9),
(23, 0x7fffe6),
(23, 0x7fffe7),
(24, 0xffffef),
(22, 0x3fffda),
(21, 0x1fffdd),
(22, 0x003f_ffd3),
(22, 0x003f_ffd4),
(22, 0x003f_ffd5),
(23, 0x007f_ffd9),
(22, 0x003f_ffd6),
(23, 0x007f_ffda),
(23, 0x007f_ffdb),
(23, 0x007f_ffdc),
(23, 0x007f_ffdd),
(23, 0x007f_ffde),
(24, 0x00ff_ffeb),
(23, 0x007f_ffdf),
(24, 0x00ff_ffec),
(24, 0x00ff_ffed),
(22, 0x003f_ffd7),
(23, 0x007f_ffe0),
(24, 0x00ff_ffee),
(23, 0x007f_ffe1),
(23, 0x007f_ffe2),
(23, 0x007f_ffe3),
(23, 0x007f_ffe4),
(21, 0x001f_ffdc),
(22, 0x003f_ffd8),
(23, 0x007f_ffe5),
(22, 0x003f_ffd9),
(23, 0x007f_ffe6),
(23, 0x007f_ffe7),
(24, 0x00ff_ffef),
(22, 0x003f_ffda),
(21, 0x001f_ffdd),
(20, 0xfffe9),
(22, 0x3fffdb),
(22, 0x3fffdc),
(23, 0x7fffe8),
(23, 0x7fffe9),
(21, 0x1fffde),
(23, 0x7fffea),
(22, 0x3fffdd),
(22, 0x3fffde),
(24, 0xfffff0),
(21, 0x1fffdf),
(22, 0x3fffdf),
(23, 0x7fffeb),
(23, 0x7fffec),
(21, 0x1fffe0),
(21, 0x1fffe1),
(22, 0x3fffe0),
(21, 0x1fffe2),
(23, 0x7fffed),
(22, 0x3fffe1),
(23, 0x7fffee),
(23, 0x7fffef),
(22, 0x003f_ffdb),
(22, 0x003f_ffdc),
(23, 0x007f_ffe8),
(23, 0x007f_ffe9),
(21, 0x001f_ffde),
(23, 0x007f_ffea),
(22, 0x003f_ffdd),
(22, 0x003f_ffde),
(24, 0x00ff_fff0),
(21, 0x001f_ffdf),
(22, 0x003f_ffdf),
(23, 0x007f_ffeb),
(23, 0x007f_ffec),
(21, 0x001f_ffe0),
(21, 0x001f_ffe1),
(22, 0x003f_ffe0),
(21, 0x001f_ffe2),
(23, 0x007f_ffed),
(22, 0x003f_ffe1),
(23, 0x007f_ffee),
(23, 0x007f_ffef),
(20, 0xfffea),
(22, 0x3fffe2),
(22, 0x3fffe3),
(22, 0x3fffe4),
(23, 0x7ffff0),
(22, 0x3fffe5),
(22, 0x3fffe6),
(23, 0x7ffff1),
(26, 0x3ffffe0),
(26, 0x3ffffe1),
(22, 0x003f_ffe2),
(22, 0x003f_ffe3),
(22, 0x003f_ffe4),
(23, 0x007f_fff0),
(22, 0x003f_ffe5),
(22, 0x003f_ffe6),
(23, 0x007f_fff1),
(26, 0x03ff_ffe0),
(26, 0x03ff_ffe1),
(20, 0xfffeb),
(19, 0x7fff1),
(22, 0x3fffe7),
(23, 0x7ffff2),
(22, 0x3fffe8),
(25, 0x1ffffec),
(26, 0x3ffffe2),
(26, 0x3ffffe3),
(26, 0x3ffffe4),
(27, 0x7ffffde),
(27, 0x7ffffdf),
(26, 0x3ffffe5),
(24, 0xfffff1),
(25, 0x1ffffed),
(22, 0x003f_ffe7),
(23, 0x007f_fff2),
(22, 0x003f_ffe8),
(25, 0x01ff_ffec),
(26, 0x03ff_ffe2),
(26, 0x03ff_ffe3),
(26, 0x03ff_ffe4),
(27, 0x07ff_ffde),
(27, 0x07ff_ffdf),
(26, 0x03ff_ffe5),
(24, 0x00ff_fff1),
(25, 0x01ff_ffed),
(19, 0x7fff2),
(21, 0x1fffe3),
(26, 0x3ffffe6),
(27, 0x7ffffe0),
(27, 0x7ffffe1),
(26, 0x3ffffe7),
(27, 0x7ffffe2),
(24, 0xfffff2),
(21, 0x1fffe4),
(21, 0x1fffe5),
(26, 0x3ffffe8),
(26, 0x3ffffe9),
(28, 0xffffffd),
(27, 0x7ffffe3),
(27, 0x7ffffe4),
(27, 0x7ffffe5),
(21, 0x001f_ffe3),
(26, 0x03ff_ffe6),
(27, 0x07ff_ffe0),
(27, 0x07ff_ffe1),
(26, 0x03ff_ffe7),
(27, 0x07ff_ffe2),
(24, 0x00ff_fff2),
(21, 0x001f_ffe4),
(21, 0x001f_ffe5),
(26, 0x03ff_ffe8),
(26, 0x03ff_ffe9),
(28, 0x0fff_fffd),
(27, 0x07ff_ffe3),
(27, 0x07ff_ffe4),
(27, 0x07ff_ffe5),
(20, 0xfffec),
(24, 0xfffff3),
(24, 0x00ff_fff3),
(20, 0xfffed),
(21, 0x1fffe6),
(22, 0x3fffe9),
(21, 0x1fffe7),
(21, 0x1fffe8),
(23, 0x7ffff3),
(22, 0x3fffea),
(22, 0x3fffeb),
(25, 0x1ffffee),
(25, 0x1ffffef),
(24, 0xfffff4),
(24, 0xfffff5),
(26, 0x3ffffea),
(23, 0x7ffff4),
(26, 0x3ffffeb),
(27, 0x7ffffe6),
(26, 0x3ffffec),
(26, 0x3ffffed),
(27, 0x7ffffe7),
(27, 0x7ffffe8),
(27, 0x7ffffe9),
(27, 0x7ffffea),
(27, 0x7ffffeb),
(28, 0xffffffe),
(27, 0x7ffffec),
(27, 0x7ffffed),
(27, 0x7ffffee),
(27, 0x7ffffef),
(27, 0x7fffff0),
(26, 0x3ffffee),
(30, 0x3fffffff),
(21, 0x001f_ffe6),
(22, 0x003f_ffe9),
(21, 0x001f_ffe7),
(21, 0x001f_ffe8),
(23, 0x007f_fff3),
(22, 0x003f_ffea),
(22, 0x003f_ffeb),
(25, 0x01ff_ffee),
(25, 0x01ff_ffef),
(24, 0x00ff_fff4),
(24, 0x00ff_fff5),
(26, 0x03ff_ffea),
(23, 0x007f_fff4),
(26, 0x03ff_ffeb),
(27, 0x07ff_ffe6),
(26, 0x03ff_ffec),
(26, 0x03ff_ffed),
(27, 0x07ff_ffe7),
(27, 0x07ff_ffe8),
(27, 0x07ff_ffe9),
(27, 0x07ff_ffea),
(27, 0x07ff_ffeb),
(28, 0x0fff_fffe),
(27, 0x07ff_ffec),
(27, 0x07ff_ffed),
(27, 0x07ff_ffee),
(27, 0x07ff_ffef),
(27, 0x07ff_fff0),
(26, 0x03ff_ffee),
(30, 0x3fff_ffff),
];
// (next-state, byte, flags)

View File

@@ -1,5 +1,5 @@
mod encoder;
mod decoder;
mod encoder;
pub(crate) mod header;
mod huffman;
mod table;

View File

@@ -4,9 +4,9 @@ use fnv::FnvHasher;
use http::header;
use http::method::Method;
use std::{cmp, mem, usize};
use std::collections::VecDeque;
use std::hash::{Hash, Hasher};
use std::{cmp, mem, usize};
/// HPACK encoder table
#[derive(Debug)]
@@ -80,7 +80,7 @@ impl Table {
slots: VecDeque::new(),
inserted: 0,
size: 0,
max_size: max_size,
max_size,
}
} else {
let capacity = cmp::max(to_raw_capacity(capacity).next_power_of_two(), 8);
@@ -91,7 +91,7 @@ impl Table {
slots: VecDeque::with_capacity(usable_capacity(capacity)),
inserted: 0,
size: 0,
max_size: max_size,
max_size,
}
}
}
@@ -140,10 +140,7 @@ impl Table {
// Right now, if this is true, the header name is always in the
// static table. At some point in the future, this might not be true
// and this logic will need to be updated.
debug_assert!(
statik.is_some(),
"skip_value_index requires a static name",
);
debug_assert!(statik.is_some(), "skip_value_index requires a static name",);
return Index::new(statik, header);
}
@@ -313,7 +310,7 @@ impl Table {
&mut self.indices[probe],
Some(Pos {
index: pos_idx,
hash: hash,
hash,
}),
);
@@ -344,8 +341,8 @@ impl Table {
self.inserted = self.inserted.wrapping_add(1);
self.slots.push_front(Slot {
hash: hash,
header: header,
hash,
header,
next: None,
});
}
@@ -534,89 +531,89 @@ impl Table {
#[cfg(test)]
fn assert_valid_state(&self, _msg: &'static str) -> bool {
/*
// Checks that the internal map structure is valid
//
// Ensure all hash codes in indices match the associated slot
for pos in &self.indices {
if let Some(pos) = *pos {
let real_idx = pos.index.wrapping_add(self.inserted);
if real_idx.wrapping_add(1) != 0 {
assert!(real_idx < self.slots.len(),
"out of index; real={}; len={}, msg={}",
real_idx, self.slots.len(), msg);
assert_eq!(pos.hash, self.slots[real_idx].hash,
"index hash does not match slot; msg={}", msg);
}
}
}
// Every index is only available once
for i in 0..self.indices.len() {
if self.indices[i].is_none() {
continue;
}
for j in i+1..self.indices.len() {
assert_ne!(self.indices[i], self.indices[j],
"duplicate indices; msg={}", msg);
}
}
for (index, slot) in self.slots.iter().enumerate() {
let mut indexed = None;
// First, see if the slot is indexed
for (i, pos) in self.indices.iter().enumerate() {
// Checks that the internal map structure is valid
//
// Ensure all hash codes in indices match the associated slot
for pos in &self.indices {
if let Some(pos) = *pos {
let real_idx = pos.index.wrapping_add(self.inserted);
if real_idx == index {
indexed = Some(i);
// Already know that there is no dup, so break
break;
if real_idx.wrapping_add(1) != 0 {
assert!(real_idx < self.slots.len(),
"out of index; real={}; len={}, msg={}",
real_idx, self.slots.len(), msg);
assert_eq!(pos.hash, self.slots[real_idx].hash,
"index hash does not match slot; msg={}", msg);
}
}
}
if let Some(actual) = indexed {
// Ensure that it is accessible..
let desired = desired_pos(self.mask, slot.hash);
let mut probe = desired;
let mut dist = 0;
// Every index is only available once
for i in 0..self.indices.len() {
if self.indices[i].is_none() {
continue;
}
probe_loop!(probe < self.indices.len(), {
assert!(self.indices[probe].is_some(),
"unexpected empty slot; probe={}; hash={:?}; msg={}",
probe, slot.hash, msg);
let pos = self.indices[probe].unwrap();
let their_dist = probe_distance(self.mask, pos.hash, probe);
let real_idx = pos.index.wrapping_add(self.inserted);
if real_idx == index {
break;
}
assert!(dist <= their_dist,
"could not find entry; actual={}; desired={};" +
"probe={}, dist={}; their_dist={}; index={}; msg={}",
actual, desired, probe, dist, their_dist,
index.wrapping_sub(self.inserted), msg);
dist += 1;
});
} else {
// There is exactly one next link
let cnt = self.slots.iter().map(|s| s.next)
.filter(|n| *n == Some(index.wrapping_sub(self.inserted)))
.count();
assert_eq!(1, cnt, "more than one node pointing here; msg={}", msg);
for j in i+1..self.indices.len() {
assert_ne!(self.indices[i], self.indices[j],
"duplicate indices; msg={}", msg);
}
}
}
*/
for (index, slot) in self.slots.iter().enumerate() {
let mut indexed = None;
// First, see if the slot is indexed
for (i, pos) in self.indices.iter().enumerate() {
if let Some(pos) = *pos {
let real_idx = pos.index.wrapping_add(self.inserted);
if real_idx == index {
indexed = Some(i);
// Already know that there is no dup, so break
break;
}
}
}
if let Some(actual) = indexed {
// Ensure that it is accessible..
let desired = desired_pos(self.mask, slot.hash);
let mut probe = desired;
let mut dist = 0;
probe_loop!(probe < self.indices.len(), {
assert!(self.indices[probe].is_some(),
"unexpected empty slot; probe={}; hash={:?}; msg={}",
probe, slot.hash, msg);
let pos = self.indices[probe].unwrap();
let their_dist = probe_distance(self.mask, pos.hash, probe);
let real_idx = pos.index.wrapping_add(self.inserted);
if real_idx == index {
break;
}
assert!(dist <= their_dist,
"could not find entry; actual={}; desired={};" +
"probe={}, dist={}; their_dist={}; index={}; msg={}",
actual, desired, probe, dist, their_dist,
index.wrapping_sub(self.inserted), msg);
dist += 1;
});
} else {
// There is exactly one next link
let cnt = self.slots.iter().map(|s| s.next)
.filter(|n| *n == Some(index.wrapping_sub(self.inserted)))
.count();
assert_eq!(1, cnt, "more than one node pointing here; msg={}", msg);
}
}
*/
// TODO: Ensure linked lists are correct: no cycles, etc...
@@ -684,11 +681,13 @@ fn index_static(header: &Header) -> Option<(usize, bool)> {
ref value,
} => match *name {
header::ACCEPT_CHARSET => Some((15, false)),
header::ACCEPT_ENCODING => if value == "gzip, deflate" {
Some((16, true))
} else {
Some((16, false))
},
header::ACCEPT_ENCODING => {
if value == "gzip, deflate" {
Some((16, true))
} else {
Some((16, false))
}
}
header::ACCEPT_LANGUAGE => Some((17, false)),
header::ACCEPT_RANGES => Some((18, false)),
header::ACCEPT => Some((19, false)),

View File

@@ -5,8 +5,8 @@ use hex::FromHex;
use serde_json::Value;
use std::fs::File;
use std::io::Cursor;
use std::io::prelude::*;
use std::io::Cursor;
use std::path::Path;
use std::str;
@@ -30,13 +30,15 @@ fn test_story(story: Value) {
.map(|case| {
let case = case.as_object().unwrap();
let size = case.get("header_table_size")
let size = case
.get("header_table_size")
.map(|v| v.as_u64().unwrap() as usize);
let wire = case.get("wire").unwrap().as_str().unwrap();
let wire: Vec<u8> = FromHex::from_hex(wire.as_bytes()).unwrap();
let expect: Vec<_> = case.get("headers")
let expect: Vec<_> = case
.get("headers")
.unwrap()
.as_array()
.unwrap()
@@ -92,7 +94,8 @@ fn test_story(story: Value) {
decoder.queue_size_update(size);
}
let mut input: Vec<_> = case.expect
let mut input: Vec<_> = case
.expect
.iter()
.map(|&(ref name, ref value)| {
Header::new(name.clone().into(), value.clone().into())
@@ -123,9 +126,7 @@ struct Case {
fn key_str(e: &Header) -> &str {
match *e {
Header::Field {
ref name, ..
} => name.as_str(),
Header::Field { ref name, .. } => name.as_str(),
Header::Authority(..) => ":authority",
Header::Method(..) => ":method",
Header::Scheme(..) => ":scheme",
@@ -136,9 +137,7 @@ fn key_str(e: &Header) -> &str {
fn value_str(e: &Header) -> &str {
match *e {
Header::Field {
ref value, ..
} => value.to_str().unwrap(),
Header::Field { ref value, .. } => value.to_str().unwrap(),
Header::Authority(ref v) => &**v,
Header::Method(ref m) => m.as_str(),
Header::Scheme(ref v) => &**v,

View File

@@ -78,17 +78,16 @@ impl FuzzHpack {
let low = rng.gen_range(0, high);
frame.resizes.extend(&[low, high]);
},
}
1..=3 => {
frame.resizes.push(rng.gen_range(128, MAX_CHUNK * 2));
},
_ => {},
}
_ => {}
}
let mut is_name_required = true;
for _ in 0..rng.gen_range(1, (num - added) + 1) {
let x: f64 = rng.gen_range(0.0, 1.0);
let x = x.powi(skew);
@@ -100,10 +99,10 @@ impl FuzzHpack {
if is_name_required {
continue;
}
},
}
Header::Field { .. } => {
is_name_required = false;
},
}
_ => {
// pseudos can't be followed by a header with no name
is_name_required = true;
@@ -153,7 +152,7 @@ impl FuzzHpack {
_ => None,
};
expect.push(h);
},
}
Err(value) => {
expect.push(Header::Field {
name: prev_name.as_ref().cloned().expect("previous header name"),
@@ -161,7 +160,6 @@ impl FuzzHpack {
});
}
}
}
let mut input = frame.headers.into_iter();
@@ -193,7 +191,7 @@ impl FuzzHpack {
.expect("partial decode");
buf = BytesMut::with_capacity(chunks.pop().unwrap_or(MAX_CHUNK));
},
}
}
}
@@ -224,7 +222,7 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
0 => {
let value = gen_string(g, 4, 20);
Header::Authority(to_shared(value))
},
}
1 => {
let method = match g.next_u32() % 6 {
0 => Method::GET,
@@ -239,12 +237,12 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
.collect();
Method::from_bytes(&bytes).unwrap()
},
}
_ => unreachable!(),
};
Header::Method(method)
},
}
2 => {
let value = match g.next_u32() % 2 {
0 => "http",
@@ -253,7 +251,7 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
};
Header::Scheme(to_shared(value.to_string()))
},
}
3 => {
let value = match g.next_u32() % 100 {
0 => "/".to_string(),
@@ -262,12 +260,12 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
};
Header::Path(to_shared(value))
},
}
4 => {
let status = (g.gen::<u16>() % 500) + 100;
Header::Status(StatusCode::from_u16(status).unwrap())
},
}
_ => unreachable!(),
}
} else {
@@ -282,10 +280,7 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
value.set_sensitive(true);
}
Header::Field {
name,
value,
}
Header::Field { name, value }
}
}
@@ -368,8 +363,9 @@ fn gen_header_name(g: &mut StdRng) -> HeaderName {
header::X_DNS_PREFETCH_CONTROL,
header::X_FRAME_OPTIONS,
header::X_XSS_PROTECTION,
]).unwrap()
.clone()
])
.unwrap()
.clone()
} else {
let value = gen_string(g, 1, 25);
HeaderName::from_bytes(value.as_bytes()).unwrap()