| #![doc(html_root_url = "https://docs.rs/http/0.2.6")] |
| |
| //! A general purpose library of common HTTP types |
| //! |
| //! This crate is a general purpose library for common types found when working |
| //! with the HTTP protocol. You'll find `Request` and `Response` types for |
| //! working as either a client or a server as well as all of their components. |
| //! Notably you'll find `Uri` for what a `Request` is requesting, a `Method` |
| //! for how it's being requested, a `StatusCode` for what sort of response came |
| //! back, a `Version` for how this was communicated, and |
| //! `HeaderName`/`HeaderValue` definitions to get grouped in a `HeaderMap` to |
| //! work with request/response headers. |
| //! |
| //! You will notably *not* find an implementation of sending requests or |
| //! spinning up a server in this crate. It's intended that this crate is the |
| //! "standard library" for HTTP clients and servers without dictating any |
| //! particular implementation. Note that this crate is still early on in its |
| //! lifecycle so the support libraries that integrate with the `http` crate are |
| //! a work in progress! Stay tuned and we'll be sure to highlight crates here |
| //! in the future. |
| //! |
| //! ## Requests and Responses |
| //! |
| //! Perhaps the main two types in this crate are the `Request` and `Response` |
| //! types. A `Request` could either be constructed to get sent off as a client |
| //! or it can also be received to generate a `Response` for a server. Similarly |
| //! as a client a `Response` is what you get after sending a `Request`, whereas |
| //! on a server you'll be manufacturing a `Response` to send back to the client. |
| //! |
| //! Each type has a number of accessors for the component fields. For as a |
| //! server you might want to inspect a requests URI to dispatch it: |
| //! |
| //! ``` |
| //! use http::{Request, Response}; |
| //! |
| //! fn response(req: Request<()>) -> http::Result<Response<()>> { |
| //! match req.uri().path() { |
| //! "/" => index(req), |
| //! "/foo" => foo(req), |
| //! "/bar" => bar(req), |
| //! _ => not_found(req), |
| //! } |
| //! } |
| //! # fn index(_req: Request<()>) -> http::Result<Response<()>> { panic!() } |
| //! # fn foo(_req: Request<()>) -> http::Result<Response<()>> { panic!() } |
| //! # fn bar(_req: Request<()>) -> http::Result<Response<()>> { panic!() } |
| //! # fn not_found(_req: Request<()>) -> http::Result<Response<()>> { panic!() } |
| //! ``` |
| //! |
| //! On a `Request` you'll also find accessors like `method` to return a |
| //! `Method` and `headers` to inspect the various headers. A `Response` |
| //! has similar methods for headers, the status code, etc. |
| //! |
| //! In addition to getters, request/response types also have mutable accessors |
| //! to edit the request/response: |
| //! |
| //! ``` |
| //! use http::{HeaderValue, Response, StatusCode}; |
| //! use http::header::CONTENT_TYPE; |
| //! |
| //! fn add_server_headers<T>(response: &mut Response<T>) { |
| //! response.headers_mut() |
| //! .insert(CONTENT_TYPE, HeaderValue::from_static("text/html")); |
| //! *response.status_mut() = StatusCode::OK; |
| //! } |
| //! ``` |
| //! |
| //! And finally, one of the most important aspects of requests/responses, the |
| //! body! The `Request` and `Response` types in this crate are *generic* in |
| //! what their body is. This allows downstream libraries to use different |
| //! representations such as `Request<Vec<u8>>`, `Response<impl Read>`, |
| //! `Request<impl Stream<Item = Vec<u8>, Error = _>>`, or even |
| //! `Response<MyCustomType>` where the custom type was deserialized from JSON. |
| //! |
| //! The body representation is intentionally flexible to give downstream |
| //! libraries maximal flexibility in implementing the body as appropriate. |
| //! |
| //! ## HTTP Headers |
| //! |
| //! Another major piece of functionality in this library is HTTP header |
| //! interpretation and generation. The `HeaderName` type serves as a way to |
| //! define header *names*, or what's to the left of the colon. A `HeaderValue` |
| //! conversely is the header *value*, or what's to the right of a colon. |
| //! |
| //! For example, if you have an HTTP request that looks like: |
| //! |
| //! ```http |
| //! GET /foo HTTP/1.1 |
| //! Accept: text/html |
| //! ``` |
| //! |
| //! Then `"Accept"` is a `HeaderName` while `"text/html"` is a `HeaderValue`. |
| //! Each of these is a dedicated type to allow for a number of interesting |
| //! optimizations and to also encode the static guarantees of each type. For |
| //! example a `HeaderName` is always a valid `&str`, but a `HeaderValue` may |
| //! not be valid UTF-8. |
| //! |
| //! The most common header names are already defined for you as constant values |
| //! in the `header` module of this crate. For example: |
| //! |
| //! ``` |
| //! use http::header::{self, HeaderName}; |
| //! |
| //! let name: HeaderName = header::ACCEPT; |
| //! assert_eq!(name.as_str(), "accept"); |
| //! ``` |
| //! |
| //! You can, however, also parse header names from strings: |
| //! |
| //! ``` |
| //! use http::header::{self, HeaderName}; |
| //! |
| //! let name = "Accept".parse::<HeaderName>().unwrap(); |
| //! assert_eq!(name, header::ACCEPT); |
| //! ``` |
| //! |
| //! Header values can be created from string literals through the `from_static` |
| //! function: |
| //! |
| //! ``` |
| //! use http::HeaderValue; |
| //! |
| //! let value = HeaderValue::from_static("text/html"); |
| //! assert_eq!(value.as_bytes(), b"text/html"); |
| //! ``` |
| //! |
| //! And header values can also be parsed like names: |
| //! |
| //! ``` |
| //! use http::HeaderValue; |
| //! |
| //! let value = "text/html"; |
| //! let value = value.parse::<HeaderValue>().unwrap(); |
| //! ``` |
| //! |
| //! Most HTTP requests and responses tend to come with more than one header, so |
| //! it's not too useful to just work with names and values only! This crate also |
| //! provides a `HeaderMap` type which is a specialized hash map for keys as |
| //! `HeaderName` and generic values. This type, like header names, is optimized |
| //! for common usage but should continue to scale with your needs over time. |
| //! |
| //! # URIs |
| //! |
| //! Each HTTP `Request` has an associated URI with it. This may just be a path |
| //! like `/index.html` but it could also be an absolute URL such as |
| //! `https://www.rust-lang.org/index.html`. A `URI` has a number of accessors to |
| //! interpret it: |
| //! |
| //! ``` |
| //! use http::Uri; |
| //! use http::uri::Scheme; |
| //! |
| //! let uri = "https://www.rust-lang.org/index.html".parse::<Uri>().unwrap(); |
| //! |
| //! assert_eq!(uri.scheme(), Some(&Scheme::HTTPS)); |
| //! assert_eq!(uri.host(), Some("www.rust-lang.org")); |
| //! assert_eq!(uri.path(), "/index.html"); |
| //! assert_eq!(uri.query(), None); |
| //! ``` |
| |
| #![deny(warnings, missing_docs, missing_debug_implementations)] |
| |
| #[cfg(test)] |
| #[macro_use] |
| extern crate doc_comment; |
| |
| #[cfg(test)] |
| doctest!("../README.md"); |
| |
| #[macro_use] |
| mod convert; |
| |
| pub mod header; |
| pub mod method; |
| pub mod request; |
| pub mod response; |
| pub mod status; |
| pub mod uri; |
| pub mod version; |
| |
| mod byte_str; |
| mod error; |
| mod extensions; |
| |
| pub use crate::error::{Error, Result}; |
| pub use crate::extensions::Extensions; |
| #[doc(no_inline)] |
| pub use crate::header::{HeaderMap, HeaderValue}; |
| pub use crate::method::Method; |
| pub use crate::request::Request; |
| pub use crate::response::Response; |
| pub use crate::status::StatusCode; |
| pub use crate::uri::Uri; |
| pub use crate::version::Version; |
| |
| fn _assert_types() { |
| fn assert_send<T: Send>() {} |
| fn assert_sync<T: Sync>() {} |
| |
| assert_send::<Request<()>>(); |
| assert_send::<Response<()>>(); |
| |
| assert_sync::<Request<()>>(); |
| assert_sync::<Response<()>>(); |
| } |
| |
| mod sealed { |
| /// Private trait to this crate to prevent traits from being implemented in |
| /// downstream crates. |
| pub trait Sealed {} |
| } |