diff --git a/src/client.rs b/src/client.rs index fd2ec71..fb57f47 100644 --- a/src/client.rs +++ b/src/client.rs @@ -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, + /// 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(my_io: T) + /// # -> Handshake + /// # { + /// // `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))) } } diff --git a/src/server.rs b/src/server.rs index e1be793..9a0e718 100644 --- a/src/server.rs +++ b/src/server.rs @@ -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, } /// Send a response back to the client @@ -361,7 +364,6 @@ impl Connection where T: AsyncRead + AsyncWrite, B: IntoBuf, - B::Buf: 'static, { fn handshake2(io: T, builder: Builder) -> Handshake { // 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(my_io: T) + /// # -> Handshake + /// # { + /// // `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 Future for Handshake 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) }