work
This commit is contained in:
@@ -4,11 +4,13 @@ use tower::http::{HeaderName, Str};
|
||||
use bytes::{Buf, Bytes};
|
||||
|
||||
use std::io::Cursor;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
/// Decodes headers using HPACK
|
||||
pub struct Decoder {
|
||||
// Protocol indicated that the max table size will update
|
||||
max_size_update: Option<usize>,
|
||||
table: Table,
|
||||
}
|
||||
|
||||
/// Represents all errors that can be encountered while performing the decoding
|
||||
@@ -112,6 +114,12 @@ enum Representation {
|
||||
SizeUpdate,
|
||||
}
|
||||
|
||||
struct Table {
|
||||
entries: VecDeque<Entry>,
|
||||
size: usize,
|
||||
max_size: usize,
|
||||
}
|
||||
|
||||
// ===== impl Decoder =====
|
||||
|
||||
impl Decoder {
|
||||
@@ -119,6 +127,7 @@ impl Decoder {
|
||||
pub fn new() -> Decoder {
|
||||
Decoder {
|
||||
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> {
|
||||
// The octet limit is chosen such that the maximum allowed *value* can
|
||||
// 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 {
|
||||
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 decoder;
|
||||
mod table;
|
||||
mod entry;
|
||||
// mod table;
|
||||
|
||||
pub use self::encoder::Encoder;
|
||||
pub use self::entry::Entry;
|
||||
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 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
|
||||
pub fn get_static(idx: usize) -> Entry {
|
||||
use tower::http::StandardHeader::*;
|
||||
|
||||
Reference in New Issue
Block a user