Use macros for proxying internal interfaces.
This commit is contained in:
@@ -3,8 +3,6 @@ use client::Client;
|
|||||||
use error;
|
use error;
|
||||||
use frame::{self, StreamId};
|
use frame::{self, StreamId};
|
||||||
use proto::*;
|
use proto::*;
|
||||||
use proto::ping_pong::{ControlPing, PingPayload};
|
|
||||||
use proto::settings::ControlSettings;
|
|
||||||
use server::Server;
|
use server::Server;
|
||||||
|
|
||||||
use bytes::{Bytes, IntoBuf};
|
use bytes::{Bytes, IntoBuf};
|
||||||
|
|||||||
@@ -4,20 +4,6 @@ use proto::*;
|
|||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
/// Exposes flow control states to "upper" layers of the transport (i.e. above
|
|
||||||
/// FlowControl).
|
|
||||||
pub trait ControlFlow {
|
|
||||||
/// Polls for the next window update from the remote.
|
|
||||||
fn poll_window_update(&mut self) -> Poll<WindowUpdate, ConnectionError>;
|
|
||||||
|
|
||||||
/// Increases the local receive capacity of a stream.
|
|
||||||
///
|
|
||||||
/// This may cause a window update to be sent to the remote.
|
|
||||||
///
|
|
||||||
/// Fails if the given stream is not active.
|
|
||||||
fn expand_window(&mut self, id: StreamId, incr: WindowSize) -> Result<(), ConnectionError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FlowControl<T> {
|
pub struct FlowControl<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
@@ -345,100 +331,5 @@ impl<T> ApplySettings for FlowControl<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Proxy.
|
proxy_control_streams!(FlowControl);
|
||||||
impl<T: ControlStreams> ControlStreams for FlowControl<T> {
|
proxy_control_ping!(FlowControl);
|
||||||
fn local_valid_id(id: StreamId) -> bool {
|
|
||||||
T::local_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_valid_id(id: StreamId) -> bool {
|
|
||||||
T::remote_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_can_open() -> bool {
|
|
||||||
T::local_can_open()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
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> {
|
|
||||||
self.inner.remote_open(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) {
|
|
||||||
self.inner.reset_stream(id, cause)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_reset(&self, id: StreamId) -> Option<Reason> {
|
|
||||||
self.inner.get_reset(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_local_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_local_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_remote_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_remote_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_active_len(&self) -> usize {
|
|
||||||
self.inner.local_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_active_len(&self) -> usize {
|
|
||||||
self.inner.remote_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_recv_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_send_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.recv_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.send_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_send_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_send_open(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_recv_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_recv_open(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Proxy.
|
|
||||||
impl<T: ControlPing> ControlPing for FlowControl<T> {
|
|
||||||
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError> {
|
|
||||||
self.inner.start_ping(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_pong(&mut self) -> Option<PingPayload> {
|
|
||||||
self.inner.take_pong()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
302
src/proto/ifaces.rs
Normal file
302
src/proto/ifaces.rs
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
use ConnectionError;
|
||||||
|
use frame::SettingSet;
|
||||||
|
use proto::*;
|
||||||
|
|
||||||
|
/// Exposes settings to "upper" layers of the transport (i.e. from Settings up to---and
|
||||||
|
/// above---Connection).
|
||||||
|
pub trait ControlSettings {
|
||||||
|
fn update_local_settings(&mut self, set: SettingSet) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
|
fn remote_push_enabled(&self) -> Option<bool>;
|
||||||
|
fn remote_max_concurrent_streams(&self) -> Option<u32>;
|
||||||
|
fn remote_initial_window_size(&self) -> WindowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// macro_rules! proxy_control_settings {
|
||||||
|
// ($outer:ident) => (
|
||||||
|
// impl<T: ControlSettings> ControlSettings for $outer<T> {
|
||||||
|
// fn update_local_settings(&mut self, set: SettingSet) -> Result<(), ConnectionError> {
|
||||||
|
// self.inner.update_local_settings(set)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn remote_push_enabled(&self) -> Option<bool> {
|
||||||
|
// self.inner.remote_push_enabled(set)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn remote_max_concurrent_streams(&self) -> Option<u32> {
|
||||||
|
// self.inner.remote_max_concurrent_streams(set)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn remote_initial_window_size(&self) -> WindowSize {
|
||||||
|
// self.inner.remote_initial_window_size(set)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
|
/// Allows settings updates to be pushed "down" the transport (i.e. from Settings down to
|
||||||
|
/// FramedWrite).
|
||||||
|
pub trait ApplySettings {
|
||||||
|
fn apply_local_settings(&mut self, set: &SettingSet) -> Result<(), ConnectionError>;
|
||||||
|
fn apply_remote_settings(&mut self, set: &SettingSet) -> Result<(), ConnectionError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! proxy_apply_settings {
|
||||||
|
($outer:ident) => (
|
||||||
|
impl<T: ApplySettings> ApplySettings for $outer<T> {
|
||||||
|
fn apply_local_settings(&mut self, set: &frame::SettingSet) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.apply_local_settings(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_remote_settings(&mut self, set: &frame::SettingSet) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.apply_remote_settings(set)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Exposes flow control states to "upper" layers of the transport (i.e. above
|
||||||
|
/// FlowControl).
|
||||||
|
pub trait ControlFlow {
|
||||||
|
/// Polls for the next window update from the remote.
|
||||||
|
fn poll_window_update(&mut self) -> Poll<WindowUpdate, ConnectionError>;
|
||||||
|
|
||||||
|
/// Increases the local receive capacity of a stream.
|
||||||
|
///
|
||||||
|
/// This may cause a window update to be sent to the remote.
|
||||||
|
///
|
||||||
|
/// Fails if the given stream is not active.
|
||||||
|
fn expand_window(&mut self, id: StreamId, incr: WindowSize) -> Result<(), ConnectionError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! proxy_control_flow {
|
||||||
|
($outer:ident) => (
|
||||||
|
impl<T: ControlFlow> ControlFlow for $outer<T> {
|
||||||
|
fn poll_window_update(&mut self) -> Poll<WindowUpdate, ConnectionError> {
|
||||||
|
self.inner.poll_window_update()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expand_window(&mut self, id: StreamId, incr: WindowSize) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.expand_window(id, incr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Exposes stream states to "upper" layers of the transport (i.e. from StreamTracker up
|
||||||
|
/// to Connection).
|
||||||
|
pub trait ControlStreams {
|
||||||
|
/// Determines whether the given stream could theoretically be opened by the local
|
||||||
|
/// side of this connection.
|
||||||
|
fn local_valid_id(id: StreamId) -> bool;
|
||||||
|
|
||||||
|
/// Determines whether the given stream could theoretically be opened by the remote
|
||||||
|
/// side of this connection.
|
||||||
|
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;
|
||||||
|
|
||||||
|
/// Indicates whether this remote endpoint may open streams (with HEADERS).
|
||||||
|
///
|
||||||
|
/// Implies that this endpoint is a server.
|
||||||
|
fn remote_can_open() -> bool {
|
||||||
|
!Self::local_can_open()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates 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>;
|
||||||
|
|
||||||
|
/// 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>;
|
||||||
|
|
||||||
|
/// 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>;
|
||||||
|
|
||||||
|
// TODO push promise
|
||||||
|
// fn local_reserve(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
|
// fn remote_reserve(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
|
/// Closes the send half of a stream.
|
||||||
|
///
|
||||||
|
/// Fails with a ProtocolError if send half of the stream was not open.
|
||||||
|
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
|
/// Closes the recv half of a stream.
|
||||||
|
///
|
||||||
|
/// Fails with a ProtocolError if recv half of the stream was not open.
|
||||||
|
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
||||||
|
|
||||||
|
/// Resets the given stream.
|
||||||
|
///
|
||||||
|
/// If the stream was already reset, the stored cause is updated.
|
||||||
|
fn reset_stream(&mut self, id: StreamId, cause: Reason);
|
||||||
|
|
||||||
|
/// Get the reason the stream was reset, if it was reset.
|
||||||
|
fn get_reset(&self, id: StreamId) -> Option<Reason>;
|
||||||
|
|
||||||
|
/// Returns true if the given stream was opened by the local peer and is not yet
|
||||||
|
/// closed.
|
||||||
|
fn is_local_active(&self, id: StreamId) -> bool;
|
||||||
|
|
||||||
|
/// Returns true if the given stream was opened by the remote peer and is not yet
|
||||||
|
/// closed.
|
||||||
|
fn is_remote_active(&self, id: StreamId) -> bool;
|
||||||
|
|
||||||
|
/// Returns true if the given stream was opened and is not yet closed.
|
||||||
|
fn is_active(&self, id: StreamId) -> bool {
|
||||||
|
if Self::local_valid_id(id) {
|
||||||
|
self.is_local_active(id)
|
||||||
|
} else {
|
||||||
|
self.is_remote_active(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of open streams initiated by the local peer.
|
||||||
|
fn local_active_len(&self) -> usize;
|
||||||
|
|
||||||
|
/// Returns the number of open streams initiated by the remote peer.
|
||||||
|
fn remote_active_len(&self) -> usize;
|
||||||
|
|
||||||
|
/// Returns true iff the recv half of the given stream is open.
|
||||||
|
fn is_recv_open(&mut self, id: StreamId) -> bool;
|
||||||
|
|
||||||
|
/// Returns true iff the send half of the given stream is open.
|
||||||
|
fn is_send_open(&mut self, id: StreamId) -> bool;
|
||||||
|
|
||||||
|
/// If the given stream ID is active and able to recv data, get its mutable recv flow
|
||||||
|
/// control state.
|
||||||
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState>;
|
||||||
|
|
||||||
|
/// If the given stream ID is active and able to send data, get its mutable send flow
|
||||||
|
/// control state.
|
||||||
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState>;
|
||||||
|
|
||||||
|
/// Updates the initial window size for the local peer.
|
||||||
|
fn update_inital_recv_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize);
|
||||||
|
|
||||||
|
/// Updates the initial window size for the remote peer.
|
||||||
|
fn update_inital_send_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! proxy_control_streams {
|
||||||
|
($outer:ident) => (
|
||||||
|
impl<T: ControlStreams> ControlStreams for $outer<T> {
|
||||||
|
fn local_valid_id(id: StreamId) -> bool {
|
||||||
|
T::local_valid_id(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remote_valid_id(id: StreamId) -> bool {
|
||||||
|
T::remote_valid_id(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local_can_open() -> bool {
|
||||||
|
T::local_can_open()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.local_open(id, sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
||||||
|
self.inner.remote_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 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) {
|
||||||
|
self.inner.reset_stream(id, cause)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_reset(&self, id: StreamId) -> Option<Reason> {
|
||||||
|
self.inner.get_reset(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_local_active(&self, id: StreamId) -> bool {
|
||||||
|
self.inner.is_local_active(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_remote_active(&self, id: StreamId) -> bool {
|
||||||
|
self.inner.is_remote_active(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local_active_len(&self) -> usize {
|
||||||
|
self.inner.local_active_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remote_active_len(&self) -> usize {
|
||||||
|
self.inner.remote_active_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_inital_recv_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
||||||
|
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_inital_send_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
||||||
|
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
|
self.inner.recv_flow_controller(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
||||||
|
self.inner.send_flow_controller(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_send_open(&mut self, id: StreamId) -> bool {
|
||||||
|
self.inner.is_send_open(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_recv_open(&mut self, id: StreamId) -> bool {
|
||||||
|
self.inner.is_recv_open(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ControlPing {
|
||||||
|
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError>;
|
||||||
|
fn take_pong(&mut self) -> Option<PingPayload>;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! proxy_control_ping {
|
||||||
|
($outer:ident) => (
|
||||||
|
impl<T: ControlPing> ControlPing for $outer<T> {
|
||||||
|
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError> {
|
||||||
|
self.inner.start_ping(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn take_pong(&mut self) -> Option<PingPayload> {
|
||||||
|
self.inner.take_pong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -7,6 +7,10 @@ use futures::*;
|
|||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use tokio_io::codec::length_delimited;
|
use tokio_io::codec::length_delimited;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod ifaces;
|
||||||
|
use self::ifaces::*;
|
||||||
|
|
||||||
mod connection;
|
mod connection;
|
||||||
mod flow_control;
|
mod flow_control;
|
||||||
mod flow_control_state;
|
mod flow_control_state;
|
||||||
@@ -24,18 +28,18 @@ mod stream_store;
|
|||||||
|
|
||||||
pub use self::connection::Connection;
|
pub use self::connection::Connection;
|
||||||
|
|
||||||
use self::flow_control::{ControlFlow, FlowControl};
|
use self::flow_control::{FlowControl};
|
||||||
use self::flow_control_state::{FlowControlState};
|
use self::flow_control_state::{FlowControlState};
|
||||||
use self::framed_read::FramedRead;
|
use self::framed_read::FramedRead;
|
||||||
use self::framed_write::FramedWrite;
|
use self::framed_write::FramedWrite;
|
||||||
use self::ping_pong::{ControlPing, PingPayload, PingPong};
|
use self::ping_pong::{PingPong};
|
||||||
use self::ready::ReadySink;
|
use self::ready::ReadySink;
|
||||||
use self::settings::{ApplySettings, ControlSettings, Settings};
|
use self::settings::Settings;
|
||||||
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;
|
||||||
use self::stream_send_open::StreamSendOpen;
|
use self::stream_send_open::StreamSendOpen;
|
||||||
use self::stream_store::{ControlStreams, StreamStore};
|
use self::stream_store::StreamStore;
|
||||||
|
|
||||||
/// Represents the internals of an HTTP/2 connection.
|
/// Represents the internals of an HTTP/2 connection.
|
||||||
///
|
///
|
||||||
@@ -140,6 +144,8 @@ type Codec<T, B> =
|
|||||||
FramedRead<
|
FramedRead<
|
||||||
FramedWrite<T, B>>;
|
FramedWrite<T, B>>;
|
||||||
|
|
||||||
|
pub type PingPayload = [u8; 8];
|
||||||
|
|
||||||
pub type WindowSize = u32;
|
pub type WindowSize = u32;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
use ConnectionError;
|
use ConnectionError;
|
||||||
use frame::{Frame, Ping, SettingSet};
|
use frame::{Frame, Ping, SettingSet};
|
||||||
use proto::{ApplySettings, ReadySink};
|
use proto::*;
|
||||||
|
|
||||||
use futures::*;
|
|
||||||
|
|
||||||
pub type PingPayload = [u8; 8];
|
|
||||||
|
|
||||||
pub trait ControlPing {
|
|
||||||
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError>;
|
|
||||||
fn take_pong(&mut self) -> Option<PingPayload>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Acknowledges ping requests from the remote.
|
/// Acknowledges ping requests from the remote.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -7,23 +7,6 @@ use bytes::BufMut;
|
|||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
/// Exposes settings to "upper" layers of the transport (i.e. from Settings up to---and
|
|
||||||
/// above---Connection).
|
|
||||||
pub trait ControlSettings {
|
|
||||||
fn update_local_settings(&mut self, set: frame::SettingSet) -> Result<(), ConnectionError>;
|
|
||||||
|
|
||||||
fn remote_push_enabled(&self) -> Option<bool>;
|
|
||||||
fn remote_max_concurrent_streams(&self) -> Option<u32>;
|
|
||||||
fn remote_initial_window_size(&self) -> WindowSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Allows settings updates to be pushed "down" the transport (i.e. from Settings down to
|
|
||||||
/// FramedWrite).
|
|
||||||
pub trait ApplySettings {
|
|
||||||
fn apply_local_settings(&mut self, set: &frame::SettingSet) -> Result<(), ConnectionError>;
|
|
||||||
fn apply_remote_settings(&mut self, set: &frame::SettingSet) -> Result<(), ConnectionError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Settings<T> {
|
pub struct Settings<T> {
|
||||||
// Upstream transport
|
// Upstream transport
|
||||||
@@ -241,12 +224,4 @@ impl<T: ControlFlow> ControlFlow for Settings<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ControlPing> ControlPing for Settings<T> {
|
proxy_control_ping!(Settings);
|
||||||
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError> {
|
|
||||||
self.inner.start_ping(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_pong(&mut self) -> Option<PingPayload> {
|
|
||||||
self.inner.take_pong()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -79,122 +79,7 @@ impl<T, U> ReadySink for StreamRecvClose<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proxy.
|
proxy_apply_settings!(StreamRecvClose);
|
||||||
impl<T: ControlStreams> ControlStreams for StreamRecvClose<T> {
|
proxy_control_flow!(StreamRecvClose);
|
||||||
fn local_valid_id(id: StreamId) -> bool {
|
proxy_control_streams!(StreamRecvClose);
|
||||||
T::local_valid_id(id)
|
proxy_control_ping!(StreamRecvClose);
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_valid_id(id: StreamId) -> bool {
|
|
||||||
T::remote_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_can_open() -> bool {
|
|
||||||
T::local_can_open()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.local_open(id, sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.remote_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 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) {
|
|
||||||
self.inner.reset_stream(id, cause)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_reset(&self, id: StreamId) -> Option<Reason> {
|
|
||||||
self.inner.get_reset(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_local_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_local_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_remote_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_remote_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_active_len(&self) -> usize {
|
|
||||||
self.inner.local_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_active_len(&self) -> usize {
|
|
||||||
self.inner.remote_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_recv_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_send_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.recv_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.send_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_send_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_send_open(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_recv_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_recv_open(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proxy.
|
|
||||||
impl<T: ApplySettings> ApplySettings for StreamRecvClose<T> {
|
|
||||||
fn apply_local_settings(&mut self, set: &frame::SettingSet) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.apply_local_settings(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_remote_settings(&mut self, set: &frame::SettingSet) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.apply_remote_settings(set)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proxy.
|
|
||||||
impl<T: ControlFlow> ControlFlow for StreamRecvClose<T> {
|
|
||||||
fn poll_window_update(&mut self) -> Poll<WindowUpdate, ConnectionError> {
|
|
||||||
self.inner.poll_window_update()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expand_window(&mut self, id: StreamId, incr: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.expand_window(id, incr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proxy.
|
|
||||||
impl<T: ControlPing> ControlPing for StreamRecvClose<T> {
|
|
||||||
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError> {
|
|
||||||
self.inner.start_ping(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_pong(&mut self) -> Option<PingPayload> {
|
|
||||||
self.inner.take_pong()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -212,100 +212,6 @@ impl<T, U> ReadySink for StreamRecvOpen<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Proxy.
|
proxy_control_flow!(StreamRecvOpen);
|
||||||
impl<T: ControlStreams> ControlStreams for StreamRecvOpen<T> {
|
proxy_control_streams!(StreamRecvOpen);
|
||||||
fn local_valid_id(id: StreamId) -> bool {
|
proxy_control_ping!(StreamRecvOpen);
|
||||||
T::local_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_valid_id(id: StreamId) -> bool {
|
|
||||||
T::remote_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_can_open() -> bool {
|
|
||||||
T::local_can_open()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.local_open(id, sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.remote_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 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) {
|
|
||||||
self.inner.reset_stream(id, cause)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_reset(&self, id: StreamId) -> Option<Reason> {
|
|
||||||
self.inner.get_reset(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_local_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_local_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_remote_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_remote_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_active_len(&self) -> usize {
|
|
||||||
self.inner.local_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_active_len(&self) -> usize {
|
|
||||||
self.inner.remote_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_recv_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_send_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.recv_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.send_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_send_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_send_open(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_recv_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_recv_open(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Proxy.
|
|
||||||
impl<T: ControlPing> ControlPing for StreamRecvOpen<T> {
|
|
||||||
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError> {
|
|
||||||
self.inner.start_ping(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_pong(&mut self) -> Option<PingPayload> {
|
|
||||||
self.inner.take_pong()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -74,111 +74,7 @@ impl<T, U> ReadySink for StreamSendClose<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Proxy.
|
proxy_apply_settings!(StreamSendClose);
|
||||||
impl<T: ApplySettings> ApplySettings for StreamSendClose<T> {
|
proxy_control_flow!(StreamSendClose);
|
||||||
fn apply_local_settings(&mut self, set: &frame::SettingSet) -> Result<(), ConnectionError> {
|
proxy_control_streams!(StreamSendClose);
|
||||||
self.inner.apply_local_settings(set)
|
proxy_control_ping!(StreamSendClose);
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_remote_settings(&mut self, set: &frame::SettingSet) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.apply_remote_settings(set)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Proxy.
|
|
||||||
impl<T: ControlStreams> ControlStreams for StreamSendClose<T> {
|
|
||||||
fn local_valid_id(id: StreamId) -> bool {
|
|
||||||
T::local_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_valid_id(id: StreamId) -> bool {
|
|
||||||
T::remote_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_can_open() -> bool {
|
|
||||||
T::local_can_open()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.local_open(id, sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.remote_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 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) {
|
|
||||||
self.inner.reset_stream(id, cause)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_reset(&self, id: StreamId) -> Option<Reason> {
|
|
||||||
self.inner.get_reset(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_local_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_local_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_remote_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_remote_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_active_len(&self) -> usize {
|
|
||||||
self.inner.local_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_active_len(&self) -> usize {
|
|
||||||
self.inner.remote_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_recv_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_send_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.recv_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.send_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_send_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_send_open(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_recv_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_recv_open(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Proxy.
|
|
||||||
impl<T: ControlPing> ControlPing for StreamSendClose<T> {
|
|
||||||
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError> {
|
|
||||||
self.inner.start_ping(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_pong(&mut self) -> Option<PingPayload> {
|
|
||||||
self.inner.take_pong()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -156,111 +156,6 @@ impl<T, U> ReadySink for StreamSendOpen<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Proxy.
|
proxy_control_flow!(StreamSendOpen);
|
||||||
impl<T: ControlStreams> ControlStreams for StreamSendOpen<T> {
|
proxy_control_streams!(StreamSendOpen);
|
||||||
fn local_valid_id(id: StreamId) -> bool {
|
proxy_control_ping!(StreamSendOpen);
|
||||||
T::local_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_valid_id(id: StreamId) -> bool {
|
|
||||||
T::remote_valid_id(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_can_open() -> bool {
|
|
||||||
T::local_can_open()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.local_open(id, sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_open(&mut self, id: StreamId, sz: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.remote_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 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) {
|
|
||||||
self.inner.reset_stream(id, cause)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_reset(&self, id: StreamId) -> Option<Reason> {
|
|
||||||
self.inner.get_reset(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_local_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_local_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_remote_active(&self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_remote_active(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn local_active_len(&self) -> usize {
|
|
||||||
self.inner.local_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remote_active_len(&self) -> usize {
|
|
||||||
self.inner.remote_active_len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_recv_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_recv_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_inital_send_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize) {
|
|
||||||
self.inner.update_inital_send_window_size(old_sz, new_sz)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.recv_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState> {
|
|
||||||
self.inner.send_flow_controller(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_send_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_send_open(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_recv_open(&mut self, id: StreamId) -> bool {
|
|
||||||
self.inner.is_recv_open(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Proxy.
|
|
||||||
impl<T: ControlFlow> ControlFlow for StreamSendOpen<T> {
|
|
||||||
fn poll_window_update(&mut self) -> Poll<WindowUpdate, ConnectionError> {
|
|
||||||
self.inner.poll_window_update()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expand_window(&mut self, id: StreamId, incr: WindowSize) -> Result<(), ConnectionError> {
|
|
||||||
self.inner.expand_window(id, incr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Proxy.
|
|
||||||
impl<T: ControlPing> ControlPing for StreamSendOpen<T> {
|
|
||||||
fn start_ping(&mut self, body: PingPayload) -> StartSend<PingPayload, ConnectionError> {
|
|
||||||
self.inner.start_ping(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_pong(&mut self) -> Option<PingPayload> {
|
|
||||||
self.inner.take_pong()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,115 +8,6 @@ use ordermap::OrderMap;
|
|||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
/// Exposes stream states to "upper" layers of the transport (i.e. from StreamTracker up
|
|
||||||
/// to Connection).
|
|
||||||
pub trait ControlStreams {
|
|
||||||
/// Determines whether the given stream could theoretically be opened by the local
|
|
||||||
/// side of this connection.
|
|
||||||
fn local_valid_id(id: StreamId) -> bool;
|
|
||||||
|
|
||||||
/// Determines whether the given stream could theoretically be opened by the remote
|
|
||||||
/// side of this connection.
|
|
||||||
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;
|
|
||||||
|
|
||||||
/// Indicates whether this remote endpoint may open streams (with HEADERS).
|
|
||||||
///
|
|
||||||
/// Implies that this endpoint is a server.
|
|
||||||
fn remote_can_open() -> bool {
|
|
||||||
!Self::local_can_open()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates 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>;
|
|
||||||
|
|
||||||
/// 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>;
|
|
||||||
|
|
||||||
/// 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>;
|
|
||||||
|
|
||||||
// TODO push promise
|
|
||||||
// fn local_reserve(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
|
||||||
// fn remote_reserve(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
|
||||||
|
|
||||||
/// Closes the send half of a stream.
|
|
||||||
///
|
|
||||||
/// Fails with a ProtocolError if send half of the stream was not open.
|
|
||||||
fn close_send_half(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
|
||||||
|
|
||||||
/// Closes the recv half of a stream.
|
|
||||||
///
|
|
||||||
/// Fails with a ProtocolError if recv half of the stream was not open.
|
|
||||||
fn close_recv_half(&mut self, id: StreamId) -> Result<(), ConnectionError>;
|
|
||||||
|
|
||||||
/// Resets the given stream.
|
|
||||||
///
|
|
||||||
/// If the stream was already reset, the stored cause is updated.
|
|
||||||
fn reset_stream(&mut self, id: StreamId, cause: Reason);
|
|
||||||
|
|
||||||
/// Get the reason the stream was reset, if it was reset.
|
|
||||||
fn get_reset(&self, id: StreamId) -> Option<Reason>;
|
|
||||||
|
|
||||||
/// Returns true if the given stream was opened by the local peer and is not yet
|
|
||||||
/// closed.
|
|
||||||
fn is_local_active(&self, id: StreamId) -> bool;
|
|
||||||
|
|
||||||
/// Returns true if the given stream was opened by the remote peer and is not yet
|
|
||||||
/// closed.
|
|
||||||
fn is_remote_active(&self, id: StreamId) -> bool;
|
|
||||||
|
|
||||||
/// Returns true if the given stream was opened and is not yet closed.
|
|
||||||
fn is_active(&self, id: StreamId) -> bool {
|
|
||||||
if Self::local_valid_id(id) {
|
|
||||||
self.is_local_active(id)
|
|
||||||
} else {
|
|
||||||
self.is_remote_active(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the number of open streams initiated by the local peer.
|
|
||||||
fn local_active_len(&self) -> usize;
|
|
||||||
|
|
||||||
/// Returns the number of open streams initiated by the remote peer.
|
|
||||||
fn remote_active_len(&self) -> usize;
|
|
||||||
|
|
||||||
/// Returns true iff the recv half of the given stream is open.
|
|
||||||
fn is_recv_open(&mut self, id: StreamId) -> bool;
|
|
||||||
|
|
||||||
/// Returns true iff the send half of the given stream is open.
|
|
||||||
fn is_send_open(&mut self, id: StreamId) -> bool;
|
|
||||||
|
|
||||||
/// If the given stream ID is active and able to recv data, get its mutable recv flow
|
|
||||||
/// control state.
|
|
||||||
fn recv_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState>;
|
|
||||||
|
|
||||||
/// If the given stream ID is active and able to send data, get its mutable send flow
|
|
||||||
/// control state.
|
|
||||||
fn send_flow_controller(&mut self, id: StreamId) -> Option<&mut FlowControlState>;
|
|
||||||
|
|
||||||
/// Updates the initial window size for the local peer.
|
|
||||||
fn update_inital_recv_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize);
|
|
||||||
|
|
||||||
/// Updates the initial window size for the remote peer.
|
|
||||||
fn update_inital_send_window_size(&mut self, old_sz: WindowSize, new_sz: WindowSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Holds the underlying stream state to be accessed by upper layers.
|
/// Holds the underlying stream state to be accessed by upper layers.
|
||||||
// TODO track reserved streams
|
// TODO track reserved streams
|
||||||
// TODO constrain the size of `reset`
|
// TODO constrain the size of `reset`
|
||||||
|
|||||||
Reference in New Issue
Block a user