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