| 1 | //! A general purpose library of common HTTP types |
| 2 | //! |
| 3 | //! This crate is a general purpose library for common types found when working |
| 4 | //! with the HTTP protocol. You'll find [`Request`] and [`Response`] types for |
| 5 | //! working as either a client or a server as well as all of their components. |
| 6 | //! Notably you'll find `Uri` for what a [`Request`] is requesting, a [`Method`] |
| 7 | //! for how it's being requested, a [`StatusCode`] for what sort of response came |
| 8 | //! back, a [`Version`] for how this was communicated, and |
| 9 | //! [`HeaderName`]/[`HeaderValue`] definitions to get grouped in a [`HeaderMap`] to |
| 10 | //! work with request/response headers. |
| 11 | //! |
| 12 | //! You will notably *not* find an implementation of sending requests or |
| 13 | //! spinning up a server in this crate. It's intended that this crate is the |
| 14 | //! "standard library" for HTTP clients and servers without dictating any |
| 15 | //! particular implementation. |
| 16 | //! |
| 17 | //! ## Requests and Responses |
| 18 | //! |
| 19 | //! Perhaps the main two types in this crate are the [`Request`] and [`Response`] |
| 20 | //! types. A [`Request`] could either be constructed to get sent off as a client |
| 21 | //! or it can also be received to generate a [`Response`] for a server. Similarly |
| 22 | //! as a client a [`Response`] is what you get after sending a [`Request`], whereas |
| 23 | //! on a server you'll be manufacturing a [`Response`] to send back to the client. |
| 24 | //! |
| 25 | //! Each type has a number of accessors for the component fields. For as a |
| 26 | //! server you might want to inspect a requests URI to dispatch it: |
| 27 | //! |
| 28 | //! ``` |
| 29 | //! use http::{Request, Response}; |
| 30 | //! |
| 31 | //! fn response(req: Request<()>) -> http::Result<Response<()>> { |
| 32 | //! match req.uri().path() { |
| 33 | //! "/" => index(req), |
| 34 | //! "/foo" => foo(req), |
| 35 | //! "/bar" => bar(req), |
| 36 | //! _ => not_found(req), |
| 37 | //! } |
| 38 | //! } |
| 39 | //! # fn index(_req: Request<()>) -> http::Result<Response<()>> { panic!() } |
| 40 | //! # fn foo(_req: Request<()>) -> http::Result<Response<()>> { panic!() } |
| 41 | //! # fn bar(_req: Request<()>) -> http::Result<Response<()>> { panic!() } |
| 42 | //! # fn not_found(_req: Request<()>) -> http::Result<Response<()>> { panic!() } |
| 43 | //! ``` |
| 44 | //! |
| 45 | //! On a [`Request`] you'll also find accessors like [`method`][Request::method] to return a |
| 46 | //! [`Method`] and [`headers`][Request::method] to inspect the various headers. A [`Response`] |
| 47 | //! has similar methods for headers, the status code, etc. |
| 48 | //! |
| 49 | //! In addition to getters, request/response types also have mutable accessors |
| 50 | //! to edit the request/response: |
| 51 | //! |
| 52 | //! ``` |
| 53 | //! use http::{HeaderValue, Response, StatusCode}; |
| 54 | //! use http::header::CONTENT_TYPE; |
| 55 | //! |
| 56 | //! fn add_server_headers<T>(response: &mut Response<T>) { |
| 57 | //! response.headers_mut() |
| 58 | //! .insert(CONTENT_TYPE, HeaderValue::from_static("text/html" )); |
| 59 | //! *response.status_mut() = StatusCode::OK; |
| 60 | //! } |
| 61 | //! ``` |
| 62 | //! |
| 63 | //! And finally, one of the most important aspects of requests/responses, the |
| 64 | //! body! The [`Request`] and [`Response`] types in this crate are *generic* in |
| 65 | //! what their body is. This allows downstream libraries to use different |
| 66 | //! representations such as `Request<Vec<u8>>`, `Response<impl Read>`, |
| 67 | //! `Request<impl Stream<Item = Vec<u8>, Error = _>>`, or even |
| 68 | //! `Response<MyCustomType>` where the custom type was deserialized from JSON. |
| 69 | //! |
| 70 | //! The body representation is intentionally flexible to give downstream |
| 71 | //! libraries maximal flexibility in implementing the body as appropriate. |
| 72 | //! |
| 73 | //! ## HTTP Headers |
| 74 | //! |
| 75 | //! Another major piece of functionality in this library is HTTP header |
| 76 | //! interpretation and generation. The `HeaderName` type serves as a way to |
| 77 | //! define header *names*, or what's to the left of the colon. A `HeaderValue` |
| 78 | //! conversely is the header *value*, or what's to the right of a colon. |
| 79 | //! |
| 80 | //! For example, if you have an HTTP request that looks like: |
| 81 | //! |
| 82 | //! ```http |
| 83 | //! GET /foo HTTP/1.1 |
| 84 | //! Accept: text/html |
| 85 | //! ``` |
| 86 | //! |
| 87 | //! Then `"Accept"` is a [`HeaderName`] while `"text/html"` is a [`HeaderValue`]. |
| 88 | //! Each of these is a dedicated type to allow for a number of interesting |
| 89 | //! optimizations and to also encode the static guarantees of each type. For |
| 90 | //! example a [`HeaderName`] is always a valid `&str`, but a [`HeaderValue`] may |
| 91 | //! not be valid UTF-8. |
| 92 | //! |
| 93 | //! The most common header names are already defined for you as constant values |
| 94 | //! in the [`header`] module of this crate. For example: |
| 95 | //! |
| 96 | //! ``` |
| 97 | //! use http::header::{self, HeaderName}; |
| 98 | //! |
| 99 | //! let name: HeaderName = header::ACCEPT; |
| 100 | //! assert_eq!(name.as_str(), "accept" ); |
| 101 | //! ``` |
| 102 | //! |
| 103 | //! You can, however, also parse header names from strings: |
| 104 | //! |
| 105 | //! ``` |
| 106 | //! use http::header::{self, HeaderName}; |
| 107 | //! |
| 108 | //! let name = "Accept" .parse::<HeaderName>().unwrap(); |
| 109 | //! assert_eq!(name, header::ACCEPT); |
| 110 | //! ``` |
| 111 | //! |
| 112 | //! Header values can be created from string literals through the [`from_static`][header::HeaderValue::from_static] |
| 113 | //! function: |
| 114 | //! |
| 115 | //! ``` |
| 116 | //! use http::HeaderValue; |
| 117 | //! |
| 118 | //! let value = HeaderValue::from_static("text/html" ); |
| 119 | //! assert_eq!(value.as_bytes(), b"text/html" ); |
| 120 | //! ``` |
| 121 | //! |
| 122 | //! And header values can also be parsed like names: |
| 123 | //! |
| 124 | //! ``` |
| 125 | //! use http::HeaderValue; |
| 126 | //! |
| 127 | //! let value = "text/html" ; |
| 128 | //! let value = value.parse::<HeaderValue>().unwrap(); |
| 129 | //! ``` |
| 130 | //! |
| 131 | //! Most HTTP requests and responses tend to come with more than one header, so |
| 132 | //! it's not too useful to just work with names and values only! This crate also |
| 133 | //! provides a [`HeaderMap`] type which is a specialized hash map for keys as |
| 134 | //! [`HeaderName`] and generic values. This type, like header names, is optimized |
| 135 | //! for common usage but should continue to scale with your needs over time. |
| 136 | //! |
| 137 | //! # URIs |
| 138 | //! |
| 139 | //! Each HTTP [`Request`] has an associated URI with it. This may just be a path |
| 140 | //! like `/index.html` but it could also be an absolute URL such as |
| 141 | //! `https://www.rust-lang.org/index.html`. A [`URI`][uri::Uri] has a number of accessors to |
| 142 | //! interpret it: |
| 143 | //! |
| 144 | //! ``` |
| 145 | //! use http::Uri; |
| 146 | //! use http::uri::Scheme; |
| 147 | //! |
| 148 | //! let uri = "https://www.rust-lang.org/index.html" .parse::<Uri>().unwrap(); |
| 149 | //! |
| 150 | //! assert_eq!(uri.scheme(), Some(&Scheme::HTTPS)); |
| 151 | //! assert_eq!(uri.host(), Some("www.rust-lang.org" )); |
| 152 | //! assert_eq!(uri.path(), "/index.html" ); |
| 153 | //! assert_eq!(uri.query(), None); |
| 154 | //! ``` |
| 155 | |
| 156 | #![deny (warnings, missing_docs, missing_debug_implementations)] |
| 157 | |
| 158 | //#![cfg_attr(not(feature = "std"), no_std)] |
| 159 | #[cfg (not(feature = "std" ))] |
| 160 | compile_error!("`std` feature currently required, support for `no_std` may be added later" ); |
| 161 | |
| 162 | #[cfg (test)] |
| 163 | #[macro_use ] |
| 164 | extern crate doc_comment; |
| 165 | |
| 166 | #[cfg (test)] |
| 167 | doctest!("../README.md" ); |
| 168 | |
| 169 | #[macro_use ] |
| 170 | mod convert; |
| 171 | |
| 172 | pub mod header; |
| 173 | pub mod method; |
| 174 | pub mod request; |
| 175 | pub mod response; |
| 176 | pub mod status; |
| 177 | pub mod uri; |
| 178 | pub mod version; |
| 179 | |
| 180 | mod byte_str; |
| 181 | mod error; |
| 182 | mod extensions; |
| 183 | |
| 184 | pub use crate::error::{Error, Result}; |
| 185 | pub use crate::extensions::Extensions; |
| 186 | #[doc (no_inline)] |
| 187 | pub use crate::header::{HeaderMap, HeaderName, HeaderValue}; |
| 188 | pub use crate::method::Method; |
| 189 | pub use crate::request::Request; |
| 190 | pub use crate::response::Response; |
| 191 | pub use crate::status::StatusCode; |
| 192 | pub use crate::uri::Uri; |
| 193 | pub use crate::version::Version; |
| 194 | |
| 195 | #[cfg (test)] |
| 196 | mod tests { |
| 197 | use super::*; |
| 198 | |
| 199 | fn assert_send_sync<T: Send + Sync>() {} |
| 200 | |
| 201 | #[test ] |
| 202 | fn request_satisfies_send_sync() { |
| 203 | assert_send_sync::<Request<()>>(); |
| 204 | } |
| 205 | |
| 206 | #[test ] |
| 207 | fn response_satisfies_send_sync() { |
| 208 | assert_send_sync::<Response<()>>(); |
| 209 | } |
| 210 | } |
| 211 | |