<commit_before>//! An augmentation of the rust-http Response struct.

use std::io::{IoResult, File, MemReader};
use std::io::util::copy;
use std::path::BytesContainer;

use http::status::{Status, InternalServerError};
use http::headers::response::HeaderCollection;

pub use HttpResponse = http::server::response::ResponseWriter;

use contenttype::get_content_type;

/// The response representation given to `Middleware`
pub struct Response<'a, 'b> {
    http_res: &'a mut HttpResponse<'b>,
    pub body: Box<Reader>,
    pub headers: Box<HeaderCollection>,
    pub status: Status
}

impl<'a, 'b> Response<'a, 'b> {
    pub fn from_http(http_res: &'a mut HttpResponse<'b>) -> Response<'a, 'b> {
        Response {
            headers: http_res.headers.clone(),
            status: http_res.status.clone(),
            http_res: http_res,
            body: box MemReader::new(vec![]) as Box<Reader>
        }
    }

    pub fn serve<S: BytesContainer>(&mut self, status: Status, body: S) {
        self.status = status;
        self.body = box MemReader::new(body.container_as_bytes().to_owned()) as Box<Reader>;
    }

    /// Serve the file located at `path`.
    ///
    /// This is usually a terminal process, and `Middleware` may want to
    /// call `Unwind` after a file is served. If the status should be
    /// anything other than `200`, the `Middleware` must set it, including in
    /// the case of an `Err`.
    ///
    /// `serve_file` will err out if the file does not exist, the process
    /// does not have correct permissions, or it has other issues in reading
    pub fn serve_file(&mut self, path: &Path) -> IoResult<()> {
        let file = try!(File::open(path));
        self.headers.content_type = path.extension_str().and_then(get_content_type);
        self.body = box file as Box<Reader>;
        Ok(())
    }

    fn serve<S: BytesContainer>(&mut self, status: Status, body: S) -> IoResult<()> {
        self.status = status;
        Ok(try!(self.write(body.container_as_bytes())))
    }

    pub fn write_back(mut self) {
        self.http_res.headers = self.headers.clone();
        self.http_res.status = self.status.clone();
        let _ = match self.body.read_to_string() {
            Ok(body) => {
                self.http_res.write_content_auto(
                    match self.headers.content_type {
                        Some(ref ctype) => ctype.clone(),
                        None => get_content_type("txt").unwrap()<commit_msg>(doc) Documented Response wrapper.<commit_after>//! An augmentation of the rust-http Response struct.

use std::io::{IoResult, File, MemReader};
use std::io::util::copy;
use std::path::BytesContainer;

use http::status::{Status, InternalServerError};
use http::headers::response::HeaderCollection;

pub use HttpResponse = http::server::response::ResponseWriter;

use contenttype::get_content_type;

/// The response representation given to `Middleware`
pub struct Response<'a, 'b> {
    http_res: &'a mut HttpResponse<'b>,
    pub body: Box<Reader>,
    pub headers: Box<HeaderCollection>,
    pub status: Status
}

impl<'a, 'b> Response<'a, 'b> {
    /// Construct a Response from an HttpResponse reference
    pub fn from_http(http_res: &'a mut HttpResponse<'b>) -> Response<'a, 'b> {
        Response {
            headers: http_res.headers.clone(),
            status: http_res.status.clone(),
            http_res: http_res,
            body: box MemReader::new(vec![]) as Box<Reader>
        }
    }

    /// Write the `Status` and data to the `Response`.
    pub fn serve<S: BytesContainer>(&mut self, status: Status, body: S) {
        self.status = status;
        self.body = box MemReader::new(body.container_as_bytes().to_owned()) as Box<Reader>;
    }

    /// Serve the file located at `path`.
    ///
    /// This usually means a request has been handlded, and `Middleware`
    /// may want to `Unwind` after a file is served. If the status should be
    /// anything other than `200`, `Middleware` must set it, including in
    /// the case of an `Err`.
    ///
    /// `serve_file` will error if the file does not exist, the process
    /// does not have correct permissions, or it has other issues in reading
    /// from the file. `Middleware` should handle this gracefully.
    pub fn serve_file(&mut self, path: &Path) -> IoResult<()> {
        let file = try!(File::open(path));
        self.headers.content_type = path.extension_str().and_then(get_content_type);
        self.body = box file as Box<Reader>;
        Ok(())
    }

    /// Internal. Should not be called by the user.
    ///
    /// `write_back` is used to put all the data added to `self`
    /// back onto an `HttpResponse` so that it is sent back to the
    /// client.
    ///
    /// `write_back` consumes the `Response`.
    pub fn write_back(mut self) {
        self.http_res.headers = self.headers.clone();
        self.http_res.status = self.status.clone();
        let _ = match self.body.read_to_string() {
            Ok(body) => {
                self.http_res.write_content_auto(
                    match self.headers.content_type {
                        Some(ref ctype) => ctype.clone(),
                        None => get_content_type("txt").unwrap()
{'fraction_non_alphanumeric': 0.13578122011856952, 'fraction_numerical': 0.0011474469305794606, 'mean_word_length': 2.6193771626297577, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7171894', 'n_tokens_mistral': 1542, 'n_tokens_neox': 1541, 'n_words': 466}