http_types/
lib.rs

1//! # Common types for HTTP operations.
2//!
3//! `http-types` provides shared types for HTTP operations. It combines a performant, streaming
4//! interface with convenient methods for creating headers, urls, and other standard HTTP types.
5//!
6//! # Example
7//!
8//! ```
9//! # fn main() -> Result<(), http_types::url::ParseError> {
10//! #
11//! use http_types::{Method, Request, Response, StatusCode};
12//!
13//! let mut req = Request::new(Method::Get, "https://example.com");
14//! req.set_body("Hello, Nori!");
15//!
16//! let mut res = Response::new(StatusCode::Ok);
17//! res.set_body("Hello, Chashu!");
18//! #
19//! # Ok(()) }
20//! ```
21//!
22//! # How does HTTP work?
23//!
24//! We couldn't possibly explain _all_ of HTTP here: there are [5 versions](enum.Version.html) of
25//! the protocol now, and lots of extensions. But, at its core, there are only a few concepts you
26//! need to know about in order to understand what this crate does.
27//!
28//! ```txt
29//!          request
30//! client ----------> server
31//!        <----------
32//!          response
33//! ```
34//!
35//! HTTP is an [RPC protocol](https://en.wikipedia.org/wiki/Remote_procedure_call). A client
36//! creates a [`Request`](struct.Request.html) containing a [`Url`](struct.Url.html),
37//! [`Method`](struct.Method.html), [`Headers`](struct.Headers.html), and optional
38//! [`Body`](struct.Body.html) and sends this to a server. The server then decodes this `Request`,
39//! does some work, and sends back a [`Response`](struct.Response.html).
40//!
41//! The `Url` works as a way to subdivide an IP address/domain into further addressable resources.
42//! The `Method` indicates what kind of operation we're trying to perform (get something, submit
43//! something, update something, etc.)
44//!
45//! ```txt
46//!   Request
47//! |-----------------|
48//! | Url             |
49//! | Method          |
50//! | Headers         |
51//! |-----------------|
52//! | Body (optional) |
53//! |-----------------|
54//! ```
55//!
56//! A `Response` consists of a [`StatusCode`](enum.StatusCode.html),
57//! [`Headers`](struct.Headers.html), and optionally a [`Body`](struct.Body.html). The client then
58//! decodes the `Response`, and can then operate on it. Usually the first thing it does is check
59//! the status code to see if its `Request` was successful or not, and then moves on to the information contained within the headers.
60//!
61//! ```txt
62//!      Response
63//! |-----------------|
64//! | StatusCode      |
65//! | Headers         |
66//! |-----------------|
67//! | Body (optional) |
68//! |-----------------|
69//! ```
70//!
71//! Both `Request` and `Response` include [`Headers`](struct.Headers.html). This is like key-value metadata for HTTP
72//! requests. It needs to be encoded in a specific way (all lowercase ASCII, only some special
73//! characters) so we use the [`HeaderName`](headers/struct.HeaderName.html) and
74//! [`HeaderValue`](headers/struct.HeaderValue.html) structs rather than strings to ensure that.
75//! Another interesting thing about this is that it's valid to have multiple instances of the
76//! same header name. This is why `Headers` allows inserting multiple values, and always returns a
77//! [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html) of headers for each key.
78//!
79//! When reading up on HTTP you might frequently hear a lot of jargon related to ther underlying
80//! protocols. But even newer HTTP versions (`HTTP/2`, `HTTP/3`) still fundamentally use the
81//! request/response model we've described so far.
82//!
83//! # The Body Type
84//!
85//! In HTTP, [`Body`](struct.Body.html) types are optional. The content of a `Body` is a stream of
86//! bytes with a specific encoding; this encoding is its [`Mime` type](struct.Mime.html). The `Mime` can
87//! be set using the [`set_content_type`](struct.Request.html#method.set_content_type) method, and
88//! there are many different possible `Mime` types.
89//!
90//! `http-types`' `Body` struct can take anything that implements
91//! [`AsyncBufRead`](https://docs.rs/futures/0.3.1/futures/io/trait.AsyncBufRead.html) and stream
92//! it out. Depending on the version of HTTP used, the underlying bytes will be transmitted
93//! differently. As a rule, if you know the size of the body it's usually more efficient to
94//! declare it up front. But if you don't, things will still work.
95
96#![deny(missing_debug_implementations, nonstandard_style)]
97#![warn(missing_docs)]
98#![allow(clippy::new_without_default)]
99#![cfg_attr(backtrace, feature(backtrace))]
100#![cfg_attr(feature = "docs", feature(doc_cfg))]
101#![doc(html_favicon_url = "https://yoshuawuyts.com/assets/http-rs/favicon.ico")]
102#![doc(html_logo_url = "https://yoshuawuyts.com/assets/http-rs/logo-rounded.png")]
103
104/// HTTP cookies.
105#[cfg(feature = "cookies")]
106pub mod cookies {
107    pub use cookie::*;
108}
109
110/// URL records.
111pub mod url {
112    pub use url::{
113        EncodingOverride, Host, OpaqueOrigin, Origin, ParseError, ParseOptions, PathSegmentsMut,
114        Position, SyntaxViolation, Url, UrlQuery,
115    };
116}
117
118#[macro_use]
119mod utils;
120
121pub mod auth;
122pub mod cache;
123pub mod conditional;
124pub mod content;
125pub mod headers;
126pub mod mime;
127pub mod other;
128pub mod proxies;
129pub mod server;
130pub mod trace;
131pub mod transfer;
132pub mod upgrade;
133
134mod body;
135mod error;
136mod extensions;
137mod macros;
138mod method;
139mod parse_utils;
140mod request;
141mod response;
142mod status;
143mod status_code;
144mod version;
145
146pub use body::Body;
147pub use error::{Error, Result};
148pub use method::Method;
149pub use request::Request;
150pub use response::Response;
151pub use status::Status;
152pub use status_code::StatusCode;
153pub use version::Version;
154
155#[doc(inline)]
156pub use trailers::Trailers;
157
158#[doc(inline)]
159pub use mime::Mime;
160
161#[doc(inline)]
162pub use headers::Headers;
163
164#[doc(inline)]
165pub use crate::url::Url;
166
167#[cfg(feature = "cookies")]
168#[doc(inline)]
169pub use crate::cookies::Cookie;
170
171pub mod security;
172pub mod trailers;
173
174#[cfg(feature = "hyperium_http")]
175mod hyperium_http;
176
177#[doc(inline)]
178pub use crate::extensions::Extensions;
179
180/// Traits for conversions between types.
181pub mod convert {
182    pub use serde::{de::DeserializeOwned, Deserialize, Serialize};
183    #[doc(inline)]
184    pub use serde_json::json;
185}
186
187// Not public API. Referenced by macro-generated code.
188#[doc(hidden)]
189pub mod private {
190    use crate::Error;
191    pub use crate::StatusCode;
192    use core::fmt::{Debug, Display};
193    pub use core::result::Result::Err;
194
195    pub fn new_adhoc<M>(message: M) -> Error
196    where
197        M: Display + Debug + Send + Sync + 'static,
198    {
199        Error::new_adhoc(message)
200    }
201}