1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
//! Streaming async HTTP 1.1 parser. //! //! At its core HTTP is a stateful RPC protocol, where a client and server //! communicate with one another by encoding and decoding messages between them. //! //! - `client` encodes HTTP requests, and decodes HTTP responses. //! - `server` decodes HTTP requests, and encodes HTTP responses. //! //! A client always starts the HTTP connection. The lifetime of an HTTP //! connection looks like this: //! //! ```txt //! 1. encode 2. decode //! \ / //! -> request -> //! client server //! <- response <- //! / \ //! 4. decode 3. encode //! ``` //! //! See also [`async-tls`](https://docs.rs/async-tls), //! [`async-std`](https://docs.rs/async-std). //! //! # Example //! //! __HTTP client__ //! //! ```no_run //! use async_h1::client; //! use async_std::net::{TcpStream}; //! use http_types::{Error, Method, Request, Url}; //! //! #[async_std::main] //! async fn main() -> Result<(), Error> { //! let stream = TcpStream::connect("127.0.0.1:8080").await?; //! let peer_addr = stream.peer_addr()?; //! println!("connecting to {}", peer_addr); //! //! for i in 0usize..2 { //! println!("making request {}/2", i + 1); //! let url = Url::parse(&format!("http://{}/foo", peer_addr)).unwrap(); //! let req = Request::new(Method::Get, dbg!(url)); //! let res = client::connect(stream.clone(), req).await?; //! println!("{:?}", res); //! } //! Ok(()) //! } //! ``` //! //! __HTTP Server__ //! //! ```no_run //! use async_std::net::{TcpStream, TcpListener}; //! use async_std::prelude::*; //! use async_std::task; //! use http_types::{Response, StatusCode}; //! //! #[async_std::main] //! async fn main() -> http_types::Result<()> { //! // Open up a TCP connection and create a URL. //! let listener = TcpListener::bind(("127.0.0.1", 8080)).await?; //! let addr = format!("http://{}", listener.local_addr()?); //! println!("listening on {}", addr); //! //! // For each incoming TCP connection, spawn a task and call `accept`. //! let mut incoming = listener.incoming(); //! while let Some(stream) = incoming.next().await { //! let stream = stream?; //! let addr = addr.clone(); //! task::spawn(async { //! if let Err(err) = accept(addr, stream).await { //! eprintln!("{}", err); //! } //! }); //! } //! Ok(()) //! } //! //! // Take a TCP stream, and convert it into sequential HTTP request / response pairs. //! async fn accept(addr: String, stream: TcpStream) -> http_types::Result<()> { //! println!("starting new connection from {}", stream.peer_addr()?); //! async_h1::accept(&addr, stream.clone(), |_req| async move { //! let mut res = Response::new(StatusCode::Ok); //! res.insert_header("Content-Type", "text/plain")?; //! res.set_body("Hello"); //! Ok(res) //! }) //! .await?; //! Ok(()) //! } //! ``` // #![forbid(unsafe_code, rust_2018_idioms)] #![deny(missing_debug_implementations, nonstandard_style)] #![warn(missing_docs, missing_doc_code_examples, unreachable_pub)] #![cfg_attr(test, deny(warnings))] /// The maximum amount of headers parsed on the server. const MAX_HEADERS: usize = 128; mod chunked; mod date; mod server; #[doc(hidden)] pub mod client; pub use client::connect; pub use server::accept;