This is an automated email from the ASF dual-hosted git repository.

suyanhanx pushed a commit to branch obs-cp
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git

commit e27e7b5993b4738d892890c997f150c02be6ca48
Author: suyanhanx <[email protected]>
AuthorDate: Sat Apr 8 12:03:53 2023 +0800

    feat(services/obs): add support copy
    
    Signed-off-by: suyanhanx <[email protected]>
---
 core/src/services/obs/backend.rs | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/core/src/services/obs/backend.rs b/core/src/services/obs/backend.rs
index 3183f02d..93ee55ff 100644
--- a/core/src/services/obs/backend.rs
+++ b/core/src/services/obs/backend.rs
@@ -44,6 +44,7 @@ use crate::*;
 ///
 /// - [x] read
 /// - [x] write
+/// - [x] copy
 /// - [x] list
 /// - [x] scan
 /// - [ ] presign
@@ -314,7 +315,7 @@ impl Accessor for ObsBackend {
         am.set_scheme(Scheme::Obs)
             .set_root(&self.root)
             .set_name(&self.bucket)
-            .set_capabilities(Read | Write | List | Scan)
+            .set_capabilities(Read | Write | Copy | List | Scan)
             .set_hints(ReadStreamable);
 
         am
@@ -366,6 +367,20 @@ impl Accessor for ObsBackend {
         ))
     }
 
+    async fn copy(&self, from: &str, to: &str, _args: OpCopy) -> 
Result<RpCopy> {
+        let resp = self.obs_copy_object(from, to).await?;
+
+        let status = resp.status();
+
+        match status {
+            StatusCode::OK => {
+                resp.into_body().consume().await?;
+                Ok(RpCopy::default())
+            }
+            _ => Err(parse_error(resp).await?),
+        }
+    }
+
     async fn stat(&self, path: &str, _: OpStat) -> Result<RpStat> {
         // Stat root always returns a DIR.
         if path == "/" {
@@ -500,6 +515,23 @@ impl ObsBackend {
         self.client.send_async(req).await
     }
 
+    async fn obs_copy_object(&self, from: &str, to: &str) -> 
Result<Response<IncomingAsyncBody>> {
+        let source = build_abs_path(&self.root, from);
+        let target = build_abs_path(&self.root, to);
+
+        let source = format!("/{}/{}", self.bucket, 
percent_encode_path(&source));
+        let url = format!("{}/{}", self.endpoint, 
percent_encode_path(&target));
+
+        let mut req = Request::put(&url)
+            .header("x-obs-copy-source", percent_encode_path(&source))
+            .body(AsyncBody::Empty)
+            .map_err(new_request_build_error)?;
+
+        self.signer.sign(&mut req).map_err(new_request_sign_error)?;
+
+        self.client.send_async(req).await
+    }
+
     pub(crate) async fn obs_list_objects(
         &self,
         path: &str,

Reply via email to