diff options
-rw-r--r-- | src/args.rs | 12 | ||||
-rw-r--r-- | src/file_upload.rs | 2 | ||||
-rw-r--r-- | src/listing.rs | 2 | ||||
-rw-r--r-- | src/main.rs | 20 | ||||
-rw-r--r-- | tests/serve_request.rs | 28 |
5 files changed, 59 insertions, 5 deletions
diff --git a/src/args.rs b/src/args.rs index 8fde78a..fe976ed 100644 --- a/src/args.rs +++ b/src/args.rs @@ -27,6 +27,13 @@ struct CLIArgs { #[structopt(name = "PATH", parse(from_os_str))] path: Option<PathBuf>, + /// The name of a directory index file to serve, like "index.html" + /// + /// Normally, when miniserve serves a directory, it creates a listing for that directory. + /// However, if a directory contains this file, miniserve will serve that file instead. + #[structopt(long, parse(from_os_str), name="index_file")] + index: Option<PathBuf>, + /// Port to use #[structopt(short = "p", long = "port", default_value = "8080")] port: u16, @@ -108,8 +115,8 @@ fn parse_auth(src: &str) -> Result<auth::RequiredAuth, ContextualError> { }; match second_part { - "sha256" => auth::RequiredAuthPassword::Sha256(hash_bin.to_owned()), - "sha512" => auth::RequiredAuthPassword::Sha512(hash_bin.to_owned()), + "sha256" => auth::RequiredAuthPassword::Sha256(hash_bin), + "sha512" => auth::RequiredAuthPassword::Sha512(hash_bin), _ => return Err(ContextualError::InvalidHashMethod(second_part.to_owned())), } } else { @@ -162,6 +169,7 @@ pub fn parse_args() -> crate::MiniserveConfig { no_symlinks: args.no_symlinks, random_route, default_color_scheme, + index: args.index, overwrite_files: args.overwrite_files, file_upload: args.file_upload, } diff --git a/src/file_upload.rs b/src/file_upload.rs index 900792f..af4fcf2 100644 --- a/src/file_upload.rs +++ b/src/file_upload.rs @@ -201,7 +201,7 @@ pub fn upload_file( .then(move |e| match e { Ok(_) => future::ok( HttpResponse::SeeOther() - .header(header::LOCATION, return_path.to_string()) + .header(header::LOCATION, return_path) .finish(), ), Err(e) => create_error_response( diff --git a/src/listing.rs b/src/listing.rs index 42eb59a..d419775 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -152,7 +152,7 @@ pub fn directory_listing<S>( let base = Path::new(serve_path); let random_route = format!("/{}", random_route.unwrap_or_default()); - let is_root = base.parent().is_none() || req.path() == random_route; + let is_root = base.parent().is_none() || Path::new(&req.path()) == Path::new(&random_route); let current_dir = match base.strip_prefix(random_route) { Ok(c_d) => Path::new("/").join(c_d), Err(_) => base.to_path_buf(), diff --git a/src/main.rs b/src/main.rs index 2482d95..9b9c628 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,6 +51,12 @@ pub struct MiniserveConfig { /// Default color scheme pub default_color_scheme: themes::ColorScheme, + /// The name of a directory index file to serve, like "index.html" + /// + /// Normally, when miniserve serves a directory, it creates a listing for that directory. + /// However, if a directory contains this file, miniserve will serve that file instead. + pub index: Option<std::path::PathBuf>, + /// Enable file upload pub file_upload: bool, @@ -129,6 +135,14 @@ fn run() -> Result<(), ContextualError> { let canon_path = miniserve_config.path.canonicalize().map_err(|e| { 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() { + + println!("{warning} The provided index file could not be found.", warning=Color::RGB(255, 192, 0).paint("Notice:").bold()); + } + } let path_string = canon_path.to_string_lossy(); println!( @@ -244,6 +258,12 @@ fn configure_app(app: App<MiniserveConfig>) -> App<MiniserveConfig> { }; if path.is_file() { None + } else if let Some(index_file) = &app.state().index { + Some( + fs::StaticFiles::new(path) + .expect("Failed to setup static file handler") + .index_file(index_file.to_string_lossy()) + ) } else { let u_r = upload_route.clone(); Some( diff --git a/tests/serve_request.rs b/tests/serve_request.rs index 7419ab1..064e196 100644 --- a/tests/serve_request.rs +++ b/tests/serve_request.rs @@ -55,7 +55,10 @@ fn serves_requests_with_non_default_port(tmpdir: TempDir, port: u16) -> Result<( .error_for_status()?; let dir_body_parsed = Document::from_read(dir_body)?; for &file in FILES { - assert!(dir_body_parsed.find(|x: &Node| x.text() == file).next().is_some()); + assert!(dir_body_parsed + .find(|x: &Node| x.text() == file) + .next() + .is_some()); } } @@ -63,3 +66,26 @@ fn serves_requests_with_non_default_port(tmpdir: TempDir, port: u16) -> Result<( Ok(()) } + +#[rstest] +fn serves_requests_custom_index_notice(tmpdir: TempDir, port: u16) -> Result<(), Error> { + let mut child = Command::cargo_bin("miniserve")? + .arg("--index=not.html") + .arg("-p") + .arg(port.to_string()) + .arg(tmpdir.path()) + .stdout(Stdio::piped()) + .spawn()?; + + sleep(Duration::from_secs(1)); + + child.kill()?; + let output = child.wait_with_output().expect("Failed to read stdout"); + let all_text = String::from_utf8(output.stdout); + + assert!(all_text + .unwrap() + .contains("The provided index file could not be found")); + + Ok(()) +} |