From 81e4fb935316905867ab27903a50302dcd3af351 Mon Sep 17 00:00:00 2001 From: Christopher Armstrong Date: Wed, 7 Feb 2018 15:31:09 -0600 Subject: [PATCH 1/2] Avoid using `Path` to calculate URIs, because it doesn't do the right thing on Windows (#67) Redirecting to index files now always uses `/` instead of backslash on windows. --- src/fs.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/fs.rs b/src/fs.rs index 547a3c415..28260e36a 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -283,12 +283,18 @@ impl Handler for StaticFiles { if path.is_dir() { if let Some(ref redir_index) = self.index { - let mut base = Path::new(req.path()).join(relpath); - base.push(redir_index); + // TODO: Don't redirect, just return the index content. + // TODO: It'd be nice if there were a good usable URL manipulation library + let mut new_path: String = req.path().to_owned(); + for el in relpath.iter() { + new_path.push_str(&el.to_string_lossy()); + new_path.push('/'); + } + new_path.push_str(redir_index); Ok(FilesystemElement::Redirect( HTTPFound .build() - .header("LOCATION", base.to_string_lossy().as_ref()) + .header::<_, &str>("LOCATION", &new_path) .finish().unwrap())) } else if self.show_index { Ok(FilesystemElement::Directory(Directory::new(self.directory.clone(), path))) @@ -340,7 +346,7 @@ mod tests { } #[test] - fn test_redirec_to_index() { + fn test_redirect_to_index() { let mut st = StaticFiles::new(".", false).index_file("index.html"); let mut req = HttpRequest::default(); req.match_info_mut().add("tail", "guide"); @@ -348,5 +354,23 @@ mod tests { let resp = st.handle(req).respond_to(HttpRequest::default()).unwrap(); assert_eq!(resp.status(), StatusCode::FOUND); assert_eq!(resp.headers().get(header::LOCATION).unwrap(), "/guide/index.html"); + + let mut req = HttpRequest::default(); + req.match_info_mut().add("tail", "guide/"); + + let resp = st.handle(req).respond_to(HttpRequest::default()).unwrap(); + assert_eq!(resp.status(), StatusCode::FOUND); + assert_eq!(resp.headers().get(header::LOCATION).unwrap(), "/guide/index.html"); + } + + #[test] + fn test_redirect_to_index_nested() { + let mut st = StaticFiles::new(".", false).index_file("Cargo.toml"); + let mut req = HttpRequest::default(); + req.match_info_mut().add("tail", "examples/basics"); + + let resp = st.handle(req).respond_to(HttpRequest::default()).unwrap(); + assert_eq!(resp.status(), StatusCode::FOUND); + assert_eq!(resp.headers().get(header::LOCATION).unwrap(), "/examples/basics/Cargo.toml"); } } From 93aa220e8d0b07d1dfe2d4952f4ad02531eb67e2 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 7 Feb 2018 13:57:58 -0800 Subject: [PATCH 2/2] remove default impl for std error, it prevents use of Fail --- src/error.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/error.rs b/src/error.rs index 3218f410e..d166636a7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,11 +4,9 @@ use std::str::Utf8Error; use std::string::FromUtf8Error; use std::io::Error as IoError; -#[cfg(actix_nightly)] -use std::error::Error as StdError; - use cookie; use httparse; +use actix::MailboxError; use futures::Canceled; use failure; use failure::{Fail, Backtrace}; @@ -96,6 +94,7 @@ impl From for Error { } } +/// Compatibility for `failure::Error` impl ResponseError for failure::Compat where T: fmt::Display + fmt::Debug + Sync + Send + 'static { } @@ -106,14 +105,6 @@ impl From for Error { } } -/// Default error is `InternalServerError` -#[cfg(actix_nightly)] -default impl ResponseError for T { - fn error_response(&self) -> HttpResponse { - HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR, Body::Empty) - } -} - /// `InternalServerError` for `JsonError` impl ResponseError for JsonError {} @@ -145,6 +136,9 @@ impl ResponseError for header::InvalidHeaderValue {} /// `InternalServerError` for `futures::Canceled` impl ResponseError for Canceled {} +/// `InternalServerError` for `actix::MailboxError` +impl ResponseError for MailboxError {} + /// A set of errors that can occur during parsing HTTP streams #[derive(Fail, Debug)] pub enum ParseError {