Add NamedFile response type.

This commit is contained in:
Sergio Benitez 2016-09-12 01:51:02 -07:00
parent 9edb1e34d2
commit 4e03bb6107
10 changed files with 92 additions and 30 deletions

View File

@ -8,8 +8,14 @@ fn run_mode(mode: &'static str) {
config.mode = cfg_mode;
config.src_base = PathBuf::from(format!("tests/{}", mode));
config.target_rustcflags = Some("-L ../target/debug/ -L ../target/debug/deps/".to_owned());
let flags = [
"-L ../target/debug/",
"-L ../target/debug/deps/",
"-L target/debug/",
"-L target/debug/deps/"
].join(" ");
config.target_rustcflags = Some(flags);
compiletest::run_tests(&config);
}

View File

@ -1,13 +1,14 @@
use rocket;
use std::fs::File;
use std::io::Error as IOError;
use rocket::response::NamedFile;
#[get(path = "/")]
pub fn index() -> File {
File::open("static/index.html").unwrap()
use std::io;
use std::path::{Path, PathBuf};
#[get("/")]
fn index() -> io::Result<NamedFile> {
NamedFile::open("static/index.html")
}
#[get("/<file>")]
pub fn files(file: &str) -> Result<File, IOError> {
File::open(format!("static/{}", file))
#[get("/<file..>")]
fn files(file: PathBuf) -> io::Result<NamedFile> {
NamedFile::open(Path::new("static/").join(file))
}

View File

@ -1,13 +1,14 @@
use rocket;
use std::fs::File;
use std::io::Error as IOError;
use rocket::response::NamedFile;
#[route(GET, path = "/")]
pub fn index() -> File {
File::open("static/index.html").unwrap()
use std::io;
use std::path::{Path, PathBuf};
#[get("/")]
fn index() -> io::Result<NamedFile> {
NamedFile::open("static/index.html")
}
#[route(GET, path = "/<file>")]
pub fn files(file: &str) -> Result<File, IOError> {
File::open(format!("static/{}", file))
#[get("/<file..>")]
fn files(file: PathBuf) -> io::Result<NamedFile> {
NamedFile::open(Path::new("static/").join(file))
}

View File

@ -4,18 +4,18 @@
extern crate rocket;
use rocket::Rocket;
use std::fs::File;
use std::io::Error as IOError;
use std::io;
use rocket::response::NamedFile;
use std::path::{Path, PathBuf};
#[get("/")]
fn index() -> File {
File::open("static/index.html").unwrap()
fn index() -> io::Result<NamedFile> {
NamedFile::open("static/index.html")
}
#[get("/<file..>")]
fn files(file: PathBuf) -> Result<File, IOError> {
File::open(Path::new("static/").join(file))
fn files(file: PathBuf) -> io::Result<NamedFile> {
NamedFile::open(Path::new("static/").join(file))
}
fn main() {

View File

@ -1,8 +1,8 @@
use std::fs::File;
use rocket::response::NamedFile;
use std::io;
use std::path::{Path, PathBuf};
#[get("/<path..>", rank = 5)]
fn all(path: PathBuf) -> io::Result<File> {
File::open(Path::new("static/").join(path))
fn all(path: PathBuf) -> io::Result<NamedFile> {
NamedFile::open(Path::new("static/").join(path))
}

View File

@ -18,3 +18,5 @@ impl_data_type_responder!(JSON: Application/Json);
impl_data_type_responder!(XML: Application/Xml);
impl_data_type_responder!(HTML: Text/Html);
impl_data_type_responder!(Plain: Text/Plain);
impl_data_type_responder!(CSS: Text/Css);
impl_data_type_responder!(JavaScript: Application/Javascript);

View File

@ -5,6 +5,7 @@ mod with_status;
mod outcome;
mod flash;
mod data_type;
mod named_file;
pub use hyper::server::Response as HyperResponse;
pub use hyper::net::Fresh as HyperFresh;
@ -19,6 +20,7 @@ pub use self::redirect::Redirect;
pub use self::with_status::StatusResponse;
pub use self::outcome::Outcome;
pub use self::flash::Flash;
pub use self::named_file::NamedFile;
use std::ops::{Deref, DerefMut};

View File

@ -0,0 +1,48 @@
use response::*;
use std::fs::File;
use std::path::{Path, PathBuf};
use response::mime::{Mime, TopLevel, SubLevel};
use std::io;
pub struct NamedFile(PathBuf, File);
impl NamedFile {
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
let file = File::open(path.as_ref())?;
Ok(NamedFile(path.as_ref().to_path_buf(), file))
}
pub fn path(&self) -> &Path {
self.0.as_path()
}
}
impl Responder for NamedFile {
fn respond<'a>(&mut self, mut res: FreshHyperResponse<'a>) -> Outcome<'a> {
if let Some(ext) = self.path().extension() {
let ext_string = ext.to_string_lossy().to_lowercase();
let (top_level, sub_level) = match ext_string.as_str() {
"txt" => (TopLevel::Text, SubLevel::Plain),
"html" => (TopLevel::Text, SubLevel::Html),
"xml" => (TopLevel::Application, SubLevel::Xml),
"js" => (TopLevel::Application, SubLevel::Javascript),
"css" => (TopLevel::Text, SubLevel::Css),
"json" => (TopLevel::Application, SubLevel::Json),
"png" => (TopLevel::Image, SubLevel::Png),
"gif" => (TopLevel::Image, SubLevel::Gif),
"bmp" => (TopLevel::Image, SubLevel::Bmp),
"jpeg" => (TopLevel::Image, SubLevel::Jpeg),
"jpg" => (TopLevel::Image, SubLevel::Jpeg),
_ => (TopLevel::Star, SubLevel::Star),
};
if top_level != TopLevel::Star && sub_level != SubLevel::Star {
let mime = Mime(top_level, sub_level, vec![]);
res.headers_mut().set(header::ContentType(mime));
}
}
self.1.respond(res)
}
}

View File

@ -1,4 +1,3 @@
// TODO: Allow streamed responses.
// const CHUNK_SIZE: u32 = 4096;
// pub struct Stream<T: Read>(T);
// impl<T> Responder for Stream<T> {

View File

@ -52,7 +52,10 @@ impl Rocket {
// Dispatch the request to the handler and update the cookies.
let mut responder = (route.handler)(&request);
res.headers_mut().set(SetCookie(request.cookies().delta()));
let cookie_delta = request.cookies().delta();
if cookie_delta.len() > 0 {
res.headers_mut().set(SetCookie(cookie_delta));
}
// Get the response.
let outcome = responder.respond(res);