diff --git a/Cargo.toml b/Cargo.toml index 28b0f1dd5..65e2d8d61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "salvo" -version = "0.19.0" +version = "0.19.1" authors = ["Chrislearn Young "] edition = "2021" description = """ @@ -51,7 +51,7 @@ members = [".", "core", "extra", "macros"] [dependencies] salvo_core = { version = "0.19.0", default-features = false, path = "./core" } -salvo_extra = { version = "0.19.0", default-features = false, optional = true, path = "./extra" } +salvo_extra = { version = "0.19.1", default-features = false, optional = true, path = "./extra" } [dev-dependencies] async-stream = "0.3" diff --git a/examples/static/test/dir1/dir2/test3.txt b/examples/static/test/dir1/dir2/test3.txt new file mode 100644 index 000000000..a44baff9d --- /dev/null +++ b/examples/static/test/dir1/dir2/test3.txt @@ -0,0 +1 @@ +dir2 test3 \ No newline at end of file diff --git a/extra/Cargo.toml b/extra/Cargo.toml index 92454729a..d6e44d0d9 100644 --- a/extra/Cargo.toml +++ b/extra/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "salvo_extra" -version = "0.19.0" +version = "0.19.1" authors = ["Chrislearn Young "] edition = "2021" description = """ diff --git a/extra/src/serve/dir.rs b/extra/src/serve/dir.rs index 167b56145..6e68acfa1 100644 --- a/extra/src/serve/dir.rs +++ b/extra/src/serve/dir.rs @@ -168,21 +168,27 @@ impl Handler for StaticDir { async fn handle(&self, req: &mut Request, depot: &mut Depot, res: &mut Response, _ctrl: &mut FlowCtrl) { let param = req.params().iter().find(|(key, _)| key.starts_with('*')); let req_path = req.uri().path(); - let base_path = if let Some((_, value)) = param { + let rel_path = if let Some((_, value)) = param { value.clone() } else { decode_url_path_safely(req_path) }; - let base_path = if base_path.starts_with('/') { - format!(".{}", base_path) - } else { - base_path.to_owned() - }; + let mut used_parts = Vec::with_capacity(8); + for part in rel_path.split('/') { + if part.is_empty() || part == "." { + continue; + } else if part == ".." { + used_parts.pop(); + } else { + used_parts.push(part); + } + } + let rel_path: String = used_parts.join("/"); let mut files: HashMap = HashMap::new(); let mut dirs: HashMap = HashMap::new(); let mut path_exist = false; for root in &self.roots { - let path = root.join(&base_path); + let path = root.join(&rel_path); if path.is_dir() && self.options.listing { path_exist = true; if !req_path.ends_with('/') { diff --git a/extra/src/serve/mod.rs b/extra/src/serve/mod.rs index c1f869c2c..99c140d06 100644 --- a/extra/src/serve/mod.rs +++ b/extra/src/serve/mod.rs @@ -57,5 +57,15 @@ mod tests { let content = access(&service, "text/plain", "http://127.0.0.1:7979/test3.txt").await; assert!(content.contains("Not Found")); + + let content = access(&service, "text/plain", "http://127.0.0.1:7979/../girl/love/eat.txt").await; + assert!(content.contains("Not Found")); + + let content = access(&service, "text/plain", "http://127.0.0.1:7979/dir1/test3.txt").await; + assert!(content.contains("copy3")); + let content = access(&service, "text/plain", "http://127.0.0.1:7979/dir1/dir2/test3.txt").await; + assert!(content == "dir2 test3"); + let content = access(&service, "text/plain", "http://127.0.0.1:7979/dir1/../dir1/test3.txt").await; + assert!(content == "copy3"); } }