1 #![doc(html_root_url = "https://docs.rs/http/0.2.9")]
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
_assert_types()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