Return an error from StaticFiles::new() if directory doesn't exist

This commit is contained in:
tessereth 2018-07-05 08:53:51 +10:00
parent dedd7cc1ac
commit 323570dc4d
No known key found for this signature in database
GPG Key ID: DF640BCE2E866153
3 changed files with 32 additions and 29 deletions

View File

@ -587,7 +587,7 @@ where
/// let app = App::new() /// let app = App::new()
/// .middleware(middleware::Logger::default()) /// .middleware(middleware::Logger::default())
/// .configure(config) // <- register resources /// .configure(config) // <- register resources
/// .handler("/static", fs::StaticFiles::new(".")); /// .handler("/static", fs::StaticFiles::new(".").unwrap());
/// } /// }
/// ``` /// ```
pub fn configure<F>(self, cfg: F) -> App<S> pub fn configure<F>(self, cfg: F) -> App<S>

View File

@ -629,6 +629,9 @@ impl From<UrlParseError> for UrlGenerationError {
/// Errors which can occur when serving static files. /// Errors which can occur when serving static files.
#[derive(Fail, Debug, PartialEq)] #[derive(Fail, Debug, PartialEq)]
pub enum StaticFileError { pub enum StaticFileError {
/// Path is not a directory
#[fail(display = "Path is not a directory")]
IsNotDirectory,
/// Cannot render directory /// Cannot render directory
#[fail(display = "Cannot render directory")] #[fail(display = "Cannot render directory")]
IsDirectory, IsDirectory,

View File

@ -555,7 +555,7 @@ fn directory_listing<S>(
/// ///
/// fn main() { /// fn main() {
/// let app = App::new() /// let app = App::new()
/// .handler("/static", fs::StaticFiles::new(".")) /// .handler("/static", fs::StaticFiles::new(".").unwrap())
/// .finish(); /// .finish();
/// } /// }
/// ``` /// ```
@ -576,7 +576,7 @@ impl<S: 'static> StaticFiles<S> {
/// `StaticFile` uses `CpuPool` for blocking filesystem operations. /// `StaticFile` uses `CpuPool` for blocking filesystem operations.
/// By default pool with 20 threads is used. /// By default pool with 20 threads is used.
/// Pool size can be changed by setting ACTIX_CPU_POOL environment variable. /// Pool size can be changed by setting ACTIX_CPU_POOL environment variable.
pub fn new<T: Into<PathBuf>>(dir: T) -> StaticFiles<S> { pub fn new<T: Into<PathBuf>>(dir: T) -> Result<StaticFiles<S>, Error> {
// use default CpuPool // use default CpuPool
let pool = { DEFAULT_CPUPOOL.lock().clone() }; let pool = { DEFAULT_CPUPOOL.lock().clone() };
@ -585,23 +585,14 @@ impl<S: 'static> StaticFiles<S> {
/// Create new `StaticFiles` instance for specified base directory and /// Create new `StaticFiles` instance for specified base directory and
/// `CpuPool`. /// `CpuPool`.
pub fn with_pool<T: Into<PathBuf>>(dir: T, pool: CpuPool) -> StaticFiles<S> { pub fn with_pool<T: Into<PathBuf>>(dir: T, pool: CpuPool) -> Result<StaticFiles<S>, Error> {
let dir = dir.into(); let dir = dir.into().canonicalize()?;
let dir = match dir.canonicalize() {
Ok(dir) => {
if !dir.is_dir() { if !dir.is_dir() {
warn!("Is not directory `{:?}`", dir); return Err(StaticFileError::IsNotDirectory.into())
};
dir
} }
Err(err) => {
warn!("Static files directory `{:?}` error: {}", dir, err);
dir
}
};
StaticFiles { Ok(StaticFiles {
directory: dir, directory: dir,
index: None, index: None,
show_index: false, show_index: false,
@ -612,7 +603,7 @@ impl<S: 'static> StaticFiles<S> {
renderer: Box::new(directory_listing), renderer: Box::new(directory_listing),
_chunk_size: 0, _chunk_size: 0,
_follow_symlinks: false, _follow_symlinks: false,
} })
} }
/// Show files listing for directories. /// Show files listing for directories.
@ -980,7 +971,7 @@ mod tests {
#[test] #[test]
fn test_named_file_ranges_status_code() { fn test_named_file_ranges_status_code() {
let mut srv = test::TestServer::with_factory(|| { let mut srv = test::TestServer::with_factory(|| {
App::new().handler("test", StaticFiles::new(".").index_file("Cargo.toml")) App::new().handler("test", StaticFiles::new(".").unwrap().index_file("Cargo.toml"))
}); });
// Valid range header // Valid range header
@ -1010,7 +1001,7 @@ mod tests {
let mut srv = test::TestServer::with_factory(|| { let mut srv = test::TestServer::with_factory(|| {
App::new().handler( App::new().handler(
"test", "test",
StaticFiles::new(".").index_file("tests/test.binary"), StaticFiles::new(".").unwrap().index_file("tests/test.binary"),
) )
}); });
@ -1058,7 +1049,7 @@ mod tests {
let mut srv = test::TestServer::with_factory(|| { let mut srv = test::TestServer::with_factory(|| {
App::new().handler( App::new().handler(
"test", "test",
StaticFiles::new(".").index_file("tests/test.binary"), StaticFiles::new(".").unwrap().index_file("tests/test.binary"),
) )
}); });
@ -1175,7 +1166,7 @@ mod tests {
#[test] #[test]
fn test_static_files() { fn test_static_files() {
let mut st = StaticFiles::new(".").show_files_listing(); let mut st = StaticFiles::new(".").unwrap().show_files_listing();
let req = TestRequest::with_uri("/missing").param("tail", "missing").finish(); let req = TestRequest::with_uri("/missing").param("tail", "missing").finish();
let resp = st.handle(&req).respond_to(&req).unwrap(); let resp = st.handle(&req).respond_to(&req).unwrap();
let resp = resp.as_msg(); let resp = resp.as_msg();
@ -1200,9 +1191,18 @@ mod tests {
assert!(format!("{:?}", resp.body()).contains("README.md")); assert!(format!("{:?}", resp.body()).contains("README.md"));
} }
#[test]
fn test_static_files_bad_directory() {
let st: Result<StaticFiles<()>, Error> = StaticFiles::new("missing");
assert!(st.is_err());
let st: Result<StaticFiles<()>, Error> = StaticFiles::new("Cargo.toml");
assert!(st.is_err());
}
#[test] #[test]
fn test_default_handler_file_missing() { fn test_default_handler_file_missing() {
let st = StaticFiles::new(".") let st = StaticFiles::new(".").unwrap()
.default_handler(|_: &_| "default content"); .default_handler(|_: &_| "default content");
let req = TestRequest::with_uri("/missing").param("tail", "missing").finish(); let req = TestRequest::with_uri("/missing").param("tail", "missing").finish();
@ -1214,7 +1214,7 @@ mod tests {
#[test] #[test]
fn test_redirect_to_index() { fn test_redirect_to_index() {
let st = StaticFiles::new(".").index_file("index.html"); let st = StaticFiles::new(".").unwrap().index_file("index.html");
let req = TestRequest::default().uri("/tests").finish(); let req = TestRequest::default().uri("/tests").finish();
let resp = st.handle(&req).respond_to(&req).unwrap(); let resp = st.handle(&req).respond_to(&req).unwrap();
@ -1237,7 +1237,7 @@ mod tests {
#[test] #[test]
fn test_redirect_to_index_nested() { fn test_redirect_to_index_nested() {
let st = StaticFiles::new(".").index_file("mod.rs"); let st = StaticFiles::new(".").unwrap().index_file("mod.rs");
let req = TestRequest::default().uri("/src/client").finish(); let req = TestRequest::default().uri("/src/client").finish();
let resp = st.handle(&req).respond_to(&req).unwrap(); let resp = st.handle(&req).respond_to(&req).unwrap();
let resp = resp.as_msg(); let resp = resp.as_msg();
@ -1253,7 +1253,7 @@ mod tests {
let mut srv = test::TestServer::with_factory(|| { let mut srv = test::TestServer::with_factory(|| {
App::new() App::new()
.prefix("public") .prefix("public")
.handler("/", StaticFiles::new(".").index_file("Cargo.toml")) .handler("/", StaticFiles::new(".").unwrap().index_file("Cargo.toml"))
}); });
let request = srv.get().uri(srv.url("/public")).finish().unwrap(); let request = srv.get().uri(srv.url("/public")).finish().unwrap();
@ -1282,7 +1282,7 @@ mod tests {
#[test] #[test]
fn integration_redirect_to_index() { fn integration_redirect_to_index() {
let mut srv = test::TestServer::with_factory(|| { let mut srv = test::TestServer::with_factory(|| {
App::new().handler("test", StaticFiles::new(".").index_file("Cargo.toml")) App::new().handler("test", StaticFiles::new(".").unwrap().index_file("Cargo.toml"))
}); });
let request = srv.get().uri(srv.url("/test")).finish().unwrap(); let request = srv.get().uri(srv.url("/test")).finish().unwrap();
@ -1311,7 +1311,7 @@ mod tests {
#[test] #[test]
fn integration_percent_encoded() { fn integration_percent_encoded() {
let mut srv = test::TestServer::with_factory(|| { let mut srv = test::TestServer::with_factory(|| {
App::new().handler("test", StaticFiles::new(".").index_file("Cargo.toml")) App::new().handler("test", StaticFiles::new(".").unwrap().index_file("Cargo.toml"))
}); });
let request = srv let request = srv