|  | //! An asynchronous, HTTP/2.0 server and client implementation. | 
|  | //! | 
|  | //! This library implements the [HTTP/2.0] specification. The implementation is | 
|  | //! asynchronous, using [futures] as the basis for the API. The implementation | 
|  | //! is also decoupled from TCP or TLS details. The user must handle ALPN and | 
|  | //! HTTP/1.1 upgrades themselves. | 
|  | //! | 
|  | //! # Getting started | 
|  | //! | 
|  | //! Add the following to your `Cargo.toml` file: | 
|  | //! | 
|  | //! ```toml | 
|  | //! [dependencies] | 
|  | //! h2 = "0.2" | 
|  | //! ``` | 
|  | //! | 
|  | //! # Layout | 
|  | //! | 
|  | //! The crate is split into [`client`] and [`server`] modules. Types that are | 
|  | //! common to both clients and servers are located at the root of the crate. | 
|  | //! | 
|  | //! See module level documentation for more details on how to use `h2`. | 
|  | //! | 
|  | //! # Handshake | 
|  | //! | 
|  | //! Both the client and the server require a connection to already be in a state | 
|  | //! ready to start the HTTP/2.0 handshake. This library does not provide | 
|  | //! facilities to do this. | 
|  | //! | 
|  | //! There are three ways to reach an appropriate state to start the HTTP/2.0 | 
|  | //! handshake. | 
|  | //! | 
|  | //! * Opening an HTTP/1.1 connection and performing an [upgrade]. | 
|  | //! * Opening a connection with TLS and use ALPN to negotiate the protocol. | 
|  | //! * Open a connection with prior knowledge, i.e. both the client and the | 
|  | //!   server assume that the connection is immediately ready to start the | 
|  | //!   HTTP/2.0 handshake once opened. | 
|  | //! | 
|  | //! Once the connection is ready to start the HTTP/2.0 handshake, it can be | 
|  | //! passed to [`server::handshake`] or [`client::handshake`]. At this point, the | 
|  | //! library will start the handshake process, which consists of: | 
|  | //! | 
|  | //! * The client sends the connection preface (a predefined sequence of 24 | 
|  | //! octets). | 
|  | //! * Both the client and the server sending a SETTINGS frame. | 
|  | //! | 
|  | //! See the [Starting HTTP/2] in the specification for more details. | 
|  | //! | 
|  | //! # Flow control | 
|  | //! | 
|  | //! [Flow control] is a fundamental feature of HTTP/2.0. The `h2` library | 
|  | //! exposes flow control to the user. | 
|  | //! | 
|  | //! An HTTP/2.0 client or server may not send unlimited data to the peer. When a | 
|  | //! stream is initiated, both the client and the server are provided with an | 
|  | //! initial window size for that stream.  A window size is the number of bytes | 
|  | //! the endpoint can send to the peer. At any point in time, the peer may | 
|  | //! increase this window size by sending a `WINDOW_UPDATE` frame. Once a client | 
|  | //! or server has sent data filling the window for a stream, no further data may | 
|  | //! be sent on that stream until the peer increases the window. | 
|  | //! | 
|  | //! There is also a **connection level** window governing data sent across all | 
|  | //! streams. | 
|  | //! | 
|  | //! Managing flow control for inbound data is done through [`FlowControl`]. | 
|  | //! Managing flow control for outbound data is done through [`SendStream`]. See | 
|  | //! the struct level documentation for those two types for more details. | 
|  | //! | 
|  | //! [HTTP/2.0]: https://http2.github.io/ | 
|  | //! [futures]: https://docs.rs/futures/ | 
|  | //! [`client`]: client/index.html | 
|  | //! [`server`]: server/index.html | 
|  | //! [Flow control]: http://httpwg.org/specs/rfc7540.html#FlowControl | 
|  | //! [`FlowControl`]: struct.FlowControl.html | 
|  | //! [`SendStream`]: struct.SendStream.html | 
|  | //! [Starting HTTP/2]: http://httpwg.org/specs/rfc7540.html#starting | 
|  | //! [upgrade]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism | 
|  | //! [`server::handshake`]: server/fn.handshake.html | 
|  | //! [`client::handshake`]: client/fn.handshake.html | 
|  |  | 
|  | #![doc(html_root_url = "https://docs.rs/h2/0.2.5")] | 
|  | #![deny(missing_debug_implementations, missing_docs)] | 
|  | #![cfg_attr(test, deny(warnings))] | 
|  |  | 
|  | macro_rules! proto_err { | 
|  | (conn: $($msg:tt)+) => { | 
|  | log::debug!("connection error PROTOCOL_ERROR -- {};", format_args!($($msg)+)) | 
|  | }; | 
|  | (stream: $($msg:tt)+) => { | 
|  | log::debug!("stream error PROTOCOL_ERROR -- {};", format_args!($($msg)+)) | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! ready { | 
|  | ($e:expr) => { | 
|  | match $e { | 
|  | ::std::task::Poll::Ready(r) => r, | 
|  | ::std::task::Poll::Pending => return ::std::task::Poll::Pending, | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | #[cfg_attr(feature = "unstable", allow(missing_docs))] | 
|  | mod codec; | 
|  | mod error; | 
|  | mod hpack; | 
|  | mod proto; | 
|  |  | 
|  | #[cfg(not(feature = "unstable"))] | 
|  | mod frame; | 
|  |  | 
|  | #[cfg(feature = "unstable")] | 
|  | #[allow(missing_docs)] | 
|  | pub mod frame; | 
|  |  | 
|  | pub mod client; | 
|  | pub mod server; | 
|  | mod share; | 
|  |  | 
|  | pub use crate::error::{Error, Reason}; | 
|  | pub use crate::share::{FlowControl, Ping, PingPong, Pong, RecvStream, SendStream, StreamId}; | 
|  |  | 
|  | #[cfg(feature = "unstable")] | 
|  | pub use codec::{Codec, RecvError, SendError, UserError}; | 
|  |  | 
|  | use std::task::Poll; | 
|  |  | 
|  | // TODO: Get rid of this trait once https://github.com/rust-lang/rust/pull/63512 | 
|  | // is stablized. | 
|  | trait PollExt<T, E> { | 
|  | /// Changes the success value of this `Poll` with the closure provided. | 
|  | fn map_ok_<U, F>(self, f: F) -> Poll<Option<Result<U, E>>> | 
|  | where | 
|  | F: FnOnce(T) -> U; | 
|  | /// Changes the error value of this `Poll` with the closure provided. | 
|  | fn map_err_<U, F>(self, f: F) -> Poll<Option<Result<T, U>>> | 
|  | where | 
|  | F: FnOnce(E) -> U; | 
|  | } | 
|  |  | 
|  | impl<T, E> PollExt<T, E> for Poll<Option<Result<T, E>>> { | 
|  | fn map_ok_<U, F>(self, f: F) -> Poll<Option<Result<U, E>>> | 
|  | where | 
|  | F: FnOnce(T) -> U, | 
|  | { | 
|  | match self { | 
|  | Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))), | 
|  | Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))), | 
|  | Poll::Ready(None) => Poll::Ready(None), | 
|  | Poll::Pending => Poll::Pending, | 
|  | } | 
|  | } | 
|  |  | 
|  | fn map_err_<U, F>(self, f: F) -> Poll<Option<Result<T, U>>> | 
|  | where | 
|  | F: FnOnce(E) -> U, | 
|  | { | 
|  | match self { | 
|  | Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))), | 
|  | Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))), | 
|  | Poll::Ready(None) => Poll::Ready(None), | 
|  | Poll::Pending => Poll::Pending, | 
|  | } | 
|  | } | 
|  | } |