hyper_sync/lib.rs
1#![doc(html_root_url = "https://docs.rs/hyper-sync/v0.10.14")]
2#![cfg_attr(test, deny(missing_docs))]
3#![cfg_attr(test, deny(warnings))]
4#![cfg_attr(all(test, feature = "nightly"), feature(test))]
5
6//! # Hyper
7//!
8//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
9//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
10//! layer over "stringly-typed" HTTP.
11//!
12//! Hyper offers both a [Client](client/index.html) and a
13//! [Server](server/index.html) which can be used to drive complex web
14//! applications written entirely in Rust.
15//!
16//! ## Internal Design
17//!
18//! Hyper is designed as a relatively low-level wrapper over raw HTTP. It should
19//! allow the implementation of higher-level abstractions with as little pain as
20//! possible, and should not irrevocably hide any information from its users.
21//!
22//! ### Common Functionality
23//!
24//! Functionality and code shared between the Server and Client implementations
25//! can be found in `src` directly - this includes `NetworkStream`s, `Method`s,
26//! `StatusCode`, and so on.
27//!
28//! #### Methods
29//!
30//! Methods are represented as a single `enum` to remain as simple as possible.
31//! Extension Methods are represented as raw `String`s. A method's safety and
32//! idempotence can be accessed using the `safe` and `idempotent` methods.
33//!
34//! #### StatusCode
35//!
36//! Status codes are also represented as a single, exhaustive, `enum`. This
37//! representation is efficient, typesafe, and ergonomic as it allows the use of
38//! `match` to disambiguate known status codes.
39//!
40//! #### Headers
41//!
42//! Hyper's [header](header/index.html) representation is likely the most
43//! complex API exposed by Hyper.
44//!
45//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
46//! typesafe API for interacting with headers that does not rely on the use of
47//! "string-typing."
48//!
49//! Each HTTP header in Hyper has an associated type and implementation of the
50//! `Header` trait, which defines an HTTP headers name as a string, how to parse
51//! that header, and how to format that header.
52//!
53//! Headers are then parsed from the string representation lazily when the typed
54//! representation of a header is requested and formatted back into their string
55//! representation when headers are written back to the client.
56//!
57//! #### NetworkStream and NetworkAcceptor
58//!
59//! These are found in `src/net.rs` and define the interface that acceptors and
60//! streams must fulfill for them to be used within Hyper. They are by and large
61//! internal tools and you should only need to mess around with them if you want to
62//! mock or replace `TcpStream` and `TcpAcceptor`.
63//!
64//! ### Server
65//!
66//! Server-specific functionality, such as `Request` and `Response`
67//! representations, are found in in `src/server`.
68//!
69//! #### Handler + Server
70//!
71//! A `Handler` in Hyper accepts a `Request` and `Response`. This is where
72//! user-code can handle each connection. The server accepts connections in a
73//! task pool with a customizable number of threads, and passes the Request /
74//! Response to the handler.
75//!
76//! #### Request
77//!
78//! An incoming HTTP Request is represented as a struct containing
79//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
80//! address, an HTTP version, and a `Method` - relatively standard stuff.
81//!
82//! `Request` implements `Reader` itself, meaning that you can ergonomically get
83//! the body out of a `Request` using standard `Reader` methods and helpers.
84//!
85//! #### Response
86//!
87//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
88//! over a `NetworkStream` which represents the Response body in addition to
89//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
90//! implementation provides a streaming interface for sending data over to the
91//! client.
92//!
93//! One of the traditional problems with representing outgoing HTTP Responses is
94//! tracking the write-status of the Response - have we written the status-line,
95//! the headers, the body, etc.? Hyper tracks this information statically using the
96//! type system and prevents you, using the type system, from writing headers after
97//! you have started writing to the body or vice versa.
98//!
99//! Hyper does this through a phantom type parameter in the definition of Response,
100//! which tracks whether you are allowed to write to the headers or the body. This
101//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
102//! indicating that you can write the headers and `Streaming` indicating that you
103//! may write to the body, but not the headers.
104//!
105//! ### Client
106//!
107//! Client-specific functionality, such as `Request` and `Response`
108//! representations, are found in `src/client`.
109//!
110//! #### Request
111//!
112//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
113//! a `NetworkStream` which represents the Request body in addition to the standard
114//! information such as headers and the request method.
115//!
116//! Outgoing Requests track their write-status in almost exactly the same way as
117//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
118//! in the documentation for server Response.
119//!
120//! Requests expose an efficient streaming interface instead of a builder pattern,
121//! but they also provide the needed interface for creating a builder pattern over
122//! the API exposed by core Hyper.
123//!
124//! #### Response
125//!
126//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
127//! a `NetworkStream` and contain headers, a status, and an http version. They
128//! implement `Reader` and can be read to get the data out of a `Response`.
129//!
130
131extern crate base64;
132extern crate bytes;
133extern crate time;
134#[macro_use] extern crate url;
135extern crate unicase;
136extern crate httparse;
137extern crate num_cpus;
138extern crate percent_encoding;
139extern crate language_tags;
140extern crate mime as mime_crate;
141
142#[macro_use]
143extern crate log;
144
145#[cfg(all(test, feature = "nightly"))]
146extern crate test;
147
148
149pub use url::Url;
150pub use client::Client;
151pub use error::{Result, Error};
152pub use method::Method::{self, Get, Head, Post, Delete};
153pub use status::StatusCode::{Ok, BadRequest, NotFound};
154pub use server::Server;
155pub use language_tags::LanguageTag;
156
157macro_rules! todo(
158 ($($arg:tt)*) => (if cfg!(not(ndebug)) {
159 trace!("TODO: {:?}", format_args!($($arg)*))
160 })
161);
162
163#[cfg(test)]
164#[macro_use]
165mod mock;
166#[doc(hidden)]
167pub mod buffer;
168pub mod client;
169pub mod error;
170pub mod method;
171pub mod header;
172pub mod http;
173pub mod net;
174pub mod server;
175pub mod status;
176pub mod uri;
177pub mod version;
178
179/// Re-exporting the mime crate, for convenience.
180pub mod mime {
181 pub use mime_crate::*;
182}
183
184fn _assert_types() {
185 fn _assert_send<T: Send>() {}
186 fn _assert_sync<T: Sync>() {}
187
188 _assert_send::<Client>();
189 _assert_send::<client::Request<net::Fresh>>();
190 _assert_send::<client::Response>();
191 _assert_send::<error::Error>();
192 _assert_send::<::client::pool::Pool<::net::DefaultConnector>>();
193
194 _assert_sync::<Client>();
195 _assert_sync::<error::Error>();
196 _assert_sync::<::client::pool::Pool<::net::DefaultConnector>>();
197}
198
199use std::any::{Any, TypeId};
200
201#[doc(hidden)]
202pub trait GetType: Any {
203 #[inline(always)]
204 fn get_type(&self) -> TypeId {
205 TypeId::of::<Self>()
206 }
207}
208
209impl<T: Any> GetType for T {}