Last active
August 29, 2015 14:13
-
-
Save pzol/749a202deaf06c4aaaaf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::io::{self, IoResult, MemReader}; | |
use hyper::status; | |
use hyper::net::Fresh; | |
pub use hyper::server::Response as HttpResponse; | |
use hyper::header::Headers; | |
pub struct Response { | |
pub body: Option<Box<Reader + Send>> | |
} | |
pub trait IntoReader { | |
type OutReader: Reader; | |
fn into_reader(self) -> Self::OutReader; | |
} | |
impl Response { | |
pub fn new() -> Response { | |
Response { body: None } | |
} | |
pub fn set_body<I>(&mut self, data: I) | |
where I: IntoReader, <I as IntoReader>::OutReader: Send { | |
self.body = Some(Box::new(data.into_reader())); | |
} | |
pub fn with_body<I>(data: I) -> Response | |
where I: IntoReader, <I as IntoReader>::OutReader: Send { | |
let mut res = Response::new(); | |
res.body = Some(Box::new(data.into_reader())); | |
res | |
} | |
pub fn write_back(self, mut http_res: HttpResponse<Fresh>) { | |
// *http_res.headers_mut() = self.headers; | |
// Default to a 404 if no response code was set | |
// *http_res.status_mut() = self.status.clone().unwrap_or(status::NotFound); | |
let out = match self.body { | |
Some(body) => write_with_body(http_res, body), | |
None => { | |
// http_res.headers_mut().set(headers::ContentLength(0)); | |
http_res.start().and_then(|res| res.end()) | |
} | |
}; | |
match out { | |
Err(e) => { | |
error!("Error writing response: {}", e); | |
}, | |
_ => {} | |
} | |
} | |
} | |
impl IntoReader for String { | |
type OutReader = MemReader; | |
fn into_reader(self) -> MemReader { | |
MemReader::new(self.into_bytes()) | |
} | |
} | |
// impl IntoReader for Path { | |
// type OutReader = File; | |
// fn into_reader(self) -> File { | |
// File::open(self).unwrap() | |
// } | |
// } | |
fn write_with_body(mut res: HttpResponse<Fresh>, mut body: Box<Reader + Send>) -> IoResult<()> { | |
// let content_type = res.headers().get::<headers::ContentType>() | |
// .map(|cx| cx.clone()) | |
// .unwrap_or_else(|| headers::ContentType("text/plain".parse().unwrap())); | |
// res.headers_mut().set(content_type); | |
let mut res = try!(res.start()); | |
// FIXME: Manually inlined io::util::copy | |
// because Box<Reader + Send> does not impl Reader. | |
// | |
// Tracking issue: rust-lang/rust#18542 | |
let mut buf = &mut [0; 1024 * 64]; | |
loop { | |
let len = match body.read(buf) { | |
Ok(len) => len, | |
Err(ref e) if e.kind == io::EndOfFile => break, | |
Err(e) => { return Err(e) }, | |
}; | |
try!(res.write(&buf[..len])) | |
} | |
res.end() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment