This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch fix-webdav in repository https://gitbox.apache.org/repos/asf/opendal.git
commit dfbf80b44b8cad7b68c65be205647975c94acca7 Author: Xuanwo <[email protected]> AuthorDate: Fri Feb 23 13:17:24 2024 +0800 fix(services/webdav): Fix endpoint suffix not handled Signed-off-by: Xuanwo <[email protected]> --- core/src/services/webdav/backend.rs | 4 ++-- core/src/services/webdav/lister.rs | 35 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/core/src/services/webdav/backend.rs b/core/src/services/webdav/backend.rs index fd2edaf154..781ed36c51 100644 --- a/core/src/services/webdav/backend.rs +++ b/core/src/services/webdav/backend.rs @@ -301,7 +301,7 @@ impl Accessor for WebdavBackend { return Err(Error::new( ErrorKind::NotFound, "Failed getting item stat: response field was not found", - )) + )); } }; @@ -379,7 +379,7 @@ impl Accessor for WebdavBackend { let result: Multistatus = quick_xml::de::from_reader(bs.reader()).map_err(new_xml_deserialize_error)?; - let l = WebdavLister::new(&self.root, path, result); + let l = WebdavLister::new(&self.endpoint, &self.root, path, result); Ok((RpList::default(), Some(oio::PageLister::new(l)))) } diff --git a/core/src/services/webdav/lister.rs b/core/src/services/webdav/lister.rs index d4d0241f3e..6c7f0bd196 100644 --- a/core/src/services/webdav/lister.rs +++ b/core/src/services/webdav/lister.rs @@ -17,10 +17,13 @@ use async_trait::async_trait; use serde::Deserialize; +use std::str::FromStr; use crate::raw::*; use crate::*; + pub struct WebdavLister { + server_path: String, root: String, path: String, multistates: Multistatus, @@ -28,8 +31,14 @@ pub struct WebdavLister { impl WebdavLister { /// TODO: sending request in `next_page` instead of in `new`. - pub fn new(root: &str, path: &str, multistates: Multistatus) -> Self { + pub fn new(endpoint: &str, root: &str, path: &str, multistates: Multistatus) -> Self { + // Some services might return the path with suffix `/remote.php/webdav/`, we need to trim them. + let server_path = http::Uri::from_str(endpoint) + .expect("must be valid http uri") + .path() + .to_string(); Self { + server_path, root: root.into(), path: path.into(), multistates, @@ -44,7 +53,7 @@ impl oio::PageList for WebdavLister { let oes = self.multistates.response.clone(); for res in oes { - let path = res.href.as_str(); + let path = res.href.trim_start_matches(&self.server_path); // Ignore the root path itself. if self.root == path { @@ -88,18 +97,18 @@ impl ListOpResponse { pub fn parse_into_metadata(&self) -> Result<Metadata> { let ListOpResponse { propstat: - Propstat { - prop: - Prop { - getlastmodified, - getcontentlength, - getcontenttype, - getetag, - resourcetype, - .. - }, - status, + Propstat { + prop: + Prop { + getlastmodified, + getcontentlength, + getcontenttype, + getetag, + resourcetype, + .. }, + status, + }, .. } = self; if let [_, code, text] = status.split(' ').collect::<Vec<_>>()[..3] {
