From 4cb481e4a5ead5b88ed1418ec1f12c0ee517ba0f Mon Sep 17 00:00:00 2001 From: AJIOB Date: Thu, 8 Feb 2024 15:50:53 +0300 Subject: [PATCH] Use absolute paths for recreate all dirs. Fixes issue #4172 --- core/src/services/webdav/backend.rs | 41 ++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/core/src/services/webdav/backend.rs b/core/src/services/webdav/backend.rs index 75106ddbe7c..b35ee1fe2a4 100644 --- a/core/src/services/webdav/backend.rs +++ b/core/src/services/webdav/backend.rs @@ -495,10 +495,9 @@ impl WebdavBackend { self.client.send(req).await } - async fn webdav_mkcol(&self, path: &str) -> Result> { - let p = build_abs_path(&self.root, path); - - let url = format!("{}/{}", self.endpoint, percent_encode_path(&p)); + async fn webdav_mkcol_absolute_path(&self, path: &str) -> Result> { + debug_assert!(path.starts_with('/'), "path must be absolute path"); + let url = format!("{}{}", self.endpoint, percent_encode_path(path)); let mut req = Request::builder().method("MKCOL").uri(&url); if let Some(auth) = &self.authorization { @@ -517,9 +516,19 @@ impl WebdavBackend { path: &str, headers: Option, ) -> Result> { - let p = build_abs_path(&self.root, path); + let p = build_rooted_abs_path(&self.root, path); - let url = format!("{}/{}", self.endpoint, percent_encode_path(&p)); + self.webdav_propfind_absolute_path(&p, headers).await + } + + async fn webdav_propfind_absolute_path( + &self, + path: &str, + headers: Option, + ) -> Result> { + debug_assert!(path.starts_with('/'), "path must be absolute path"); + + let url = format!("{}{}", self.endpoint, percent_encode_path(path)); let mut req = Request::builder().method("PROPFIND").uri(&url); if let Some(auth) = &self.authorization { @@ -620,7 +629,14 @@ impl WebdavBackend { } async fn create_dir_internal(&self, path: &str) -> Result<()> { - let resp = self.webdav_mkcol(path).await?; + let p = build_rooted_abs_path(&self.root, path); + self.create_dir_internal_absolute_path(&p).await + } + + async fn create_dir_internal_absolute_path(&self, path: &str) -> Result<()> { + debug_assert!(path.starts_with('/'), "path must be absolute path"); + + let resp = self.webdav_mkcol_absolute_path(path).await?; let status = resp.status(); @@ -638,7 +654,10 @@ impl WebdavBackend { } } - async fn ensure_parent_path(&self, mut path: &str) -> Result<()> { + async fn ensure_parent_path(&self, path: &str) -> Result<()> { + let path = build_rooted_abs_path(&self.root, path); + let mut path = path.as_str(); + let mut dirs = VecDeque::default(); while path != "/" { @@ -650,7 +669,9 @@ impl WebdavBackend { header_map.insert("Depth", "0".parse().unwrap()); header_map.insert(header::ACCEPT, "application/xml".parse().unwrap()); - let resp = self.webdav_propfind(parent, Some(header_map)).await?; + let resp = self + .webdav_propfind_absolute_path(parent, Some(header_map)) + .await?; match resp.status() { StatusCode::OK | StatusCode::MULTI_STATUS => break, StatusCode::NOT_FOUND => { @@ -662,7 +683,7 @@ impl WebdavBackend { } for dir in dirs { - self.create_dir_internal(dir).await?; + self.create_dir_internal_absolute_path(dir).await?; } Ok(()) }