diff --git a/src/server.rs b/src/server.rs index cbcf8e7..3dd3692 100644 --- a/src/server.rs +++ b/src/server.rs @@ -265,7 +265,7 @@ pub struct Builder { /// stream. This is [not yet /// implemented](https://github.com/carllerche/h2/issues/185). /// -/// If the `Response` instance is dropped without sending a response, then the +/// If the `Respond` instance is dropped without sending a response, then the /// HTTP/2.0 stream will be reset. /// /// See [module] level docs for more details. @@ -433,11 +433,13 @@ where /// they will be queued and returned on the next call to [`poll`]. /// /// This function will advance the internal connection state, driving - /// progress on all the other handles (e.g. `RecvStream` and `SendStream`). + /// progress on all the other handles (e.g. [`RecvStream`] and [`SendStream`]). /// /// See [here](index.html#managing-the-connection) for more details. /// /// [`poll`]: struct.Server.html#method.poll + /// [`RecvStream`]: ../struct.RecvStream.html + /// [`SendStream`]: ../struct.SendStream.html pub fn poll_close(&mut self) -> Poll<(), ::Error> { self.connection.poll().map_err(Into::into) } @@ -799,7 +801,22 @@ impl Default for Builder { // ===== impl Respond ===== impl Respond { - /// Send a response + /// Send a response to a client request. + /// + /// On success, a [`SendStream`] instance is returned. This instance can be + /// used to stream the response body and send trailers. + /// + /// If a body or trailers will be sent on the returned [`SendStream`] + /// instance, then `end_of_stream` must be set to `true` when calling this + /// function. + /// + /// The [`Respond`] instance is already associated with a received request. + /// This function may only be called once per instance and only if + /// [`send_reset`] has not been previously called. + /// + /// [`Respond`]: # + /// [`SendStream`]: ../struct.SendStream.html + /// [`send_reset`]: #method.send_reset pub fn send_response( &mut self, response: Response<()>, @@ -811,7 +828,21 @@ impl Respond { .map_err(Into::into) } - /// Reset the stream + /// Send a stream reset to the peer. + /// + /// This essentially cancels the stream, including any inbound or outbound + /// data streams. + /// + /// If this function is called before [`send_response`], a call to + /// [`send_response`] will result in an error. + /// + /// If this function is called while a [`SendStream`] instance is active, + /// any further use of the instance will result in an error. + /// + /// This function should only be called once. + /// + /// [`send_response`]: #method.send_response + /// [`SendStream`]: ../struct.SendStream.html pub fn send_reset(&mut self, reason: Reason) { self.inner.send_reset(reason) } @@ -1077,9 +1108,8 @@ impl proto::Peer for Peer { } } - - // ===== impl Handshaking ===== + impl fmt::Debug for Handshaking where B: IntoBuf diff --git a/src/share.rs b/src/share.rs index 155d6e3..b85657c 100644 --- a/src/share.rs +++ b/src/share.rs @@ -8,19 +8,70 @@ use http::{HeaderMap}; use std::fmt; -/// Send frames to a remote. +/// Send the body stream and trailers to the peer. #[derive(Debug)] pub struct SendStream { inner: proto::StreamRef, } -/// Receive frames from a remote. +/// Receive the body stream and trailers from the peer. #[must_use = "streams do nothing unless polled"] pub struct RecvStream { inner: ReleaseCapacity, } /// A handle to release window capacity to a remote stream. +/// +/// This type allows the caller to manage inbound data [flow control]. The +/// caller is expected to call [`release_capacity`] after dropping data frames. +/// +/// # Overview +/// +/// Each stream has a window size. This window size is the maximum amount of +/// inbound data that can be in-flight. In-flight data is defined as data that +/// has been received, but not yet released. +/// +/// When a stream is created, the window size is set to the connection's initial +/// window size value. When a data frame is received, the window size is then +/// decremented by size of the data frame before the data is provided to the +/// caller. As the caller finishes using the data, [`release_capacity`] must be +/// called. This will then increment the window size again, allowing the peer to +/// send more data. +/// +/// There is also a connection level window as well as the stream level window. +/// Received data counts against the connection level window as well and calls +/// to [`release_capacity`] will also increment the connection level window. +/// +/// # Sending `WINDOW_UPDATE` frames +/// +/// `WINDOW_UPDATE` frames will not be sent out for **every** call to +/// `release_capacity`, as this would end up slowing down the protocol. Instead, +/// `h2` waits until the window size is increased to a certain threshold and +/// then sends out a single `WINDOW_UPDATE` frame representing all the calls to +/// `release_capacity` since the last `WINDOW_UPDATE` frame. +/// +/// This essentially batches window updating. +/// +/// # Scenarios +/// +/// Following is a basic scenario with an HTTP/2.0 connection containing a +/// single active stream. +/// +/// * A new stream is activated. The receive window is initialized to 1024 (the +/// value of the initial window size for this connection). +/// * A `DATA` frame is received containing a payload of 400 bytes. +/// * The receive window size is reduced to 424 bytes. +/// * [`release_capacity`] is called with 200. +/// * The receive window size is now 624 bytes. The peer may send no more than +/// this. +/// * A `DATA` frame is received with a payload of 624 bytes. +/// * The window size is now 0 bytes. The peer may not send any more data. +/// * [`release_capacity`] is called with 1024. +/// * The receive window size is now 1024 bytes. The peer may now send more +/// data. +/// +/// [flow control]: ../index.html#flow-control +/// [`release_capacity`]: struct.ReleaseCapacity.html#method.release_capacity #[derive(Debug)] pub struct ReleaseCapacity { inner: proto::OpaqueStreamRef, @@ -97,7 +148,7 @@ impl RecvStream { &mut self.inner } - /// Poll trailers + /// Returns received trailers. /// /// This function **must** not be called until `Body::poll` returns `None`. pub fn poll_trailers(&mut self) -> Poll, ::Error> { @@ -130,6 +181,22 @@ impl ReleaseCapacity { } /// Release window capacity back to remote stream. + /// + /// This releases capacity back to the stream level and the connection level + /// windows. Both window sizes will be increased by `sz`. + /// + /// See [struct level] documentation for more details. + /// + /// # Panics + /// + /// This function panics if increasing the receive window size by `sz` would + /// result in a window size greater than the target window size set by + /// [`set_target_window_size`]. In other words, the caller cannot release + /// more capacity than data has been received. If 1024 bytes of data have + /// been received, at most 1024 bytes can be released. + /// + /// [struct level]: # + /// [`set_target_window_size`]: server/struct.Server.html#method.set_target_window_size pub fn release_capacity(&mut self, sz: usize) -> Result<(), ::Error> { if sz > proto::MAX_WINDOW_SIZE as usize { return Err(UserError::ReleaseCapacityTooBig.into());