use std::io::net::ip::SocketAddr;
use std::fmt::{mod, Show};
use hyper::uri::RequestUri::{AbsoluteUri, AbsolutePath};
use hyper::header::Headers;
use hyper::method::Method;
use typemap::TypeMap;
use plugin::Extensible;
pub use hyper::server::request::Request as HttpRequest;
pub use self::url::Url;
use {headers};
mod url;
pub struct Request {
pub url: Url,
pub remote_addr: SocketAddr,
pub headers: Headers,
pub body: Vec<u8>,
pub method: Method,
pub extensions: TypeMap
}
impl Show for Request {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(writeln!(f, "Request {{"));
try!(writeln!(f, " url: {}", self.url));
try!(writeln!(f, " method: {}", self.method));
try!(writeln!(f, " remote_addr: {}", self.remote_addr));
try!(writeln!(f, " body: {}", self.body));
try!(write!(f, "}}"));
Ok(())
}
}
impl Request {
pub fn from_http(mut req: HttpRequest) -> Result<Request, String> {
let url = match req.uri {
AbsoluteUri(ref url) => {
match Url::from_generic_url(url.clone()) {
Ok(url) => url,
Err(e) => return Err(e)
}
},
AbsolutePath(ref path) => {
let url_string = match req.headers.get::<headers::Host>() {
Some(ref host) => {
format!("http://{}{}", host.hostname, path)
},
None => return Err("No host specified in request".to_string())
};
match Url::parse(url_string.as_slice()) {
Ok(url) => url,
Err(e) => return Err(format!("Couldn't parse requested URL: {}", e))
}
},
_ => return Err("Unsupported request URI".to_string())
};
let body = match req.read_to_end() {
Ok(body) => body,
Err(e) => return Err(format!("Couldn't read request body: {}", e))
};
Ok(Request {
url: url,
remote_addr: req.remote_addr,
headers: req.headers,
body: body,
method: req.method,
extensions: TypeMap::new()
})
}
}
impl Extensible for Request {
fn extensions(&self) -> &TypeMap {
&self.extensions
}
fn extensions_mut(&mut self) -> &mut TypeMap {
&mut self.extensions
}
}