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] {

Reply via email to