Add docs for shared types (#216)
Add documentation for types shared between the client and server.
This commit is contained in:
		| @@ -884,7 +884,7 @@ impl Builder { | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     /// Set the maximum number of concurrent locally reset streams. | ||||
|     /// Sets the maximum number of concurrent locally reset streams. | ||||
|     /// | ||||
|     /// When a stream is explicitly reset by either calling | ||||
|     /// [`SendResponse::send_reset`] or by dropping a [`SendResponse`] instance | ||||
| @@ -972,7 +972,7 @@ impl Builder { | ||||
|         self | ||||
|     } | ||||
|  | ||||
|     /// Set the first stream ID to something other than 1. | ||||
|     /// Sets the first stream ID to something other than 1. | ||||
|     #[cfg(feature = "unstable")] | ||||
|     pub fn initial_stream_id(&mut self, stream_id: u32) -> &mut Self { | ||||
|         self.stream_id = stream_id.into(); | ||||
|   | ||||
							
								
								
									
										27
									
								
								src/error.rs
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/error.rs
									
									
									
									
									
								
							| @@ -5,7 +5,16 @@ use std::{error, fmt, io}; | ||||
|  | ||||
| pub use frame::Reason; | ||||
|  | ||||
| /// The error type for HTTP/2 operations | ||||
| /// Represents HTTP/2.0 operation errors. | ||||
| /// | ||||
| /// `Error` covers error cases raised by protocol errors caused by the | ||||
| /// peer, I/O (transport) errors, and errors caused by the user of the library. | ||||
| /// | ||||
| /// If the error was caused by the remote peer, then it will contain a | ||||
| /// [`Reason`] which can be obtained with the [`reason`] function. | ||||
| /// | ||||
| /// [`Reason`]: struct.Reason.html | ||||
| /// [`reason`]: #method.reason | ||||
| #[derive(Debug)] | ||||
| pub struct Error { | ||||
|     kind: Kind, | ||||
| @@ -112,19 +121,3 @@ impl error::Error for Error { | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // ===== impl User ===== | ||||
|  | ||||
| /* | ||||
| impl User { | ||||
|     pub fn description(&self) -> &str { | ||||
|         user_desc!(*self) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Display for User { | ||||
|     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         write!(fmt, "{}", self.description()) | ||||
|     } | ||||
| } | ||||
| */ | ||||
|   | ||||
| @@ -1,11 +1,21 @@ | ||||
| use std::fmt; | ||||
|  | ||||
|  | ||||
| /// HTTP2 Error codes | ||||
| /// HTTP/2.0 error codes. | ||||
| /// | ||||
| /// Error codes are used in `RST_STREAM` and `GOAWAY` frames to convey the | ||||
| /// reasons for the stream or connection error. For example, | ||||
| /// [`SendStream::send_reset`] takes a `Reason` argument. Also, the `Error` type | ||||
| /// may contain a `Reason`. | ||||
| /// | ||||
| /// Error codes share a common code space. Some error codes apply only to | ||||
| /// streams, others apply only to connections, and others may apply to either. | ||||
| /// See [RFC 7540] for more information. | ||||
| /// | ||||
| /// See [Error Codes in the spec][spec]. | ||||
| /// | ||||
| /// [spec}: http://httpwg.org/specs/rfc7540.html#ErrorCodes | ||||
| /// [spec]: http://httpwg.org/specs/rfc7540.html#ErrorCodes | ||||
| /// [`SendStream::send_reset`]: struct.SendStream.html#method.send_reset | ||||
| #[derive(PartialEq, Eq, Clone, Copy)] | ||||
| pub struct Reason(u32); | ||||
|  | ||||
|   | ||||
							
								
								
									
										216
									
								
								src/share.rs
									
									
									
									
									
								
							
							
						
						
									
										216
									
								
								src/share.rs
									
									
									
									
									
								
							| @@ -8,13 +8,116 @@ use http::{HeaderMap}; | ||||
|  | ||||
| use std::fmt; | ||||
|  | ||||
| /// Send the body stream and trailers to the peer. | ||||
| /// Sends the body stream and trailers to the remote peer. | ||||
| /// | ||||
| /// # Overview | ||||
| /// | ||||
| /// A `SendStream` is provided by [`SendRequest`] and [`SendResponse`] once the | ||||
| /// HTTP/2.0 message header has been sent sent. It is used to stream the message | ||||
| /// body and send the message trailers. See method level documentation for more | ||||
| /// details. | ||||
| /// | ||||
| /// The `SendStream` instance is also used to manage outbound flow control. | ||||
| /// | ||||
| /// If a `SendStream` is dropped without explicitly closing the send stream, a | ||||
| /// `RST_STREAM` frame will be sent. This essentially cancels the request / | ||||
| /// response exchange. | ||||
| /// | ||||
| /// The ways to explicitly close the send stream are: | ||||
| /// | ||||
| /// * Set `end_of_stream` to true when calling [`send_request`], | ||||
| ///   [`send_response`], or [`send_data`]. | ||||
| /// * Send trailers with [`send_trailers`]. | ||||
| /// * Explicitly reset the stream with [`send_reset`]. | ||||
| /// | ||||
| /// # Flow control | ||||
| /// | ||||
| /// In HTTP/2.0, data cannot be sent to the remote peer unless there is | ||||
| /// available window capacity on both the stream and the connection. When a data | ||||
| /// frame is sent, both the stream window and the connection window are | ||||
| /// decremented. When the stream level window reaches zero, no further data can | ||||
| /// be sent on that stream. When the connection level window reaches zero, no | ||||
| /// further data can be sent on any stream for that connection. | ||||
| /// | ||||
| /// When the remote peer is ready to receive more data, it sends `WINDOW_UPDATE` | ||||
| /// frames. These frames increment the windows. See the [specification] for more | ||||
| /// details on the principles of HTTP/2.0 flow control. | ||||
| /// | ||||
| /// The implications for sending data are that the caller **should** ensure that | ||||
| /// both the stream and the connection has available window capacity before | ||||
| /// loading the data to send into memory. The `SendStream` instance provides the | ||||
| /// necessary APIs to perform this logic. This, however, is not an oblication. | ||||
| /// If the caller attempts to send data on a stream when there is no available | ||||
| /// window capacity, the library will buffer the data until capacity becomes | ||||
| /// available, at which point the buffer will be flushed to the connection. | ||||
| /// | ||||
| /// **NOTE**: There is no bound on the amount of data that the library will | ||||
| /// buffer. If you are sending large amounts of data, you really should hook | ||||
| /// into the flow control lifecycle. Otherwise, you risk using up significant | ||||
| /// amounts of memory. | ||||
| /// | ||||
| /// To hook into the flow control lifecycle, the caller signals to the library | ||||
| /// that it intends to send data by calling [`reserve_capacity`], specifying the | ||||
| /// amount of data, in octets, that the caller intends to send. After this, | ||||
| /// `poll_capacity` is used to be notified when the requested capacity is | ||||
| /// assigned to the stream. Once [`poll_capacity`] returns `Ready` with the number | ||||
| /// of octets available to the stream, the caller is able to actually send the | ||||
| /// data using [`send_data`]. | ||||
| /// | ||||
| /// Because there is also a connection level window that applies to **all** | ||||
| /// streams on a connection, when capacity is assigned to a stream (indicated by | ||||
| /// `poll_capacity` returning `Ready`), this capacity is reserved on the | ||||
| /// connection and will **not** be assigned to any other stream. If data is | ||||
| /// never written to the stream, that capacity is effectively lost to other | ||||
| /// streams and this introduces the risk of deadlocking a connection. | ||||
| /// | ||||
| /// To avoid throttling data on a connection, the caller should not reserve | ||||
| /// capacity until ready to send data and once any capacity is assigned to the | ||||
| /// stream, the caller should immediately send data consuming this capacity. | ||||
| /// There is no guarantee as to when the full capacity requested will become | ||||
| /// available. For example, if the caller requests 64 KB of data and 512 bytes | ||||
| /// become available, the caller should immediately send 512 bytes of data. | ||||
| /// | ||||
| /// See [`reserve_capacity`] documentation for more details. | ||||
| /// | ||||
| /// [`SendRequest`]: client/struct.SendRequest.html | ||||
| /// [`SendResponse`]: server/struct.SendResponse.html | ||||
| /// [specification]: http://httpwg.org/specs/rfc7540.html#FlowControl | ||||
| /// [`reserve_capacity`]: #method.reserve_capacity | ||||
| /// [`poll_capacity`]: #method.poll_capacity | ||||
| /// [`send_data`]: #method.send_data | ||||
| /// [`send_request`]: client/struct.SendRequest.html#method.send_request | ||||
| /// [`send_response`]: server/struct.SendResponse.html#method.send_response | ||||
| /// [`send_data`]: #method.send_data | ||||
| /// [`send_trailers`]: #method.send_trailers | ||||
| /// [`send_reset`]: #method.send_reset | ||||
| #[derive(Debug)] | ||||
| pub struct SendStream<B: IntoBuf> { | ||||
|     inner: proto::StreamRef<B::Buf>, | ||||
| } | ||||
|  | ||||
| /// Receive the body stream and trailers from the peer. | ||||
| /// Receives the body stream and trailers from the remote peer. | ||||
| /// | ||||
| /// A `RecvStream` is provided by [`client::ResponseFuture`] and | ||||
| /// [`server::Connection`] with the received HTTP/2.0 message head (the response | ||||
| /// and request head respectively). | ||||
| /// | ||||
| /// A `RecvStream` instance is used to receive the streaming message body and | ||||
| /// any trailers from the remote peer. It is also used to manage inbound flow | ||||
| /// control. | ||||
| /// | ||||
| /// See method level documentation for more details on receiving data. See | ||||
| /// [`ReleaseCapacity`] for more details on inbound flow control. | ||||
| /// | ||||
| /// Note that this type implements [`Stream`], yielding the received data frames. | ||||
| /// When this implementation is used, the capacity is immediately released when | ||||
| /// the data is yielded. It is recommended to only use this API when the data | ||||
| /// will not be retained in memory for extended periods of time. | ||||
| /// | ||||
| /// [`client::ResponseFuture`]: client/struct.ResponseFuture.html | ||||
| /// [`server::Connection`]: server/struct.Connection.html | ||||
| /// [`ReleaseCapacity`]: struct.ReleaseCapacity.html | ||||
| /// [`Stream`]: https://docs.rs/futures/0.1/futures/stream/trait.Stream.html | ||||
| #[must_use = "streams do nothing unless polled"] | ||||
| pub struct RecvStream { | ||||
|     inner: ReleaseCapacity, | ||||
| @@ -84,36 +187,135 @@ impl<B: IntoBuf> SendStream<B> { | ||||
|         SendStream { inner } | ||||
|     } | ||||
|  | ||||
|     /// Request capacity to send data | ||||
|     /// Requests capacity to send data. | ||||
|     /// | ||||
|     /// This function is used to express intent to send data. This requests | ||||
|     /// connection level capacity. Once the capacity is available, it is | ||||
|     /// assigned to the stream and not reused by other streams. | ||||
|     /// | ||||
|     /// This function may be called repeatedly. The `capacity` argument is the | ||||
|     /// **total** amount of requested capacity. Sequential calls to | ||||
|     /// `reserve_capacity` are *not* additive. Given the following: | ||||
|     /// | ||||
|     /// ```rust | ||||
|     /// # use h2::*; | ||||
|     /// # fn doc(mut send_stream: SendStream<&'static [u8]>) { | ||||
|     /// send_stream.reserve_capacity(100); | ||||
|     /// send_stream.reserve_capacity(200); | ||||
|     /// # } | ||||
|     /// ``` | ||||
|     /// | ||||
|     /// After the second call to `reserve_capacity`, the *total* requested | ||||
|     /// capacity will be 200. | ||||
|     /// | ||||
|     /// `reserve_capacity` is also used to cancel previous capacity requests. | ||||
|     /// Given the following: | ||||
|     /// | ||||
|     /// ```rust | ||||
|     /// # use h2::*; | ||||
|     /// # fn doc(mut send_stream: SendStream<&'static [u8]>) { | ||||
|     /// send_stream.reserve_capacity(100); | ||||
|     /// send_stream.reserve_capacity(0); | ||||
|     /// # } | ||||
|     /// ``` | ||||
|     /// | ||||
|     /// After the second call to `reserve_capacity`, the *total* requested | ||||
|     /// capcaity will be 0, i.e. there is no requested capacity for the stream. | ||||
|     /// | ||||
|     /// If `reserve_capacity` is called with a lower value than the amount of | ||||
|     /// capacity **currently** assigned to the stream, this capacity will be | ||||
|     /// returned to the connection to be re-assigned to other streams. | ||||
|     /// | ||||
|     /// Also, the amount of capacity that is reserved gets decremented as data | ||||
|     /// is sent. For example: | ||||
|     /// | ||||
|     /// ```rust | ||||
|     /// # use h2::*; | ||||
|     /// # fn doc(mut send_stream: SendStream<&'static [u8]>) { | ||||
|     /// send_stream.reserve_capacity(100); | ||||
|     /// | ||||
|     /// let capacity = send_stream.poll_capacity(); | ||||
|     /// // capacity == 5; | ||||
|     /// | ||||
|     /// send_stream.send_data(b"hello", false).unwrap(); | ||||
|     /// // At this point, the total amount of requested capacity is 95 bytes. | ||||
|     /// | ||||
|     /// // Calling `reserve_capacity` with `100` again essentially requests an | ||||
|     /// // additional 5 bytes. | ||||
|     /// send_stream.reserve_capacity(100); | ||||
|     /// # } | ||||
|     /// ``` | ||||
|     /// | ||||
|     /// See [Flow contro](struct.SendStream.html#flow-control) for an overview | ||||
|     /// of how send flow control works. | ||||
|     pub fn reserve_capacity(&mut self, capacity: usize) { | ||||
|         // TODO: Check for overflow | ||||
|         self.inner.reserve_capacity(capacity as WindowSize) | ||||
|     } | ||||
|  | ||||
|     /// Returns the stream's current send capacity. | ||||
|     /// | ||||
|     /// This allows the caller to check the current amount of available capacity | ||||
|     /// before sending data. | ||||
|     pub fn capacity(&self) -> usize { | ||||
|         self.inner.capacity() as usize | ||||
|     } | ||||
|  | ||||
|     /// Request to be notified when the stream's capacity increases | ||||
|     /// Requests to be notified when the stream's capacity increases. | ||||
|     /// | ||||
|     /// Before calling this, capacity should be requested with | ||||
|     /// [`reserve_capacity`]. Once capacity is requested, the connection will | ||||
|     /// assign capacity to the stream **as it becomes available**. There is no | ||||
|     /// guarantee as to when and in what increments capacity gets assigned to | ||||
|     /// the stream. | ||||
|     /// | ||||
|     /// To get notified when the available capacity increases, the caller calls | ||||
|     /// `poll_capacity`, which returns `Ready(Some(n))` when `n` has been | ||||
|     /// increased by the connection. Note that `n` here represents the **total** | ||||
|     /// amount of assigned capacity at that point in time. It is also possible | ||||
|     /// that `n` is lower than the previous call if, since then, the caller has | ||||
|     /// sent data. | ||||
|     pub fn poll_capacity(&mut self) -> Poll<Option<usize>, ::Error> { | ||||
|         let res = try_ready!(self.inner.poll_capacity()); | ||||
|         Ok(Async::Ready(res.map(|v| v as usize))) | ||||
|     } | ||||
|  | ||||
|     /// Send a single data frame | ||||
|     /// Sends a single data frame to the remote peer. | ||||
|     /// | ||||
|     /// This function may be called repeatedly as long as `end_of_stream` is set | ||||
|     /// to `false`. Setting `end_of_stream` to `true` sets the end stream flag | ||||
|     /// on the data frame. Any further calls to `send_data` or `send_trailers` | ||||
|     /// will return an [`Error`]. | ||||
|     /// | ||||
|     /// `send_data` can be called without reserving capacity. In this case, the | ||||
|     /// data is buffered and the capacity is implicitly requested. Once the | ||||
|     /// capacity becomes available, the data is flushed to the connection. | ||||
|     /// However, this buffering is unbounded. As such, sending large amounts of | ||||
|     /// data without reserving capacity before hand could result in large | ||||
|     /// amounts of data being buffered in memory. | ||||
|     /// | ||||
|     /// [`Error`]: struct.Error.html | ||||
|     pub fn send_data(&mut self, data: B, end_of_stream: bool) -> Result<(), ::Error> { | ||||
|         self.inner | ||||
|             .send_data(data.into_buf(), end_of_stream) | ||||
|             .map_err(Into::into) | ||||
|     } | ||||
|  | ||||
|     /// Send trailers | ||||
|     /// Sends trailers to the remote peer. | ||||
|     /// | ||||
|     /// Sending trailers implicitly closes the send stream. Once the send stream | ||||
|     /// is closed, no more data can be sent. | ||||
|     pub fn send_trailers(&mut self, trailers: HeaderMap) -> Result<(), ::Error> { | ||||
|         self.inner.send_trailers(trailers).map_err(Into::into) | ||||
|     } | ||||
|  | ||||
|     /// Reset the stream | ||||
|     /// Resets the stream. | ||||
|     /// | ||||
|     /// This cancels the request / response exchange. If the response has not | ||||
|     /// yet been received, the associatd `ResponseFuture` will return an | ||||
|     /// [`Error`] to reflect the canceled exchange. | ||||
|     /// | ||||
|     /// [`Error`]: struct.Error.html | ||||
|     pub fn send_reset(&mut self, reason: Reason) { | ||||
|         self.inner.send_reset(reason) | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user