cogo_http/
lib.rs

1#![doc(html_root_url = "https://docs.rs/hyper/v0.10.16")]
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//! cogo-http 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//! cogo-http 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//! cogo-http 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 cogo-http 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 cogo-http 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.? cogo-http 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//! cogo-http 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 time;
133#[macro_use] extern crate url;
134extern crate unicase;
135extern crate httparse;
136extern crate traitobject;
137extern crate typeable;
138
139#[cfg_attr(test, macro_use)]
140extern crate language_tags;
141
142#[macro_use]
143extern crate mime as mime_crate;
144
145#[macro_use]
146extern crate log;
147
148#[cfg(all(test, feature = "nightly"))]
149extern crate test;
150
151
152pub use url::Url;
153pub use client::Client;
154pub use error::{Result, Error};
155pub use method::Method::{Get, Head, Post, Delete};
156pub use status::StatusCode::{Ok, BadRequest, NotFound};
157pub use server::Server;
158pub use language_tags::LanguageTag;
159
160macro_rules! todo(
161    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
162        trace!("TODO: {:?}", format_args!($($arg)*))
163    })
164);
165
166//#[cfg(test)]
167#[macro_use]
168pub mod mock;
169#[doc(hidden)]
170pub mod buffer;
171pub mod client;
172pub mod error;
173pub mod method;
174pub mod header;
175pub mod http;
176pub mod net;
177pub mod server;
178pub mod status;
179pub mod uri;
180pub mod version;
181pub mod multipart;
182pub mod query;
183pub mod path;
184pub mod route;
185pub mod runtime;
186pub mod json;
187
188/// Re-exporting the mime crate, for convenience.
189pub mod mime {
190    pub use mime_crate::*;
191}
192
193
194fn _assert_types() {
195    fn _assert_send<T: Send>() {}
196    fn _assert_sync<T: Sync>() {}
197
198    _assert_send::<Client>();
199    _assert_send::<client::Request<net::Fresh>>();
200    _assert_send::<client::Response>();
201    _assert_send::<error::Error>();
202    _assert_send::<crate::client::pool::Pool<crate::net::DefaultConnector>>();
203
204    _assert_sync::<Client>();
205    _assert_sync::<error::Error>();
206    _assert_sync::<crate::client::pool::Pool<crate::net::DefaultConnector>>();
207}