add Client config to disable server push

- Adds `Client::builder().enable_push(false)` to disable push
- Client sends a GO_AWAY if receiving a push when it's disabled
This commit is contained in:
Sean McArthur
2017-09-14 15:16:16 -07:00
parent ed4e67c1a4
commit a8a4cd2be1
13 changed files with 406 additions and 62 deletions

View File

@@ -64,12 +64,13 @@ where
) -> Connection<T, P, B> {
// TODO: Actually configure
let streams = Streams::new(streams::Config {
max_remote_initiated: None,
init_remote_window_sz: DEFAULT_INITIAL_WINDOW_SIZE,
max_local_initiated: None,
init_local_window_sz: settings
local_init_window_sz: settings
.initial_window_size()
.unwrap_or(DEFAULT_INITIAL_WINDOW_SIZE),
local_max_initiated: None,
local_push_enabled: settings.is_push_enabled(),
remote_init_window_sz: DEFAULT_INITIAL_WINDOW_SIZE,
remote_max_initiated: None,
});
Connection {
state: State::Open,

View File

@@ -34,9 +34,9 @@ where
/// Create a new `Counts` using the provided configuration values.
pub fn new(config: &Config) -> Self {
Counts {
max_send_streams: config.max_local_initiated,
max_send_streams: config.local_max_initiated,
num_send_streams: 0,
max_recv_streams: config.max_remote_initiated,
max_recv_streams: config.remote_max_initiated,
num_recv_streams: 0,
blocked_open: None,
_p: PhantomData,

View File

@@ -31,15 +31,18 @@ use http::{Request, Response};
#[derive(Debug)]
pub struct Config {
/// Maximum number of remote initiated streams
pub max_remote_initiated: Option<usize>,
/// Initial window size of remote initiated streams
pub init_remote_window_sz: WindowSize,
/// Initial window size of locally initiated streams
pub local_init_window_sz: WindowSize,
/// Maximum number of locally initiated streams
pub max_local_initiated: Option<usize>,
pub local_max_initiated: Option<usize>,
/// Initial window size of locally initiated streams
pub init_local_window_sz: WindowSize,
/// If the local peer is willing to receive push promises
pub local_push_enabled: bool,
/// Initial window size of remote initiated streams
pub remote_init_window_sz: WindowSize,
/// Maximum number of remote initiated streams
pub remote_max_initiated: Option<usize>,
}

View File

@@ -49,11 +49,11 @@ where
pub fn new(config: &Config) -> Prioritize<B, P> {
let mut flow = FlowControl::new();
flow.inc_window(config.init_local_window_sz)
flow.inc_window(config.local_init_window_sz)
.ok()
.expect("invalid initial window size");
flow.assign_capacity(config.init_local_window_sz);
flow.assign_capacity(config.local_init_window_sz);
trace!("Prioritize::new; flow={:?}", flow);

View File

@@ -38,6 +38,9 @@ where
/// Refused StreamId, this represents a frame that must be sent out.
refused: Option<StreamId>,
/// If push promises are allowed to be recevied.
is_push_enabled: bool,
_p: PhantomData<B>,
}
@@ -71,7 +74,7 @@ where
flow.assign_capacity(DEFAULT_INITIAL_WINDOW_SIZE);
Recv {
init_window_sz: config.init_local_window_sz,
init_window_sz: config.local_init_window_sz,
flow: flow,
next_stream_id: next_stream_id.into(),
pending_window_updates: store::Queue::new(),
@@ -79,6 +82,7 @@ where
pending_accept: store::Queue::new(),
buffer: Buffer::new(),
refused: None,
is_push_enabled: config.local_push_enabled,
_p: PhantomData,
}
}
@@ -429,10 +433,20 @@ where
// TODO: Are there other rules?
if P::is_server() {
// The remote is a client and cannot reserve
trace!("recv_push_promise; error remote is client");
return Err(RecvError::Connection(ProtocolError));
}
if !promised_id.is_server_initiated() {
trace!(
"recv_push_promise; error promised id is invalid {:?}",
promised_id
);
return Err(RecvError::Connection(ProtocolError));
}
if !self.is_push_enabled {
trace!("recv_push_promise; error push is disabled");
return Err(RecvError::Connection(ProtocolError));
}

View File

@@ -35,7 +35,7 @@ where
Send {
next_stream_id: next_stream_id.into(),
init_window_sz: config.init_local_window_sz,
init_window_sz: config.local_init_window_sz,
prioritize: Prioritize::new(config),
}
}

View File

@@ -285,6 +285,7 @@ impl State {
..
} => true,
HalfClosedLocal(AwaitingHeaders) => true,
ReservedRemote => true,
_ => false,
}
}