add some benches with other http libs
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
//! # Client
|
||||
//! HTTP Client
|
||||
use url::Url;
|
||||
|
||||
use method::{Get, Method};
|
||||
use method::{Get, Head, Post, Delete, Method};
|
||||
|
||||
pub use self::request::Request;
|
||||
pub use self::response::Response;
|
||||
@@ -16,6 +16,22 @@ pub fn get(url: Url) -> HttpResult<Request> {
|
||||
request(Get, url)
|
||||
}
|
||||
|
||||
/// Create a HEAD client request.
|
||||
pub fn head(url: Url) -> HttpResult<Request> {
|
||||
request(Head, url)
|
||||
}
|
||||
|
||||
/// Create a POST client request.
|
||||
pub fn post(url: Url) -> HttpResult<Request> {
|
||||
// TODO: should this accept a Body parameter? or just let user `write` to the request?
|
||||
request(Post, url)
|
||||
}
|
||||
|
||||
/// Create a DELETE client request.
|
||||
pub fn delete(url: Url) -> HttpResult<Request> {
|
||||
request(Delete, url)
|
||||
}
|
||||
|
||||
/// Create a client request.
|
||||
pub fn request(method: Method, url: Url) -> HttpResult<Request> {
|
||||
Request::new(method, url)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! # Client Requests
|
||||
//! Client Requests
|
||||
use std::io::net::tcp::TcpStream;
|
||||
use std::io::IoResult;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! # Client Responses
|
||||
//! Client Responses
|
||||
use std::io::{Reader, IoResult};
|
||||
use std::io::net::tcp::TcpStream;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! # Headers
|
||||
//! Headers container, and common header fields.
|
||||
//!
|
||||
//! hyper has the opinion that Headers should be strongly-typed, because that's
|
||||
//! why we're using Rust in the first place. To set or get any header, an object
|
||||
|
||||
@@ -11,7 +11,9 @@ extern crate url;
|
||||
pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port};
|
||||
pub use mimewrapper::mime;
|
||||
pub use url::Url;
|
||||
pub use client::{get};
|
||||
pub use client::{get, head, post, delete, request};
|
||||
pub use method::{Get, Head, Post, Delete};
|
||||
pub use status::{Ok, BadRequest, NotFound};
|
||||
pub use server::Server;
|
||||
|
||||
use std::fmt;
|
||||
@@ -30,7 +32,7 @@ struct Trace;
|
||||
impl fmt::Show for Trace {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let _ = backtrace::write(fmt);
|
||||
Ok(())
|
||||
::std::result::Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! # HTTP Method
|
||||
//! The HTTP request method
|
||||
use std::fmt;
|
||||
use std::from_str::FromStr;
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! # Server
|
||||
use std::io::net::tcp::TcpListener;
|
||||
use std::io::{Acceptor, Listener, IoResult};
|
||||
//! HTTP Server
|
||||
use std::io::net::tcp::{TcpListener, TcpAcceptor};
|
||||
use std::io::{Acceptor, Listener, IoResult, EndOfFile};
|
||||
use std::io::net::ip::{IpAddr, Port};
|
||||
|
||||
pub use self::request::Request;
|
||||
@@ -30,53 +30,72 @@ impl Server {
|
||||
}
|
||||
|
||||
/// Binds to a socket, and starts handling connections.
|
||||
pub fn listen<H: Handler>(&self, mut handler: H) {
|
||||
let listener = match TcpListener::bind(self.ip.to_string().as_slice(), self.port) {
|
||||
Ok(listener) => listener,
|
||||
Err(err) => fail!("Listen failed: {}", err)
|
||||
};
|
||||
let mut acceptor = listener.listen();
|
||||
pub fn listen<H: Handler + 'static>(&self, mut handler: H) -> IoResult<Listening> {
|
||||
let listener = try!(TcpListener::bind(self.ip.to_string().as_slice(), self.port));
|
||||
let acceptor = try!(listener.listen());
|
||||
let worker = acceptor.clone();
|
||||
|
||||
for conn in acceptor.incoming() {
|
||||
match conn {
|
||||
Ok(stream) => {
|
||||
debug!("Incoming stream");
|
||||
let clone = stream.clone();
|
||||
let req = match Request::new(stream) {
|
||||
Ok(r) => r,
|
||||
Err(err) => {
|
||||
error!("creating Request: {}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let mut res = Response::new(clone);
|
||||
res.version = req.version;
|
||||
match handler.handle(req, res) {
|
||||
Ok(..) => debug!("Stream handled"),
|
||||
Err(e) => {
|
||||
error!("Error from handler: {}", e)
|
||||
//TODO try to send a status code
|
||||
spawn(proc() {
|
||||
let mut acceptor = worker;
|
||||
for conn in acceptor.incoming() {
|
||||
match conn {
|
||||
Ok(stream) => {
|
||||
debug!("Incoming stream");
|
||||
let clone = stream.clone();
|
||||
let req = match Request::new(stream) {
|
||||
Ok(r) => r,
|
||||
Err(err) => {
|
||||
error!("creating Request: {}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let mut res = Response::new(clone);
|
||||
res.version = req.version;
|
||||
match handler.handle(req, res) {
|
||||
Ok(..) => debug!("Stream handled"),
|
||||
Err(e) => {
|
||||
error!("Error from handler: {}", e)
|
||||
//TODO try to send a status code
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(ref e) if e.kind == EndOfFile => break, // server closed
|
||||
Err(e) => {
|
||||
error!("Connection failed: {}", e);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Connection failed: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Listening {
|
||||
acceptor: acceptor
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// A listening server, which can later be closed.
|
||||
pub struct Listening {
|
||||
acceptor: TcpAcceptor
|
||||
}
|
||||
|
||||
impl Listening {
|
||||
/// Stop the server from listening to it's socket address.
|
||||
pub fn close(mut self) -> IoResult<()> {
|
||||
debug!("closing server");
|
||||
self.acceptor.close_accept()
|
||||
}
|
||||
}
|
||||
|
||||
/// A handler that can handle incoming requests for a server.
|
||||
pub trait Handler {
|
||||
pub trait Handler: Send {
|
||||
/// Receives a `Request`/`Response` pair, and should perform some action on them.
|
||||
///
|
||||
/// This could reading from the request, and writing to the response.
|
||||
fn handle(&mut self, req: Request, res: Response) -> IoResult<()>;
|
||||
}
|
||||
|
||||
impl<'a> Handler for |Request, Response|: 'a -> IoResult<()> {
|
||||
impl Handler for fn(Request, Response) -> IoResult<()> {
|
||||
fn handle(&mut self, req: Request, res: Response) -> IoResult<()> {
|
||||
(*self)(req, res)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! # Server Requests
|
||||
//! Server Requests
|
||||
//!
|
||||
//! These are requests that a `hyper::Server` receives, and include its method,
|
||||
//! target URI, headers, and message body.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! # Server Responses
|
||||
//! Server Responses
|
||||
//!
|
||||
//! These are responses sent by a `hyper::Server` to clients, after
|
||||
//! receiving a request.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! # RequestUri
|
||||
//! HTTP RequestUris
|
||||
use url::Url;
|
||||
|
||||
/// The Request-URI of a Request's StartLine.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! # HTTP Versions
|
||||
//! HTTP Versions enum
|
||||
//!
|
||||
//! Instead of relying on typo-prone Strings, use expected HTTP versions as
|
||||
//! the `HttpVersion` enum.
|
||||
|
||||
Reference in New Issue
Block a user