This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch add-nextcloud-test-for-webdav in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit 4a5d2070e0c8552a05ace456b9ca486e3a4ade21 Author: Xuanwo <[email protected]> AuthorDate: Thu Jul 13 22:42:11 2023 +0800 Polish API Signed-off-by: Xuanwo <[email protected]> --- core/src/services/webdav/backend.rs | 23 ++++++---------- core/src/services/webdav/pager.rs | 52 ++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 44 deletions(-) diff --git a/core/src/services/webdav/backend.rs b/core/src/services/webdav/backend.rs index 3a1ff789b..11aa91d5d 100644 --- a/core/src/services/webdav/backend.rs +++ b/core/src/services/webdav/backend.rs @@ -428,6 +428,7 @@ impl Accessor for WebdavBackend { let bs = resp.into_body().bytes().await?; let result: Multistatus = quick_xml::de::from_reader(bs.reader()).map_err(new_xml_deserialize_error)?; + log::info!("got response: {result:?}"); Ok(( RpList::default(), @@ -640,15 +641,11 @@ impl WebdavBackend { match status { StatusCode::CREATED - | StatusCode::OK - // `File exists` will return `Method Not Allowed` - | StatusCode::METHOD_NOT_ALLOWED - // create existing dir will return conflict - | StatusCode::CONFLICT - // create existing file will return no_content - | StatusCode::NO_CONTENT - // ALlow mutiple status - | StatusCode::MULTI_STATUS=> { + // Allow mutiple status + | StatusCode::MULTI_STATUS + // The MKCOL method can only be performed on a deleted or non-existent resource. + // This error means the directory already exists which is allowed by create_dir. + | StatusCode::METHOD_NOT_ALLOWED => { resp.into_body().consume().await?; Ok(()) } @@ -662,21 +659,17 @@ impl WebdavBackend { while path != "/" { // check path first. let parent = get_parent(path); - log::info!("parent: {}", parent); - if parent == "/" { - break; - } let mut header_map = HeaderMap::new(); // not include children header_map.insert("Depth", "0".parse().unwrap()); header_map.insert(header::ACCEPT, "application/xml".parse().unwrap()); - let resp = self.webdav_propfind(path, Some(header_map)).await?; + let resp = self.webdav_propfind(parent, Some(header_map)).await?; match resp.status() { StatusCode::OK | StatusCode::MULTI_STATUS => break, StatusCode::NOT_FOUND => { - dirs.push_front(path); + dirs.push_front(parent); path = parent } _ => return Err(parse_error(resp).await?), diff --git a/core/src/services/webdav/pager.rs b/core/src/services/webdav/pager.rs index 4bbf1e135..dc1e63ad1 100644 --- a/core/src/services/webdav/pager.rs +++ b/core/src/services/webdav/pager.rs @@ -46,34 +46,27 @@ impl oio::Page for WebdavPager { }; let oes = mem::take(&mut self.multistates.response); - let oes = oes - .into_iter() - .filter_map(|de| { - let path = de.href; - - // Ignore the root path itself. - if self.root == path { - return None; - } - - let normalized_path = build_rel_path(&self.root, &path); - if normalized_path == self.path { - // WebDav server may return the current path as an entry. - return None; - } - - let entry = if de.propstat.prop.resourcetype.value == Some(ResourceType::Collection) - { - oio::Entry::new(&normalized_path, Metadata::new(EntryMode::DIR)) - } else { - oio::Entry::new(&normalized_path, Metadata::new(EntryMode::FILE)) - }; - - Some(entry) - }) - .collect(); - - Ok(Some(oes)) + let mut entries = Vec::with_capacity(oes.len()); + + for res in oes { + let path = res.href.as_str(); + + // Ignore the root path itself. + if self.root == path { + continue; + } + + let normalized_path = build_rel_path(&self.root, path); + if normalized_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)) + } + + Ok(Some(entries)) } } @@ -116,7 +109,7 @@ impl ListOpResponse { } } - let mode = if href.ends_with('/') { + let mode: EntryMode = if href.ends_with('/') { EntryMode::DIR } else { EntryMode::FILE @@ -134,6 +127,7 @@ impl ListOpResponse { if let Some(v) = getetag { m.set_etag(v); } + // https://www.rfc-editor.org/rfc/rfc4918#section-14.18 m.set_last_modified(parse_datetime_from_rfc2822(getlastmodified)?); Ok(m)
