More header encoding work

This commit is contained in:
Carl Lerche
2017-06-19 11:53:03 -07:00
parent b4c3161d74
commit 327ca79550
2 changed files with 96 additions and 15 deletions

View File

@@ -92,19 +92,22 @@ impl Encoder {
if let Some(resume) = resume { if let Some(resume) = resume {
let len = dst.len(); let len = dst.len();
if let Some(ref value) = resume.value { let res = match resume.value {
unimplemented!(); Some(ref value) => {
} else { self.encode_header_without_name(
// Encode the header &resume.index,
match self.encode_header(&resume.index, dst) { value,
Err(EncoderError::BufferOverflow) => { dst)
}
None => {
self.encode_header(&resume.index, dst)
}
};
if try!(is_buffer_overflow(res)) {
dst.truncate(len); dst.truncate(len);
return Ok(Encode::Partial(resume)); return Ok(Encode::Partial(resume));
} }
Err(e) => return Err(e),
Ok(_) => {}
}
}
} }
let mut last_index = None; let mut last_index = None;
@@ -229,11 +232,13 @@ impl Encoder {
-> Result<(), EncoderError> -> Result<(), EncoderError>
{ {
match *last { match *last {
Index::Indexed(idx, ..) | Index::Indexed(..) |
Index::Name(idx, ..) | Index::Name(..) |
Index::Inserted(idx) | Index::Inserted(..) |
Index::InsertedValue(idx, ..) => Index::InsertedValue(..) =>
{ {
let idx = self.table.resolve_idx(last);
try!(encode_not_indexed( try!(encode_not_indexed(
idx, idx,
value.as_ref(), value.as_ref(),
@@ -744,6 +749,70 @@ mod test {
} }
#[test] #[test]
fn test_nameless_header() {
let mut encoder = Encoder::default();
let res = encode(&mut encoder, vec![
Header::Field {
name: Some("hello".parse().unwrap()),
value: HeaderValue::try_from_bytes(b"world").unwrap(),
},
Header::Field {
name: None,
value: HeaderValue::try_from_bytes(b"zomg").unwrap(),
},
]);
assert_eq!(&[0x40, 0x80 | 4], &res[0..2]);
assert_eq!("hello", huff_decode(&res[2..6]));
assert_eq!(0x80 | 4, res[6]);
assert_eq!("world", huff_decode(&res[7..11]));
// Next is not indexed
assert_eq!(&[15, 47, 0x80 | 3], &res[11..14]);
assert_eq!("zomg", huff_decode(&res[14..]));
}
#[test]
fn test_nameless_header_at_resume() {
let mut encoder = Encoder::default();
let mut dst = BytesMut::from(Vec::with_capacity(11));
let mut input = vec![
Header::Field {
name: Some("hello".parse().unwrap()),
value: HeaderValue::try_from_bytes(b"world").unwrap(),
},
Header::Field {
name: None,
value: HeaderValue::try_from_bytes(b"zomg").unwrap(),
},
].into_iter();
let resume = match encoder.encode(None, &mut input, &mut dst).unwrap() {
Encode::Partial(r) => r,
_ => panic!(),
};
assert_eq!(&[0x40, 0x80 | 4], &dst[0..2]);
assert_eq!("hello", huff_decode(&dst[2..6]));
assert_eq!(0x80 | 4, dst[6]);
assert_eq!("world", huff_decode(&dst[7..11]));
dst.clear();
match encoder.encode(Some(resume), &mut input, &mut dst).unwrap() {
Encode::Full => {}
_ => panic!(),
}
// Next is not indexed
assert_eq!(&[15, 47, 0x80 | 3], &dst[0..3]);
assert_eq!("zomg", huff_decode(&dst[3..]));
}
#[test]
#[ignore]
fn test_evicted_overflow() { fn test_evicted_overflow() {
// Not sure what the best way to do this is. // Not sure what the best way to do this is.
} }

View File

@@ -120,6 +120,18 @@ impl Table {
} }
} }
pub fn resolve_idx(&self, index: &Index) -> usize {
use self::Index::*;
match *index {
Indexed(idx, ..) => idx,
Name(idx, ..) => idx,
Inserted(idx) => idx + DYN_OFFSET,
InsertedValue(idx, _) => idx,
NotIndexed(_) => panic!("cannot resolve index"),
}
}
/// Index the header in the HPACK table. /// Index the header in the HPACK table.
pub fn index(&mut self, header: Header) -> Index { pub fn index(&mut self, header: Header) -> Index {
// Check the static table // Check the static table