rustfmt: add trailing commas in match arms, set fn call to block stle (#85)

This commit is contained in:
Sean McArthur
2017-09-12 19:29:06 -07:00
committed by Carl Lerche
parent de1edf4873
commit f7d14861e5
37 changed files with 894 additions and 973 deletions

View File

@@ -35,7 +35,7 @@ where_pred_indent = "Visual"
generics_indent = "Block" generics_indent = "Block"
struct_lit_style = "Block" struct_lit_style = "Block"
struct_lit_multiline_style = "ForceMulti" struct_lit_multiline_style = "ForceMulti"
fn_call_style = "Visual" fn_call_style = "Block"
report_todo = "Never" report_todo = "Never"
report_fixme = "Never" report_fixme = "Never"
chain_indent = "Block" chain_indent = "Block"
@@ -57,7 +57,7 @@ wrap_comments = false
comment_width = 80 comment_width = 80
normalize_comments = false normalize_comments = false
wrap_match_arms = true wrap_match_arms = true
match_block_trailing_comma = false match_block_trailing_comma = true
indent_match_arms = true indent_match_arms = true
match_pattern_separator_break_point = "Back" match_pattern_separator_break_point = "Back"
closure_block_indent_threshold = 0 closure_block_indent_threshold = 0

View File

@@ -27,11 +27,12 @@ pub fn main() {
let _ = env_logger::init(); let _ = env_logger::init();
let tls_client_config = std::sync::Arc::new({ let tls_client_config = std::sync::Arc::new({
let mut c = rustls::ClientConfig::new(); let mut c = rustls::ClientConfig::new();
c.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS); c.root_store
c.alpn_protocols.push(ALPN_H2.to_owned()); .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
c c.alpn_protocols.push(ALPN_H2.to_owned());
}); c
});
// Sync DNS resolution. // Sync DNS resolution.
let addr = "http2.akamai.com:443" let addr = "http2.akamai.com:443"

View File

@@ -36,10 +36,10 @@ impl Future for Process {
match try_ready!(self.body.poll()) { match try_ready!(self.body.poll()) {
Some(chunk) => { Some(chunk) => {
println!("GOT CHUNK = {:?}", chunk); println!("GOT CHUNK = {:?}", chunk);
} },
None => { None => {
self.trailers = true; self.trailers = true;
} },
} }
} }
} }

View File

@@ -1,4 +1,3 @@
extern crate bytes; extern crate bytes;
extern crate env_logger; extern crate env_logger;
extern crate futures; extern crate futures;
@@ -57,8 +56,9 @@ pub fn main() {
Ok(()) Ok(())
}).and_then(|_| { }).and_then(|_| {
println!("~~~~~~~~~~~~~~~~~~~~~~~~~~~ H2 connection CLOSE !!!!!! \ println!(
~~~~~~~~~~~"); "~~~~~~~~~~~~~~~~~~~~~~~~~~~ H2 connection CLOSE !!!!!! ~~~~~~~~~~~"
);
Ok(()) Ok(())
}) })
}) })

View File

@@ -1,4 +1,3 @@
extern crate bytes; extern crate bytes;
extern crate env_logger; extern crate env_logger;
extern crate futures; extern crate futures;
@@ -49,8 +48,9 @@ pub fn main() {
Ok(()) Ok(())
}).and_then(|_| { }).and_then(|_| {
println!("~~~~~~~~~~~~~~~~~~~~~~~~~~~ H2 connection CLOSE !!!!!! \ println!(
~~~~~~~~~~~"); "~~~~~~~~~~~~~~~~~~~~~~~~~~~ H2 connection CLOSE !!!!!! ~~~~~~~~~~~"
);
Ok(()) Ok(())
}) })
}) })

View File

@@ -80,9 +80,9 @@ where
Ok(AsyncSink::Ready) => { Ok(AsyncSink::Ready) => {
let connection = Connection::new(codec); let connection = Connection::new(codec);
Ok(Client { Ok(Client {
connection, connection,
}) })
} },
Ok(_) => unreachable!(), Ok(_) => unreachable!(),
Err(e) => Err(::Error::from(e)), Err(e) => Err(::Error::from(e)),
} }
@@ -294,13 +294,15 @@ impl proto::Peer for Peer {
fn convert_send_message(id: StreamId, request: Self::Send, end_of_stream: bool) -> Headers { fn convert_send_message(id: StreamId, request: Self::Send, end_of_stream: bool) -> Headers {
use http::request::Parts; use http::request::Parts;
let (Parts { let (
method, Parts {
uri, method,
headers, uri,
.. headers,
}, ..
_) = request.into_parts(); },
_,
) = request.into_parts();
// Build the set pseudo header set. All requests will include `method` // Build the set pseudo header set. All requests will include `method`
// and `path`. // and `path`.
@@ -332,10 +334,10 @@ impl proto::Peer for Peer {
// TODO: Should there be more specialized handling for different // TODO: Should there be more specialized handling for different
// kinds of errors // kinds of errors
return Err(RecvError::Stream { return Err(RecvError::Stream {
id: stream_id, id: stream_id,
reason: ProtocolError, reason: ProtocolError,
}); });
} },
}; };
*response.headers_mut() = fields; *response.headers_mut() = fields;

View File

@@ -70,24 +70,24 @@ impl<T> FramedRead<T> {
let res = frame::Settings::load(head, &bytes[frame::HEADER_LEN..]); let res = frame::Settings::load(head, &bytes[frame::HEADER_LEN..]);
res.map_err(|_| Connection(ProtocolError))?.into() res.map_err(|_| Connection(ProtocolError))?.into()
} },
Kind::Ping => { Kind::Ping => {
let res = frame::Ping::load(head, &bytes[frame::HEADER_LEN..]); let res = frame::Ping::load(head, &bytes[frame::HEADER_LEN..]);
res.map_err(|_| Connection(ProtocolError))?.into() res.map_err(|_| Connection(ProtocolError))?.into()
} },
Kind::WindowUpdate => { Kind::WindowUpdate => {
let res = frame::WindowUpdate::load(head, &bytes[frame::HEADER_LEN..]); let res = frame::WindowUpdate::load(head, &bytes[frame::HEADER_LEN..]);
res.map_err(|_| Connection(ProtocolError))?.into() res.map_err(|_| Connection(ProtocolError))?.into()
} },
Kind::Data => { Kind::Data => {
let _ = bytes.split_to(frame::HEADER_LEN); let _ = bytes.split_to(frame::HEADER_LEN);
let res = frame::Data::load(head, bytes.freeze()); let res = frame::Data::load(head, bytes.freeze());
// TODO: Should this always be connection level? Probably not... // TODO: Should this always be connection level? Probably not...
res.map_err(|_| Connection(ProtocolError))?.into() res.map_err(|_| Connection(ProtocolError))?.into()
} },
Kind::Headers => { Kind::Headers => {
// Drop the frame header // Drop the frame header
// TODO: Change to drain: carllerche/bytes#130 // TODO: Change to drain: carllerche/bytes#130
@@ -101,23 +101,23 @@ impl<T> FramedRead<T> {
// treat this as a stream error (Section 5.4.2) of type // treat this as a stream error (Section 5.4.2) of type
// `PROTOCOL_ERROR`. // `PROTOCOL_ERROR`.
return Err(Stream { return Err(Stream {
id: head.stream_id(), id: head.stream_id(),
reason: ProtocolError, reason: ProtocolError,
}); });
} },
_ => return Err(Connection(ProtocolError)), _ => return Err(Connection(ProtocolError)),
}; };
if headers.is_end_headers() { if headers.is_end_headers() {
// Load the HPACK encoded headers & return the frame // Load the HPACK encoded headers & return the frame
match headers.load_hpack(payload, &mut self.hpack) { match headers.load_hpack(payload, &mut self.hpack) {
Ok(_) => {} Ok(_) => {},
Err(frame::Error::MalformedMessage) => { Err(frame::Error::MalformedMessage) => {
return Err(Stream { return Err(Stream {
id: head.stream_id(), id: head.stream_id(),
reason: ProtocolError, reason: ProtocolError,
}); });
} },
Err(_) => return Err(Connection(ProtocolError)), Err(_) => return Err(Connection(ProtocolError)),
} }
@@ -125,25 +125,25 @@ impl<T> FramedRead<T> {
} else { } else {
// Defer loading the frame // Defer loading the frame
self.partial = Some(Partial { self.partial = Some(Partial {
frame: Continuable::Headers(headers), frame: Continuable::Headers(headers),
buf: payload, buf: payload,
}); });
return Ok(None); return Ok(None);
} }
} },
Kind::Reset => { Kind::Reset => {
let res = frame::Reset::load(head, &bytes[frame::HEADER_LEN..]); let res = frame::Reset::load(head, &bytes[frame::HEADER_LEN..]);
res.map_err(|_| Connection(ProtocolError))?.into() res.map_err(|_| Connection(ProtocolError))?.into()
} },
Kind::GoAway => { Kind::GoAway => {
let res = frame::GoAway::load(&bytes[frame::HEADER_LEN..]); let res = frame::GoAway::load(&bytes[frame::HEADER_LEN..]);
res.map_err(|_| Connection(ProtocolError))?.into() res.map_err(|_| Connection(ProtocolError))?.into()
} },
Kind::PushPromise => { Kind::PushPromise => {
let res = frame::PushPromise::load(head, &bytes[frame::HEADER_LEN..]); let res = frame::PushPromise::load(head, &bytes[frame::HEADER_LEN..]);
res.map_err(|_| Connection(ProtocolError))?.into() res.map_err(|_| Connection(ProtocolError))?.into()
} },
Kind::Priority => { Kind::Priority => {
if head.stream_id() == 0 { if head.stream_id() == 0 {
// Invalid stream identifier // Invalid stream identifier
@@ -157,13 +157,13 @@ impl<T> FramedRead<T> {
// treat this as a stream error (Section 5.4.2) of type // treat this as a stream error (Section 5.4.2) of type
// `PROTOCOL_ERROR`. // `PROTOCOL_ERROR`.
return Err(Stream { return Err(Stream {
id: head.stream_id(), id: head.stream_id(),
reason: ProtocolError, reason: ProtocolError,
}); });
} },
Err(_) => return Err(Connection(ProtocolError)), Err(_) => return Err(Connection(ProtocolError)),
} }
} },
Kind::Continuation => { Kind::Continuation => {
// TODO: Un-hack this // TODO: Un-hack this
let end_of_headers = (head.flag() & 0x4) == 0x4; let end_of_headers = (head.flag() & 0x4) == 0x4;
@@ -189,24 +189,24 @@ impl<T> FramedRead<T> {
} }
match frame.load_hpack(partial.buf, &mut self.hpack) { match frame.load_hpack(partial.buf, &mut self.hpack) {
Ok(_) => {} Ok(_) => {},
Err(frame::Error::MalformedMessage) => { Err(frame::Error::MalformedMessage) => {
return Err(Stream { return Err(Stream {
id: head.stream_id(), id: head.stream_id(),
reason: ProtocolError, reason: ProtocolError,
}); });
} },
Err(_) => return Err(Connection(ProtocolError)), Err(_) => return Err(Connection(ProtocolError)),
} }
frame.into() frame.into()
} },
} }
} },
Kind::Unknown => { Kind::Unknown => {
// Unknown frames are ignored // Unknown frames are ignored
return Ok(None); return Ok(None);
} },
}; };
Ok(Some(frame)) Ok(Some(frame))

View File

@@ -120,32 +120,32 @@ where
// Save off the last frame... // Save off the last frame...
self.last_data_frame = Some(v); self.last_data_frame = Some(v);
} }
} },
Frame::Headers(v) => { Frame::Headers(v) => {
if let Some(continuation) = v.encode(&mut self.hpack, self.buf.get_mut()) { if let Some(continuation) = v.encode(&mut self.hpack, self.buf.get_mut()) {
self.next = Some(Next::Continuation(continuation)); self.next = Some(Next::Continuation(continuation));
} }
} },
Frame::PushPromise(v) => { Frame::PushPromise(v) => {
debug!("unimplemented PUSH_PROMISE write; frame={:?}", v); debug!("unimplemented PUSH_PROMISE write; frame={:?}", v);
unimplemented!(); unimplemented!();
} },
Frame::Settings(v) => { Frame::Settings(v) => {
v.encode(self.buf.get_mut()); v.encode(self.buf.get_mut());
trace!("encoded settings; rem={:?}", self.buf.remaining()); trace!("encoded settings; rem={:?}", self.buf.remaining());
} },
Frame::GoAway(v) => { Frame::GoAway(v) => {
v.encode(self.buf.get_mut()); v.encode(self.buf.get_mut());
trace!("encoded go_away; rem={:?}", self.buf.remaining()); trace!("encoded go_away; rem={:?}", self.buf.remaining());
} },
Frame::Ping(v) => { Frame::Ping(v) => {
v.encode(self.buf.get_mut()); v.encode(self.buf.get_mut());
trace!("encoded ping; rem={:?}", self.buf.remaining()); trace!("encoded ping; rem={:?}", self.buf.remaining());
} },
Frame::WindowUpdate(v) => { Frame::WindowUpdate(v) => {
v.encode(self.buf.get_mut()); v.encode(self.buf.get_mut());
trace!("encoded window_update; rem={:?}", self.buf.remaining()); trace!("encoded window_update; rem={:?}", self.buf.remaining());
} },
Frame::Priority(_) => { Frame::Priority(_) => {
/* /*
@@ -153,11 +153,11 @@ where
trace!("encoded priority; rem={:?}", self.buf.remaining()); trace!("encoded priority; rem={:?}", self.buf.remaining());
*/ */
unimplemented!(); unimplemented!();
} },
Frame::Reset(v) => { Frame::Reset(v) => {
v.encode(self.buf.get_mut()); v.encode(self.buf.get_mut());
trace!("encoded reset; rem={:?}", self.buf.remaining()); trace!("encoded reset; rem={:?}", self.buf.remaining());
} },
} }
Ok(()) Ok(())
@@ -172,10 +172,10 @@ where
Some(Next::Data(ref mut frame)) => { Some(Next::Data(ref mut frame)) => {
let mut buf = Buf::by_ref(&mut self.buf).chain(frame.payload_mut()); let mut buf = Buf::by_ref(&mut self.buf).chain(frame.payload_mut());
try_ready!(self.inner.write_buf(&mut buf)); try_ready!(self.inner.write_buf(&mut buf));
} },
_ => { _ => {
try_ready!(self.inner.write_buf(&mut self.buf)); try_ready!(self.inner.write_buf(&mut self.buf));
} },
} }
} }
@@ -183,11 +183,11 @@ where
match self.next.take() { match self.next.take() {
Some(Next::Data(frame)) => { Some(Next::Data(frame)) => {
self.last_data_frame = Some(frame); self.last_data_frame = Some(frame);
} },
Some(Next::Continuation(_)) => { Some(Next::Continuation(_)) => {
unimplemented!(); unimplemented!();
} },
None => {} None => {},
} }
trace!("flushing buffer"); trace!("flushing buffer");

View File

@@ -121,11 +121,11 @@ impl Data<Bytes> {
}; };
Ok(Data { Ok(Data {
stream_id: head.stream_id(), stream_id: head.stream_id(),
data: payload, data: payload,
flags: flags, flags: flags,
pad_len: pad_len, pad_len: pad_len,
}) })
} }
} }

View File

@@ -35,9 +35,9 @@ impl GoAway {
let error_code = unpack_octets_4!(payload, 4, u32); let error_code = unpack_octets_4!(payload, 4, u32);
Ok(GoAway { Ok(GoAway {
last_stream_id: last_stream_id, last_stream_id: last_stream_id,
error_code: error_code, error_code: error_code,
}) })
} }
pub fn encode<B: BufMut>(&self, dst: &mut B) { pub fn encode<B: BufMut>(&self, dst: &mut B) {

View File

@@ -218,7 +218,7 @@ impl Headers {
reg = true; reg = true;
self.fields.append(name, value); self.fields.append(name, value);
} }
} },
Authority(v) => set_pseudo!(authority, v), Authority(v) => set_pseudo!(authority, v),
Method(v) => set_pseudo!(method, v), Method(v) => set_pseudo!(method, v),
Scheme(v) => set_pseudo!(scheme, v), Scheme(v) => set_pseudo!(scheme, v),
@@ -285,13 +285,11 @@ impl Headers {
let ret = match encoder.encode(None, &mut headers, dst) { let ret = match encoder.encode(None, &mut headers, dst) {
hpack::Encode::Full => None, hpack::Encode::Full => None,
hpack::Encode::Partial(state) => { hpack::Encode::Partial(state) => Some(Continuation {
Some(Continuation { stream_id: self.stream_id,
stream_id: self.stream_id, hpack: state,
hpack: state, headers: headers,
headers: headers, }),
})
}
}; };
// Compute the frame length // Compute the frame length
@@ -336,10 +334,10 @@ impl PushPromise {
let (promised_id, _) = StreamId::parse(&payload[..4]); let (promised_id, _) = StreamId::parse(&payload[..4]);
Ok(PushPromise { Ok(PushPromise {
stream_id: head.stream_id(), stream_id: head.stream_id(),
promised_id: promised_id, promised_id: promised_id,
flags: flags, flags: flags,
}) })
} }
pub fn stream_id(&self) -> StreamId { pub fn stream_id(&self) -> StreamId {

View File

@@ -69,9 +69,9 @@ impl Ping {
let ack = head.flag() & ACK_FLAG != 0; let ack = head.flag() & ACK_FLAG != 0;
Ok(Ping { Ok(Ping {
ack, ack,
payload, payload,
}) })
} }
pub fn encode<B: BufMut>(&self, dst: &mut B) { pub fn encode<B: BufMut>(&self, dst: &mut B) {

View File

@@ -29,9 +29,9 @@ impl Priority {
} }
Ok(Priority { Ok(Priority {
stream_id: head.stream_id(), stream_id: head.stream_id(),
dependency: dependency, dependency: dependency,
}) })
} }
} }

View File

@@ -40,7 +40,7 @@ impl Reason {
ConnectError => { ConnectError => {
"connection established in response to a CONNECT request \ "connection established in response to a CONNECT request \
was reset or abnormally closed" was reset or abnormally closed"
} },
EnhanceYourCalm => "detected excessive load generating behavior", EnhanceYourCalm => "detected excessive load generating behavior",
InadequateSecurity => "security properties do not meet minimum requirements", InadequateSecurity => "security properties do not meet minimum requirements",
Http11Required => "endpoint requires HTTP/1.1", Http11Required => "endpoint requires HTTP/1.1",

View File

@@ -32,15 +32,17 @@ impl Reset {
let error_code = unpack_octets_4!(payload, 0, u32); let error_code = unpack_octets_4!(payload, 0, u32);
Ok(Reset { Ok(Reset {
stream_id: head.stream_id(), stream_id: head.stream_id(),
error_code: error_code, error_code: error_code,
}) })
} }
pub fn encode<B: BufMut>(&self, dst: &mut B) { pub fn encode<B: BufMut>(&self, dst: &mut B) {
trace!("encoding RESET; id={:?} code={}", trace!(
self.stream_id, "encoding RESET; id={:?} code={}",
self.error_code); self.stream_id,
self.error_code
);
let head = Head::new(Kind::Reset, 0, self.stream_id); let head = Head::new(Kind::Reset, 0, self.stream_id);
head.encode(4, dst); head.encode(4, dst);
dst.put_u32::<BigEndian>(self.error_code); dst.put_u32::<BigEndian>(self.error_code);

View File

@@ -109,38 +109,34 @@ impl Settings {
match Setting::load(raw) { match Setting::load(raw) {
Some(HeaderTableSize(val)) => { Some(HeaderTableSize(val)) => {
settings.header_table_size = Some(val); settings.header_table_size = Some(val);
} },
Some(EnablePush(val)) => { Some(EnablePush(val)) => match val {
match val { 0 | 1 => {
0 | 1 => { settings.enable_push = Some(val);
settings.enable_push = Some(val); },
} _ => {
_ => { return Err(Error::InvalidSettingValue);
return Err(Error::InvalidSettingValue); },
} },
}
}
Some(MaxConcurrentStreams(val)) => { Some(MaxConcurrentStreams(val)) => {
settings.max_concurrent_streams = Some(val); settings.max_concurrent_streams = Some(val);
} },
Some(InitialWindowSize(val)) => { Some(InitialWindowSize(val)) => if val as usize > MAX_INITIAL_WINDOW_SIZE {
if val as usize > MAX_INITIAL_WINDOW_SIZE { return Err(Error::InvalidSettingValue);
return Err(Error::InvalidSettingValue); } else {
} else { settings.initial_window_size = Some(val);
settings.initial_window_size = Some(val); },
}
}
Some(MaxFrameSize(val)) => { Some(MaxFrameSize(val)) => {
if val < DEFAULT_MAX_FRAME_SIZE || val as usize > MAX_MAX_FRAME_SIZE { if val < DEFAULT_MAX_FRAME_SIZE || val as usize > MAX_MAX_FRAME_SIZE {
return Err(Error::InvalidSettingValue); return Err(Error::InvalidSettingValue);
} else { } else {
settings.max_frame_size = Some(val); settings.max_frame_size = Some(val);
} }
} },
Some(MaxHeaderListSize(val)) => { Some(MaxHeaderListSize(val)) => {
settings.max_header_list_size = Some(val); settings.max_header_list_size = Some(val);
} },
None => {} None => {},
} }
} }

View File

@@ -42,9 +42,9 @@ impl WindowUpdate {
} }
Ok(WindowUpdate { Ok(WindowUpdate {
stream_id: head.stream_id(), stream_id: head.stream_id(),
size_increment, size_increment,
}) })
} }
pub fn encode<B: BufMut>(&self, dst: &mut B) { pub fn encode<B: BufMut>(&self, dst: &mut B) {

View File

@@ -186,7 +186,7 @@ impl Decoder {
trace!(" Indexed; rem={:?}", src.remaining()); trace!(" Indexed; rem={:?}", src.remaining());
can_resize = false; can_resize = false;
f(self.decode_indexed(src)?); f(self.decode_indexed(src)?);
} },
LiteralWithIndexing => { LiteralWithIndexing => {
trace!(" LiteralWithIndexing; rem={:?}", src.remaining()); trace!(" LiteralWithIndexing; rem={:?}", src.remaining());
can_resize = false; can_resize = false;
@@ -196,13 +196,13 @@ impl Decoder {
self.table.insert(entry.clone()); self.table.insert(entry.clone());
f(entry); f(entry);
} },
LiteralWithoutIndexing => { LiteralWithoutIndexing => {
trace!(" LiteralWithoutIndexing; rem={:?}", src.remaining()); trace!(" LiteralWithoutIndexing; rem={:?}", src.remaining());
can_resize = false; can_resize = false;
let entry = self.decode_literal(src, false)?; let entry = self.decode_literal(src, false)?;
f(entry); f(entry);
} },
LiteralNeverIndexed => { LiteralNeverIndexed => {
trace!(" LiteralNeverIndexed; rem={:?}", src.remaining()); trace!(" LiteralNeverIndexed; rem={:?}", src.remaining());
can_resize = false; can_resize = false;
@@ -211,7 +211,7 @@ impl Decoder {
// TODO: Track that this should never be indexed // TODO: Track that this should never be indexed
f(entry); f(entry);
} },
SizeUpdate => { SizeUpdate => {
trace!(" SizeUpdate; rem={:?}", src.remaining()); trace!(" SizeUpdate; rem={:?}", src.remaining());
if !can_resize { if !can_resize {
@@ -220,7 +220,7 @@ impl Decoder {
// Handle the dynamic table size update // Handle the dynamic table size update
self.process_size_update(src)?; self.process_size_update(src)?;
} },
} }
} }
@@ -234,9 +234,11 @@ impl Decoder {
return Err(DecoderError::InvalidMaxDynamicSize); return Err(DecoderError::InvalidMaxDynamicSize);
} }
debug!("Decoder changed max table size from {} to {}", debug!(
self.table.size(), "Decoder changed max table size from {} to {}",
new_size); self.table.size(),
new_size
);
self.table.set_max_size(new_size); self.table.set_max_size(new_size);
@@ -287,9 +289,11 @@ impl Decoder {
let len = decode_int(buf, 7)?; let len = decode_int(buf, 7)?;
if len > buf.remaining() { if len > buf.remaining() {
trace!("decode_string underflow; len={}; remaining={}", trace!(
len, "decode_string underflow; len={}; remaining={}",
buf.remaining()); len,
buf.remaining()
);
return Err(DecoderError::StringUnderflow); return Err(DecoderError::StringUnderflow);
} }
@@ -489,7 +493,7 @@ impl Table {
// Can never happen as the size of the table must reach // Can never happen as the size of the table must reach
// 0 by the time we've exhausted all elements. // 0 by the time we've exhausted all elements.
panic!("Size of table != 0, but no headers left!"); panic!("Size of table != 0, but no headers left!");
} },
}; };
self.size -= last.len(); self.size -= last.len();
@@ -563,288 +567,194 @@ pub fn get_static(idx: usize) -> Header {
12 => Header::Status(StatusCode::BAD_REQUEST), 12 => Header::Status(StatusCode::BAD_REQUEST),
13 => Header::Status(StatusCode::NOT_FOUND), 13 => Header::Status(StatusCode::NOT_FOUND),
14 => Header::Status(StatusCode::INTERNAL_SERVER_ERROR), 14 => Header::Status(StatusCode::INTERNAL_SERVER_ERROR),
15 => { 15 => Header::Field {
Header::Field { name: header::ACCEPT_CHARSET,
name: header::ACCEPT_CHARSET, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 16 => Header::Field {
} name: header::ACCEPT_ENCODING,
16 => { value: HeaderValue::from_static("gzip, deflate"),
Header::Field { },
name: header::ACCEPT_ENCODING, 17 => Header::Field {
value: HeaderValue::from_static("gzip, deflate"), name: header::ACCEPT_LANGUAGE,
} value: HeaderValue::from_static(""),
} },
17 => { 18 => Header::Field {
Header::Field { name: header::ACCEPT_RANGES,
name: header::ACCEPT_LANGUAGE, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 19 => Header::Field {
} name: header::ACCEPT,
18 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::ACCEPT_RANGES, 20 => Header::Field {
value: HeaderValue::from_static(""), name: header::ACCESS_CONTROL_ALLOW_ORIGIN,
} value: HeaderValue::from_static(""),
} },
19 => { 21 => Header::Field {
Header::Field { name: header::AGE,
name: header::ACCEPT, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 22 => Header::Field {
} name: header::ALLOW,
20 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::ACCESS_CONTROL_ALLOW_ORIGIN, 23 => Header::Field {
value: HeaderValue::from_static(""), name: header::AUTHORIZATION,
} value: HeaderValue::from_static(""),
} },
21 => { 24 => Header::Field {
Header::Field { name: header::CACHE_CONTROL,
name: header::AGE, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 25 => Header::Field {
} name: header::CONTENT_DISPOSITION,
22 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::ALLOW, 26 => Header::Field {
value: HeaderValue::from_static(""), name: header::CONTENT_ENCODING,
} value: HeaderValue::from_static(""),
} },
23 => { 27 => Header::Field {
Header::Field { name: header::CONTENT_LANGUAGE,
name: header::AUTHORIZATION, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 28 => Header::Field {
} name: header::CONTENT_LENGTH,
24 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::CACHE_CONTROL, 29 => Header::Field {
value: HeaderValue::from_static(""), name: header::CONTENT_LOCATION,
} value: HeaderValue::from_static(""),
} },
25 => { 30 => Header::Field {
Header::Field { name: header::CONTENT_RANGE,
name: header::CONTENT_DISPOSITION, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 31 => Header::Field {
} name: header::CONTENT_TYPE,
26 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::CONTENT_ENCODING, 32 => Header::Field {
value: HeaderValue::from_static(""), name: header::COOKIE,
} value: HeaderValue::from_static(""),
} },
27 => { 33 => Header::Field {
Header::Field { name: header::DATE,
name: header::CONTENT_LANGUAGE, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 34 => Header::Field {
} name: header::ETAG,
28 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::CONTENT_LENGTH, 35 => Header::Field {
value: HeaderValue::from_static(""), name: header::EXPECT,
} value: HeaderValue::from_static(""),
} },
29 => { 36 => Header::Field {
Header::Field { name: header::EXPIRES,
name: header::CONTENT_LOCATION, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 37 => Header::Field {
} name: header::FROM,
30 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::CONTENT_RANGE, 38 => Header::Field {
value: HeaderValue::from_static(""), name: header::HOST,
} value: HeaderValue::from_static(""),
} },
31 => { 39 => Header::Field {
Header::Field { name: header::IF_MATCH,
name: header::CONTENT_TYPE, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 40 => Header::Field {
} name: header::IF_MODIFIED_SINCE,
32 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::COOKIE, 41 => Header::Field {
value: HeaderValue::from_static(""), name: header::IF_NONE_MATCH,
} value: HeaderValue::from_static(""),
} },
33 => { 42 => Header::Field {
Header::Field { name: header::IF_RANGE,
name: header::DATE, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 43 => Header::Field {
} name: header::IF_UNMODIFIED_SINCE,
34 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::ETAG, 44 => Header::Field {
value: HeaderValue::from_static(""), name: header::LAST_MODIFIED,
} value: HeaderValue::from_static(""),
} },
35 => { 45 => Header::Field {
Header::Field { name: header::LINK,
name: header::EXPECT, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 46 => Header::Field {
} name: header::LOCATION,
36 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::EXPIRES, 47 => Header::Field {
value: HeaderValue::from_static(""), name: header::MAX_FORWARDS,
} value: HeaderValue::from_static(""),
} },
37 => { 48 => Header::Field {
Header::Field { name: header::PROXY_AUTHENTICATE,
name: header::FROM, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 49 => Header::Field {
} name: header::PROXY_AUTHORIZATION,
38 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::HOST, 50 => Header::Field {
value: HeaderValue::from_static(""), name: header::RANGE,
} value: HeaderValue::from_static(""),
} },
39 => { 51 => Header::Field {
Header::Field { name: header::REFERER,
name: header::IF_MATCH, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 52 => Header::Field {
} name: header::REFRESH,
40 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::IF_MODIFIED_SINCE, 53 => Header::Field {
value: HeaderValue::from_static(""), name: header::RETRY_AFTER,
} value: HeaderValue::from_static(""),
} },
41 => { 54 => Header::Field {
Header::Field { name: header::SERVER,
name: header::IF_NONE_MATCH, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 55 => Header::Field {
} name: header::SET_COOKIE,
42 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::IF_RANGE, 56 => Header::Field {
value: HeaderValue::from_static(""), name: header::STRICT_TRANSPORT_SECURITY,
} value: HeaderValue::from_static(""),
} },
43 => { 57 => Header::Field {
Header::Field { name: header::TRANSFER_ENCODING,
name: header::IF_UNMODIFIED_SINCE, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 58 => Header::Field {
} name: header::USER_AGENT,
44 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::LAST_MODIFIED, 59 => Header::Field {
value: HeaderValue::from_static(""), name: header::VARY,
} value: HeaderValue::from_static(""),
} },
45 => { 60 => Header::Field {
Header::Field { name: header::VIA,
name: header::LINK, value: HeaderValue::from_static(""),
value: HeaderValue::from_static(""), },
} 61 => Header::Field {
} name: header::WWW_AUTHENTICATE,
46 => { value: HeaderValue::from_static(""),
Header::Field { },
name: header::LOCATION,
value: HeaderValue::from_static(""),
}
}
47 => {
Header::Field {
name: header::MAX_FORWARDS,
value: HeaderValue::from_static(""),
}
}
48 => {
Header::Field {
name: header::PROXY_AUTHENTICATE,
value: HeaderValue::from_static(""),
}
}
49 => {
Header::Field {
name: header::PROXY_AUTHORIZATION,
value: HeaderValue::from_static(""),
}
}
50 => {
Header::Field {
name: header::RANGE,
value: HeaderValue::from_static(""),
}
}
51 => {
Header::Field {
name: header::REFERER,
value: HeaderValue::from_static(""),
}
}
52 => {
Header::Field {
name: header::REFRESH,
value: HeaderValue::from_static(""),
}
}
53 => {
Header::Field {
name: header::RETRY_AFTER,
value: HeaderValue::from_static(""),
}
}
54 => {
Header::Field {
name: header::SERVER,
value: HeaderValue::from_static(""),
}
}
55 => {
Header::Field {
name: header::SET_COOKIE,
value: HeaderValue::from_static(""),
}
}
56 => {
Header::Field {
name: header::STRICT_TRANSPORT_SECURITY,
value: HeaderValue::from_static(""),
}
}
57 => {
Header::Field {
name: header::TRANSFER_ENCODING,
value: HeaderValue::from_static(""),
}
}
58 => {
Header::Field {
name: header::USER_AGENT,
value: HeaderValue::from_static(""),
}
}
59 => {
Header::Field {
name: header::VARY,
value: HeaderValue::from_static(""),
}
}
60 => {
Header::Field {
name: header::VIA,
value: HeaderValue::from_static(""),
}
}
61 => {
Header::Field {
name: header::WWW_AUTHENTICATE,
value: HeaderValue::from_static(""),
}
}
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@@ -47,31 +47,27 @@ impl Encoder {
#[allow(dead_code)] #[allow(dead_code)]
pub fn update_max_size(&mut self, val: usize) { pub fn update_max_size(&mut self, val: usize) {
match self.size_update { match self.size_update {
Some(SizeUpdate::One(old)) => { Some(SizeUpdate::One(old)) => if val > old {
if val > old { if old > self.table.max_size() {
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)); self.size_update = Some(SizeUpdate::One(val));
} else { } else {
self.size_update = Some(SizeUpdate::Two(min, val)); 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(min, val));
},
None => { None => {
if val != self.table.max_size() { if val != self.table.max_size() {
// Don't bother writing a frame if the value already matches // Don't bother writing a frame if the value already matches
// the table's max size. // the table's max size.
self.size_update = Some(SizeUpdate::One(val)); self.size_update = Some(SizeUpdate::One(val));
} }
} },
} }
} }
@@ -124,13 +120,13 @@ impl Encoder {
if res.is_err() { if res.is_err() {
dst.truncate(len); dst.truncate(len);
return Encode::Partial(EncodeState { return Encode::Partial(EncodeState {
index: index, index: index,
value: None, value: None,
}); });
} }
last_index = Some(index); last_index = Some(index);
} },
// The header does not have an associated name. This means that // The header does not have an associated name. This means that
// the name is the same as the previously yielded header. In // the name is the same as the previously yielded header. In
// which case, we skip table lookup and just use the same index // which case, we skip table lookup and just use the same index
@@ -142,11 +138,11 @@ impl Encoder {
if res.is_err() { if res.is_err() {
dst.truncate(len); dst.truncate(len);
return Encode::Partial(EncodeState { return Encode::Partial(EncodeState {
index: last_index.unwrap(), index: last_index.unwrap(),
value: Some(value), value: Some(value),
}); });
} }
} },
}; };
} }
@@ -158,14 +154,14 @@ impl Encoder {
Some(SizeUpdate::One(val)) => { Some(SizeUpdate::One(val)) => {
self.table.resize(val); self.table.resize(val);
encode_size_update(val, dst)?; encode_size_update(val, dst)?;
} },
Some(SizeUpdate::Two(min, max)) => { Some(SizeUpdate::Two(min, max)) => {
self.table.resize(min); self.table.resize(min);
self.table.resize(max); self.table.resize(max);
encode_size_update(min, dst)?; encode_size_update(min, dst)?;
encode_size_update(max, dst)?; encode_size_update(max, dst)?;
} },
None => {} None => {},
} }
Ok(()) Ok(())
@@ -175,12 +171,12 @@ impl Encoder {
match *index { match *index {
Index::Indexed(idx, _) => { Index::Indexed(idx, _) => {
encode_int(idx, 7, 0x80, dst)?; encode_int(idx, 7, 0x80, dst)?;
} },
Index::Name(idx, _) => { Index::Name(idx, _) => {
let header = self.table.resolve(&index); let header = self.table.resolve(&index);
encode_not_indexed(idx, header.value_slice(), header.is_sensitive(), dst)?; encode_not_indexed(idx, header.value_slice(), header.is_sensitive(), dst)?;
} },
Index::Inserted(_) => { Index::Inserted(_) => {
let header = self.table.resolve(&index); let header = self.table.resolve(&index);
@@ -194,7 +190,7 @@ impl Encoder {
encode_str(header.name().as_slice(), dst)?; encode_str(header.name().as_slice(), dst)?;
encode_str(header.value_slice(), dst)?; encode_str(header.value_slice(), dst)?;
} },
Index::InsertedValue(idx, _) => { Index::InsertedValue(idx, _) => {
let header = self.table.resolve(&index); let header = self.table.resolve(&index);
@@ -202,15 +198,17 @@ impl Encoder {
encode_int(idx, 6, 0b01000000, dst)?; encode_int(idx, 6, 0b01000000, dst)?;
encode_str(header.value_slice(), dst)?; encode_str(header.value_slice(), dst)?;
} },
Index::NotIndexed(_) => { Index::NotIndexed(_) => {
let header = self.table.resolve(&index); let header = self.table.resolve(&index);
encode_not_indexed2(header.name().as_slice(), encode_not_indexed2(
header.value_slice(), header.name().as_slice(),
header.is_sensitive(), header.value_slice(),
dst)?; header.is_sensitive(),
} dst,
)?;
},
} }
Ok(()) Ok(())
@@ -230,15 +228,17 @@ impl Encoder {
let idx = self.table.resolve_idx(last); let idx = self.table.resolve_idx(last);
encode_not_indexed(idx, value.as_ref(), value.is_sensitive(), dst)?; encode_not_indexed(idx, value.as_ref(), value.is_sensitive(), dst)?;
} },
Index::NotIndexed(_) => { Index::NotIndexed(_) => {
let last = self.table.resolve(last); let last = self.table.resolve(last);
encode_not_indexed2(last.name().as_slice(), encode_not_indexed2(
value.as_ref(), last.name().as_slice(),
value.is_sensitive(), value.as_ref(),
dst)?; value.is_sensitive(),
} dst,
)?;
},
} }
Ok(()) Ok(())
@@ -570,8 +570,10 @@ mod test {
// Using the name component of a previously indexed header (without // Using the name component of a previously indexed header (without
// sensitive flag set) // sensitive flag set)
let _ = encode(&mut encoder, let _ = encode(
vec![self::header("my-password", "not-so-secret")]); &mut encoder,
vec![self::header("my-password", "not-so-secret")],
);
let name = "my-password".parse().unwrap(); let name = "my-password".parse().unwrap();
let mut value = HeaderValue::from_bytes(b"12345").unwrap(); let mut value = HeaderValue::from_bytes(b"12345").unwrap();
@@ -794,7 +796,7 @@ mod test {
dst.clear(); dst.clear();
match encoder.encode(Some(resume), &mut input, &mut dst) { match encoder.encode(Some(resume), &mut input, &mut dst) {
Encode::Full => {} Encode::Full => {},
_ => panic!(), _ => panic!(),
} }

View File

@@ -38,25 +38,23 @@ impl Header<Option<HeaderName>> {
use self::Header::*; use self::Header::*;
Ok(match self { Ok(match self {
Field { Field {
name: Some(n), name: Some(n),
value, value,
} => { } => Field {
Field { name: n,
name: n, value: value,
value: value, },
} Field {
} name: None,
Field { value,
name: None, } => return Err(value),
value, Authority(v) => Authority(v),
} => return Err(value), Method(v) => Method(v),
Authority(v) => Authority(v), Scheme(v) => Scheme(v),
Method(v) => Method(v), Path(v) => Path(v),
Scheme(v) => Scheme(v), Status(v) => Status(v),
Path(v) => Path(v), })
Status(v) => Status(v),
})
} }
} }
@@ -67,23 +65,23 @@ impl Header {
b"authority" => { b"authority" => {
let value = String::try_from(value)?; let value = String::try_from(value)?;
Ok(Header::Authority(value)) Ok(Header::Authority(value))
} },
b"method" => { b"method" => {
let method = Method::from_bytes(&value)?; let method = Method::from_bytes(&value)?;
Ok(Header::Method(method)) Ok(Header::Method(method))
} },
b"scheme" => { b"scheme" => {
let value = String::try_from(value)?; let value = String::try_from(value)?;
Ok(Header::Scheme(value)) Ok(Header::Scheme(value))
} },
b"path" => { b"path" => {
let value = String::try_from(value)?; let value = String::try_from(value)?;
Ok(Header::Path(value)) Ok(Header::Path(value))
} },
b"status" => { b"status" => {
let status = StatusCode::from_bytes(&value)?; let status = StatusCode::from_bytes(&value)?;
Ok(Header::Status(status)) Ok(Header::Status(status))
} },
_ => Err(DecoderError::InvalidPseudoheader), _ => Err(DecoderError::InvalidPseudoheader),
} }
} else { } else {
@@ -92,9 +90,9 @@ impl Header {
let value = HeaderValue::from_bytes(&value)?; let value = HeaderValue::from_bytes(&value)?;
Ok(Header::Field { Ok(Header::Field {
name: name, name: name,
value: value, value: value,
}) })
} }
} }
@@ -151,37 +149,27 @@ impl Header {
} => a == value, } => a == value,
_ => false, _ => false,
} }
} },
Header::Authority(ref a) => { Header::Authority(ref a) => match *other {
match *other { Header::Authority(ref b) => a == b,
Header::Authority(ref b) => a == b, _ => false,
_ => false, },
} Header::Method(ref a) => match *other {
} Header::Method(ref b) => a == b,
Header::Method(ref a) => { _ => false,
match *other { },
Header::Method(ref b) => a == b, Header::Scheme(ref a) => match *other {
_ => false, Header::Scheme(ref b) => a == b,
} _ => false,
} },
Header::Scheme(ref a) => { Header::Path(ref a) => match *other {
match *other { Header::Path(ref b) => a == b,
Header::Scheme(ref b) => a == b, _ => false,
_ => false, },
} Header::Status(ref a) => match *other {
} Header::Status(ref b) => a == b,
Header::Path(ref a) => { _ => false,
match *other { },
Header::Path(ref b) => a == b,
_ => false,
}
}
Header::Status(ref a) => {
match *other {
Header::Status(ref b) => a == b,
_ => false,
}
}
} }
} }
@@ -201,20 +189,18 @@ impl Header {
match *self { match *self {
Header::Field { Header::Field {
ref name, .. ref name, ..
} => { } => match *name {
match *name { header::AGE |
header::AGE | header::AUTHORIZATION |
header::AUTHORIZATION | header::CONTENT_LENGTH |
header::CONTENT_LENGTH | header::ETAG |
header::ETAG | header::IF_MODIFIED_SINCE |
header::IF_MODIFIED_SINCE | header::IF_NONE_MATCH |
header::IF_NONE_MATCH | header::LOCATION |
header::LOCATION | header::COOKIE |
header::COOKIE | header::SET_COOKIE => true,
header::SET_COOKIE => true, _ => false,
_ => false, },
}
}
Header::Path(..) => true, Header::Path(..) => true,
_ => false, _ => false,
} }
@@ -228,12 +214,10 @@ impl From<Header> for Header<Option<HeaderName>> {
Header::Field { Header::Field {
name, name,
value, value,
} => { } => Header::Field {
Header::Field { name: Some(name),
name: Some(name), value,
value, },
}
}
Header::Authority(v) => Header::Authority(v), Header::Authority(v) => Header::Authority(v),
Header::Method(v) => Header::Method(v), Header::Method(v) => Header::Method(v),
Header::Scheme(v) => Header::Scheme(v), Header::Scheme(v) => Header::Scheme(v),
@@ -246,12 +230,10 @@ impl From<Header> for Header<Option<HeaderName>> {
impl<'a> Name<'a> { impl<'a> Name<'a> {
pub fn into_entry(self, value: Bytes) -> Result<Header, DecoderError> { pub fn into_entry(self, value: Bytes) -> Result<Header, DecoderError> {
match self { match self {
Name::Field(name) => { Name::Field(name) => Ok(Header::Field {
Ok(Header::Field { name: name.clone(),
name: name.clone(), value: HeaderValue::from_bytes(&*value)?,
value: HeaderValue::from_bytes(&*value)?, }),
})
}
Name::Authority => Ok(Header::Authority(String::try_from(value)?)), Name::Authority => Ok(Header::Authority(String::try_from(value)?)),
Name::Method => Ok(Header::Method(Method::from_bytes(&*value)?)), Name::Method => Ok(Header::Method(Method::from_bytes(&*value)?)),
Name::Scheme => Ok(Header::Scheme(String::try_from(value)?)), Name::Scheme => Ok(Header::Scheme(String::try_from(value)?)),
@@ -262,7 +244,7 @@ impl<'a> Name<'a> {
// TODO: better error handling // TODO: better error handling
Err(_) => Err(DecoderError::InvalidStatusCode), Err(_) => Err(DecoderError::InvalidStatusCode),
} }
} },
} }
} }

View File

@@ -292,11 +292,13 @@ impl Table {
let pos_idx = 0usize.wrapping_sub(self.inserted); let pos_idx = 0usize.wrapping_sub(self.inserted);
let prev = mem::replace(&mut self.indices[probe], let prev = mem::replace(
Some(Pos { &mut self.indices[probe],
index: pos_idx, Some(Pos {
hash: hash, index: pos_idx,
})); hash: hash,
}),
);
if let Some(mut prev) = prev { if let Some(mut prev) = prev {
// Shift forward // Shift forward
@@ -325,10 +327,10 @@ impl Table {
self.inserted = self.inserted.wrapping_add(1); self.inserted = self.inserted.wrapping_add(1);
self.slots.push_front(Slot { self.slots.push_front(Slot {
hash: hash, hash: hash,
header: header, header: header,
next: None, next: None,
}); });
} }
pub fn resize(&mut self, size: usize) { pub fn resize(&mut self, size: usize) {
@@ -377,12 +379,14 @@ impl Table {
// Update the size // Update the size
self.size -= slot.header.len(); self.size -= slot.header.len();
debug_assert_eq!(self.indices debug_assert_eq!(
.iter() self.indices
.filter_map(|p| *p) .iter()
.filter(|p| p.index == pos_idx) .filter_map(|p| *p)
.count(), .filter(|p| p.index == pos_idx)
1); .count(),
1
);
// Find the associated position // Find the associated position
probe_loop!(probe < self.indices.len(), { probe_loop!(probe < self.indices.len(), {
@@ -495,12 +499,12 @@ impl Table {
} }
debug_assert!({ debug_assert!({
let them = self.indices[probe].unwrap(); let them = self.indices[probe].unwrap();
let their_distance = probe_distance(self.mask, them.hash, probe); let their_distance = probe_distance(self.mask, them.hash, probe);
let our_distance = probe_distance(self.mask, pos.hash, probe); let our_distance = probe_distance(self.mask, pos.hash, probe);
their_distance >= our_distance their_distance >= our_distance
}); });
}); });
} }
} }
@@ -661,97 +665,85 @@ fn index_static(header: &Header) -> Option<(usize, bool)> {
Header::Field { Header::Field {
ref name, ref name,
ref value, ref value,
} => { } => match *name {
match *name { header::ACCEPT_CHARSET => Some((15, false)),
header::ACCEPT_CHARSET => Some((15, false)), header::ACCEPT_ENCODING => if value == "gzip, deflate" {
header::ACCEPT_ENCODING => { Some((16, true))
if value == "gzip, deflate" { } else {
Some((16, true)) Some((16, false))
} else { },
Some((16, false)) header::ACCEPT_LANGUAGE => Some((17, false)),
} header::ACCEPT_RANGES => Some((18, false)),
} header::ACCEPT => Some((19, false)),
header::ACCEPT_LANGUAGE => Some((17, false)), header::ACCESS_CONTROL_ALLOW_ORIGIN => Some((20, false)),
header::ACCEPT_RANGES => Some((18, false)), header::AGE => Some((21, false)),
header::ACCEPT => Some((19, false)), header::ALLOW => Some((22, false)),
header::ACCESS_CONTROL_ALLOW_ORIGIN => Some((20, false)), header::AUTHORIZATION => Some((23, false)),
header::AGE => Some((21, false)), header::CACHE_CONTROL => Some((24, false)),
header::ALLOW => Some((22, false)), header::CONTENT_DISPOSITION => Some((25, false)),
header::AUTHORIZATION => Some((23, false)), header::CONTENT_ENCODING => Some((26, false)),
header::CACHE_CONTROL => Some((24, false)), header::CONTENT_LANGUAGE => Some((27, false)),
header::CONTENT_DISPOSITION => Some((25, false)), header::CONTENT_LENGTH => Some((28, false)),
header::CONTENT_ENCODING => Some((26, false)), header::CONTENT_LOCATION => Some((29, false)),
header::CONTENT_LANGUAGE => Some((27, false)), header::CONTENT_RANGE => Some((30, false)),
header::CONTENT_LENGTH => Some((28, false)), header::CONTENT_TYPE => Some((31, false)),
header::CONTENT_LOCATION => Some((29, false)), header::COOKIE => Some((32, false)),
header::CONTENT_RANGE => Some((30, false)), header::DATE => Some((33, false)),
header::CONTENT_TYPE => Some((31, false)), header::ETAG => Some((34, false)),
header::COOKIE => Some((32, false)), header::EXPECT => Some((35, false)),
header::DATE => Some((33, false)), header::EXPIRES => Some((36, false)),
header::ETAG => Some((34, false)), header::FROM => Some((37, false)),
header::EXPECT => Some((35, false)), header::HOST => Some((38, false)),
header::EXPIRES => Some((36, false)), header::IF_MATCH => Some((39, false)),
header::FROM => Some((37, false)), header::IF_MODIFIED_SINCE => Some((40, false)),
header::HOST => Some((38, false)), header::IF_NONE_MATCH => Some((41, false)),
header::IF_MATCH => Some((39, false)), header::IF_RANGE => Some((42, false)),
header::IF_MODIFIED_SINCE => Some((40, false)), header::IF_UNMODIFIED_SINCE => Some((43, false)),
header::IF_NONE_MATCH => Some((41, false)), header::LAST_MODIFIED => Some((44, false)),
header::IF_RANGE => Some((42, false)), header::LINK => Some((45, false)),
header::IF_UNMODIFIED_SINCE => Some((43, false)), header::LOCATION => Some((46, false)),
header::LAST_MODIFIED => Some((44, false)), header::MAX_FORWARDS => Some((47, false)),
header::LINK => Some((45, false)), header::PROXY_AUTHENTICATE => Some((48, false)),
header::LOCATION => Some((46, false)), header::PROXY_AUTHORIZATION => Some((49, false)),
header::MAX_FORWARDS => Some((47, false)), header::RANGE => Some((50, false)),
header::PROXY_AUTHENTICATE => Some((48, false)), header::REFERER => Some((51, false)),
header::PROXY_AUTHORIZATION => Some((49, false)), header::REFRESH => Some((52, false)),
header::RANGE => Some((50, false)), header::RETRY_AFTER => Some((53, false)),
header::REFERER => Some((51, false)), header::SERVER => Some((54, false)),
header::REFRESH => Some((52, false)), header::SET_COOKIE => Some((55, false)),
header::RETRY_AFTER => Some((53, false)), header::STRICT_TRANSPORT_SECURITY => Some((56, false)),
header::SERVER => Some((54, false)), header::TRANSFER_ENCODING => Some((57, false)),
header::SET_COOKIE => Some((55, false)), header::USER_AGENT => Some((58, false)),
header::STRICT_TRANSPORT_SECURITY => Some((56, false)), header::VARY => Some((59, false)),
header::TRANSFER_ENCODING => Some((57, false)), header::VIA => Some((60, false)),
header::USER_AGENT => Some((58, false)), header::WWW_AUTHENTICATE => Some((61, false)),
header::VARY => Some((59, false)), _ => None,
header::VIA => Some((60, false)), },
header::WWW_AUTHENTICATE => Some((61, false)),
_ => None,
}
}
Header::Authority(_) => Some((1, false)), Header::Authority(_) => Some((1, false)),
Header::Method(ref v) => { Header::Method(ref v) => match *v {
match *v { Method::GET => Some((2, true)),
Method::GET => Some((2, true)), Method::POST => Some((3, true)),
Method::POST => Some((3, true)), _ => Some((2, false)),
_ => Some((2, false)), },
} Header::Scheme(ref v) => match &**v {
} "http" => Some((6, true)),
Header::Scheme(ref v) => { "https" => Some((7, true)),
match &**v { _ => Some((6, false)),
"http" => Some((6, true)), },
"https" => Some((7, true)), Header::Path(ref v) => match &**v {
_ => Some((6, false)), "/" => Some((4, true)),
} "/index.html" => Some((5, true)),
} _ => Some((4, false)),
Header::Path(ref v) => { },
match &**v { Header::Status(ref v) => match u16::from(*v) {
"/" => Some((4, true)), 200 => Some((8, true)),
"/index.html" => Some((5, true)), 204 => Some((9, true)),
_ => Some((4, false)), 206 => Some((10, true)),
} 304 => Some((11, true)),
} 400 => Some((12, true)),
Header::Status(ref v) => { 404 => Some((13, true)),
match u16::from(*v) { 500 => Some((14, true)),
200 => Some((8, true)), _ => Some((8, false)),
204 => Some((9, true)), },
206 => Some((10, true)),
304 => Some((11, true)),
400 => Some((12, true)),
404 => Some((13, true)),
500 => Some((14, true)),
_ => Some((8, false)),
}
}
} }
} }

View File

@@ -81,11 +81,11 @@ impl FuzzHpack {
let low = rng.gen_range(0, high); let low = rng.gen_range(0, high);
frame.resizes.extend(&[low, high]); frame.resizes.extend(&[low, high]);
} },
1...3 => { 1...3 => {
frame.resizes.push(rng.gen_range(128, MAX_CHUNK * 2)); frame.resizes.push(rng.gen_range(128, MAX_CHUNK * 2));
} },
_ => {} _ => {},
} }
for _ in 0..rng.gen_range(1, (num - added) + 1) { for _ in 0..rng.gen_range(1, (num - added) + 1) {
@@ -155,7 +155,7 @@ impl FuzzHpack {
.unwrap(); .unwrap();
buf = BytesMut::with_capacity(chunks.pop().unwrap_or(MAX_CHUNK)); buf = BytesMut::with_capacity(chunks.pop().unwrap_or(MAX_CHUNK));
} },
} }
} }
@@ -185,7 +185,7 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
0 => { 0 => {
let value = gen_string(g, 4, 20); let value = gen_string(g, 4, 20);
Header::Authority(to_shared(value)) Header::Authority(to_shared(value))
} },
1 => { 1 => {
let method = match g.next_u32() % 6 { let method = match g.next_u32() % 6 {
0 => Method::GET, 0 => Method::GET,
@@ -200,12 +200,12 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
.collect(); .collect();
Method::from_bytes(&bytes).unwrap() Method::from_bytes(&bytes).unwrap()
} },
_ => unreachable!(), _ => unreachable!(),
}; };
Header::Method(method) Header::Method(method)
} },
2 => { 2 => {
let value = match g.next_u32() % 2 { let value = match g.next_u32() % 2 {
0 => "http", 0 => "http",
@@ -214,7 +214,7 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
}; };
Header::Scheme(to_shared(value.to_string())) Header::Scheme(to_shared(value.to_string()))
} },
3 => { 3 => {
let value = match g.next_u32() % 100 { let value = match g.next_u32() % 100 {
0 => "/".to_string(), 0 => "/".to_string(),
@@ -223,12 +223,12 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
}; };
Header::Path(to_shared(value)) Header::Path(to_shared(value))
} },
4 => { 4 => {
let status = (g.gen::<u16>() % 500) + 100; let status = (g.gen::<u16>() % 500) + 100;
Header::Status(StatusCode::from_u16(status).unwrap()) Header::Status(StatusCode::from_u16(status).unwrap())
} },
_ => unreachable!(), _ => unreachable!(),
} }
} else { } else {

View File

@@ -61,11 +61,11 @@ where
pub fn new(codec: Codec<T, Prioritized<B::Buf>>) -> Connection<T, P, B> { pub fn new(codec: Codec<T, Prioritized<B::Buf>>) -> Connection<T, P, B> {
// TODO: Actually configure // TODO: Actually configure
let streams = Streams::new(streams::Config { let streams = Streams::new(streams::Config {
max_remote_initiated: None, max_remote_initiated: None,
init_remote_window_sz: DEFAULT_INITIAL_WINDOW_SIZE, init_remote_window_sz: DEFAULT_INITIAL_WINDOW_SIZE,
max_local_initiated: None, max_local_initiated: None,
init_local_window_sz: DEFAULT_INITIAL_WINDOW_SIZE, init_local_window_sz: DEFAULT_INITIAL_WINDOW_SIZE,
}); });
Connection { Connection {
state: State::Open, state: State::Open,
@@ -85,8 +85,10 @@ where
// The order of these calls don't really matter too much as only one // The order of these calls don't really matter too much as only one
// should have pending work. // should have pending work.
try_ready!(self.ping_pong.send_pending_pong(&mut self.codec)); try_ready!(self.ping_pong.send_pending_pong(&mut self.codec));
try_ready!(self.settings try_ready!(
.send_pending_ack(&mut self.codec, &mut self.streams)); self.settings
.send_pending_ack(&mut self.codec, &mut self.streams)
);
try_ready!(self.streams.send_pending_refusal(&mut self.codec)); try_ready!(self.streams.send_pending_refusal(&mut self.codec));
Ok(().into()) Ok(().into())
@@ -112,7 +114,7 @@ where
try_ready!(self.streams.poll_complete(&mut self.codec)); try_ready!(self.streams.poll_complete(&mut self.codec));
return Ok(Async::NotReady); return Ok(Async::NotReady);
} },
// Attempting to read a frame resulted in a connection level // Attempting to read a frame resulted in a connection level
// error. This is handled by setting a GO_AWAY frame followed by // error. This is handled by setting a GO_AWAY frame followed by
// terminating the connection. // terminating the connection.
@@ -127,17 +129,17 @@ where
// Transition to the going away state. // Transition to the going away state.
self.state = State::GoAway(frame); self.state = State::GoAway(frame);
} },
// Attempting to read a frame resulted in a stream level error. // Attempting to read a frame resulted in a stream level error.
// This is handled by resetting the frame then trying to read // This is handled by resetting the frame then trying to read
// another frame. // another frame.
Err(Stream { Err(Stream {
id, id,
reason, reason,
}) => { }) => {
trace!("stream level error; id={:?}; reason={:?}", id, reason); trace!("stream level error; id={:?}; reason={:?}", id, reason);
self.streams.send_reset(id, reason); self.streams.send_reset(id, reason);
} },
// Attempting to read a frame resulted in an I/O error. All // Attempting to read a frame resulted in an I/O error. All
// active streams must be reset. // active streams must be reset.
// //
@@ -150,9 +152,9 @@ where
// Return the error // Return the error
return Err(e); return Err(e);
} },
} }
} },
State::GoAway(frame) => { State::GoAway(frame) => {
// Ensure the codec is ready to accept the frame // Ensure the codec is ready to accept the frame
try_ready!(self.codec.poll_ready()); try_ready!(self.codec.poll_ready());
@@ -165,17 +167,17 @@ where
// GO_AWAY sent, transition the connection to an errored state // GO_AWAY sent, transition the connection to an errored state
self.state = State::Flush(frame.reason()); self.state = State::Flush(frame.reason());
} },
State::Flush(reason) => { State::Flush(reason) => {
// Flush the codec // Flush the codec
try_ready!(self.codec.flush()); try_ready!(self.codec.flush());
// Transition the state to error // Transition the state to error
self.state = State::Error(reason); self.state = State::Error(reason);
} },
State::Error(reason) => { State::Error(reason) => {
return Err(reason.into()); return Err(reason.into());
} },
} }
} }
} }
@@ -191,46 +193,46 @@ where
Some(Headers(frame)) => { Some(Headers(frame)) => {
trace!("recv HEADERS; frame={:?}", frame); trace!("recv HEADERS; frame={:?}", frame);
self.streams.recv_headers(frame)?; self.streams.recv_headers(frame)?;
} },
Some(Data(frame)) => { Some(Data(frame)) => {
trace!("recv DATA; frame={:?}", frame); trace!("recv DATA; frame={:?}", frame);
self.streams.recv_data(frame)?; self.streams.recv_data(frame)?;
} },
Some(Reset(frame)) => { Some(Reset(frame)) => {
trace!("recv RST_STREAM; frame={:?}", frame); trace!("recv RST_STREAM; frame={:?}", frame);
self.streams.recv_reset(frame)?; self.streams.recv_reset(frame)?;
} },
Some(PushPromise(frame)) => { Some(PushPromise(frame)) => {
trace!("recv PUSH_PROMISE; frame={:?}", frame); trace!("recv PUSH_PROMISE; frame={:?}", frame);
self.streams.recv_push_promise(frame)?; self.streams.recv_push_promise(frame)?;
} },
Some(Settings(frame)) => { Some(Settings(frame)) => {
trace!("recv SETTINGS; frame={:?}", frame); trace!("recv SETTINGS; frame={:?}", frame);
self.settings.recv_settings(frame); self.settings.recv_settings(frame);
} },
Some(GoAway(_)) => { Some(GoAway(_)) => {
// TODO: handle the last_processed_id. Also, should this be // TODO: handle the last_processed_id. Also, should this be
// handled as an error? // handled as an error?
// let _ = RecvError::Proto(frame.reason()); // let _ = RecvError::Proto(frame.reason());
return Ok(().into()); return Ok(().into());
} },
Some(Ping(frame)) => { Some(Ping(frame)) => {
trace!("recv PING; frame={:?}", frame); trace!("recv PING; frame={:?}", frame);
self.ping_pong.recv_ping(frame); self.ping_pong.recv_ping(frame);
} },
Some(WindowUpdate(frame)) => { Some(WindowUpdate(frame)) => {
trace!("recv WINDOW_UPDATE; frame={:?}", frame); trace!("recv WINDOW_UPDATE; frame={:?}", frame);
self.streams.recv_window_update(frame)?; self.streams.recv_window_update(frame)?;
} },
Some(Priority(frame)) => { Some(Priority(frame)) => {
trace!("recv PRIORITY; frame={:?}", frame); trace!("recv PRIORITY; frame={:?}", frame);
// TODO: handle // TODO: handle
} },
None => { None => {
// TODO: Is this correct? // TODO: Is this correct?
trace!("codec closed"); trace!("codec closed");
return Ok(Async::Ready(())); return Ok(Async::Ready(()));
} },
} }
} }
} }

View File

@@ -50,41 +50,41 @@ impl<T> Deque<T> {
pub fn push_back(&mut self, buf: &mut Buffer<T>, value: T) { pub fn push_back(&mut self, buf: &mut Buffer<T>, value: T) {
let key = buf.slab.insert(Slot { let key = buf.slab.insert(Slot {
value, value,
next: None, next: None,
}); });
match self.indices { match self.indices {
Some(ref mut idxs) => { Some(ref mut idxs) => {
buf.slab[idxs.tail].next = Some(key); buf.slab[idxs.tail].next = Some(key);
idxs.tail = key; idxs.tail = key;
} },
None => { None => {
self.indices = Some(Indices { self.indices = Some(Indices {
head: key, head: key,
tail: key, tail: key,
}); });
} },
} }
} }
pub fn push_front(&mut self, buf: &mut Buffer<T>, value: T) { pub fn push_front(&mut self, buf: &mut Buffer<T>, value: T) {
let key = buf.slab.insert(Slot { let key = buf.slab.insert(Slot {
value, value,
next: None, next: None,
}); });
match self.indices { match self.indices {
Some(ref mut idxs) => { Some(ref mut idxs) => {
buf.slab[key].next = Some(idxs.head); buf.slab[key].next = Some(idxs.head);
idxs.head = key; idxs.head = key;
} },
None => { None => {
self.indices = Some(Indices { self.indices = Some(Indices {
head: key, head: key,
tail: key, tail: key,
}); });
} },
} }
} }
@@ -102,7 +102,7 @@ impl<T> Deque<T> {
} }
return Some(slot.value); return Some(slot.value);
} },
None => None, None => None,
} }
} }

View File

@@ -110,10 +110,12 @@ impl FlowControl {
return Err(Reason::FlowControlError); return Err(Reason::FlowControlError);
} }
trace!("inc_window; sz={}; old={}; new={}", trace!(
sz, "inc_window; sz={}; old={}; new={}",
self.window_size, sz,
val); self.window_size,
val
);
self.window_size = val; self.window_size = val;
Ok(()) Ok(())
@@ -131,10 +133,12 @@ impl FlowControl {
/// Decrements the window reflecting data has actually been sent. The caller /// Decrements the window reflecting data has actually been sent. The caller
/// must ensure that the window has capacity. /// must ensure that the window has capacity.
pub fn send_data(&mut self, sz: WindowSize) { pub fn send_data(&mut self, sz: WindowSize) {
trace!("send_data; sz={}; window={}; available={}", trace!(
sz, "send_data; sz={}; window={}; available={}",
self.window_size, sz,
self.available); self.window_size,
self.available
);
// Ensure that the argument is correct // Ensure that the argument is correct
assert!(sz <= self.window_size as WindowSize); assert!(sz <= self.window_size as WindowSize);

View File

@@ -111,10 +111,12 @@ where
// Update the buffered data counter // Update the buffered data counter
stream.buffered_send_data += sz; stream.buffered_send_data += sz;
trace!("send_data; sz={}; buffered={}; requested={}", trace!(
sz, "send_data; sz={}; buffered={}; requested={}",
stream.buffered_send_data, sz,
stream.requested_send_capacity); stream.buffered_send_data,
stream.requested_send_capacity
);
// Implicitly request more send capacity if not enough has been // Implicitly request more send capacity if not enough has been
// requested yet. // requested yet.
@@ -130,9 +132,11 @@ where
self.reserve_capacity(0, stream); self.reserve_capacity(0, stream);
} }
trace!("send_data (2); available={}; buffered={}", trace!(
stream.send_flow.available(), "send_data (2); available={}; buffered={}",
stream.buffered_send_data); stream.send_flow.available(),
stream.buffered_send_data
);
if stream.send_flow.available() >= stream.buffered_send_data { if stream.send_flow.available() >= stream.buffered_send_data {
// The stream currently has capacity to send the data frame, so // The stream currently has capacity to send the data frame, so
@@ -152,11 +156,13 @@ where
/// Request capacity to send data /// Request capacity to send data
pub fn reserve_capacity(&mut self, capacity: WindowSize, stream: &mut store::Ptr<B, P>) { pub fn reserve_capacity(&mut self, capacity: WindowSize, stream: &mut store::Ptr<B, P>) {
trace!("reserve_capacity; stream={:?}; requested={:?}; effective={:?}; curr={:?}", trace!(
stream.id, "reserve_capacity; stream={:?}; requested={:?}; effective={:?}; curr={:?}",
capacity, stream.id,
capacity + stream.buffered_send_data, capacity,
stream.requested_send_capacity); capacity + stream.buffered_send_data,
stream.requested_send_capacity
);
// Actual capacity is `capacity` + the current amount of buffered data. // Actual capacity is `capacity` + the current amount of buffered data.
// It it were less, then we could never send out the buffered data. // It it were less, then we could never send out the buffered data.
@@ -196,11 +202,13 @@ where
inc: WindowSize, inc: WindowSize,
stream: &mut store::Ptr<B, P>, stream: &mut store::Ptr<B, P>,
) -> Result<(), Reason> { ) -> Result<(), Reason> {
trace!("recv_stream_window_update; stream={:?}; state={:?}; inc={}; flow={:?}", trace!(
stream.id, "recv_stream_window_update; stream={:?}; state={:?}; inc={}; flow={:?}",
stream.state, stream.id,
inc, stream.state,
stream.send_flow); inc,
stream.send_flow
);
// Update the stream level flow control. // Update the stream level flow control.
stream.send_flow.inc_window(inc)?; stream.send_flow.inc_window(inc)?;
@@ -254,16 +262,20 @@ where
// The amount of additional capacity that the stream requests. // The amount of additional capacity that the stream requests.
// Don't assign more than the window has available! // Don't assign more than the window has available!
let additional = cmp::min(total_requested - stream.send_flow.available(), let additional = cmp::min(
// Can't assign more than what is available total_requested - stream.send_flow.available(),
stream.send_flow.window_size() - stream.send_flow.available()); // Can't assign more than what is available
stream.send_flow.window_size() - stream.send_flow.available(),
);
trace!("try_assign_capacity; requested={}; additional={}; buffered={}; window={}; conn={}", trace!(
total_requested, "try_assign_capacity; requested={}; additional={}; buffered={}; window={}; conn={}",
additional, total_requested,
stream.buffered_send_data, additional,
stream.send_flow.window_size(), stream.buffered_send_data,
self.flow.available()); stream.send_flow.window_size(),
self.flow.available()
);
if additional == 0 { if additional == 0 {
// Nothing more to do // Nothing more to do
@@ -273,9 +285,11 @@ where
// If the stream has requested capacity, then it must be in the // If the stream has requested capacity, then it must be in the
// streaming state (more data could be sent) or there is buffered data // streaming state (more data could be sent) or there is buffered data
// waiting to be sent. // waiting to be sent.
debug_assert!(stream.state.is_send_streaming() || stream.buffered_send_data > 0, debug_assert!(
"state={:?}", stream.state.is_send_streaming() || stream.buffered_send_data > 0,
stream.state); "state={:?}",
stream.state
);
// The amount of currently available capacity on the connection // The amount of currently available capacity on the connection
let conn_available = self.flow.available(); let conn_available = self.flow.available();
@@ -296,12 +310,13 @@ where
self.flow.claim_capacity(assign); self.flow.claim_capacity(assign);
} }
trace!("try_assign_capacity; available={}; requested={}; buffered={}; \ trace!(
has_unavailable={:?}", "try_assign_capacity; available={}; requested={}; buffered={}; has_unavailable={:?}",
stream.send_flow.available(), stream.send_flow.available(),
stream.requested_send_capacity, stream.requested_send_capacity,
stream.buffered_send_data, stream.buffered_send_data,
stream.send_flow.has_unavailable()); stream.send_flow.has_unavailable()
);
if stream.send_flow.available() < stream.requested_send_capacity { if stream.send_flow.available() < stream.requested_send_capacity {
if stream.send_flow.has_unavailable() { if stream.send_flow.has_unavailable() {
@@ -367,7 +382,7 @@ where
// Because, always try to reclaim... // Because, always try to reclaim...
self.reclaim_frame(store, dst); self.reclaim_frame(store, dst);
} },
None => { None => {
// Try to flush the codec. // Try to flush the codec.
try_ready!(dst.flush()); try_ready!(dst.flush());
@@ -379,7 +394,7 @@ where
// No need to poll ready as poll_complete() does this for // No need to poll ready as poll_complete() does this for
// us... // us...
} },
} }
} }
} }
@@ -400,9 +415,11 @@ where
// First check if there are any data chunks to take back // First check if there are any data chunks to take back
if let Some(frame) = dst.take_last_data_frame() { if let Some(frame) = dst.take_last_data_frame() {
trace!(" -> reclaimed; frame={:?}; sz={}", trace!(
frame, " -> reclaimed; frame={:?}; sz={}",
frame.payload().remaining()); frame,
frame.payload().remaining()
);
let mut eos = false; let mut eos = false;
let key = frame.payload().stream; let key = frame.payload().stream;
@@ -474,20 +491,24 @@ where
let stream_capacity = stream.send_flow.available(); let stream_capacity = stream.send_flow.available();
let sz = frame.payload().remaining(); let sz = frame.payload().remaining();
trace!(" --> data frame; stream={:?}; sz={}; eos={:?}; \ trace!(
window={}; available={}; requested={}", " --> data frame; stream={:?}; sz={}; eos={:?}; window={}; \
frame.stream_id(), available={}; requested={}",
sz, frame.stream_id(),
frame.is_end_stream(), sz,
stream_capacity, frame.is_end_stream(),
stream.send_flow.available(), stream_capacity,
stream.requested_send_capacity); stream.send_flow.available(),
stream.requested_send_capacity
);
// Zero length data frames always have capacity to // Zero length data frames always have capacity to
// be sent. // be sent.
if sz > 0 && stream_capacity == 0 { if sz > 0 && stream_capacity == 0 {
trace!(" --> stream capacity is 0; requested={}", trace!(
stream.requested_send_capacity); " --> stream capacity is 0; requested={}",
stream.requested_send_capacity
);
// Ensure that the stream is waiting for // Ensure that the stream is waiting for
// connection level capacity // connection level capacity
@@ -551,7 +572,7 @@ where
stream: stream.key(), stream: stream.key(),
} }
})) }))
} },
frame => frame.map(|_| unreachable!()), frame => frame.map(|_| unreachable!()),
}; };
@@ -568,7 +589,7 @@ where
counts.transition_after(stream, is_counted); counts.transition_after(stream, is_counted);
return Some(frame); return Some(frame);
} },
None => return None, None => return None,
} }
} }

View File

@@ -150,7 +150,7 @@ where
Ok(v) => v, Ok(v) => v,
Err(_) => { Err(_) => {
unimplemented!(); unimplemented!();
} },
}; };
stream.content_length = ContentLength::Remaining(content_length); stream.content_length = ContentLength::Remaining(content_length);
@@ -185,9 +185,9 @@ where
if stream.ensure_content_length_zero().is_err() { if stream.ensure_content_length_zero().is_err() {
return Err(RecvError::Stream { return Err(RecvError::Stream {
id: stream.id, id: stream.id,
reason: ProtocolError, reason: ProtocolError,
}); });
} }
let trailers = frame.into_fields(); let trailers = frame.into_fields();
@@ -264,10 +264,12 @@ where
return Err(RecvError::Connection(ProtocolError)); return Err(RecvError::Connection(ProtocolError));
} }
trace!("recv_data; size={}; connection={}; stream={}", trace!(
sz, "recv_data; size={}; connection={}; stream={}",
self.flow.window_size(), sz,
stream.recv_flow.window_size()); self.flow.window_size(),
stream.recv_flow.window_size()
);
// Ensure that there is enough capacity on the connection before acting // Ensure that there is enough capacity on the connection before acting
// on the stream. // on the stream.
@@ -286,17 +288,17 @@ where
if stream.dec_content_length(frame.payload().len()).is_err() { if stream.dec_content_length(frame.payload().len()).is_err() {
return Err(RecvError::Stream { return Err(RecvError::Stream {
id: stream.id, id: stream.id,
reason: ProtocolError, reason: ProtocolError,
}); });
} }
if frame.is_end_stream() { if frame.is_end_stream() {
if stream.ensure_content_length_zero().is_err() { if stream.ensure_content_length_zero().is_err() {
return Err(RecvError::Stream { return Err(RecvError::Stream {
id: stream.id, id: stream.id,
reason: ProtocolError, reason: ProtocolError,
}); });
} }
if stream.state.recv_close().is_err() { if stream.state.recv_close().is_err() {
@@ -343,9 +345,11 @@ where
// TODO: All earlier stream IDs should be implicitly closed. // TODO: All earlier stream IDs should be implicitly closed.
// Now, create a new entry for the stream // Now, create a new entry for the stream
let mut new_stream = Stream::new(frame.promised_id(), let mut new_stream = Stream::new(
send.init_window_sz(), frame.promised_id(),
self.init_window_sz); send.init_window_sz(),
self.init_window_sz,
);
new_stream.state.reserve_remote()?; new_stream.state.reserve_remote()?;
@@ -559,7 +563,7 @@ where
// No more data frames // No more data frames
Ok(None.into()) Ok(None.into())
} },
None => { None => {
if stream.state.is_recv_closed() { if stream.state.is_recv_closed() {
// No more data frames will be received // No more data frames will be received
@@ -569,7 +573,7 @@ where
stream.recv_task = Some(task::current()); stream.recv_task = Some(task::current());
Ok(Async::NotReady) Ok(Async::NotReady)
} }
} },
} }
} }
@@ -584,7 +588,7 @@ where
// the entire set of data frames have been consumed. What should // the entire set of data frames have been consumed. What should
// we do? // we do?
unimplemented!(); unimplemented!();
} },
None => { None => {
if stream.state.is_recv_closed() { if stream.state.is_recv_closed() {
// There will be no trailer frame // There will be no trailer frame
@@ -594,7 +598,7 @@ where
stream.recv_task = Some(task::current()); stream.recv_task = Some(task::current());
Ok(Async::NotReady) Ok(Async::NotReady)
} }
} },
} }
} }
} }
@@ -630,7 +634,7 @@ where
stream.recv_task = Some(task::current()); stream.recv_task = Some(task::current());
Ok(Async::NotReady) Ok(Async::NotReady)
} },
} }
} }
} }

View File

@@ -70,9 +70,11 @@ where
stream: &mut store::Ptr<B, P>, stream: &mut store::Ptr<B, P>,
task: &mut Option<Task>, task: &mut Option<Task>,
) -> Result<(), UserError> { ) -> Result<(), UserError> {
trace!("send_headers; frame={:?}; init_window={:?}", trace!(
frame, "send_headers; frame={:?}; init_window={:?}",
self.init_window_sz); frame,
self.init_window_sz
);
let end_stream = frame.is_end_stream(); let end_stream = frame.is_end_stream();
@@ -261,10 +263,12 @@ where
let stream = &mut *stream; let stream = &mut *stream;
stream.send_flow.dec_window(dec); stream.send_flow.dec_window(dec);
trace!("decremented stream window; id={:?}; decr={}; flow={:?}", trace!(
stream.id, "decremented stream window; id={:?}; decr={}; flow={:?}",
dec, stream.id,
stream.send_flow); dec,
stream.send_flow
);
// TODO: Probably try to assign capacity? // TODO: Probably try to assign capacity?

View File

@@ -83,40 +83,34 @@ impl State {
let local = Peer::Streaming; let local = Peer::Streaming;
self.inner = match self.inner { self.inner = match self.inner {
Idle => { Idle => if eos {
if eos { HalfClosedLocal(AwaitingHeaders)
HalfClosedLocal(AwaitingHeaders) } else {
} else { Open {
Open { local,
local, remote: AwaitingHeaders,
remote: AwaitingHeaders,
}
} }
} },
Open { Open {
local: AwaitingHeaders, local: AwaitingHeaders,
remote, remote,
} => { } => if eos {
if eos { HalfClosedLocal(remote)
HalfClosedLocal(remote) } else {
} else { Open {
Open { local,
local, remote,
remote,
}
} }
} },
HalfClosedRemote(AwaitingHeaders) => { HalfClosedRemote(AwaitingHeaders) => if eos {
if eos { Closed(None)
Closed(None) } else {
} else { HalfClosedRemote(local)
HalfClosedRemote(local) },
}
}
_ => { _ => {
// All other transitions result in a protocol error // All other transitions result in a protocol error
return Err(UnexpectedFrameType); return Err(UnexpectedFrameType);
} },
}; };
return Ok(()); return Ok(());
@@ -142,7 +136,7 @@ impl State {
remote, remote,
} }
} }
} },
ReservedRemote => { ReservedRemote => {
initial = true; initial = true;
@@ -154,31 +148,27 @@ impl State {
remote, remote,
} }
} }
} },
Open { Open {
local, local,
remote: AwaitingHeaders, remote: AwaitingHeaders,
} => { } => if eos {
if eos { HalfClosedRemote(local)
HalfClosedRemote(local) } else {
} else { Open {
Open { local,
local, remote,
remote,
}
} }
} },
HalfClosedLocal(AwaitingHeaders) => { HalfClosedLocal(AwaitingHeaders) => if eos {
if eos { Closed(None)
Closed(None) } else {
} else { HalfClosedLocal(remote)
HalfClosedLocal(remote) },
}
}
_ => { _ => {
// All other transitions result in a protocol error // All other transitions result in a protocol error
return Err(RecvError::Connection(ProtocolError)); return Err(RecvError::Connection(ProtocolError));
} },
}; };
return Ok(initial); return Ok(initial);
@@ -190,7 +180,7 @@ impl State {
Idle => { Idle => {
self.inner = ReservedRemote; self.inner = ReservedRemote;
Ok(()) Ok(())
} },
_ => Err(RecvError::Connection(ProtocolError)), _ => Err(RecvError::Connection(ProtocolError)),
} }
} }
@@ -205,12 +195,12 @@ impl State {
trace!("recv_close: Open => HalfClosedRemote({:?})", local); trace!("recv_close: Open => HalfClosedRemote({:?})", local);
self.inner = HalfClosedRemote(local); self.inner = HalfClosedRemote(local);
Ok(()) Ok(())
} },
HalfClosedLocal(..) => { HalfClosedLocal(..) => {
trace!("recv_close: HalfClosedLocal => Closed"); trace!("recv_close: HalfClosedLocal => Closed");
self.inner = Closed(None); self.inner = Closed(None);
Ok(()) Ok(())
} },
_ => Err(RecvError::Connection(ProtocolError)), _ => Err(RecvError::Connection(ProtocolError)),
} }
} }
@@ -219,14 +209,14 @@ impl State {
use proto::Error::*; use proto::Error::*;
match self.inner { match self.inner {
Closed(..) => {} Closed(..) => {},
_ => { _ => {
trace!("recv_err; err={:?}", err); trace!("recv_err; err={:?}", err);
self.inner = Closed(match *err { self.inner = Closed(match *err {
Proto(reason) => Some(Cause::Proto(reason)), Proto(reason) => Some(Cause::Proto(reason)),
Io(..) => Some(Cause::Io), Io(..) => Some(Cause::Io),
}); });
} },
} }
} }
@@ -239,11 +229,11 @@ impl State {
// The remote side will continue to receive data. // The remote side will continue to receive data.
trace!("send_close: Open => HalfClosedLocal({:?})", remote); trace!("send_close: Open => HalfClosedLocal({:?})", remote);
self.inner = HalfClosedLocal(remote); self.inner = HalfClosedLocal(remote);
} },
HalfClosedRemote(..) => { HalfClosedRemote(..) => {
trace!("send_close: HalfClosedRemote => Closed"); trace!("send_close: HalfClosedRemote => Closed");
self.inner = Closed(None); self.inner = Closed(None);
} },
_ => panic!("transition send_close on unexpected state"), _ => panic!("transition send_close on unexpected state"),
} }
} }

View File

@@ -106,9 +106,9 @@ where
}; };
Some(Ptr { Some(Ptr {
key: Key(key), key: Key(key),
store: self, store: self,
}) })
} }
pub fn insert(&mut self, id: StreamId, val: Stream<B, P>) -> Ptr<B, P> { pub fn insert(&mut self, id: StreamId, val: Stream<B, P>) -> Ptr<B, P> {
@@ -125,17 +125,13 @@ where
use self::ordermap::Entry::*; use self::ordermap::Entry::*;
match self.ids.entry(id) { match self.ids.entry(id) {
Occupied(e) => { Occupied(e) => Entry::Occupied(OccupiedEntry {
Entry::Occupied(OccupiedEntry { ids: e,
ids: e, }),
}) Vacant(e) => Entry::Vacant(VacantEntry {
} ids: e,
Vacant(e) => { slab: &mut self.slab,
Entry::Vacant(VacantEntry { }),
ids: e,
slab: &mut self.slab,
})
}
} }
} }
@@ -151,9 +147,9 @@ where
let key = *self.ids.get_index(i).unwrap().1; let key = *self.ids.get_index(i).unwrap().1;
f(Ptr { f(Ptr {
key: Key(key), key: Key(key),
store: self, store: self,
})?; })?;
// TODO: This logic probably could be better... // TODO: This logic probably could be better...
let new_len = self.ids.len(); let new_len = self.ids.len();
@@ -268,14 +264,14 @@ where
// Update the tail pointer // Update the tail pointer
idxs.tail = stream.key(); idxs.tail = stream.key();
} },
None => { None => {
trace!(" -> first entry"); trace!(" -> first entry");
self.indices = Some(store::Indices { self.indices = Some(store::Indices {
head: stream.key(), head: stream.key(),
tail: stream.key(), tail: stream.key(),
}); });
} },
} }
true true

View File

@@ -217,14 +217,12 @@ where
/// Returns `Err` when the decrement cannot be completed due to overflow. /// Returns `Err` when the decrement cannot be completed due to overflow.
pub fn dec_content_length(&mut self, len: usize) -> Result<(), ()> { pub fn dec_content_length(&mut self, len: usize) -> Result<(), ()> {
match self.content_length { match self.content_length {
ContentLength::Remaining(ref mut rem) => { ContentLength::Remaining(ref mut rem) => match rem.checked_sub(len as u64) {
match rem.checked_sub(len as u64) { Some(val) => *rem = val,
Some(val) => *rem = val, None => return Err(()),
None => return Err(()), },
}
}
ContentLength::Head => return Err(()), ContentLength::Head => return Err(()),
_ => {} _ => {},
} }
Ok(()) Ok(())

View File

@@ -66,14 +66,14 @@ where
pub fn new(config: Config) -> Self { pub fn new(config: Config) -> Self {
Streams { Streams {
inner: Arc::new(Mutex::new(Inner { inner: Arc::new(Mutex::new(Inner {
counts: Counts::new(&config), counts: Counts::new(&config),
actions: Actions { actions: Actions {
recv: Recv::new(&config), recv: Recv::new(&config),
send: Send::new(&config), send: Send::new(&config),
task: None, task: None,
}, },
store: Store::new(), store: Store::new(),
})), })),
} }
} }
@@ -85,27 +85,29 @@ where
let key = match me.store.find_entry(id) { let key = match me.store.find_entry(id) {
Entry::Occupied(e) => e.key(), Entry::Occupied(e) => e.key(),
Entry::Vacant(e) => { Entry::Vacant(e) => match me.actions.recv.open(id, &mut me.counts)? {
match me.actions.recv.open(id, &mut me.counts)? { Some(stream_id) => {
Some(stream_id) => { let stream = Stream::new(
let stream = Stream::new(stream_id, stream_id,
me.actions.send.init_window_sz(), me.actions.send.init_window_sz(),
me.actions.recv.init_window_sz()); me.actions.recv.init_window_sz(),
);
e.insert(stream) e.insert(stream)
} },
None => return Ok(()), None => return Ok(()),
} },
}
}; };
let stream = me.store.resolve(key); let stream = me.store.resolve(key);
let actions = &mut me.actions; let actions = &mut me.actions;
me.counts.transition(stream, |counts, stream| { me.counts.transition(stream, |counts, stream| {
trace!("recv_headers; stream={:?}; state={:?}", trace!(
stream.id, "recv_headers; stream={:?}; state={:?}",
stream.state); stream.id,
stream.state
);
let res = if stream.state.is_recv_headers() { let res = if stream.state.is_recv_headers() {
actions.recv.recv_headers(frame, stream, counts) actions.recv.recv_headers(frame, stream, counts)
@@ -160,7 +162,7 @@ where
.map_err(RecvError::Connection)?; .map_err(RecvError::Connection)?;
return Ok(()); return Ok(());
} },
}; };
let actions = &mut me.actions; let actions = &mut me.actions;
@@ -211,11 +213,11 @@ where
// This result is ignored as there is nothing to do when there // This result is ignored as there is nothing to do when there
// is an error. The stream is reset by the function on error and // is an error. The stream is reset by the function on error and
// the error is informational. // the error is informational.
let _ = me.actions let _ = me.actions.send.recv_stream_window_update(
.send frame.size_increment(),
.recv_stream_window_update(frame.size_increment(), &mut stream,
&mut stream, &mut me.actions.task,
&mut me.actions.task); );
} else { } else {
me.actions me.actions
.recv .recv
@@ -255,7 +257,7 @@ where
// Return the key // Return the key
Some(key) Some(key)
} },
None => None, None => None,
} }
}; };
@@ -294,9 +296,11 @@ where
try_ready!(me.actions.recv.poll_complete(&mut me.store, dst)); try_ready!(me.actions.recv.poll_complete(&mut me.store, dst));
// Send any other pending frames // Send any other pending frames
try_ready!(me.actions try_ready!(me.actions.send.poll_complete(
.send &mut me.store,
.poll_complete(&mut me.store, &mut me.counts, dst)); &mut me.counts,
dst
));
// Nothing else to do, track the task // Nothing else to do, track the task
me.actions.task = Some(task::current()); me.actions.task = Some(task::current());
@@ -335,9 +339,11 @@ where
// Initialize a new stream. This fails if the connection is at capacity. // Initialize a new stream. This fails if the connection is at capacity.
let stream_id = me.actions.send.open(&mut me.counts)?; let stream_id = me.actions.send.open(&mut me.counts)?;
let mut stream = Stream::new(stream_id, let mut stream = Stream::new(
me.actions.send.init_window_sz(), stream_id,
me.actions.recv.init_window_sz()); me.actions.send.init_window_sz(),
me.actions.recv.init_window_sz(),
);
if *request.method() == Method::HEAD { if *request.method() == Method::HEAD {
stream.content_length = ContentLength::Head; stream.content_length = ContentLength::Head;
@@ -363,9 +369,9 @@ where
}; };
Ok(StreamRef { Ok(StreamRef {
inner: self.inner.clone(), inner: self.inner.clone(),
key: key, key: key,
}) })
} }
pub fn send_reset(&mut self, id: StreamId, reason: Reason) { pub fn send_reset(&mut self, id: StreamId, reason: Reason) {
@@ -374,16 +380,14 @@ where
let key = match me.store.find_entry(id) { let key = match me.store.find_entry(id) {
Entry::Occupied(e) => e.key(), Entry::Occupied(e) => e.key(),
Entry::Vacant(e) => { Entry::Vacant(e) => match me.actions.recv.open(id, &mut me.counts) {
match me.actions.recv.open(id, &mut me.counts) { Ok(Some(stream_id)) => {
Ok(Some(stream_id)) => { let stream = Stream::new(stream_id, 0, 0);
let stream = Stream::new(stream_id, 0, 0);
e.insert(stream) e.insert(stream)
} },
_ => return, _ => return,
} },
}
}; };
let stream = me.store.resolve(key); let stream = me.store.resolve(key);
@@ -651,8 +655,8 @@ where
res: Result<(), RecvError>, res: Result<(), RecvError>,
) -> Result<(), RecvError> { ) -> Result<(), RecvError> {
if let Err(RecvError::Stream { if let Err(RecvError::Stream {
reason, .. reason, ..
}) = res }) = res
{ {
// Reset the stream. // Reset the stream.
self.send.send_reset(reason, stream, &mut self.task); self.send.send_reset(reason, stream, &mut self.task);

View File

@@ -127,8 +127,8 @@ where
// If the socket is closed, don't return anything // If the socket is closed, don't return anything
// TODO: drop any pending streams // TODO: drop any pending streams
return Ok(None.into()); return Ok(None.into());
} },
_ => {} _ => {},
} }
if let Some(inner) = self.connection.next_incoming() { if let Some(inner) = self.connection.next_incoming() {
@@ -296,7 +296,7 @@ where
} }
dst.send_data(chunk, false)?; dst.send_data(chunk, false)?;
} },
None => { None => {
// TODO: It would be nice to not have to send an extra // TODO: It would be nice to not have to send an extra
// frame... // frame...
@@ -305,7 +305,7 @@ where
} }
return Ok(Async::Ready(self.dst.take().unwrap())); return Ok(Async::Ready(self.dst.take().unwrap()));
} },
} }
} }
} }
@@ -416,12 +416,14 @@ impl proto::Peer for Peer {
use http::response::Parts; use http::response::Parts;
// Extract the components of the HTTP request // Extract the components of the HTTP request
let (Parts { let (
status, Parts {
headers, status,
.. headers,
}, ..
_) = response.into_parts(); },
_,
) = response.into_parts();
// Build the set pseudo header set. All requests will include `method` // Build the set pseudo header set. All requests will include `method`
// and `path`. // and `path`.
@@ -500,10 +502,10 @@ impl proto::Peer for Peer {
// TODO: Should there be more specialized handling for different // TODO: Should there be more specialized handling for different
// kinds of errors // kinds of errors
return Err(RecvError::Stream { return Err(RecvError::Stream {
id: stream_id, id: stream_id,
reason: ProtocolError, reason: ProtocolError,
}); });
} },
}; };
*request.headers_mut() = fields; *request.headers_mut() = fields;

View File

@@ -124,6 +124,8 @@ fn update_max_frame_len_at_rest() {
codec.set_max_recv_frame_size(2); codec.set_max_recv_frame_size(2);
assert_eq!(codec.max_recv_frame_size(), 2); assert_eq!(codec.max_recv_frame_size(), 2);
assert_eq!(codec.poll().unwrap_err().description(), assert_eq!(
"frame size too big"); codec.poll().unwrap_err().description(),
"frame size too big"
);
} }

View File

@@ -241,8 +241,10 @@ fn recv_data_overflows_connection_window() {
// client should see a flow control error // client should see a flow control error
let conn = h2.then(|res| { let conn = h2.then(|res| {
let err = res.unwrap_err(); let err = res.unwrap_err();
assert_eq!(err.to_string(), assert_eq!(
"protocol error: flow-control protocol violated"); err.to_string(),
"protocol error: flow-control protocol violated"
);
Ok::<(), ()>(()) Ok::<(), ()>(())
}); });
conn.unwrap().join(req) conn.unwrap().join(req)
@@ -498,8 +500,8 @@ fn recv_window_update_on_stream_closed_by_data_frame() {
// Wait for the response // Wait for the response
h2.drive(GetResponse { h2.drive(GetResponse {
stream: Some(stream), stream: Some(stream),
}) })
}) })
.and_then(|(h2, (response, mut stream))| { .and_then(|(h2, (response, mut stream))| {
assert_eq!(response.status(), StatusCode::OK); assert_eq!(response.status(), StatusCode::OK);
@@ -514,7 +516,9 @@ fn recv_window_update_on_stream_closed_by_data_frame() {
let srv = srv.assert_client_handshake() let srv = srv.assert_client_handshake()
.unwrap() .unwrap()
.recv_settings() .recv_settings()
.recv_frame(frames::headers(1).request("POST", "https://http2.akamai.com/")) .recv_frame(
frames::headers(1).request("POST", "https://http2.akamai.com/"),
)
.send_frame(frames::headers(1).response(200)) .send_frame(frames::headers(1).response(200))
.recv_frame(frames::data(1, "hello").eos()) .recv_frame(frames::data(1, "hello").eos())
.send_frame(frames::window_update(1, 5)) .send_frame(frames::window_update(1, 5))
@@ -553,8 +557,8 @@ fn reserved_capacity_assigned_in_multi_window_updates() {
stream.send_data("world".into(), true).unwrap(); stream.send_data("world".into(), true).unwrap();
h2.drive(GetResponse { h2.drive(GetResponse {
stream: Some(stream), stream: Some(stream),
}) })
}) })
.and_then(|(h2, (response, _))| { .and_then(|(h2, (response, _))| {
assert_eq!(response.status(), StatusCode::NO_CONTENT); assert_eq!(response.status(), StatusCode::NO_CONTENT);

View File

@@ -193,7 +193,10 @@ fn send_data_receive_window_update() {
stream.reserve_capacity(frame::DEFAULT_INITIAL_WINDOW_SIZE as usize); stream.reserve_capacity(frame::DEFAULT_INITIAL_WINDOW_SIZE as usize);
// Wait for capacity // Wait for capacity
h2.drive(util::wait_for_capacity(stream, frame::DEFAULT_INITIAL_WINDOW_SIZE as usize)) h2.drive(util::wait_for_capacity(
stream,
frame::DEFAULT_INITIAL_WINDOW_SIZE as usize,
))
}) })
.and_then(|(h2, mut stream)| { .and_then(|(h2, mut stream)| {
let payload = vec![0; frame::DEFAULT_INITIAL_WINDOW_SIZE as usize]; let payload = vec![0; frame::DEFAULT_INITIAL_WINDOW_SIZE as usize];

View File

@@ -184,9 +184,11 @@ fn closed_streams_are_released() {
let srv = srv.assert_client_handshake() let srv = srv.assert_client_handshake()
.unwrap() .unwrap()
.recv_settings() .recv_settings()
.recv_frame(frames::headers(1) .recv_frame(
.request("GET", "https://example.com/") frames::headers(1)
.eos()) .request("GET", "https://example.com/")
.eos(),
)
.send_frame(frames::headers(1).response(204).eos()) .send_frame(frames::headers(1).response(204).eos())
.close(); .close();