]> OzVa Git service - ozva-cloud/commitdiff
feat: support path prefix
authorsigoden <sigoden@gmail.com>
Thu, 2 Jun 2022 00:32:31 +0000 (08:32 +0800)
committersigoden <sigoden@gmail.com>
Thu, 2 Jun 2022 00:32:31 +0000 (08:32 +0800)
src/args.rs
src/server.rs

index c419329397d89f6f4d7dfb8b62b412ea711e5abb..eb1b3e00b3fba09feade501a321fa269d4b75707 100644 (file)
@@ -33,6 +33,12 @@ fn app() -> clap::Command<'static> {
                 .allow_invalid_utf8(true)
                 .help("Path to a root directory for serving files"),
         )
+        .arg(
+            Arg::new("path-prefix")
+                .long("path-prefix")
+                .value_name("path")
+                .help("Specify an url path prefix"),
+        )
         .arg(
             Arg::new("allow-all")
                 .short('A')
@@ -92,6 +98,7 @@ pub struct Args {
     pub address: String,
     pub port: u16,
     pub path: PathBuf,
+    pub path_prefix: Option<String>,
     pub auth: Option<String>,
     pub no_auth_read: bool,
     pub allow_upload: bool,
@@ -111,6 +118,7 @@ impl Args {
         let address = matches.value_of("address").unwrap_or_default().to_owned();
         let port = matches.value_of_t::<u16>("port")?;
         let path = Args::parse_path(matches.value_of_os("path").unwrap_or_default())?;
+        let path_prefix = matches.value_of("path-prefix").map(|v| v.to_owned());
         let cors = matches.is_present("cors");
         let auth = matches.value_of("auth").map(|v| v.to_owned());
         let no_auth_read = matches.is_present("no-auth-read");
@@ -124,6 +132,7 @@ impl Args {
             address,
             port,
             path,
+            path_prefix,
             auth,
             no_auth_read,
             cors,
index 4e37c115ea35f79cf681ed5141c540d62b638ad4..17f20c330ef9538334e5da21063a7693ad93483a 100644 (file)
@@ -506,7 +506,22 @@ impl InnerService {
         } else {
             decoded_path.into_owned()
         };
-        Some(self.args.path.join(&slashes_switched))
+        let stripped_path = match self.strip_path_prefix(&slashes_switched) {
+            Some(path) => path,
+            None => return None,
+        };
+        Some(self.args.path.join(&stripped_path))
+    }
+
+    fn strip_path_prefix<'a, P: AsRef<Path>>(&self, path: &'a P) -> Option<&'a Path> {
+        let path = path.as_ref();
+        match self.args.path_prefix.as_deref() {
+            Some(prefix) => {
+                let prefix = prefix.trim_start_matches('/');
+                path.strip_prefix(prefix).ok()
+            }
+            None => Some(path),
+        }
     }
 
     async fn to_pathitem<P: AsRef<Path>>(