From 3d7aebca1a49019c52c5a53df5aca346bf6de557 Mon Sep 17 00:00:00 2001 From: Suyan Date: Sat, 8 Apr 2023 12:26:06 +0800 Subject: [PATCH] feat(services/obs): Add Copy Support (#1876) feat(services/obs): add support copy Signed-off-by: suyanhanx --- 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 3183f02dba0..93ee55ffbaf 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 { + 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 { // 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> { + 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,