From ed0ed2a39687f31953ad5af9647143efe7a9528a Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Thu, 21 Dec 2017 21:51:36 -0800 Subject: [PATCH] Defer NamedFile's Responder impl to File. --- lib/src/response/named_file.rs | 18 ++++++------------ lib/src/response/responder.rs | 8 ++++++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/src/response/named_file.rs b/lib/src/response/named_file.rs index b6b08395..04a446e0 100644 --- a/lib/src/response/named_file.rs +++ b/lib/src/response/named_file.rs @@ -4,9 +4,8 @@ use std::io; use std::ops::{Deref, DerefMut}; use request::Request; -use response::{Response, Responder}; -use http::{Status, ContentType}; -use response::Body; +use response::{self, Responder}; +use http::ContentType; /// A file with an associated name; responds with the Content-Type based on the /// file extension. @@ -80,20 +79,15 @@ impl NamedFile { /// [ContentType::from_extension](/rocket/http/struct.ContentType.html#method.from_extension) /// for more information. If you would like to stream a file with a different /// Content-Type than that implied by its extension, use a `File` directly. -impl Responder<'static> for NamedFile { - fn respond_to(self, _: &Request) -> Result, Status> { - let mut response = Response::new(); - if let Some(ext) = self.path().extension() { +impl<'r> Responder<'r> for NamedFile { + fn respond_to(self, req: &Request) -> response::Result<'r> { + let mut response = self.1.respond_to(req)?; + if let Some(ext) = self.0.extension() { if let Some(ct) = ContentType::from_extension(&ext.to_string_lossy()) { response.set_header(ct); } } - match self.0.metadata() { - Ok(meta) => response.set_raw_body(Body::Sized(self.take_file(), meta.len())), - Err(_) => response.set_streamed_body(self.take_file()) - } - Ok(response) } } diff --git a/lib/src/response/responder.rs b/lib/src/response/responder.rs index 362269d7..1a7671e2 100644 --- a/lib/src/response/responder.rs +++ b/lib/src/response/responder.rs @@ -3,7 +3,7 @@ use std::io::{Cursor, BufReader}; use std::fmt; use http::{Status, ContentType}; -use response::{self, Response}; +use response::{self, Response, Body}; use request::Request; /// Trait implemented by types that generate responses for clients. @@ -223,7 +223,11 @@ impl<'r> Responder<'r> for Vec { /// Returns a response with a sized body for the file. Always returns `Ok`. impl<'r> Responder<'r> for File { fn respond_to(self, _: &Request) -> response::Result<'r> { - Response::build().streamed_body(BufReader::new(self)).ok() + let (metadata, file) = (self.metadata(), BufReader::new(self)); + match metadata { + Ok(md) => Response::build().raw_body(Body::Sized(file, md.len())).ok(), + Err(_) => Response::build().streamed_body(file).ok() + } } }