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