diff --git a/src/listing.rs b/src/listing.rs index 66aea6b69..b9e9437e1 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -162,6 +162,7 @@ pub fn directory_listing( dirs_first: bool, hide_version_footer: bool, title: Option, + index: Option, ) -> Result { use actix_web::dev::BodyEncoding; let serve_path = req.path(); @@ -246,6 +247,22 @@ pub fn directory_listing( return Ok(ServiceResponse::new(req.clone(), res)); } + // Serve index file. If it doesn't exist, ignore and list content. + if let Some(index_path) = index { + if let Ok(index_file) = actix_files::NamedFile::open(dir.path.join(index_path)) { + let res = match index_file.into_response(req) { + Ok(res) => res, + Err(err) => { + log::error!("Error while serving index file: {:?}", err); + HttpResponse::InternalServerError().body(Body::Empty) + } + }; + return Ok(ServiceResponse::new(req.clone(), res)); + } else { + log::warn!("Index file could not be found for {}", serve_path); + } + } + let mut entries: Vec = Vec::new(); for entry in dir.path.read_dir()? { diff --git a/src/main.rs b/src/main.rs index 84a4cb8ee..7390c1e8f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use actix_web::{ use actix_web::{middleware, App, HttpRequest, HttpResponse}; use actix_web_httpauth::middleware::HttpAuthentication; use http::header::HeaderMap; -use log::{error, warn}; +use log::warn; use structopt::clap::crate_version; use structopt::StructOpt; use yansi::{Color, Paint}; @@ -250,15 +250,6 @@ async fn run(miniserve_config: MiniserveConfig) -> Result<(), ContextualError> { ContextualError::IoError("Failed to resolve path to be served".to_string(), e) })?; - if let Some(index_path) = &miniserve_config.index { - let has_index: std::path::PathBuf = [&canon_path, index_path].iter().collect(); - if !has_index.exists() { - error!( - "The file '{}' provided for option --index could not be found.", - index_path.to_string_lossy() - ); - } - } let path_string = canon_path.to_string_lossy(); println!( @@ -415,6 +406,7 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { let dirs_first = conf.dirs_first; let hide_version_footer = conf.hide_version_footer; let title = conf.title.clone(); + let index = conf.index.clone(); upload_route = if let Some(random_route) = conf.random_route.clone() { format!("/{}/upload", random_route) } else { @@ -422,10 +414,6 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { }; if path.is_file() { None - } else if let Some(index_file) = &conf.index { - Some( - actix_files::Files::new(&full_route, path).index_file(index_file.to_string_lossy()), - ) } else { let u_r = upload_route.clone(); let files; @@ -457,6 +445,7 @@ fn configure_app(app: &mut web::ServiceConfig, conf: &MiniserveConfig) { dirs_first, hide_version_footer, title.clone(), + index.clone(), ) }) .default_handler(web::to(error_404)); diff --git a/tests/serve_request.rs b/tests/serve_request.rs index 6477bc230..21d3521dc 100644 --- a/tests/serve_request.rs +++ b/tests/serve_request.rs @@ -177,10 +177,21 @@ fn serves_requests_with_randomly_assigned_port(tmpdir: TempDir) -> Result<(), Er Ok(()) } -#[rstest] -fn serves_requests_custom_index_notice(tmpdir: TempDir, port: u16) -> Result<(), Error> { +#[rstest( + index, + exists, + case(FILES[0], true), + case("not.html", false), +)] +fn serves_requests_custom_index_notice( + tmpdir: TempDir, + port: u16, + index: &str, + exists: bool, +) -> Result<(), Error> { let mut child = Command::cargo_bin("miniserve")? - .arg("--index=not.html") + .arg(format!("--index={}", index)) + .arg("--verbose") .arg("-p") .arg(port.to_string()) .arg(tmpdir.path()) @@ -190,13 +201,16 @@ fn serves_requests_custom_index_notice(tmpdir: TempDir, port: u16) -> Result<(), sleep(Duration::from_secs(1)); + reqwest::blocking::get(format!("http://localhost:{}", port).as_str())?.error_for_status()?; + child.kill()?; let output = child.wait_with_output().expect("Failed to read stdout"); - let all_text = String::from_utf8(output.stderr); + let all_text = String::from_utf8(output.stdout); - assert!(all_text - .unwrap() - .contains("The file 'not.html' provided for option --index could not be found.")); + assert_ne!( + exists, + all_text.unwrap().contains("Index file could not be found") + ); Ok(()) }