Move internal design overview to documentation, add examples to README
While the README examples are not checked by rustdoc, they are important to have as they show-off hyper to the world :)
This commit is contained in:
147
README.md
147
README.md
@@ -17,6 +17,47 @@ complex web applications written entirely in Rust.
|
|||||||
|
|
||||||
The documentation is located at [http://hyperium.github.io/hyper](http://hyperium.github.io/hyper).
|
The documentation is located at [http://hyperium.github.io/hyper](http://hyperium.github.io/hyper).
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Echo Server:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn echo(mut incoming: Incoming) {
|
||||||
|
for (_, mut res) in incoming {
|
||||||
|
*res.status_mut() = hyper::status::Ok;
|
||||||
|
let mut res = res.start().unwrap();
|
||||||
|
res.write(b"Hello World!");
|
||||||
|
res.end().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let server = Server::http(Ipv4Addr(127, 0, 0, 1), 1337);
|
||||||
|
server.listen(echo).unwrap();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Client:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn main() {
|
||||||
|
// Creating an outgoing request.
|
||||||
|
let mut req = Request::get(Url::parse("http://www.gooogle.com/")).unwrap();
|
||||||
|
|
||||||
|
// Setting a header.
|
||||||
|
req.headers_mut().set(Foo);
|
||||||
|
|
||||||
|
// Start the Request, writing headers and starting streaming.
|
||||||
|
let res = req.start().unwrap()
|
||||||
|
// Send the Request.
|
||||||
|
.send().unwrap()
|
||||||
|
// Read the Response.
|
||||||
|
.read_to_string().unwrap()
|
||||||
|
|
||||||
|
println!("Response: {}", res);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Scientific\* Benchmarks
|
## Scientific\* Benchmarks
|
||||||
|
|
||||||
[Client Bench:](./benches/client.rs)
|
[Client Bench:](./benches/client.rs)
|
||||||
@@ -56,112 +97,6 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured
|
|||||||
|
|
||||||
\* No science was harmed in the making of this benchmark.
|
\* No science was harmed in the making of this benchmark.
|
||||||
|
|
||||||
## Internal Design
|
|
||||||
|
|
||||||
Hyper is designed as a relatively low-level wrapped over raw HTTP. It should
|
|
||||||
allow the implementation of higher-level abstractions with as little pain as
|
|
||||||
possible, and should not irrevocably hide any information from its users.
|
|
||||||
|
|
||||||
### Common Functionality
|
|
||||||
|
|
||||||
Functionality and code shared between the Server and Client implementations can
|
|
||||||
be found in `src` directly - this includes `NetworkStream`s, `Method`s,
|
|
||||||
`StatusCode`, and so on.
|
|
||||||
|
|
||||||
#### Methods
|
|
||||||
|
|
||||||
Methods are represented as a single `enum` to remain as simple as possible.
|
|
||||||
Extension Methods are represented as raw `String`s. A method's safety and
|
|
||||||
idempotence can be accessed using the `safe` and `idempotent` methods.
|
|
||||||
|
|
||||||
#### StatusCode
|
|
||||||
|
|
||||||
Status codes are also represented as a single, exhaustive, `enum`. This
|
|
||||||
representation is efficient, typesafe, and ergonomic as it allows the use of
|
|
||||||
`match` to disambiguate known status codes.
|
|
||||||
|
|
||||||
#### Headers
|
|
||||||
|
|
||||||
Hyper's header representation is likely the most complex API exposed by Hyper.
|
|
||||||
|
|
||||||
Hyper's headers are an abstraction over an internal `HashMap` and provides a
|
|
||||||
typesafe API for interacting with headers that does not rely on the use of
|
|
||||||
"string-typing."
|
|
||||||
|
|
||||||
Each HTTP header in Hyper has an associated type and implementation of the
|
|
||||||
`Header` trait, which defines an HTTP headers name as a string, how to parse
|
|
||||||
that header, and how to format that header.
|
|
||||||
|
|
||||||
Headers are then parsed from the string representation lazily when the typed
|
|
||||||
representation of a header is requested and formatted back into their string
|
|
||||||
representation when headers are written back to the client.
|
|
||||||
|
|
||||||
#### NetworkStream and NetworkAcceptor
|
|
||||||
|
|
||||||
These are found in `src/net.rs` and define the interface that acceptors and
|
|
||||||
streams must fulfill for them to be used within Hyper. They are by and large
|
|
||||||
internal tools and you should only need to mess around with them if you want to
|
|
||||||
mock or replace `TcpStream` and `TcpAcceptor`.
|
|
||||||
|
|
||||||
### Server
|
|
||||||
|
|
||||||
Server-specific functionality, such as `Request` and `Response`
|
|
||||||
representations, are found in in `src/server`.
|
|
||||||
|
|
||||||
#### Request
|
|
||||||
|
|
||||||
An incoming HTTP Request is represented as a struct containing
|
|
||||||
a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
|
|
||||||
address, an HTTP version, and a `Method` - relatively standard stuff.
|
|
||||||
|
|
||||||
`Request` implements `Reader` itself, meaning that you can ergonomically get
|
|
||||||
the body out of a `Request` using standard `Reader` methods and helpers.
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
|
|
||||||
An outgoing HTTP Response is also represented as a struct containing a `Writer`
|
|
||||||
over a `NetworkStream` which represents the Response body in addition to
|
|
||||||
standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
|
|
||||||
implementation provides a streaming interface for sending data over to the
|
|
||||||
client.
|
|
||||||
|
|
||||||
One of the traditional problems with representing outgoing HTTP Responses is
|
|
||||||
tracking the write-status of the Response - have we written the status-line,
|
|
||||||
the headers, the body, etc.? Hyper tracks this information statically using the
|
|
||||||
type system and prevents you, using the type system, from writing headers after
|
|
||||||
you have started writing to the body or vice versa.
|
|
||||||
|
|
||||||
Hyper does this through a phantom type parameter in the definition of Response,
|
|
||||||
which tracks whether you are allowed to write to the headers or the body. This
|
|
||||||
phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
|
|
||||||
indicating that you can write the headers and `Streaming` indicating that you
|
|
||||||
may write to the body, but not the headers.
|
|
||||||
|
|
||||||
### Client
|
|
||||||
|
|
||||||
Client-specific functionality, such as `Request` and `Response`
|
|
||||||
representations, are found in `src/client`.
|
|
||||||
|
|
||||||
#### Request
|
|
||||||
|
|
||||||
An outgoing HTTP Request is represented as a struct containing a `Writer` over
|
|
||||||
a `NetworkStream` which represents the Request body in addition to the standard
|
|
||||||
information such as headers and the request method.
|
|
||||||
|
|
||||||
Outgoing Requests track their write-status in almost exactly the same way as
|
|
||||||
outgoing HTTP Responses do on the Server, so we will defer to the explanation
|
|
||||||
in the documentation for sever Response.
|
|
||||||
|
|
||||||
Requests expose an efficient streaming interface instead of a builder pattern,
|
|
||||||
but they also provide the needed interface for creating a builder pattern over
|
|
||||||
the API exposed by core Hyper.
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
|
|
||||||
Incoming HTTP Responses are represented as a struct containing a `Reader` over
|
|
||||||
a `NetworkStream` and contain headers, a status, and an http version. They
|
|
||||||
implement `Reader` and can be read to get the data out of a `Response`.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](./LICENSE)
|
[MIT](./LICENSE)
|
||||||
|
|||||||
123
src/lib.rs
123
src/lib.rs
@@ -1,9 +1,130 @@
|
|||||||
//! # hyper
|
|
||||||
#![feature(macro_rules, phase, default_type_params)]
|
#![feature(macro_rules, phase, default_type_params)]
|
||||||
#![deny(missing_doc)]
|
#![deny(missing_doc)]
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
#![experimental]
|
#![experimental]
|
||||||
|
|
||||||
|
//! # Hyper
|
||||||
|
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
|
||||||
|
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
|
||||||
|
//! layer over "stringly-typed" HTTP.
|
||||||
|
//!
|
||||||
|
//! Hyper offers both an HTTP/S client an HTTP server which can be used to drive
|
||||||
|
//! complex web applications written entirely in Rust.
|
||||||
|
//!
|
||||||
|
//! ## Internal Design
|
||||||
|
//!
|
||||||
|
//! Hyper is designed as a relatively low-level wrapped over raw HTTP. It should
|
||||||
|
//! allow the implementation of higher-level abstractions with as little pain as
|
||||||
|
//! possible, and should not irrevocably hide any information from its users.
|
||||||
|
//!
|
||||||
|
//! ### Common Functionality
|
||||||
|
//!
|
||||||
|
//! Functionality and code shared between the Server and Client implementations can
|
||||||
|
//! be found in `src` directly - this includes `NetworkStream`s, `Method`s,
|
||||||
|
//! `StatusCode`, and so on.
|
||||||
|
//!
|
||||||
|
//! #### Methods
|
||||||
|
//!
|
||||||
|
//! Methods are represented as a single `enum` to remain as simple as possible.
|
||||||
|
//! Extension Methods are represented as raw `String`s. A method's safety and
|
||||||
|
//! idempotence can be accessed using the `safe` and `idempotent` methods.
|
||||||
|
//!
|
||||||
|
//! #### StatusCode
|
||||||
|
//!
|
||||||
|
//! Status codes are also represented as a single, exhaustive, `enum`. This
|
||||||
|
//! representation is efficient, typesafe, and ergonomic as it allows the use of
|
||||||
|
//! `match` to disambiguate known status codes.
|
||||||
|
//!
|
||||||
|
//! #### Headers
|
||||||
|
//!
|
||||||
|
//! Hyper's header representation is likely the most complex API exposed by Hyper.
|
||||||
|
//!
|
||||||
|
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
|
||||||
|
//! typesafe API for interacting with headers that does not rely on the use of
|
||||||
|
//! "string-typing."
|
||||||
|
//!
|
||||||
|
//! Each HTTP header in Hyper has an associated type and implementation of the
|
||||||
|
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
|
||||||
|
//! that header, and how to format that header.
|
||||||
|
//!
|
||||||
|
//! Headers are then parsed from the string representation lazily when the typed
|
||||||
|
//! representation of a header is requested and formatted back into their string
|
||||||
|
//! representation when headers are written back to the client.
|
||||||
|
//!
|
||||||
|
//! #### NetworkStream and NetworkAcceptor
|
||||||
|
//!
|
||||||
|
//! These are found in `src/net.rs` and define the interface that acceptors and
|
||||||
|
//! streams must fulfill for them to be used within Hyper. They are by and large
|
||||||
|
//! internal tools and you should only need to mess around with them if you want to
|
||||||
|
//! mock or replace `TcpStream` and `TcpAcceptor`.
|
||||||
|
//!
|
||||||
|
//! ### Server
|
||||||
|
//!
|
||||||
|
//! Server-specific functionality, such as `Request` and `Response`
|
||||||
|
//! representations, are found in in `src/serer`.
|
||||||
|
//!
|
||||||
|
//! #### Handler + Server
|
||||||
|
//!
|
||||||
|
//! A Handler in Hyper just accepts an Iterator of `(Request, Response)` pairs and
|
||||||
|
//! does whatever it wants with it. This gives Handlers maximum flexibility to decide
|
||||||
|
//! on concurrency strategy and exactly how they want to distribute the work of
|
||||||
|
//! dealing with `Request` and `Response.`
|
||||||
|
//!
|
||||||
|
//! #### Request
|
||||||
|
//!
|
||||||
|
//! An incoming HTTP Request is represented as a struct containing
|
||||||
|
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
|
||||||
|
//! address, an HTTP version, and a `Method` - relatively standard stuff.
|
||||||
|
//!
|
||||||
|
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
|
||||||
|
//! the body out of a `Request` using standard `Reader` methods and helpers.
|
||||||
|
//!
|
||||||
|
//! #### Response
|
||||||
|
//!
|
||||||
|
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
|
||||||
|
//! over a `NetworkStream` which represents the Response body in addition to
|
||||||
|
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
|
||||||
|
//! implementation provides a streaming interface for sending data over to the
|
||||||
|
//! client.
|
||||||
|
//!
|
||||||
|
//! One of the traditional problems with representing outgoing HTTP Responses is
|
||||||
|
//! tracking the write-status of the Response - have we written the status-line,
|
||||||
|
//! the headers, the body, etc.? Hyper tracks this information statically using the
|
||||||
|
//! type system and prevents you, using the type system, from writing headers after
|
||||||
|
//! you have started writing to the body or vice versa.
|
||||||
|
//!
|
||||||
|
//! Hyper does this through a phantom type parameter in the definition of Response,
|
||||||
|
//! which tracks whether you are allowed to write to the headers or the body. This
|
||||||
|
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
|
||||||
|
//! indicating that you can write the headers and `Streaming` indicating that you
|
||||||
|
//! may write to the body, but not the headers.
|
||||||
|
//!
|
||||||
|
//! ### Client
|
||||||
|
//!
|
||||||
|
//! Client-specific functionality, such as `Request` and `Response`
|
||||||
|
//! representations, are found in `src/client`.
|
||||||
|
//!
|
||||||
|
//! #### Request
|
||||||
|
//!
|
||||||
|
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
|
||||||
|
//! a `NetworkStream` which represents the Request body in addition to the standard
|
||||||
|
//! information such as headers and the request method.
|
||||||
|
//!
|
||||||
|
//! Outgoing Requests track their write-status in almost exactly the same way as
|
||||||
|
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
|
||||||
|
//! in the documentation for sever Response.
|
||||||
|
//!
|
||||||
|
//! Requests expose an efficient streaming interface instead of a builder pattern,
|
||||||
|
//! but they also provide the needed interface for creating a builder pattern over
|
||||||
|
//! the API exposed by core Hyper.
|
||||||
|
//!
|
||||||
|
//! #### Response
|
||||||
|
//!
|
||||||
|
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
|
||||||
|
//! a `NetworkStream` and contain headers, a status, and an http version. They
|
||||||
|
//! implement `Reader` and can be read to get the data out of a `Response`.
|
||||||
|
//!
|
||||||
|
|
||||||
extern crate time;
|
extern crate time;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate openssl;
|
extern crate openssl;
|
||||||
|
|||||||
Reference in New Issue
Block a user