use std::old_io::net::ip::IpAddr;
use hyper::net::Fresh;
use hyper::Server as HttpServer;
use { Request, Response, WebResult, status };
use request::HttpRequest;
use response::HttpResponse;
pub struct Service<H> {
handler: H
}
impl<H: Handler + 'static> Service<H> {
pub fn new(handler: H) -> Service<H> {
Service { handler: handler }
}
pub fn listen(self, addr: IpAddr, port: u16) {
HttpServer::http(addr, port).listen(self).unwrap();
}
}
pub trait Handler: Send + Sync {
fn call(&self, &Request) -> WebResult<Response>;
}
impl<F> Handler for F where F: Fn(&Request) -> WebResult<Response>, F: Sync + Send {
fn call(&self, req: &Request) -> WebResult<Response> {
self(req)
}
}
impl<H: Handler> ::hyper::server::Handler for Service<H> {
fn handle(&self, http_req: HttpRequest, mut http_res: HttpResponse<Fresh>) {
let req = match Request::from_http(http_req) {
Ok(req) => req,
Err(_) => {
*http_res.status_mut() = status::BadRequest;
let http_res = match http_res.start() {
Ok(res) => res,
Err(_) => return,
};
let _ = http_res.end();
return;
}
};
let res = self.handler.call(&req);
match res {
Ok(res) => res.write_back(http_res),
Err(e) => {
error!("Error handling:\n{:?}\nError was: {}", req, e);
*http_res.status_mut() = status::BadRequest;
let http_res = match http_res.start() {
Ok(res) => res,
Err(_) => return,
};
let _ = http_res.end();
}
}
}
}