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 4b33fcdec feat: Add create_dir, remove, copy and rename API for
oay-webdav (#2832)
4b33fcdec is described below
commit 4b33fcdecdf4d3752bbe42f8155b5b66f2de144b
Author: Flash <[email protected]>
AuthorDate: Wed Aug 9 22:34:20 2023 +0800
feat: Add create_dir, remove, copy and rename API for oay-webdav (#2832)
* impl some missing api for oay-webdav
* use `map_err` to omit `match`
---
bin/oay/src/services/webdav/webdav_file.rs | 2 +-
bin/oay/src/services/webdav/webdavfs.rs | 87 ++++++++++++++++++++++++++++--
2 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/bin/oay/src/services/webdav/webdav_file.rs
b/bin/oay/src/services/webdav/webdav_file.rs
index 5a10813ea..73e1892be 100644
--- a/bin/oay/src/services/webdav/webdav_file.rs
+++ b/bin/oay/src/services/webdav/webdav_file.rs
@@ -83,7 +83,7 @@ impl DavFile for WebdavFile {
}
}
-fn convert_error(opendal_error: opendal::Error) -> dav_server::fs::FsError {
+pub fn convert_error(opendal_error: opendal::Error) -> dav_server::fs::FsError
{
match opendal_error.kind() {
opendal::ErrorKind::AlreadyExists | opendal::ErrorKind::IsSameFile => {
dav_server::fs::FsError::Exists
diff --git a/bin/oay/src/services/webdav/webdavfs.rs
b/bin/oay/src/services/webdav/webdavfs.rs
index 3eda5c539..0a974dfd9 100644
--- a/bin/oay/src/services/webdav/webdavfs.rs
+++ b/bin/oay/src/services/webdav/webdavfs.rs
@@ -15,9 +15,11 @@
// specific language governing permissions and limitations
// under the License.
+use std::path::Path;
use std::pin::Pin;
use std::task::Poll::{Pending, Ready};
+use dav_server::davpath::DavPath;
use dav_server::fs::DavDirEntry;
use dav_server::fs::DavFile;
use dav_server::fs::DavFileSystem;
@@ -30,7 +32,7 @@ use opendal::Operator;
use crate::services::webdav::webdav_dir_entry::WebDAVDirEntry;
-use super::webdav_file::WebdavFile;
+use super::webdav_file::{convert_error, WebdavFile};
use super::webdav_metadata::WebdavMetaData;
#[derive(Clone)]
@@ -73,8 +75,87 @@ impl DavFileSystem for WebdavFs {
path: &'a dav_server::davpath::DavPath,
) -> dav_server::fs::FsFuture<Box<dyn dav_server::fs::DavMetaData>> {
async move {
- let opendal_metadata =
self.op.stat(path.as_url_string().as_str()).await.unwrap();
- Ok(Box::new(WebdavMetaData::new(opendal_metadata)) as Box<dyn
DavMetaData>)
+ let opendal_metadata =
self.op.stat(path.as_url_string().as_str()).await;
+ match opendal_metadata {
+ Ok(metadata) => {
+ let webdav_metadata = WebdavMetaData::new(metadata);
+ Ok(Box::new(webdav_metadata) as Box<dyn DavMetaData>)
+ }
+ Err(e) => Err(convert_error(e)),
+ }
+ }
+ .boxed()
+ }
+
+ fn create_dir<'a>(&'a self, path: &'a DavPath) ->
dav_server::fs::FsFuture<()> {
+ async move {
+ let path = path.as_url_string();
+
+ // check if the parent path is exist.
+ // During MKCOL processing, a server MUST make the Request-URI a
member of its parent collection, unless the Request-URI is "/". If no such
ancestor exists, the method MUST fail.
+ // refer to
https://datatracker.ietf.org/doc/html/rfc2518#section-8.3.1
+ let parent = Path::new(&path).parent().unwrap();
+ match self.op.is_exist(parent.to_str().unwrap()).await {
+ Ok(exist) => {
+ if !exist && parent != Path::new("/") {
+ return Err(dav_server::fs::FsError::NotFound);
+ }
+ }
+ Err(e) => {
+ return Err(convert_error(e));
+ }
+ }
+
+ let path = path.as_str();
+ // check if the given path is exist (MKCOL on existing collection
should fail (RFC2518:8.3.1))
+ let exist = self.op.is_exist(path).await;
+ match exist {
+ Ok(exist) => match exist {
+ true => Err(dav_server::fs::FsError::Exists),
+ false => {
+ let res = self.op.create_dir(path).await;
+ match res {
+ Ok(_) => Ok(()),
+ Err(e) => Err(convert_error(e)),
+ }
+ }
+ },
+ Err(e) => Err(convert_error(e)),
+ }
+ }
+ .boxed()
+ }
+
+ fn remove_file<'a>(&'a self, path: &'a DavPath) ->
dav_server::fs::FsFuture<()> {
+ async move {
+ self.op
+ .delete(path.as_url_string().as_str())
+ .await
+ .map_err(convert_error)
+ }
+ .boxed()
+ }
+
+ fn remove_dir<'a>(&'a self, path: &'a DavPath) ->
dav_server::fs::FsFuture<()> {
+ self.remove_file(path)
+ }
+
+ fn copy<'a>(&'a self, from: &'a DavPath, to: &'a DavPath) ->
dav_server::fs::FsFuture<()> {
+ async move {
+ self.op
+ .copy(&from.as_url_string(), &to.as_url_string())
+ .await
+ .map_err(convert_error)
+ }
+ .boxed()
+ }
+
+ fn rename<'a>(&'a self, from: &'a DavPath, to: &'a DavPath) ->
dav_server::fs::FsFuture<()> {
+ async move {
+ self.op
+ .rename(from.as_url_string().as_str(),
to.as_url_string().as_str())
+ .await
+ .map_err(convert_error)
}
.boxed()
}