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;
|
use crate::auth::AuthMethod;
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
use crate::tls::{load_certs, load_private_key};
|
use crate::tls::{load_certs, load_private_key};
|
||||||
|
use crate::utils::encode_uri;
|
||||||
use crate::BoxResult;
|
use crate::BoxResult;
|
||||||
|
|
||||||
pub fn build_cli() -> Command<'static> {
|
pub fn build_cli() -> Command<'static> {
|
||||||
|
@ -196,7 +197,7 @@ impl Args {
|
||||||
let uri_prefix = if path_prefix.is_empty() {
|
let uri_prefix = if path_prefix.is_empty() {
|
||||||
"/".to_owned()
|
"/".to_owned()
|
||||||
} else {
|
} else {
|
||||||
format!("/{}/", &path_prefix)
|
format!("/{}/", &encode_uri(&path_prefix))
|
||||||
};
|
};
|
||||||
let hidden: String = matches
|
let hidden: String = matches
|
||||||
.value_of("hidden")
|
.value_of("hidden")
|
||||||
|
|
|
@ -45,15 +45,30 @@ const BUF_SIZE: usize = 65536;
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
args: Arc<Args>,
|
args: Arc<Args>,
|
||||||
assets_prefix: String,
|
assets_prefix: String,
|
||||||
|
single_file_req_paths: Vec<String>,
|
||||||
running: Arc<AtomicBool>,
|
running: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
pub fn new(args: Arc<Args>, running: Arc<AtomicBool>) -> Self {
|
pub fn new(args: Arc<Args>, running: Arc<AtomicBool>) -> Self {
|
||||||
let assets_prefix = format!("{}__dufs_v{}_", args.uri_prefix, env!("CARGO_PKG_VERSION"));
|
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 {
|
Self {
|
||||||
args,
|
args,
|
||||||
running,
|
running,
|
||||||
|
single_file_req_paths,
|
||||||
assets_prefix,
|
assets_prefix,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,8 +133,16 @@ impl Server {
|
||||||
let head_only = method == Method::HEAD;
|
let head_only = method == Method::HEAD;
|
||||||
|
|
||||||
if self.args.path_is_file {
|
if self.args.path_is_file {
|
||||||
self.handle_send_file(&self.args.path, headers, head_only, &mut res)
|
if self
|
||||||
.await?;
|
.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);
|
return Ok(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,8 @@
|
||||||
mod fixtures;
|
mod fixtures;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use assert_cmd::prelude::*;
|
use fixtures::{server, Error, TestServer};
|
||||||
use assert_fs::fixture::TempDir;
|
|
||||||
use fixtures::{port, server, tmpdir, wait_for_port, Error, TestServer};
|
|
||||||
use rstest::rstest;
|
use rstest::rstest;
|
||||||
use std::process::{Command, Stdio};
|
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
fn path_prefix_index(#[with(&["--path-prefix", "xyz"])] server: TestServer) -> Result<(), Error> {
|
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>"));
|
assert!(text.contains("<D:href>/xyz/</D:href>"));
|
||||||
Ok(())
|
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