chore: cargo fmt, clippy
This commit is contained in:
committed by
Sean McArthur
parent
e72d6dc189
commit
f46840f3fa
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
mod encoder;
|
||||
mod decoder;
|
||||
mod encoder;
|
||||
pub(crate) mod header;
|
||||
mod huffman;
|
||||
mod table;
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user