feat: make --path-prefix works on serving single file (#102)
This commit is contained in:
parent
4e84e6c532
commit
4e823e8bba
4 changed files with 88 additions and 26 deletions
|
@ -10,6 +10,7 @@ use crate::auth::AccessControl;
|
|||
use crate::auth::AuthMethod;
|
||||
#[cfg(feature = "tls")]
|
||||
use crate::tls::{load_certs, load_private_key};
|
||||
use crate::utils::encode_uri;
|
||||
use crate::BoxResult;
|
||||
|
||||
pub fn build_cli() -> Command<'static> {
|
||||
|
@ -196,7 +197,7 @@ impl Args {
|
|||
let uri_prefix = if path_prefix.is_empty() {
|
||||
"/".to_owned()
|
||||
} else {
|
||||
format!("/{}/", &path_prefix)
|
||||
format!("/{}/", &encode_uri(&path_prefix))
|
||||
};
|
||||
let hidden: String = matches
|
||||
.value_of("hidden")
|
||||
|
|
|
@ -45,15 +45,30 @@ const BUF_SIZE: usize = 65536;
|
|||
pub struct Server {
|
||||
args: Arc<Args>,
|
||||
assets_prefix: String,
|
||||
single_file_req_paths: Vec<String>,
|
||||
running: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub fn new(args: Arc<Args>, running: Arc<AtomicBool>) -> Self {
|
||||
let assets_prefix = format!("{}__dufs_v{}_", args.uri_prefix, env!("CARGO_PKG_VERSION"));
|
||||
let single_file_req_paths = if args.path_is_file {
|
||||
vec![
|
||||
args.uri_prefix.to_string(),
|
||||
args.uri_prefix[0..args.uri_prefix.len() - 1].to_string(),
|
||||
encode_uri(&format!(
|
||||
"{}{}",
|
||||
&args.uri_prefix,
|
||||
get_file_name(&args.path)
|
||||
)),
|
||||
]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
Self {
|
||||
args,
|
||||
running,
|
||||
single_file_req_paths,
|
||||
assets_prefix,
|
||||
}
|
||||
}
|
||||
|
@ -118,8 +133,16 @@ impl Server {
|
|||
let head_only = method == Method::HEAD;
|
||||
|
||||
if self.args.path_is_file {
|
||||
self.handle_send_file(&self.args.path, headers, head_only, &mut res)
|
||||
.await?;
|
||||
if self
|
||||
.single_file_req_paths
|
||||
.iter()
|
||||
.any(|v| v.as_str() == req_path)
|
||||
{
|
||||
self.handle_send_file(&self.args.path, headers, head_only, &mut res)
|
||||
.await?;
|
||||
} else {
|
||||
status_not_found(&mut res);
|
||||
}
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,8 @@
|
|||
mod fixtures;
|
||||
mod utils;
|
||||
|
||||
use assert_cmd::prelude::*;
|
||||
use assert_fs::fixture::TempDir;
|
||||
use fixtures::{port, server, tmpdir, wait_for_port, Error, TestServer};
|
||||
use fixtures::{server, Error, TestServer};
|
||||
use rstest::rstest;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
#[rstest]
|
||||
fn path_prefix_index(#[with(&["--path-prefix", "xyz"])] server: TestServer) -> Result<(), Error> {
|
||||
|
@ -33,22 +30,3 @@ fn path_prefix_propfind(
|
|||
assert!(text.contains("<D:href>/xyz/</D:href>"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case("index.html")]
|
||||
fn serve_single_file(tmpdir: TempDir, port: u16, #[case] file: &str) -> Result<(), Error> {
|
||||
let mut child = Command::cargo_bin("dufs")?
|
||||
.arg(tmpdir.path().join(file))
|
||||
.arg("-p")
|
||||
.arg(port.to_string())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
wait_for_port(port);
|
||||
|
||||
let resp = reqwest::blocking::get(format!("http://localhost:{}/index.html", port))?;
|
||||
assert_eq!(resp.text()?, "This is index.html");
|
||||
|
||||
child.kill()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
60
tests/single_file.rs
Normal file
60
tests/single_file.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
//! Run file server with different args
|
||||
|
||||
mod fixtures;
|
||||
mod utils;
|
||||
|
||||
use assert_cmd::prelude::*;
|
||||
use assert_fs::fixture::TempDir;
|
||||
use fixtures::{port, tmpdir, wait_for_port, Error};
|
||||
use rstest::rstest;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
#[rstest]
|
||||
#[case("index.html")]
|
||||
fn single_file(tmpdir: TempDir, port: u16, #[case] file: &str) -> Result<(), Error> {
|
||||
let mut child = Command::cargo_bin("dufs")?
|
||||
.arg(tmpdir.path().join(file))
|
||||
.arg("-p")
|
||||
.arg(port.to_string())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
wait_for_port(port);
|
||||
|
||||
let resp = reqwest::blocking::get(format!("http://localhost:{}", port))?;
|
||||
assert_eq!(resp.text()?, "This is index.html");
|
||||
let resp = reqwest::blocking::get(format!("http://localhost:{}/", port))?;
|
||||
assert_eq!(resp.text()?, "This is index.html");
|
||||
let resp = reqwest::blocking::get(format!("http://localhost:{}/index.html", port))?;
|
||||
assert_eq!(resp.text()?, "This is index.html");
|
||||
|
||||
child.kill()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case("index.html")]
|
||||
fn path_prefix_single_file(tmpdir: TempDir, port: u16, #[case] file: &str) -> Result<(), Error> {
|
||||
let mut child = Command::cargo_bin("dufs")?
|
||||
.arg(tmpdir.path().join(file))
|
||||
.arg("-p")
|
||||
.arg(port.to_string())
|
||||
.arg("--path-prefix")
|
||||
.arg("xyz")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
wait_for_port(port);
|
||||
|
||||
let resp = reqwest::blocking::get(format!("http://localhost:{}/xyz", port))?;
|
||||
assert_eq!(resp.text()?, "This is index.html");
|
||||
let resp = reqwest::blocking::get(format!("http://localhost:{}/xyz/", port))?;
|
||||
assert_eq!(resp.text()?, "This is index.html");
|
||||
let resp = reqwest::blocking::get(format!("http://localhost:{}/xyz/index.html", port))?;
|
||||
assert_eq!(resp.text()?, "This is index.html");
|
||||
let resp = reqwest::blocking::get(format!("http://localhost:{}", port))?;
|
||||
assert_eq!(resp.status(), 404);
|
||||
|
||||
child.kill()?;
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in a new issue