Add more library API documentation (#190)
This includes a section on inbound data control flow.
This commit is contained in:
@@ -265,7 +265,7 @@ pub struct Builder {
|
|||||||
/// stream. This is [not yet
|
/// stream. This is [not yet
|
||||||
/// implemented](https://github.com/carllerche/h2/issues/185).
|
/// 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.
|
/// HTTP/2.0 stream will be reset.
|
||||||
///
|
///
|
||||||
/// See [module] level docs for more details.
|
/// See [module] level docs for more details.
|
||||||
@@ -433,11 +433,13 @@ where
|
|||||||
/// they will be queued and returned on the next call to [`poll`].
|
/// they will be queued and returned on the next call to [`poll`].
|
||||||
///
|
///
|
||||||
/// This function will advance the internal connection state, driving
|
/// 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.
|
/// See [here](index.html#managing-the-connection) for more details.
|
||||||
///
|
///
|
||||||
/// [`poll`]: struct.Server.html#method.poll
|
/// [`poll`]: struct.Server.html#method.poll
|
||||||
|
/// [`RecvStream`]: ../struct.RecvStream.html
|
||||||
|
/// [`SendStream`]: ../struct.SendStream.html
|
||||||
pub fn poll_close(&mut self) -> Poll<(), ::Error> {
|
pub fn poll_close(&mut self) -> Poll<(), ::Error> {
|
||||||
self.connection.poll().map_err(Into::into)
|
self.connection.poll().map_err(Into::into)
|
||||||
}
|
}
|
||||||
@@ -799,7 +801,22 @@ impl Default for Builder {
|
|||||||
// ===== impl Respond =====
|
// ===== impl Respond =====
|
||||||
|
|
||||||
impl<B: IntoBuf> Respond<B> {
|
impl<B: IntoBuf> Respond<B> {
|
||||||
/// 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(
|
pub fn send_response(
|
||||||
&mut self,
|
&mut self,
|
||||||
response: Response<()>,
|
response: Response<()>,
|
||||||
@@ -811,7 +828,21 @@ impl<B: IntoBuf> Respond<B> {
|
|||||||
.map_err(Into::into)
|
.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) {
|
pub fn send_reset(&mut self, reason: Reason) {
|
||||||
self.inner.send_reset(reason)
|
self.inner.send_reset(reason)
|
||||||
}
|
}
|
||||||
@@ -1077,9 +1108,8 @@ impl proto::Peer for Peer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===== impl Handshaking =====
|
// ===== impl Handshaking =====
|
||||||
|
|
||||||
impl<T, B> fmt::Debug for Handshaking<T, B>
|
impl<T, B> fmt::Debug for Handshaking<T, B>
|
||||||
where
|
where
|
||||||
B: IntoBuf
|
B: IntoBuf
|
||||||
|
|||||||
73
src/share.rs
73
src/share.rs
@@ -8,19 +8,70 @@ use http::{HeaderMap};
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// Send frames to a remote.
|
/// Send the body stream and trailers to the peer.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SendStream<B: IntoBuf> {
|
pub struct SendStream<B: IntoBuf> {
|
||||||
inner: proto::StreamRef<B::Buf>,
|
inner: proto::StreamRef<B::Buf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive frames from a remote.
|
/// Receive the body stream and trailers from the peer.
|
||||||
#[must_use = "streams do nothing unless polled"]
|
#[must_use = "streams do nothing unless polled"]
|
||||||
pub struct RecvStream {
|
pub struct RecvStream {
|
||||||
inner: ReleaseCapacity,
|
inner: ReleaseCapacity,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A handle to release window capacity to a remote stream.
|
/// 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)]
|
#[derive(Debug)]
|
||||||
pub struct ReleaseCapacity {
|
pub struct ReleaseCapacity {
|
||||||
inner: proto::OpaqueStreamRef,
|
inner: proto::OpaqueStreamRef,
|
||||||
@@ -97,7 +148,7 @@ impl RecvStream {
|
|||||||
&mut self.inner
|
&mut self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Poll trailers
|
/// Returns received trailers.
|
||||||
///
|
///
|
||||||
/// This function **must** not be called until `Body::poll` returns `None`.
|
/// This function **must** not be called until `Body::poll` returns `None`.
|
||||||
pub fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, ::Error> {
|
pub fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, ::Error> {
|
||||||
@@ -130,6 +181,22 @@ impl ReleaseCapacity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Release window capacity back to remote stream.
|
/// 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> {
|
pub fn release_capacity(&mut self, sz: usize) -> Result<(), ::Error> {
|
||||||
if sz > proto::MAX_WINDOW_SIZE as usize {
|
if sz > proto::MAX_WINDOW_SIZE as usize {
|
||||||
return Err(UserError::ReleaseCapacityTooBig.into());
|
return Err(UserError::ReleaseCapacityTooBig.into());
|
||||||
|
|||||||
Reference in New Issue
Block a user