http/
lib.rs

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"))]
160compile_error!("`std` feature currently required, support for `no_std` may be added later");
161
162#[cfg(test)]
163#[macro_use]
164extern crate doc_comment;
165
166#[cfg(test)]
167doctest!("../README.md");
168
169#[macro_use]
170mod convert;
171
172pub mod header;
173pub mod method;
174pub mod request;
175pub mod response;
176pub mod status;
177pub mod uri;
178pub mod version;
179
180mod byte_str;
181mod error;
182mod extensions;
183
184pub use crate::error::{Error, Result};
185pub use crate::extensions::Extensions;
186#[doc(no_inline)]
187pub use crate::header::{HeaderMap, HeaderName, HeaderValue};
188pub use crate::method::Method;
189pub use crate::request::Request;
190pub use crate::response::Response;
191pub use crate::status::StatusCode;
192pub use crate::uri::Uri;
193pub use crate::version::Version;
194
195#[cfg(test)]
196mod 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}