This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
The following commit(s) were added to refs/heads/main by this push:
new d68078d9f fix(services/webdav): decode path before set Entry (#3020)
d68078d9f is described below
commit d68078d9f568c3d56f0600abcbac998b32ff4404
Author: G-XD <[email protected]>
AuthorDate: Thu Sep 7 19:08:00 2023 +0800
fix(services/webdav): decode path before set Entry (#3020)
---
core/src/raw/http_util/mod.rs | 1 +
core/src/raw/http_util/uri.rs | 50 +++++++++++++++++++++++++++++++++++++++
core/src/services/webdav/pager.rs | 6 +++--
3 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/core/src/raw/http_util/mod.rs b/core/src/raw/http_util/mod.rs
index 2d6946db7..0bf62ee93 100644
--- a/core/src/raw/http_util/mod.rs
+++ b/core/src/raw/http_util/mod.rs
@@ -45,6 +45,7 @@ pub use header::parse_last_modified;
pub use header::parse_location;
mod uri;
+pub use uri::percent_decode_path;
pub use uri::percent_encode_path;
mod error;
diff --git a/core/src/raw/http_util/uri.rs b/core/src/raw/http_util/uri.rs
index e40349642..1f3b893e0 100644
--- a/core/src/raw/http_util/uri.rs
+++ b/core/src/raw/http_util/uri.rs
@@ -15,6 +15,7 @@
// specific language governing permissions and limitations
// under the License.
+use percent_encoding::percent_decode_str;
use percent_encoding::utf8_percent_encode;
use percent_encoding::AsciiSet;
use percent_encoding::NON_ALPHANUMERIC;
@@ -47,6 +48,16 @@ pub fn percent_encode_path(path: &str) -> String {
utf8_percent_encode(path, &PATH_ENCODE_SET).to_string()
}
+/// percent_decode_path will do percent decoding for http decode path.
+///
+/// If the input is not percent encoded or not valid utf8, return the input.
+pub fn percent_decode_path(path: &str) -> String {
+ match percent_decode_str(path).decode_utf8() {
+ Ok(v) => v.to_string(),
+ Err(_) => path.to_string(),
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -79,4 +90,43 @@ mod tests {
assert_eq!(actual, expected, "{name}");
}
}
+
+ #[test]
+ fn test_percent_decode_path() {
+ let cases = vec![
+ (
+ "Reserved Characters",
+ "%3B%2C/%3F%3A%40%26%3D%2B%24",
+ ";,/?:@&=+$",
+ ),
+ ("Unescaped Characters", "-_.!~*'()", "-_.!~*'()"),
+ ("Number Sign", "%23", "#"),
+ (
+ "Alphanumeric Characters + Space",
+ "ABC%20abc%20123",
+ "ABC abc 123",
+ ),
+ (
+ "Unicode Characters",
+
"%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81%E2%9D%A4",
+ "你好,世界!❤",
+ ),
+ (
+ "Double Encoded Characters",
+ "Double%2520Encoded",
+ "Double%20Encoded",
+ ),
+ (
+ "Not Percent Encoded Characters",
+ "/not percent encoded/path;,/?:@&=+$-",
+ "/not percent encoded/path;,/?:@&=+$-",
+ ),
+ ];
+
+ for (name, input, expected) in cases {
+ let actual = percent_decode_path(input);
+
+ assert_eq!(actual, expected, "{name}");
+ }
+ }
}
diff --git a/core/src/services/webdav/pager.rs
b/core/src/services/webdav/pager.rs
index 03195c069..519cae33f 100644
--- a/core/src/services/webdav/pager.rs
+++ b/core/src/services/webdav/pager.rs
@@ -62,13 +62,15 @@ impl oio::Page for WebdavPager {
}
let normalized_path = build_rel_path(&self.root, path);
- if normalized_path == self.path {
+ let decoded_path = percent_decode_path(normalized_path.as_str());
+
+ if normalized_path == self.path || decoded_path == self.path {
// WebDav server may return the current path as an entry.
continue;
}
let meta = res.parse_into_metadata()?;
- entries.push(oio::Entry::new(&normalized_path, meta))
+ entries.push(oio::Entry::new(&decoded_path, meta))
}
Ok(Some(entries))