Add initial_connection_window_size to Builders (#249)

There is currently no way to configure the initial target window size
for connections. The `Builder::initial_connection_window_size` utilities
make this configurable so that all new connections have this target
window size set.
This commit is contained in:
Oliver Gould
2018-03-28 14:46:56 -07:00
committed by GitHub
parent 430d28723f
commit 01d81b46c2
2 changed files with 94 additions and 7 deletions

View File

@@ -351,6 +351,9 @@ pub struct Builder {
/// MAX_CONCURRENT_STREAMS specified in the frame.
initial_max_send_streams: usize,
/// Initial target window size for new connections.
initial_target_connection_window_size: Option<u32>,
/// Maximum number of locally reset streams to keep at a time.
reset_stream_max: usize,
@@ -678,6 +681,7 @@ impl Builder {
Builder {
reset_stream_duration: Duration::from_secs(proto::DEFAULT_RESET_STREAM_SECS),
reset_stream_max: proto::DEFAULT_RESET_STREAM_MAX,
initial_target_connection_window_size: None,
initial_max_send_streams: usize::MAX,
settings: Default::default(),
stream_id: 1.into(),
@@ -720,6 +724,42 @@ impl Builder {
self
}
/// Indicates the initial window size (in octets) for connection-level flow control
/// for received data.
///
/// The initial window of a connection is used as part of flow control. For more details,
/// see [`ReleaseCapacity`].
///
/// The default value is 65,535.
///
/// [`ReleaseCapacity`]: ../struct.ReleaseCapacity.html
///
/// # Examples
///
/// ```
/// # extern crate h2;
/// # extern crate tokio_io;
/// # use tokio_io::*;
/// # use h2::client::*;
/// #
/// # fn doc<T: AsyncRead + AsyncWrite>(my_io: T)
/// # -> Handshake<T>
/// # {
/// // `client_fut` is a future representing the completion of the HTTP/2.0
/// // handshake.
/// let client_fut = Builder::new()
/// .initial_connection_window_size(1_000_000)
/// .handshake(my_io);
/// # client_fut
/// # }
/// #
/// # pub fn main() {}
/// ```
pub fn initial_connection_window_size(&mut self, size: u32) -> &mut Self {
self.initial_target_connection_window_size = Some(size);
self
}
/// Indicates the size (in octets) of the largest HTTP/2.0 frame payload that the
/// configured client is able to accept.
///
@@ -1266,7 +1306,7 @@ where
.buffer(self.builder.settings.clone().into())
.expect("invalid SETTINGS frame");
let connection = proto::Connection::new(codec, proto::Config {
let inner = proto::Connection::new(codec, proto::Config {
next_stream_id: self.builder.stream_id,
initial_max_send_streams: self.builder.initial_max_send_streams,
reset_stream_duration: self.builder.reset_stream_duration,
@@ -1274,12 +1314,15 @@ where
settings: self.builder.settings.clone(),
});
let send_request = SendRequest {
inner: connection.streams().clone(),
inner: inner.streams().clone(),
pending: None,
};
let connection = Connection {
inner: connection,
};
let mut connection = Connection { inner };
if let Some(sz) = self.builder.initial_target_connection_window_size {
connection.set_target_window_size(sz);
}
Ok(Async::Ready((send_request, connection)))
}
}

View File

@@ -261,6 +261,9 @@ pub struct Builder {
/// Initial `Settings` frame to send as part of the handshake.
settings: Settings,
/// Initial target window size for new connections.
initial_target_connection_window_size: Option<u32>,
}
/// Send a response back to the client
@@ -361,7 +364,6 @@ impl<T, B> Connection<T, B>
where
T: AsyncRead + AsyncWrite,
B: IntoBuf,
B::Buf: 'static,
{
fn handshake2(io: T, builder: Builder) -> Handshake<T, B> {
// Create the codec.
@@ -518,6 +520,7 @@ impl Builder {
reset_stream_duration: Duration::from_secs(proto::DEFAULT_RESET_STREAM_SECS),
reset_stream_max: proto::DEFAULT_RESET_STREAM_MAX,
settings: Settings::default(),
initial_target_connection_window_size: None,
}
}
@@ -557,6 +560,42 @@ impl Builder {
self
}
/// Indicates the initial window size (in octets) for connection-level flow control
/// for received data.
///
/// The initial window of a connection is used as part of flow control. For more details,
/// see [`ReleaseCapacity`].
///
/// The default value is 65,535.
///
/// [`ReleaseCapacity`]: ../struct.ReleaseCapacity.html
///
/// # Examples
///
/// ```
/// # extern crate h2;
/// # extern crate tokio_io;
/// # use tokio_io::*;
/// # use h2::server::*;
/// #
/// # fn doc<T: AsyncRead + AsyncWrite>(my_io: T)
/// # -> Handshake<T>
/// # {
/// // `server_fut` is a future representing the completion of the HTTP/2.0
/// // handshake.
/// let server_fut = Builder::new()
/// .initial_connection_window_size(1_000_000)
/// .handshake(my_io);
/// # server_fut
/// # }
/// #
/// # pub fn main() {}
/// ```
pub fn initial_connection_window_size(&mut self, size: u32) -> &mut Self {
self.initial_target_connection_window_size = Some(size);
self
}
/// Indicates the size (in octets) of the largest HTTP/2.0 frame payload that the
/// configured server is able to accept.
///
@@ -1032,8 +1071,13 @@ impl<T, B: IntoBuf> Future for Handshake<T, B>
reset_stream_max: self.builder.reset_stream_max,
settings: self.builder.settings.clone(),
});
trace!("Handshake::poll(); connection established!");
Connection { connection }
let mut c = Connection { connection };
if let Some(sz) = self.builder.initial_target_connection_window_size {
c.set_target_window_size(sz);
}
c
});
Ok(server)
}