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 643ddb84 feat: add if-match support for obs (#2023)
643ddb84 is described below

commit 643ddb8452bf44fac675a7cd22ec1b341413b073
Author: Hao <[email protected]>
AuthorDate: Mon Apr 17 22:37:05 2023 +0800

    feat: add if-match support for obs (#2023)
    
    * feat: add if-match support for obs
    
    * chore: change parameters localtion
---
 core/src/services/obs/backend.rs | 15 +++++++++------
 core/src/services/obs/core.rs    | 23 +++++++++++++++++++++--
 core/src/services/obs/writer.rs  |  1 +
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/core/src/services/obs/backend.rs b/core/src/services/obs/backend.rs
index fb5fc2f2..3412999e 100644
--- a/core/src/services/obs/backend.rs
+++ b/core/src/services/obs/backend.rs
@@ -315,9 +315,9 @@ impl Accessor for ObsBackend {
     }
 
     async fn create_dir(&self, path: &str, _: OpCreate) -> Result<RpCreate> {
-        let mut req = self
-            .core
-            .obs_put_object_request(path, Some(0), None, AsyncBody::Empty)?;
+        let mut req =
+            self.core
+                .obs_put_object_request(path, Some(0), None, None, 
AsyncBody::Empty)?;
 
         self.core.sign(&mut req).await?;
 
@@ -335,7 +335,10 @@ impl Accessor for ObsBackend {
     }
 
     async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, 
Self::Reader)> {
-        let resp = self.core.obs_get_object(path, args.range()).await?;
+        let resp = self
+            .core
+            .obs_get_object(path, args.range(), args.if_match())
+            .await?;
 
         let status = resp.status();
 
@@ -376,13 +379,13 @@ impl Accessor for ObsBackend {
         }
     }
 
-    async fn stat(&self, path: &str, _: OpStat) -> Result<RpStat> {
+    async fn stat(&self, path: &str, args: OpStat) -> Result<RpStat> {
         // Stat root always returns a DIR.
         if path == "/" {
             return Ok(RpStat::new(Metadata::new(EntryMode::DIR)));
         }
 
-        let resp = self.core.obs_get_head_object(path).await?;
+        let resp = self.core.obs_get_head_object(path, args.if_match()).await?;
 
         let status = resp.status();
 
diff --git a/core/src/services/obs/core.rs b/core/src/services/obs/core.rs
index 540ef84b..a71a048d 100644
--- a/core/src/services/obs/core.rs
+++ b/core/src/services/obs/core.rs
@@ -22,6 +22,7 @@ use crate::raw::*;
 use crate::*;
 use http::header::CONTENT_LENGTH;
 use http::header::CONTENT_TYPE;
+use http::header::IF_MATCH;
 use http::Request;
 use http::Response;
 use reqsign::HuaweicloudObsCredential;
@@ -84,6 +85,7 @@ impl ObsCore {
         &self,
         path: &str,
         range: BytesRange,
+        if_match: Option<&str>,
     ) -> Result<Response<IncomingAsyncBody>> {
         let p = build_abs_path(&self.root, path);
 
@@ -91,6 +93,10 @@ impl ObsCore {
 
         let mut req = Request::get(&url);
 
+        if let Some(if_match) = if_match {
+            req = req.header(IF_MATCH, if_match);
+        }
+
         if !range.is_full() {
             req = req.header(http::header::RANGE, range.to_header())
         }
@@ -109,6 +115,7 @@ impl ObsCore {
         path: &str,
         size: Option<usize>,
         content_type: Option<&str>,
+        if_match: Option<&str>,
         body: AsyncBody,
     ) -> Result<Request<AsyncBody>> {
         let p = build_abs_path(&self.root, path);
@@ -117,6 +124,10 @@ impl ObsCore {
 
         let mut req = Request::put(&url);
 
+        if let Some(if_match) = if_match {
+            req = req.header(IF_MATCH, if_match);
+        }
+
         if let Some(size) = size {
             req = req.header(CONTENT_LENGTH, size)
         }
@@ -130,7 +141,11 @@ impl ObsCore {
         Ok(req)
     }
 
-    pub async fn obs_get_head_object(&self, path: &str) -> 
Result<Response<IncomingAsyncBody>> {
+    pub async fn obs_get_head_object(
+        &self,
+        path: &str,
+        if_match: Option<&str>,
+    ) -> Result<Response<IncomingAsyncBody>> {
         let p = build_abs_path(&self.root, path);
 
         let url = format!("{}/{}", self.endpoint, percent_encode_path(&p));
@@ -138,7 +153,11 @@ impl ObsCore {
         // The header 'Origin' is optional for API calling, the doc has 
mistake, confirmed with customer service of huaweicloud.
         // https://support.huaweicloud.com/intl/en-us/api-obs/obs_04_0084.html
 
-        let req = Request::head(&url);
+        let mut req = Request::head(&url);
+
+        if let Some(if_match) = if_match {
+            req = req.header(IF_MATCH, if_match);
+        }
 
         let mut req = req
             .body(AsyncBody::Empty)
diff --git a/core/src/services/obs/writer.rs b/core/src/services/obs/writer.rs
index 21c685c7..080e0919 100644
--- a/core/src/services/obs/writer.rs
+++ b/core/src/services/obs/writer.rs
@@ -47,6 +47,7 @@ impl oio::Write for ObsWriter {
             &self.path,
             Some(bs.len()),
             self.op.content_type(),
+            self.op.if_match(),
             AsyncBody::Bytes(bs),
         )?;
 

Reply via email to