diff --git a/crates/protocols/Cargo.toml b/crates/protocols/Cargo.toml index d8f4b601f..29e46ddf5 100644 --- a/crates/protocols/Cargo.toml +++ b/crates/protocols/Cargo.toml @@ -53,7 +53,7 @@ swift = [ "dep:base64", "dep:async-compression", ] -webdav = ["dep:dav-server", "dep:hyper", "dep:hyper-util", "dep:http-body-util", "dep:tokio-rustls", "dep:base64", "dep:rustls"] +webdav = ["dep:dav-server", "dep:hyper", "dep:hyper-util", "dep:http-body-util", "dep:tokio-rustls", "dep:base64", "dep:rustls", "dep:percent-encoding"] [dependencies] # Core RustFS dependencies diff --git a/crates/protocols/src/webdav/driver.rs b/crates/protocols/src/webdav/driver.rs index 01dfd3173..c017f902f 100644 --- a/crates/protocols/src/webdav/driver.rs +++ b/crates/protocols/src/webdav/driver.rs @@ -21,6 +21,7 @@ use dav_server::fs::{ DavDirEntry, DavFile, DavFileSystem, DavMetaData, FsError, FsFuture, FsResult, FsStream, OpenOptions, ReadDirMeta, }; use futures_util::{FutureExt, StreamExt, stream}; +use percent_encoding::percent_decode_str; use rustfs_utils::path; use s3s::dto::*; use std::fmt::Debug; @@ -432,7 +433,10 @@ where /// Parse WebDAV path to bucket and object key fn parse_path(&self, path: &DavPath) -> Result<(String, Option), FsError> { let path_str = path.as_url_string(); - let cleaned_path = path::clean(&path_str); + let decoded_path = percent_decode_str(&path_str) + .decode_utf8() + .map_err(|_| FsError::GeneralFailure)?; + let cleaned_path = path::clean(&decoded_path); let (bucket, object) = path::path_to_bucket_object(&cleaned_path); if bucket.is_empty() {