]> OzVa Git service - ozva-cloud/commitdiff
feat: make --path-prefix works on serving single file (#102)
authorsigoden <sigoden@gmail.com>
Fri, 8 Jul 2022 11:30:05 +0000 (19:30 +0800)
committerGitHub <noreply@github.com>
Fri, 8 Jul 2022 11:30:05 +0000 (19:30 +0800)
src/args.rs
src/server.rs
tests/args.rs
tests/single_file.rs [new file with mode: 0644]

index e4815c1109eebb9711929686176fd4cb5a8a8824..bb0672085999366c7b681d765885a9c6d00f31ca 100644 (file)
@@ -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")
index 46e64dfe21ace80af3033b806a972de13edd536e..456ed3dfb525188bf37b84748be3a47c2271d432 100644 (file)
@@ -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);
         }
 
index db6180325abce741fd3bf126c98b3d50618f2901..91e0eb1004edadb170a905bd51906b42ffda5073 100644 (file)
@@ -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(())
-}
diff --git a/tests/single_file.rs b/tests/single_file.rs
new file mode 100644 (file)
index 0000000..1d97f3f
--- /dev/null
@@ -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(())
+}