wip: stream state management seems good, but tests fail
This commit is contained in:
@@ -66,6 +66,22 @@ pub enum Frame<T = Bytes> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Frame<T> {
|
impl<T> Frame<T> {
|
||||||
|
pub fn is_connection_frame(&self) -> bool {
|
||||||
|
use self::Frame::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
&Headers(..) |
|
||||||
|
&Data(..) |
|
||||||
|
&PushPromise(..) |
|
||||||
|
&Reset(..) => false,
|
||||||
|
|
||||||
|
&WindowUpdate(ref v) => v.stream_id().is_zero(),
|
||||||
|
|
||||||
|
&Ping(_) |
|
||||||
|
&Settings(_) => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stream_id(&self) -> StreamId {
|
pub fn stream_id(&self) -> StreamId {
|
||||||
use self::Frame::*;
|
use self::Frame::*;
|
||||||
|
|
||||||
|
|||||||
@@ -78,19 +78,19 @@ impl<T, U> FlowControl<T>
|
|||||||
|
|
||||||
// Flow control utitlities.
|
// Flow control utitlities.
|
||||||
impl<T: ControlStreams> FlowControl<T> {
|
impl<T: ControlStreams> FlowControl<T> {
|
||||||
fn local_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
if id.is_zero() {
|
if id.is_zero() {
|
||||||
Some(&mut self.local_connection)
|
Some(&mut self.local_connection)
|
||||||
} else {
|
} else {
|
||||||
self.inner.local_flow_controller(id)
|
self.inner.recv_flow_controller(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
if id.is_zero() {
|
if id.is_zero() {
|
||||||
Some(&mut self.remote_connection)
|
Some(&mut self.remote_connection)
|
||||||
} else {
|
} else {
|
||||||
self.inner.remote_flow_controller(id)
|
self.inner.send_flow_controller(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ impl<T: ControlStreams> ControlFlow for FlowControl<T> {
|
|||||||
|
|
||||||
// TODO this should probably account for stream priority?
|
// TODO this should probably account for stream priority?
|
||||||
while let Some(id) = self.remote_pending_streams.pop_front() {
|
while let Some(id) = self.remote_pending_streams.pop_front() {
|
||||||
if let Some(mut flow) = self.remote_flow_controller(id) {
|
if let Some(mut flow) = self.send_flow_controller(id) {
|
||||||
if let Some(incr) = flow.apply_window_update() {
|
if let Some(incr) = flow.apply_window_update() {
|
||||||
return Ok(Async::Ready(WindowUpdate::new(id, incr)));
|
return Ok(Async::Ready(WindowUpdate::new(id, incr)));
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ impl<T: ControlStreams> ControlFlow for FlowControl<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expand_window(&mut self, id: StreamId, incr: WindowSize) -> Result<(), ConnectionError> {
|
fn expand_window(&mut self, id: StreamId, incr: WindowSize) -> Result<(), ConnectionError> {
|
||||||
let added = match self.local_flow_controller(id) {
|
let added = match self.recv_flow_controller(id) {
|
||||||
None => false,
|
None => false,
|
||||||
Some(mut fc) => {
|
Some(mut fc) => {
|
||||||
fc.expand_window(incr);
|
fc.expand_window(incr);
|
||||||
@@ -153,7 +153,7 @@ impl<T, U> FlowControl<T>
|
|||||||
|
|
||||||
while let Some(id) = self.local_pending_streams.pop_front() {
|
while let Some(id) = self.local_pending_streams.pop_front() {
|
||||||
if self.inner.get_reset(id).is_none() {
|
if self.inner.get_reset(id).is_none() {
|
||||||
let update = self.local_flow_controller(id).and_then(|s| s.apply_window_update());
|
let update = self.recv_flow_controller(id).and_then(|s| s.apply_window_update());
|
||||||
if let Some(incr) = update {
|
if let Some(incr) = update {
|
||||||
try_ready!(self.try_send(frame::WindowUpdate::new(id, incr)));
|
try_ready!(self.try_send(frame::WindowUpdate::new(id, incr)));
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ impl<T> Stream for FlowControl<T>
|
|||||||
loop {
|
loop {
|
||||||
match try_ready!(self.inner.poll()) {
|
match try_ready!(self.inner.poll()) {
|
||||||
Some(WindowUpdate(v)) => {
|
Some(WindowUpdate(v)) => {
|
||||||
if let Some(fc) = self.remote_flow_controller(v.stream_id()) {
|
if let Some(fc) = self.send_flow_controller(v.stream_id()) {
|
||||||
fc.expand_window(v.size_increment());
|
fc.expand_window(v.size_increment());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,7 @@ impl<T> Stream for FlowControl<T>
|
|||||||
}
|
}
|
||||||
// If this frame ends the stream, there may no longer be a flow
|
// If this frame ends the stream, there may no longer be a flow
|
||||||
// controller. That's fine.
|
// controller. That's fine.
|
||||||
if let Some(fc) = self.local_flow_controller(v.stream_id()) {
|
if let Some(fc) = self.recv_flow_controller(v.stream_id()) {
|
||||||
if fc.claim_window(sz).is_err() {
|
if fc.claim_window(sz).is_err() {
|
||||||
return Err(error::Reason::FlowControlError.into())
|
return Err(error::Reason::FlowControlError.into())
|
||||||
}
|
}
|
||||||
@@ -248,7 +248,7 @@ impl<T, U> Sink for FlowControl<T>
|
|||||||
|
|
||||||
// Ensure there's enough capacity on stream.
|
// Ensure there's enough capacity on stream.
|
||||||
{
|
{
|
||||||
let mut fc = self.inner.remote_flow_controller(v.stream_id())
|
let mut fc = self.inner.send_flow_controller(v.stream_id())
|
||||||
.expect("no remote stream for data frame");
|
.expect("no remote stream for data frame");
|
||||||
if fc.claim_window(sz).is_err() {
|
if fc.claim_window(sz).is_err() {
|
||||||
return Err(error::User::FlowControlViolation.into())
|
return Err(error::User::FlowControlViolation.into())
|
||||||
@@ -311,7 +311,7 @@ impl<T> ApplySettings for FlowControl<T>
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.inner.local_update_inital_window_size(old_window_size, new_window_size);
|
self.inner.update_inital_recv_window_size(old_window_size, new_window_size);
|
||||||
self.local_initial = new_window_size;
|
self.local_initial = new_window_size;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -325,7 +325,7 @@ impl<T> ApplySettings for FlowControl<T>
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.inner.remote_update_inital_window_size(old_window_size, new_window_size);
|
self.inner.update_inital_send_window_size(old_window_size, new_window_size);
|
||||||
self.remote_initial = new_window_size;
|
self.remote_initial = new_window_size;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -348,16 +348,24 @@ impl<T: ControlStreams> ControlStreams for FlowControl<T> {
|
|||||||
self.inner.local_open(id, sz)
|
self.inner.local_open(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn local_open_recv_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.local_open_recv_half(id, sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remote_open_send_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.remote_open_send_half(id, sz)
|
||||||
|
}
|
||||||
|
|
||||||
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.remote_open(id, sz)
|
self.inner.remote_open(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_local_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_local_half(id)
|
self.inner.close_send_half(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_remote_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_remote_half(id)
|
self.inner.close_recv_half(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
||||||
@@ -383,20 +391,20 @@ impl<T: ControlStreams> ControlStreams for FlowControl<T> {
|
|||||||
self.inner.remote_active_len()
|
self.inner.remote_active_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_recv_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.local_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_send_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.remote_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.local_flow_controller(id)
|
self.inner.recv_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.remote_flow_controller(id)
|
self.inner.send_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ use self::framed_write::FramedWrite;
|
|||||||
use self::ping_pong::{ControlPing, PingPayload, PingPong};
|
use self::ping_pong::{ControlPing, PingPayload, PingPong};
|
||||||
use self::ready::ReadySink;
|
use self::ready::ReadySink;
|
||||||
use self::settings::{ApplySettings, /*ControlSettings,*/ Settings};
|
use self::settings::{ApplySettings, /*ControlSettings,*/ Settings};
|
||||||
use self::state::{StreamState, PeerState};
|
|
||||||
use self::stream_recv_close::StreamRecvClose;
|
use self::stream_recv_close::StreamRecvClose;
|
||||||
use self::stream_recv_open::StreamRecvOpen;
|
use self::stream_recv_open::StreamRecvOpen;
|
||||||
use self::stream_send_close::StreamSendClose;
|
use self::stream_send_close::StreamSendClose;
|
||||||
@@ -172,8 +171,8 @@ pub fn from_server_handshaker<T, P, B>(settings: Settings<FramedWrite<T, B::Buf>
|
|||||||
P: Peer,
|
P: Peer,
|
||||||
B: IntoBuf,
|
B: IntoBuf,
|
||||||
{
|
{
|
||||||
let initial_local_window_size = settings.local_settings().initial_window_size();
|
let initial_recv_window_size = settings.local_settings().initial_window_size();
|
||||||
let initial_remote_window_size = settings.remote_settings().initial_window_size();
|
let initial_send_window_size = settings.remote_settings().initial_window_size();
|
||||||
let local_max_concurrency = settings.local_settings().max_concurrent_streams();
|
let local_max_concurrency = settings.local_settings().max_concurrent_streams();
|
||||||
let remote_max_concurrency = settings.remote_settings().max_concurrent_streams();
|
let remote_max_concurrency = settings.remote_settings().max_concurrent_streams();
|
||||||
|
|
||||||
@@ -187,16 +186,17 @@ pub fn from_server_handshaker<T, P, B>(settings: Settings<FramedWrite<T, B::Buf>
|
|||||||
.num_skip(0) // Don't skip the header
|
.num_skip(0) // Don't skip the header
|
||||||
.new_read(io);
|
.new_read(io);
|
||||||
|
|
||||||
|
trace!("composing transport");
|
||||||
StreamSendOpen::new(
|
StreamSendOpen::new(
|
||||||
initial_remote_window_size,
|
initial_send_window_size,
|
||||||
remote_max_concurrency,
|
remote_max_concurrency,
|
||||||
StreamRecvClose::new(
|
StreamRecvClose::new(
|
||||||
FlowControl::new(
|
FlowControl::new(
|
||||||
initial_local_window_size,
|
initial_recv_window_size,
|
||||||
initial_remote_window_size,
|
initial_send_window_size,
|
||||||
StreamSendClose::new(
|
StreamSendClose::new(
|
||||||
StreamRecvOpen::new(
|
StreamRecvOpen::new(
|
||||||
initial_local_window_size,
|
initial_recv_window_size,
|
||||||
local_max_concurrency,
|
local_max_concurrency,
|
||||||
StreamStore::new(
|
StreamStore::new(
|
||||||
PingPong::new(
|
PingPong::new(
|
||||||
@@ -205,3 +205,4 @@ pub fn from_server_handshaker<T, P, B>(settings: Settings<FramedWrite<T, B::Buf>
|
|||||||
|
|
||||||
connection::new(transport)
|
connection::new(transport)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use {ConnectionError, Peer};
|
use ConnectionError;
|
||||||
use error::Reason::*;
|
use error::Reason::*;
|
||||||
use error::User::*;
|
use error::User::*;
|
||||||
use proto::{FlowControlState, WindowSize};
|
use proto::{FlowControlState, WindowSize};
|
||||||
@@ -59,126 +59,113 @@ pub enum StreamState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StreamState {
|
impl StreamState {
|
||||||
// /// Transition the state to represent headers being received.
|
pub fn new_open_sending(sz: WindowSize) -> StreamState {
|
||||||
// ///
|
StreamState::Open {
|
||||||
// /// Returns true if this state transition results in iniitializing the
|
local: PeerState::AwaitingHeaders,
|
||||||
// /// stream id. `Err` is returned if this is an invalid state transition.
|
remote: PeerState::streaming(sz),
|
||||||
// pub fn recv_headers<P>(&mut self, eos: bool, initial_window_size: WindowSize)
|
}
|
||||||
// -> Result<bool, ConnectionError>
|
}
|
||||||
// where P: Peer
|
|
||||||
// {
|
|
||||||
// use self::StreamState::*;
|
|
||||||
// use self::PeerState::*;
|
|
||||||
|
|
||||||
// match *self {
|
pub fn new_open_recving(sz: WindowSize) -> StreamState {
|
||||||
// Idle => {
|
StreamState::Open {
|
||||||
// let local = Headers;
|
local: PeerState::streaming(sz),
|
||||||
// if eos {
|
remote: PeerState::AwaitingHeaders,
|
||||||
// *self = HalfClosedRemote(local);
|
}
|
||||||
// } else {
|
}
|
||||||
// let remote = Data(FlowControlState::with_initial_size(initial_window_size));
|
|
||||||
// *self = Open { local, remote };
|
|
||||||
// }
|
|
||||||
// Ok(true)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Open { local, remote } => {
|
/// Opens the send-half of a stream if it is not already open.
|
||||||
// try!(remote.check_is_headers(ProtocolError.into()));
|
///
|
||||||
// if !eos {
|
/// Returns true iff the send half was not previously open.
|
||||||
// // Received non-trailers HEADERS on open remote.
|
pub fn open_send_half(&mut self, sz: WindowSize) -> Result<bool, ConnectionError> {
|
||||||
// return Err(ProtocolError.into());
|
use self::StreamState::*;
|
||||||
// }
|
use self::PeerState::*;
|
||||||
// *self = HalfClosedRemote(local);
|
|
||||||
// Ok(false)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// HalfClosedLocal(headers) => {
|
// Try to avoid copying `self` by first checking to see whether the stream needs
|
||||||
// try!(headers.check_is_headers(ProtocolError.into()));
|
// to be updated.
|
||||||
// if eos {
|
match self {
|
||||||
// *self = Closed;
|
&mut Idle |
|
||||||
// } else {
|
&mut Closed |
|
||||||
// let remote = FlowControlState::with_initial_size(initial_window_size);
|
&mut HalfClosedRemote(..) => {
|
||||||
// *self = HalfClosedLocal(Data(remote));
|
return Err(ProtocolError.into());
|
||||||
// };
|
}
|
||||||
// Ok(false)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Closed | HalfClosedRemote(..) => {
|
&mut Open { remote: Streaming(..), .. } |
|
||||||
// Err(ProtocolError.into())
|
&mut HalfClosedLocal(Streaming(..)) => {
|
||||||
// }
|
return Ok(false);
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Transition the state to represent headers being sent.
|
&mut Open { remote: AwaitingHeaders, .. } |
|
||||||
// ///
|
&mut HalfClosedLocal(AwaitingHeaders) => {}
|
||||||
// /// Returns true if this state transition results in initializing the stream
|
}
|
||||||
// /// id. `Err` is returned if this is an invalid state transition.
|
|
||||||
// pub fn send_headers<P: Peer>(&mut self,
|
|
||||||
// eos: bool,
|
|
||||||
// initial_window_size: WindowSize)
|
|
||||||
// -> Result<bool, ConnectionError>
|
|
||||||
// {
|
|
||||||
// use self::StreamState::*;
|
|
||||||
// use self::PeerState::*;
|
|
||||||
|
|
||||||
// match *self {
|
match *self {
|
||||||
// Idle => {
|
Open { local, remote: AwaitingHeaders } => {
|
||||||
// *self = if eos {
|
*self = Open {
|
||||||
// HalfClosedLocal(Headers)
|
local,
|
||||||
// } else {
|
remote: PeerState::streaming(sz),
|
||||||
// Open {
|
};
|
||||||
// local: Data(FlowControlState::with_initial_size(initial_window_size)),
|
}
|
||||||
// remote: Headers,
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok(true)
|
HalfClosedLocal(AwaitingHeaders) => {
|
||||||
// }
|
*self = HalfClosedLocal(PeerState::streaming(sz));
|
||||||
|
}
|
||||||
|
|
||||||
// Open { local, remote } => {
|
_ => unreachable!()
|
||||||
// try!(local.check_is_headers(UnexpectedFrameType.into()));
|
}
|
||||||
|
|
||||||
// *self = if eos {
|
Ok(true)
|
||||||
// HalfClosedLocal(remote)
|
}
|
||||||
// } else {
|
|
||||||
// let fc = FlowControlState::with_initial_size(initial_window_size);
|
|
||||||
// let local = Data(fc);
|
|
||||||
// Open { local, remote }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok(false)
|
pub fn open_recv_half(&mut self, sz: WindowSize) -> Result<bool, ConnectionError> {
|
||||||
// }
|
use self::StreamState::*;
|
||||||
|
use self::PeerState::*;
|
||||||
|
|
||||||
// HalfClosedRemote(local) => {
|
// Try to avoid copying `self` by first checking to see whether the stream needs
|
||||||
// try!(local.check_is_headers(UnexpectedFrameType.into()));
|
// to be updated.
|
||||||
|
match self {
|
||||||
|
&mut Idle |
|
||||||
|
&mut Closed |
|
||||||
|
&mut HalfClosedLocal(..) => {
|
||||||
|
return Err(ProtocolError.into());
|
||||||
|
}
|
||||||
|
|
||||||
// *self = if eos {
|
&mut Open { local: Streaming(..), .. } |
|
||||||
// Closed
|
&mut HalfClosedRemote(Streaming(..)) => {
|
||||||
// } else {
|
return Ok(false);
|
||||||
// let fc = FlowControlState::with_initial_size(initial_window_size);
|
}
|
||||||
// HalfClosedRemote(Data(fc))
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Ok(false)
|
&mut Open { local: AwaitingHeaders, .. } |
|
||||||
// }
|
&mut HalfClosedRemote(AwaitingHeaders) => {}
|
||||||
|
}
|
||||||
|
|
||||||
// Closed | HalfClosedLocal(..) => {
|
match *self {
|
||||||
// Err(UnexpectedFrameType.into())
|
Open { remote, local: AwaitingHeaders } => {
|
||||||
// }
|
*self = Open {
|
||||||
// }
|
local: PeerState::streaming(sz),
|
||||||
// }
|
remote,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
HalfClosedLocal(AwaitingHeaders) => {
|
||||||
|
*self = HalfClosedRemote(PeerState::streaming(sz));
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_can_send_data(&self) -> Result<(), ConnectionError> {
|
pub fn check_can_send_data(&self) -> Result<(), ConnectionError> {
|
||||||
use self::StreamState::*;
|
use self::StreamState::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
&Open { ref remote, .. } => {
|
&Open { ref remote, .. } => {
|
||||||
try!(remote.check_is_data(UnexpectedFrameType.into()));
|
try!(remote.check_streaming(UnexpectedFrameType.into()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
&HalfClosedLocal(ref remote) => {
|
&HalfClosedLocal(ref remote) => {
|
||||||
try!(remote.check_is_data(UnexpectedFrameType.into()));
|
try!(remote.check_streaming(UnexpectedFrameType.into()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,15 +177,14 @@ impl StreamState {
|
|||||||
|
|
||||||
pub fn check_can_recv_data(&self) -> Result<(), ConnectionError> {
|
pub fn check_can_recv_data(&self) -> Result<(), ConnectionError> {
|
||||||
use self::StreamState::*;
|
use self::StreamState::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
&Open { ref local, .. } => {
|
&Open { ref local, .. } => {
|
||||||
try!(local.check_is_data(ProtocolError.into()));
|
try!(local.check_streaming(ProtocolError.into()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
&HalfClosedRemote(ref local) => {
|
&HalfClosedRemote(ref local) => {
|
||||||
try!(local.check_is_data(ProtocolError.into()));
|
try!(local.check_streaming(ProtocolError.into()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,17 +194,21 @@ impl StreamState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Indicates that the local side will not send more data to the remote.
|
||||||
|
///
|
||||||
/// Returns true iff the stream is fully closed.
|
/// Returns true iff the stream is fully closed.
|
||||||
pub fn close_local(&mut self) -> Result<bool, ConnectionError> {
|
pub fn close_send_half(&mut self) -> Result<bool, ConnectionError> {
|
||||||
use self::StreamState::*;
|
use self::StreamState::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
Open { remote, .. } => {
|
Open { local, .. } => {
|
||||||
*self = HalfClosedLocal(remote);
|
// The local side will continue to receive data.
|
||||||
|
trace!("close_send_half: Open => HalfClosedRemote({:?})", local);
|
||||||
|
*self = HalfClosedRemote(local);
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
HalfClosedLocal(remote) => {
|
HalfClosedLocal(..) => {
|
||||||
|
trace!("close_send_half: HalfClosedLocal => Closed");
|
||||||
*self = Closed;
|
*self = Closed;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
@@ -229,17 +219,21 @@ impl StreamState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Indicates that the remote side will not send more data to the local.
|
||||||
|
///
|
||||||
/// Returns true iff the stream is fully closed.
|
/// Returns true iff the stream is fully closed.
|
||||||
pub fn close_remote(&mut self) -> Result<bool, ConnectionError> {
|
pub fn close_recv_half(&mut self) -> Result<bool, ConnectionError> {
|
||||||
use self::StreamState::*;
|
use self::StreamState::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
Open { local, .. } => {
|
Open { remote, .. } => {
|
||||||
*self = HalfClosedRemote(local);
|
// The remote side will continue to receive data.
|
||||||
|
trace!("close_recv_half: Open => HalfClosedLocal({:?})", remote);
|
||||||
|
*self = HalfClosedLocal(remote);
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
HalfClosedRemote(local) => {
|
HalfClosedRemote(..) => {
|
||||||
|
trace!("close_recv_half: HalfClosedRemoteOpen => Closed");
|
||||||
*self = Closed;
|
*self = Closed;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
@@ -250,24 +244,20 @@ impl StreamState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_flow_controller(&mut self) -> Option<&mut FlowControlState> {
|
pub fn recv_flow_controller(&mut self) -> Option<&mut FlowControlState> {
|
||||||
use self::StreamState::*;
|
use self::StreamState::*;
|
||||||
use self::PeerState::*;
|
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
&mut Open { local: Data(ref mut fc), .. } |
|
&mut Open { ref mut local, .. } |
|
||||||
&mut HalfClosedRemote(Data(ref mut fc)) => Some(fc),
|
&mut HalfClosedRemote(ref mut local) => local.flow_controller(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remote_flow_controller(&mut self) -> Option<&mut FlowControlState> {
|
pub fn send_flow_controller(&mut self) -> Option<&mut FlowControlState> {
|
||||||
use self::StreamState::*;
|
use self::StreamState::*;
|
||||||
use self::PeerState::*;
|
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
&mut Open { remote: Data(ref mut fc), .. } |
|
&mut Open { ref mut remote, .. } |
|
||||||
&mut HalfClosedLocal(Data(ref mut fc)) => Some(fc),
|
&mut HalfClosedLocal(ref mut remote) => remote.flow_controller(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,27 +271,36 @@ impl Default for StreamState {
|
|||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum PeerState {
|
pub enum PeerState {
|
||||||
Headers,
|
AwaitingHeaders,
|
||||||
/// Contains a FlowControlState representing the _receiver_ of this this data stream.
|
/// Contains a FlowControlState representing the _receiver_ of this this data stream.
|
||||||
Data(FlowControlState),
|
Streaming(FlowControlState),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PeerState {
|
||||||
|
fn default() -> Self {
|
||||||
|
PeerState::AwaitingHeaders
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PeerState {
|
impl PeerState {
|
||||||
|
fn streaming(sz: WindowSize) -> PeerState {
|
||||||
|
PeerState::Streaming(FlowControlState::with_initial_size(sz))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check_is_headers(&self, err: ConnectionError) -> Result<(), ConnectionError> {
|
fn check_streaming(&self, err: ConnectionError) -> Result<(), ConnectionError> {
|
||||||
use self::PeerState::*;
|
use self::PeerState::*;
|
||||||
match self {
|
match self {
|
||||||
&Headers => Ok(()),
|
&Streaming(..) => Ok(()),
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn flow_controller(&mut self) -> Option<&mut FlowControlState> {
|
||||||
fn check_is_data(&self, err: ConnectionError) -> Result<(), ConnectionError> {
|
|
||||||
use self::PeerState::*;
|
use self::PeerState::*;
|
||||||
match self {
|
match self {
|
||||||
&Data(_) => Ok(()),
|
&mut Streaming(ref mut fc) => Some(fc),
|
||||||
_ => Err(err),
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use proto::ready::ReadySink;
|
|||||||
// TODO reset_streams needs to be bounded.
|
// TODO reset_streams needs to be bounded.
|
||||||
// TODO track reserved streams (PUSH_PROMISE).
|
// TODO track reserved streams (PUSH_PROMISE).
|
||||||
|
|
||||||
|
/// Handles end-of-stream frames sent from the remote.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StreamRecvClose<T> {
|
pub struct StreamRecvClose<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
@@ -32,11 +33,24 @@ impl<T> Stream for StreamRecvClose<T>
|
|||||||
type Error = T::Error;
|
type Error = T::Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Option<T::Item>, T::Error> {
|
fn poll(&mut self) -> Poll<Option<T::Item>, T::Error> {
|
||||||
use frame::Frame::*;
|
let frame = match try_ready!(self.inner.poll()) {
|
||||||
|
None => return Ok(Async::Ready(None)),
|
||||||
|
Some(f) => f,
|
||||||
|
};
|
||||||
|
|
||||||
let frame = try_ready!(self.inner.poll());
|
let id = frame.stream_id();
|
||||||
|
if !id.is_zero() {
|
||||||
|
if frame.is_end_stream() {
|
||||||
|
if let &Frame::Reset(ref rst) = &frame {
|
||||||
|
self.inner.reset_stream(id, rst.reason());
|
||||||
|
} else {
|
||||||
|
debug_assert!(self.inner.is_active(id));
|
||||||
|
self.inner.close_recv_half(id)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unimplemented!()
|
Ok(Async::Ready(Some(frame)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,12 +101,20 @@ impl<T: ControlStreams> ControlStreams for StreamRecvClose<T> {
|
|||||||
self.inner.remote_open(id, sz)
|
self.inner.remote_open(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_local_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn local_open_recv_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_local_half(id)
|
self.inner.local_open_recv_half(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_remote_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn remote_open_send_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_remote_half(id)
|
self.inner.remote_open_send_half(id, sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.close_send_half(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.close_recv_half(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
||||||
@@ -119,20 +141,20 @@ impl<T: ControlStreams> ControlStreams for StreamRecvClose<T> {
|
|||||||
self.inner.remote_active_len()
|
self.inner.remote_active_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_recv_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.local_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_send_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.remote_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.local_flow_controller(id)
|
self.inner.recv_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.remote_flow_controller(id)
|
self.inner.send_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ impl<T, U> StreamRecvOpen<T>
|
|||||||
fn send_refuse(&mut self, id: StreamId) -> Poll<(), ConnectionError> {
|
fn send_refuse(&mut self, id: StreamId) -> Poll<(), ConnectionError> {
|
||||||
debug_assert!(self.pending_refuse.is_none());
|
debug_assert!(self.pending_refuse.is_none());
|
||||||
|
|
||||||
let f = frame::Reset::new(id, Reason::RefusedStream);
|
let f = frame::Reset::new(id, RefusedStream);
|
||||||
match self.inner.start_send(f.into())? {
|
match self.inner.start_send(f.into())? {
|
||||||
AsyncSink::Ready => {
|
AsyncSink::Ready => {
|
||||||
self.inner.reset_stream(id, Reason::RefusedStream);
|
self.inner.reset_stream(id, RefusedStream);
|
||||||
Ok(Async::Ready(()))
|
Ok(Async::Ready(()))
|
||||||
}
|
}
|
||||||
AsyncSink::NotReady(_) => {
|
AsyncSink::NotReady(_) => {
|
||||||
@@ -51,6 +51,13 @@ impl<T, U> StreamRecvOpen<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_pending_refuse(&mut self) -> Poll<(), ConnectionError> {
|
||||||
|
if let Some(id) = self.pending_refuse.take() {
|
||||||
|
try_ready!(self.send_refuse(id));
|
||||||
|
}
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles updates to `SETTINGS_MAX_CONCURRENT_STREAMS`.
|
/// Handles updates to `SETTINGS_MAX_CONCURRENT_STREAMS`.
|
||||||
@@ -99,18 +106,39 @@ impl<T, U> Stream for StreamRecvOpen<T>
|
|||||||
|
|
||||||
// Since there's only one slot for pending refused streams, it must be cleared
|
// Since there's only one slot for pending refused streams, it must be cleared
|
||||||
// before polling a frame from the transport.
|
// before polling a frame from the transport.
|
||||||
if let Some(id) = self.pending_refuse.take() {
|
try_ready!(self.send_pending_refuse());
|
||||||
try_ready!(self.send_refuse(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
trace!("poll");
|
||||||
loop {
|
loop {
|
||||||
let frame = match try_ready!(self.inner.poll()) {
|
let frame = match self.inner.poll()? {
|
||||||
None => return Ok(Async::Ready(None)),
|
Async::NotReady => {
|
||||||
Some(f) => f,
|
panic!("poll: NotReady");
|
||||||
|
}
|
||||||
|
Async::Ready(None) => {
|
||||||
|
panic!("poll: None");
|
||||||
|
}
|
||||||
|
Async::Ready(Some(f)) => {
|
||||||
|
trace!("poll: id={:?} eos={}", f.stream_id(), f.is_end_stream());
|
||||||
|
f
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
// let frame = match try_ready!(self.inner.poll()) {
|
||||||
|
// None => return Ok(Async::Ready(None)),
|
||||||
|
// Some(f) => f,
|
||||||
|
// };
|
||||||
|
|
||||||
let id = frame.stream_id();
|
let id = frame.stream_id();
|
||||||
|
trace!("poll: id={:?}", id);
|
||||||
if id.is_zero() {
|
if id.is_zero() {
|
||||||
|
if !frame.is_connection_frame() {
|
||||||
|
return Err(ProtocolError.into())
|
||||||
|
}
|
||||||
|
// Nothing to do on connection frames.
|
||||||
|
return Ok(Async::Ready(Some(frame)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let &Reset(_) = &frame {
|
||||||
|
// Resetting handled by StreamRecvClose.
|
||||||
return Ok(Async::Ready(Some(frame)));
|
return Ok(Async::Ready(Some(frame)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,20 +157,29 @@ impl<T, U> Stream for StreamRecvOpen<T>
|
|||||||
|
|
||||||
if let Some(max) = self.max_concurrency {
|
if let Some(max) = self.max_concurrency {
|
||||||
if (max as usize) < self.inner.remote_active_len() {
|
if (max as usize) < self.inner.remote_active_len() {
|
||||||
return Err(RefusedStream.into());
|
let _ = self.send_refuse(id)?;
|
||||||
|
debug!("refusing stream that would exceed max_concurrency");
|
||||||
|
|
||||||
|
// There's no point in returning an error to the application.
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.inner.remote_open(id, self.initial_window_size)?;
|
self.inner.remote_open(id, self.initial_window_size)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Receiving on local stream MUST be on active stream.
|
// If the frame is part of a local stream, it MUST already exist.
|
||||||
if !self.inner.is_local_active(id) && !frame.is_reset() {
|
if self.inner.is_local_active(id) {
|
||||||
|
if let &Headers(..) = &frame {
|
||||||
|
self.inner.local_open_recv_half(id, self.initial_window_size)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return Err(ProtocolError.into());
|
return Err(ProtocolError.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let &Data(..) = &frame {
|
if let &Data(..) = &frame {
|
||||||
|
// Ensures we've already received headers for this stream.
|
||||||
self.inner.check_can_recv_data(id)?;
|
self.inner.check_can_recv_data(id)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,32 +198,17 @@ impl<T, U> Sink for StreamRecvOpen<T>
|
|||||||
type SinkError = T::SinkError;
|
type SinkError = T::SinkError;
|
||||||
|
|
||||||
fn start_send(&mut self, frame: T::SinkItem) -> StartSend<T::SinkItem, T::SinkError> {
|
fn start_send(&mut self, frame: T::SinkItem) -> StartSend<T::SinkItem, T::SinkError> {
|
||||||
use frame::Frame::*;
|
|
||||||
|
|
||||||
// The local must complete refusing the remote stream before sending any other
|
// The local must complete refusing the remote stream before sending any other
|
||||||
// frames.
|
// frames.
|
||||||
if let Some(id) = self.pending_refuse.take() {
|
if self.send_pending_refuse()?.is_not_ready() {
|
||||||
if self.send_refuse(id)?.is_not_ready() {
|
|
||||||
return Ok(AsyncSink::NotReady(frame));
|
return Ok(AsyncSink::NotReady(frame));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let id = frame.stream_id();
|
|
||||||
if !id.is_zero() {
|
|
||||||
// enforced by StreamSend.
|
|
||||||
debug_assert!(self.inner.get_reset(id).is_none());
|
|
||||||
|
|
||||||
let eos = frame.is_end_stream();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.inner.start_send(frame)
|
self.inner.start_send(frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_complete(&mut self) -> Poll<(), T::SinkError> {
|
fn poll_complete(&mut self) -> Poll<(), T::SinkError> {
|
||||||
if let Some(id) = self.pending_refuse.take() {
|
try_ready!(self.send_pending_refuse());
|
||||||
try_ready!(self.send_refuse(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.inner.poll_complete()
|
self.inner.poll_complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,12 +354,20 @@ impl<T: ControlStreams> ControlStreams for StreamRecvOpen<T> {
|
|||||||
self.inner.remote_open(id, sz)
|
self.inner.remote_open(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_local_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn local_open_recv_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_local_half(id)
|
self.inner.local_open_recv_half(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_remote_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn remote_open_send_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_remote_half(id)
|
self.inner.remote_open_send_half(id, sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.close_send_half(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.close_recv_half(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
||||||
@@ -364,20 +394,20 @@ impl<T: ControlStreams> ControlStreams for StreamRecvOpen<T> {
|
|||||||
self.inner.remote_active_len()
|
self.inner.remote_active_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_recv_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.local_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_send_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.remote_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.local_flow_controller(id)
|
self.inner.recv_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.remote_flow_controller(id)
|
self.inner.send_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
|||||||
@@ -43,12 +43,17 @@ impl<T, U> Sink for StreamSendClose<T>
|
|||||||
type SinkError = ConnectionError;
|
type SinkError = ConnectionError;
|
||||||
|
|
||||||
fn start_send(&mut self, frame: Self::SinkItem) -> StartSend<Frame<U>, ConnectionError> {
|
fn start_send(&mut self, frame: Self::SinkItem) -> StartSend<Frame<U>, ConnectionError> {
|
||||||
if frame.is_end_stream() {
|
|
||||||
let id = frame.stream_id();
|
let id = frame.stream_id();
|
||||||
|
let eos = frame.is_end_stream();
|
||||||
|
trace!("start_send: id={:?} eos={}", id, eos);
|
||||||
|
if !id.is_zero() {
|
||||||
|
if frame.is_end_stream() {
|
||||||
if let &Frame::Reset(ref rst) = &frame {
|
if let &Frame::Reset(ref rst) = &frame {
|
||||||
self.inner.reset_stream(id, rst.reason());
|
self.inner.reset_stream(id, rst.reason());
|
||||||
} else {
|
} else {
|
||||||
self.inner.close_local_half(id)?;
|
debug_assert!(self.inner.is_active(id));
|
||||||
|
self.inner.close_send_half(id)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,12 +106,20 @@ impl<T: ControlStreams> ControlStreams for StreamSendClose<T> {
|
|||||||
self.inner.remote_open(id, sz)
|
self.inner.remote_open(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_local_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn local_open_recv_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_local_half(id)
|
self.inner.local_open_recv_half(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_remote_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn remote_open_send_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_remote_half(id)
|
self.inner.remote_open_send_half(id, sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.close_send_half(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.close_recv_half(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
||||||
@@ -133,20 +146,20 @@ impl<T: ControlStreams> ControlStreams for StreamSendClose<T> {
|
|||||||
self.inner.remote_active_len()
|
self.inner.remote_active_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_recv_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.local_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_send_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.remote_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.local_flow_controller(id)
|
self.inner.recv_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.remote_flow_controller(id)
|
self.inner.send_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ impl<T> Stream for StreamSendOpen<T>
|
|||||||
type Error = ConnectionError;
|
type Error = ConnectionError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Option<Frame>, ConnectionError> {
|
fn poll(&mut self) -> Poll<Option<Frame>, ConnectionError> {
|
||||||
|
trace!("poll");
|
||||||
self.inner.poll()
|
self.inner.poll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,18 +81,19 @@ impl<T, U> Sink for StreamSendOpen<T>
|
|||||||
type SinkError = T::SinkError;
|
type SinkError = T::SinkError;
|
||||||
|
|
||||||
fn start_send(&mut self, frame: T::SinkItem) -> StartSend<T::SinkItem, T::SinkError> {
|
fn start_send(&mut self, frame: T::SinkItem) -> StartSend<T::SinkItem, T::SinkError> {
|
||||||
use frame::Frame::*;
|
|
||||||
|
|
||||||
let id = frame.stream_id();
|
let id = frame.stream_id();
|
||||||
|
trace!("start_send: id={:?}", id);
|
||||||
if id.is_zero() {
|
if id.is_zero() {
|
||||||
|
if !frame.is_connection_frame() {
|
||||||
|
return Err(InvalidStreamId.into())
|
||||||
|
}
|
||||||
// Nothing to do on connection frames.
|
// Nothing to do on connection frames.
|
||||||
return self.inner.start_send(frame);
|
return self.inner.start_send(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the stream immediately and send the Reset on the underlying transport.
|
// Reset the stream immediately and send the Reset on the underlying transport.
|
||||||
if let Reset(rst) = frame {
|
if let &Frame::Reset(..) = &frame {
|
||||||
self.inner.reset_stream(id, rst.reason());
|
return self.inner.start_send(frame);
|
||||||
return self.inner.start_send(Reset(rst));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the stream hasn't been closed otherwise.
|
// Ensure that the stream hasn't been closed otherwise.
|
||||||
@@ -111,19 +113,26 @@ impl<T, U> Sink for StreamSendOpen<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!("creating new local stream");
|
||||||
self.inner.local_open(id, self.initial_window_size)?;
|
self.inner.local_open(id, self.initial_window_size)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If the frame was part of a remote stream, it MUST already exist.
|
// If the frame is part of a remote stream, it MUST already exist.
|
||||||
if !self.inner.is_remote_active(id) && !frame.is_reset() {
|
if self.inner.is_remote_active(id) {
|
||||||
|
if let &Frame::Headers(..) = &frame {
|
||||||
|
self.inner.remote_open_send_half(id, self.initial_window_size)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return Err(InvalidStreamId.into());
|
return Err(InvalidStreamId.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let &Data(..) = &frame {
|
if let &Frame::Data(..) = &frame {
|
||||||
|
// Ensures we've already sent headers for this stream.
|
||||||
self.inner.check_can_send_data(id)?;
|
self.inner.check_can_send_data(id)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!("sending frame...");
|
||||||
return self.inner.start_send(frame);
|
return self.inner.start_send(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,12 +173,20 @@ impl<T: ControlStreams> ControlStreams for StreamSendOpen<T> {
|
|||||||
self.inner.remote_open(id, sz)
|
self.inner.remote_open(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_local_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn local_open_recv_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_local_half(id)
|
self.inner.local_open_recv_half(id, sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_remote_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn remote_open_send_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
self.inner.close_remote_half(id)
|
self.inner.remote_open_send_half(id, sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.close_send_half(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.close_recv_half(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
fn reset_stream(&mut self, id: StreamId, cause: Reason) {
|
||||||
@@ -196,20 +213,20 @@ impl<T: ControlStreams> ControlStreams for StreamSendOpen<T> {
|
|||||||
self.inner.remote_active_len()
|
self.inner.remote_active_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_recv_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.local_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_send_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
self.inner.remote_update_inital_window_size(old_sz, new_sz)
|
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.local_flow_controller(id)
|
self.inner.recv_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
self.inner.remote_flow_controller(id)
|
self.inner.send_flow_controller(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use {ConnectionError, Peer, StreamId};
|
use {ConnectionError, Peer, StreamId};
|
||||||
use error::Reason::{NoError, ProtocolError};
|
use error::Reason::{NoError, ProtocolError};
|
||||||
use proto::*;
|
use proto::*;
|
||||||
use proto::state::{StreamState, PeerState};
|
use proto::state::StreamState;
|
||||||
|
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use ordermap::OrderMap;
|
use ordermap::OrderMap;
|
||||||
@@ -14,19 +14,44 @@ pub trait ControlStreams {
|
|||||||
fn local_valid_id(id: StreamId) -> bool;
|
fn local_valid_id(id: StreamId) -> bool;
|
||||||
fn remote_valid_id(id: StreamId) -> bool;
|
fn remote_valid_id(id: StreamId) -> bool;
|
||||||
|
|
||||||
|
/// Indicates whether this local endpoint may open streams (with HEADERS).
|
||||||
|
///
|
||||||
|
/// Implies that this endpoint is a client.
|
||||||
fn local_can_open() -> bool;
|
fn local_can_open() -> bool;
|
||||||
|
|
||||||
|
/// Indicates whether this remote endpoint may open streams (with HEADERS).
|
||||||
|
///
|
||||||
|
/// Implies that this endpoint is a server.
|
||||||
fn remote_can_open() -> bool {
|
fn remote_can_open() -> bool {
|
||||||
!Self::local_can_open()
|
!Self::local_can_open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new stream in the OPEN state from the local side (i.e. as a Client).
|
||||||
|
///
|
||||||
|
/// Must only be called when local_can_open returns true.
|
||||||
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError>;
|
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
|
/// Create a new stream in the OPEN state from the remote side (i.e. as a Server).
|
||||||
|
///
|
||||||
|
/// Must only be called when remote_can_open returns true.
|
||||||
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError>;
|
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
|
/// Prepare the receive side of a local stream to receive data from the remote.
|
||||||
|
///
|
||||||
|
/// Typically called when a client receives a response header.
|
||||||
|
fn local_open_recv_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
|
/// Prepare the send side of a remote stream to receive data from the local endpoint.
|
||||||
|
///
|
||||||
|
/// Typically called when a server sends a response header.
|
||||||
|
fn remote_open_send_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
// fn local_reserve(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
// fn local_reserve(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
// fn remote_reserve(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
// fn remote_reserve(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
fn close_local_half(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
/// Close the local half of a stream so that the local side may not RECEIVE
|
||||||
fn close_remote_half(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
|
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
fn reset_stream(&mut self, id: StreamId, cause: Reason);
|
fn reset_stream(&mut self, id: StreamId, cause: Reason);
|
||||||
fn get_reset(&self, id: StreamId) -> Option<Reason>;
|
fn get_reset(&self, id: StreamId) -> Option<Reason>;
|
||||||
@@ -34,14 +59,22 @@ pub trait ControlStreams {
|
|||||||
fn is_local_active(&self, id: StreamId) -> bool;
|
fn is_local_active(&self, id: StreamId) -> bool;
|
||||||
fn is_remote_active(&self, id: StreamId) -> bool;
|
fn is_remote_active(&self, id: StreamId) -> bool;
|
||||||
|
|
||||||
|
fn is_active(&self, id: StreamId) -> bool {
|
||||||
|
if Self::local_valid_id(id) {
|
||||||
|
self.is_local_active(id)
|
||||||
|
} else {
|
||||||
|
self.is_remote_active(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn local_active_len(&self) -> usize;
|
fn local_active_len(&self) -> usize;
|
||||||
fn remote_active_len(&self) -> usize;
|
fn remote_active_len(&self) -> usize;
|
||||||
|
|
||||||
fn local_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState>;
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState>;
|
||||||
fn remote_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState>;
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState>;
|
||||||
|
|
||||||
fn local_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32);
|
fn update_inital_recv_window_size(&mut self, old_sz: u32, new_sz: u32);
|
||||||
fn remote_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32);
|
fn update_inital_send_window_size(&mut self, old_sz: u32, new_sz: u32);
|
||||||
|
|
||||||
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
fn check_can_send_data(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
fn check_can_recv_data(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
fn check_can_recv_data(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
@@ -160,35 +193,49 @@ impl<T, P: Peer> ControlStreams for StreamStore<T, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Open a new stream from the local side (i.e. as a Client).
|
/// Open a new stream from the local side (i.e. as a Client).
|
||||||
//
|
|
||||||
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
debug_assert!(Self::local_can_open());
|
|
||||||
assert!(Self::local_valid_id(id));
|
assert!(Self::local_valid_id(id));
|
||||||
|
debug_assert!(Self::local_can_open());
|
||||||
debug_assert!(!self.local_active.contains_key(&id));
|
debug_assert!(!self.local_active.contains_key(&id));
|
||||||
|
|
||||||
self.local_active.insert(id, StreamState::Open {
|
self.local_active.insert(id, StreamState::new_open_sending(sz));
|
||||||
remote: PeerState::Data(FlowControlState::with_initial_size(sz)),
|
|
||||||
local: PeerState::Headers,
|
|
||||||
});
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Open a new stream from the remote side (i.e. as a Server).
|
/// Open a new stream from the remote side (i.e. as a Server).
|
||||||
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
debug_assert!(Self::remote_can_open());
|
|
||||||
assert!(Self::remote_valid_id(id));
|
assert!(Self::remote_valid_id(id));
|
||||||
|
debug_assert!(Self::remote_can_open());
|
||||||
debug_assert!(!self.remote_active.contains_key(&id));
|
debug_assert!(!self.remote_active.contains_key(&id));
|
||||||
|
|
||||||
self.remote_active.insert(id, StreamState::Open {
|
self.remote_active.insert(id, StreamState::new_open_recving(sz));
|
||||||
local: PeerState::Data(FlowControlState::with_initial_size(sz)),
|
|
||||||
remote: PeerState::Headers,
|
|
||||||
});
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_local_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn local_open_recv_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
|
assert!(Self::local_valid_id(id));
|
||||||
|
debug_assert!(self.local_active.contains_key(&id));
|
||||||
|
|
||||||
|
match self.local_active.get_mut(&id) {
|
||||||
|
Some(s) => s.open_recv_half(sz).map(|_| {}),
|
||||||
|
None => Err(ProtocolError.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remote_open_send_half(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
|
assert!(Self::remote_valid_id(id));
|
||||||
|
debug_assert!(Self::remote_can_open());
|
||||||
|
debug_assert!(self.remote_active.contains_key(&id));
|
||||||
|
|
||||||
|
match self.remote_active.get_mut(&id) {
|
||||||
|
Some(s) => s.open_send_half(sz).map(|_| {}),
|
||||||
|
None => Err(ProtocolError.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
let fully_closed = self.get_active_mut(id)
|
let fully_closed = self.get_active_mut(id)
|
||||||
.map(|s| s.close_local())
|
.map(|s| s.close_send_half())
|
||||||
.unwrap_or_else(|| Err(ProtocolError.into()))?;
|
.unwrap_or_else(|| Err(ProtocolError.into()))?;
|
||||||
|
|
||||||
if fully_closed {
|
if fully_closed {
|
||||||
@@ -198,9 +245,9 @@ impl<T, P: Peer> ControlStreams for StreamStore<T, P> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_remote_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError> {
|
||||||
let fully_closed = self.get_active_mut(id)
|
let fully_closed = self.get_active_mut(id)
|
||||||
.map(|s| s.close_remote())
|
.map(|s| s.close_recv_half())
|
||||||
.unwrap_or_else(|| Err(ProtocolError.into()))?;
|
.unwrap_or_else(|| Err(ProtocolError.into()))?;
|
||||||
|
|
||||||
if fully_closed {
|
if fully_closed {
|
||||||
@@ -235,18 +282,18 @@ impl<T, P: Peer> ControlStreams for StreamStore<T, P> {
|
|||||||
self.remote_active.len()
|
self.remote_active.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_recv_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
if new_sz < old_sz {
|
if new_sz < old_sz {
|
||||||
let decr = old_sz - new_sz;
|
let decr = old_sz - new_sz;
|
||||||
|
|
||||||
for s in self.local_active.values_mut() {
|
for s in self.local_active.values_mut() {
|
||||||
if let Some(fc) = s.local_flow_controller() {
|
if let Some(fc) = s.recv_flow_controller() {
|
||||||
fc.shrink_window(decr);
|
fc.shrink_window(decr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s in self.remote_active.values_mut() {
|
for s in self.remote_active.values_mut() {
|
||||||
if let Some(fc) = s.local_flow_controller() {
|
if let Some(fc) = s.recv_flow_controller() {
|
||||||
fc.shrink_window(decr);
|
fc.shrink_window(decr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,31 +301,31 @@ impl<T, P: Peer> ControlStreams for StreamStore<T, P> {
|
|||||||
let incr = new_sz - old_sz;
|
let incr = new_sz - old_sz;
|
||||||
|
|
||||||
for s in self.local_active.values_mut() {
|
for s in self.local_active.values_mut() {
|
||||||
if let Some(fc) = s.local_flow_controller() {
|
if let Some(fc) = s.recv_flow_controller() {
|
||||||
fc.expand_window(incr);
|
fc.expand_window(incr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s in self.remote_active.values_mut() {
|
for s in self.remote_active.values_mut() {
|
||||||
if let Some(fc) = s.local_flow_controller() {
|
if let Some(fc) = s.recv_flow_controller() {
|
||||||
fc.expand_window(incr);
|
fc.expand_window(incr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_update_inital_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
fn update_inital_send_window_size(&mut self, old_sz: u32, new_sz: u32) {
|
||||||
if new_sz < old_sz {
|
if new_sz < old_sz {
|
||||||
let decr = old_sz - new_sz;
|
let decr = old_sz - new_sz;
|
||||||
|
|
||||||
for s in self.local_active.values_mut() {
|
for s in self.local_active.values_mut() {
|
||||||
if let Some(fc) = s.remote_flow_controller() {
|
if let Some(fc) = s.send_flow_controller() {
|
||||||
fc.shrink_window(decr);
|
fc.shrink_window(decr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s in self.remote_active.values_mut() {
|
for s in self.remote_active.values_mut() {
|
||||||
if let Some(fc) = s.remote_flow_controller() {
|
if let Some(fc) = s.send_flow_controller() {
|
||||||
fc.shrink_window(decr);
|
fc.shrink_window(decr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,36 +333,36 @@ impl<T, P: Peer> ControlStreams for StreamStore<T, P> {
|
|||||||
let incr = new_sz - old_sz;
|
let incr = new_sz - old_sz;
|
||||||
|
|
||||||
for s in self.local_active.values_mut() {
|
for s in self.local_active.values_mut() {
|
||||||
if let Some(fc) = s.remote_flow_controller() {
|
if let Some(fc) = s.send_flow_controller() {
|
||||||
fc.expand_window(incr);
|
fc.expand_window(incr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for s in self.remote_active.values_mut() {
|
for s in self.remote_active.values_mut() {
|
||||||
if let Some(fc) = s.remote_flow_controller() {
|
if let Some(fc) = s.send_flow_controller() {
|
||||||
fc.expand_window(incr);
|
fc.expand_window(incr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
if id.is_zero() {
|
if id.is_zero() {
|
||||||
None
|
None
|
||||||
} else if P::is_valid_local_stream_id(id) {
|
} else if P::is_valid_local_stream_id(id) {
|
||||||
self.local_active.get_mut(&id).and_then(|s| s.local_flow_controller())
|
self.local_active.get_mut(&id).and_then(|s| s.recv_flow_controller())
|
||||||
} else {
|
} else {
|
||||||
self.remote_active.get_mut(&id).and_then(|s| s.local_flow_controller())
|
self.remote_active.get_mut(&id).and_then(|s| s.recv_flow_controller())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remote_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
if id.is_zero() {
|
if id.is_zero() {
|
||||||
None
|
None
|
||||||
} else if P::is_valid_local_stream_id(id) {
|
} else if P::is_valid_local_stream_id(id) {
|
||||||
self.local_active.get_mut(&id).and_then(|s| s.remote_flow_controller())
|
self.local_active.get_mut(&id).and_then(|s| s.send_flow_controller())
|
||||||
} else {
|
} else {
|
||||||
self.remote_active.get_mut(&id).and_then(|s| s.remote_flow_controller())
|
self.remote_active.get_mut(&id).and_then(|s| s.send_flow_controller())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user