1 //! An asynchronous, HTTP/2 server and client implementation. 2 //! 3 //! This library implements the [HTTP/2] specification. The implementation is 4 //! asynchronous, using [futures] as the basis for the API. The implementation 5 //! is also decoupled from TCP or TLS details. The user must handle ALPN and 6 //! HTTP/1.1 upgrades themselves. 7 //! 8 //! # Getting started 9 //! 10 //! Add the following to your `Cargo.toml` file: 11 //! 12 //! ```toml 13 //! [dependencies] 14 //! h2 = "0.3" 15 //! ``` 16 //! 17 //! # Layout 18 //! 19 //! The crate is split into [`client`] and [`server`] modules. Types that are 20 //! common to both clients and servers are located at the root of the crate. 21 //! 22 //! See module level documentation for more details on how to use `h2`. 23 //! 24 //! # Handshake 25 //! 26 //! Both the client and the server require a connection to already be in a state 27 //! ready to start the HTTP/2 handshake. This library does not provide 28 //! facilities to do this. 29 //! 30 //! There are three ways to reach an appropriate state to start the HTTP/2 31 //! handshake. 32 //! 33 //! * Opening an HTTP/1.1 connection and performing an [upgrade]. 34 //! * Opening a connection with TLS and use ALPN to negotiate the protocol. 35 //! * Open a connection with prior knowledge, i.e. both the client and the 36 //! server assume that the connection is immediately ready to start the 37 //! HTTP/2 handshake once opened. 38 //! 39 //! Once the connection is ready to start the HTTP/2 handshake, it can be 40 //! passed to [`server::handshake`] or [`client::handshake`]. At this point, the 41 //! library will start the handshake process, which consists of: 42 //! 43 //! * The client sends the connection preface (a predefined sequence of 24 44 //! octets). 45 //! * Both the client and the server sending a SETTINGS frame. 46 //! 47 //! See the [Starting HTTP/2] in the specification for more details. 48 //! 49 //! # Flow control 50 //! 51 //! [Flow control] is a fundamental feature of HTTP/2. The `h2` library 52 //! exposes flow control to the user. 53 //! 54 //! An HTTP/2 client or server may not send unlimited data to the peer. When a 55 //! stream is initiated, both the client and the server are provided with an 56 //! initial window size for that stream. A window size is the number of bytes 57 //! the endpoint can send to the peer. At any point in time, the peer may 58 //! increase this window size by sending a `WINDOW_UPDATE` frame. Once a client 59 //! or server has sent data filling the window for a stream, no further data may 60 //! be sent on that stream until the peer increases the window. 61 //! 62 //! There is also a **connection level** window governing data sent across all 63 //! streams. 64 //! 65 //! Managing flow control for inbound data is done through [`FlowControl`]. 66 //! Managing flow control for outbound data is done through [`SendStream`]. See 67 //! the struct level documentation for those two types for more details. 68 //! 69 //! [HTTP/2]: https://http2.github.io/ 70 //! [futures]: https://docs.rs/futures/ 71 //! [`client`]: client/index.html 72 //! [`server`]: server/index.html 73 //! [Flow control]: http://httpwg.org/specs/rfc7540.html#FlowControl 74 //! [`FlowControl`]: struct.FlowControl.html 75 //! [`SendStream`]: struct.SendStream.html 76 //! [Starting HTTP/2]: http://httpwg.org/specs/rfc7540.html#starting 77 //! [upgrade]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism 78 //! [`server::handshake`]: server/fn.handshake.html 79 //! [`client::handshake`]: client/fn.handshake.html 80 81 #![doc(html_root_url = "https://docs.rs/h2/0.3.9")] 82 #![deny(missing_debug_implementations, missing_docs)] 83 #![cfg_attr(test, deny(warnings))] 84 85 macro_rules! proto_err { 86 (conn: $($msg:tt)+) => { 87 tracing::debug!("connection error PROTOCOL_ERROR -- {};", format_args!($($msg)+)) 88 }; 89 (stream: $($msg:tt)+) => { 90 tracing::debug!("stream error PROTOCOL_ERROR -- {};", format_args!($($msg)+)) 91 }; 92 } 93 94 macro_rules! ready { 95 ($e:expr) => { 96 match $e { 97 ::std::task::Poll::Ready(r) => r, 98 ::std::task::Poll::Pending => return ::std::task::Poll::Pending, 99 } 100 }; 101 } 102 103 #[cfg_attr(feature = "unstable", allow(missing_docs))] 104 mod codec; 105 mod error; 106 mod hpack; 107 108 #[cfg(not(feature = "unstable"))] 109 mod proto; 110 111 #[cfg(feature = "unstable")] 112 #[allow(missing_docs)] 113 pub mod proto; 114 115 #[cfg(not(feature = "unstable"))] 116 mod frame; 117 118 #[cfg(feature = "unstable")] 119 #[allow(missing_docs)] 120 pub mod frame; 121 122 pub mod client; 123 pub mod ext; 124 pub mod server; 125 mod share; 126 127 #[cfg(fuzzing)] 128 #[cfg_attr(feature = "unstable", allow(missing_docs))] 129 pub mod fuzz_bridge; 130 131 pub use crate::error::{Error, Reason}; 132 pub use crate::share::{FlowControl, Ping, PingPong, Pong, RecvStream, SendStream, StreamId}; 133 134 #[cfg(feature = "unstable")] 135 pub use codec::{Codec, SendError, UserError}; 136 137 use std::task::Poll; 138 139 // TODO: Get rid of this trait once https://github.com/rust-lang/rust/pull/63512 140 // is stabilized. 141 trait PollExt<T, E> { 142 /// Changes the success value of this `Poll` with the closure provided. map_ok_<U, F>(self, f: F) -> Poll<Option<Result<U, E>>> where F: FnOnce(T) -> U143 fn map_ok_<U, F>(self, f: F) -> Poll<Option<Result<U, E>>> 144 where 145 F: FnOnce(T) -> U; 146 /// Changes the error value of this `Poll` with the closure provided. map_err_<U, F>(self, f: F) -> Poll<Option<Result<T, U>>> where F: FnOnce(E) -> U147 fn map_err_<U, F>(self, f: F) -> Poll<Option<Result<T, U>>> 148 where 149 F: FnOnce(E) -> U; 150 } 151 152 impl<T, E> PollExt<T, E> for Poll<Option<Result<T, E>>> { map_ok_<U, F>(self, f: F) -> Poll<Option<Result<U, E>>> where F: FnOnce(T) -> U,153 fn map_ok_<U, F>(self, f: F) -> Poll<Option<Result<U, E>>> 154 where 155 F: FnOnce(T) -> U, 156 { 157 match self { 158 Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))), 159 Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))), 160 Poll::Ready(None) => Poll::Ready(None), 161 Poll::Pending => Poll::Pending, 162 } 163 } 164 map_err_<U, F>(self, f: F) -> Poll<Option<Result<T, U>>> where F: FnOnce(E) -> U,165 fn map_err_<U, F>(self, f: F) -> Poll<Option<Result<T, U>>> 166 where 167 F: FnOnce(E) -> U, 168 { 169 match self { 170 Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))), 171 Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))), 172 Poll::Ready(None) => Poll::Ready(None), 173 Poll::Pending => Poll::Pending, 174 } 175 } 176 } 177