2016-09-12 09:43:34 +00:00
|
|
|
use response::*;
|
|
|
|
use std::io::{Read, Write, ErrorKind};
|
2016-03-28 09:34:09 +00:00
|
|
|
|
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-09-19 23:24:01 +00:00
|
|
|
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
|
2016-09-12 09:43:34 +00:00
|
|
|
let mut stream = res.start().unwrap();
|
|
|
|
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);
|
|
|
|
return Outcome::FailStop;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
return Outcome::FailStop;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Err(e) = stream.end() {
|
|
|
|
error_!("Stream end() failed: {:?}", e);
|
|
|
|
return Outcome::FailStop;
|
|
|
|
}
|
|
|
|
|
|
|
|
Outcome::Complete
|
|
|
|
}
|
|
|
|
}
|