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