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 | |