1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
use std::io::Read; use std::fmt::{self, Debug}; use request::Request; use response::{Response, Responder, DEFAULT_CHUNK_SIZE}; use http::Status; /// Streams a response to a client from an arbitrary `Read`er type. /// /// The client is sent a "chunked" response, where the chunk size is at most /// 4KiB. This means that at most 4KiB are stored in memory while the response /// is being sent. This type should be used when sending responses that are /// arbitrarily large in size, such as when streaming from a local socket. pub struct Stream<T: Read>(T, u64); impl<T: Read> Stream<T> { /// Create a new stream from the given `reader` and sets the chunk size for /// each streamed chunk to `chunk_size` bytes. /// /// # Example /// /// Stream a response from whatever is in `stdin` with a chunk size of 10 /// bytes. Note: you probably shouldn't do this. /// /// ```rust /// use std::io; /// use rocket::response::Stream; /// /// # #[allow(unused_variables)] /// let response = Stream::chunked(io::stdin(), 10); /// ``` pub fn chunked(reader: T, chunk_size: u64) -> Stream<T> { Stream(reader, chunk_size) } } impl<T: Read + Debug> Debug for Stream<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Stream({:?})", self.0) } } /// Create a new stream from the given `reader`. /// /// # Example /// /// Stream a response from whatever is in `stdin`. Note: you probably /// shouldn't do this. /// /// ```rust /// use std::io; /// use rocket::response::Stream; /// /// # #[allow(unused_variables)] /// let response = Stream::from(io::stdin()); /// ``` impl<T: Read> From<T> for Stream<T> { fn from(reader: T) -> Self { Stream(reader, DEFAULT_CHUNK_SIZE) } } /// Sends a response to the client using the "Chunked" transfer encoding. The /// maximum chunk size is 4KiB. /// /// # Failure /// /// If reading from the input stream fails at any point during the response, the /// response is abandoned, and the response ends abruptly. An error is printed /// to the console with an indication of what went wrong. impl<'r, T: Read + 'r> Responder<'r> for Stream<T> { fn respond_to(self, _: &Request) -> Result<Response<'r>, Status> { Response::build().chunked_body(self.0, self.1).ok() } }