2016-09-12 09:43:34 +00:00
|
|
|
use std::io::{Read, Write, ErrorKind};
|
2016-03-28 09:34:09 +00:00
|
|
|
|
2016-10-08 02:09:05 +00:00
|
|
|
use response::{Responder, Outcome, ResponseOutcome};
|
2016-10-04 00:09:13 +00:00
|
|
|
use http::hyper::FreshHyperResponse;
|
|
|
|
|
2016-09-25 11:07:03 +00:00
|
|
|
// TODO: Support custom chunk sizes.
|
|
|
|
/// The default size of each chunk in the streamed response.
|
2016-09-12 09:43:34 +00:00
|
|
|
pub const CHUNK_SIZE: usize = 4096;
|
|
|
|
|
2016-09-25 11:07:03 +00:00
|
|
|
pub struct Stream<T: Read>(Box<T>);
|
2016-09-12 09:43:34 +00:00
|
|
|
|
|
|
|
impl<T: Read> Stream<T> {
|
|
|
|
pub fn from(reader: T) -> Stream<T> {
|
|
|
|
Stream(Box::new(reader))
|
|
|
|
}
|
2016-09-25 11:07:03 +00:00
|
|
|
|
2016-09-30 22:20:11 +00:00
|
|
|
// pub fn chunked(mut self, size: usize) -> Self {
|
|
|
|
// self.1 = size;
|
|
|
|
// self
|
|
|
|
// }
|
2016-09-25 11:07:03 +00:00
|
|
|
|
2016-09-30 22:20:11 +00:00
|
|
|
// #[inline(always)]
|
|
|
|
// pub fn chunk_size(&self) -> usize {
|
|
|
|
// self.1
|
|
|
|
// }
|
2016-09-12 09:43:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Read> Responder for Stream<T> {
|
2016-10-08 02:09:05 +00:00
|
|
|
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> ResponseOutcome<'a> {
|
2016-10-09 11:29:02 +00:00
|
|
|
let mut stream = match res.start() {
|
|
|
|
Ok(s) => s,
|
|
|
|
Err(e) => {
|
|
|
|
error_!("Failed opening response stream: {:?}", e);
|
|
|
|
return Outcome::Failure;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-09-12 09:43:34 +00:00
|
|
|
let mut buffer = [0; CHUNK_SIZE];
|
|
|
|
let mut complete = false;
|
|
|
|
while !complete {
|
2016-09-25 11:07:03 +00:00
|
|
|
let mut read = 0;
|
|
|
|
while read < buffer.len() && !complete {
|
|
|
|
match self.0.read(&mut buffer[read..]) {
|
2016-09-12 09:43:34 +00:00
|
|
|
Ok(n) if n == 0 => complete = true,
|
2016-09-25 11:07:03 +00:00
|
|
|
Ok(n) => read += n,
|
2016-09-12 09:43:34 +00:00
|
|
|
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
|
|
|
|
Err(ref e) => {
|
|
|
|
error_!("Error streaming response: {:?}", e);
|
2016-10-08 06:20:49 +00:00
|
|
|
return Outcome::Failure;
|
2016-09-12 09:43:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-25 11:07:03 +00:00
|
|
|
if let Err(e) = stream.write_all(&buffer[..read]) {
|
2016-09-12 09:43:34 +00:00
|
|
|
error_!("Stream write_all() failed: {:?}", e);
|
2016-10-08 06:20:49 +00:00
|
|
|
return Outcome::Failure;
|
2016-09-12 09:43:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Err(e) = stream.end() {
|
|
|
|
error_!("Stream end() failed: {:?}", e);
|
2016-10-08 06:20:49 +00:00
|
|
|
return Outcome::Failure;
|
2016-09-12 09:43:34 +00:00
|
|
|
}
|
|
|
|
|
2016-10-08 02:09:05 +00:00
|
|
|
Outcome::Success
|
2016-09-12 09:43:34 +00:00
|
|
|
}
|
|
|
|
}
|