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 e3fb7b00 feat(services/s3): Add if-match support (#2033)
e3fb7b00 is described below
commit e3fb7b0017f33f6112b832ad74d60a02fcd6aabf
Author: leenstx <[email protected]>
AuthorDate: Tue Apr 18 23:14:21 2023 +0800
feat(services/s3): Add if-match support (#2033)
* feat: s3: Add if-match support #1972
* feat: s3: Add if-match support #1972
---------
Co-authored-by: leenstx • <[email protected]>
---
core/src/services/s3/backend.rs | 12 +++++++++---
core/src/services/s3/core.rs | 22 ++++++++++++++++++++--
2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/core/src/services/s3/backend.rs b/core/src/services/s3/backend.rs
index c3fa6aac..da2f1181 100644
--- a/core/src/services/s3/backend.rs
+++ b/core/src/services/s3/backend.rs
@@ -944,7 +944,7 @@ impl Accessor for S3Backend {
async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead,
Self::Reader)> {
let resp = self
.core
- .s3_get_object(path, args.range(), args.if_none_match())
+ .s3_get_object(path, args.range(), args.if_none_match(),
args.if_match())
.await?;
let status = resp.status();
@@ -967,6 +967,7 @@ impl Accessor for S3Backend {
args.content_type(),
args.content_disposition(),
args.cache_control(),
+ args.if_match(),
)
.await?;
@@ -1017,7 +1018,10 @@ impl Accessor for S3Backend {
return Ok(RpStat::new(Metadata::new(EntryMode::DIR)));
}
- let resp = self.core.s3_head_object(path, args.if_none_match()).await?;
+ let resp = self
+ .core
+ .s3_head_object(path, args.if_none_match(), args.if_match())
+ .await?;
let status = resp.status();
@@ -1059,7 +1063,8 @@ impl Accessor for S3Backend {
// We will not send this request out, just for signing.
let mut req = match args.operation() {
PresignOperation::Stat(v) => {
- self.core.s3_head_object_request(path, v.if_none_match())?
+ self.core
+ .s3_head_object_request(path, v.if_none_match(),
v.if_match())?
}
PresignOperation::Read(v) => self.core.s3_get_object_request(
path,
@@ -1067,6 +1072,7 @@ impl Accessor for S3Backend {
v.override_content_disposition(),
v.override_cache_control(),
v.if_none_match(),
+ v.if_match(),
)?,
PresignOperation::Write(_) => {
self.core
diff --git a/core/src/services/s3/core.rs b/core/src/services/s3/core.rs
index b9f2281a..c618b87d 100644
--- a/core/src/services/s3/core.rs
+++ b/core/src/services/s3/core.rs
@@ -29,6 +29,7 @@ use http::header::CACHE_CONTROL;
use http::header::CONTENT_DISPOSITION;
use http::header::CONTENT_LENGTH;
use http::header::CONTENT_TYPE;
+use http::header::IF_MATCH;
use http::header::IF_NONE_MATCH;
use http::HeaderValue;
use http::Request;
@@ -206,6 +207,7 @@ impl S3Core {
&self,
path: &str,
if_none_match: Option<&str>,
+ if_match: Option<&str>,
) -> Result<Request<AsyncBody>> {
let p = build_abs_path(&self.root, path);
@@ -219,6 +221,10 @@ impl S3Core {
req = req.header(IF_NONE_MATCH, if_none_match);
}
+ if let Some(if_match) = if_match {
+ req = req.header(IF_MATCH, if_match);
+ }
+
let req = req
.body(AsyncBody::Empty)
.map_err(new_request_build_error)?;
@@ -233,6 +239,7 @@ impl S3Core {
override_content_disposition: Option<&str>,
override_cache_control: Option<&str>,
if_none_match: Option<&str>,
+ if_match: Option<&str>,
) -> Result<Request<AsyncBody>> {
let p = build_abs_path(&self.root, path);
@@ -269,6 +276,9 @@ impl S3Core {
req = req.header(IF_NONE_MATCH, if_none_match);
}
+ if let Some(if_match) = if_match {
+ req = req.header(IF_MATCH, if_match);
+ }
// Set SSE headers.
// TODO: how will this work with presign?
req = self.insert_sse_headers(req, false);
@@ -285,8 +295,10 @@ impl S3Core {
path: &str,
range: BytesRange,
if_none_match: Option<&str>,
+ if_match: Option<&str>,
) -> Result<Response<IncomingAsyncBody>> {
- let mut req = self.s3_get_object_request(path, range, None, None,
if_none_match)?;
+ let mut req =
+ self.s3_get_object_request(path, range, None, None, if_none_match,
if_match)?;
self.sign(&mut req).await?;
@@ -342,8 +354,9 @@ impl S3Core {
&self,
path: &str,
if_none_match: Option<&str>,
+ if_match: Option<&str>,
) -> Result<Response<IncomingAsyncBody>> {
- let mut req = self.s3_head_object_request(path, if_none_match)?;
+ let mut req = self.s3_head_object_request(path, if_none_match,
if_match)?;
self.sign(&mut req).await?;
@@ -476,6 +489,7 @@ impl S3Core {
content_type: Option<&str>,
content_disposition: Option<&str>,
cache_control: Option<&str>,
+ if_match: Option<&str>,
) -> Result<Response<IncomingAsyncBody>> {
let p = build_abs_path(&self.root, path);
@@ -495,6 +509,10 @@ impl S3Core {
req = req.header(CACHE_CONTROL, cache_control)
}
+ if let Some(if_match) = if_match {
+ req = req.header(IF_MATCH, if_match)
+ }
+
// Set storage class header
if let Some(v) = &self.default_storage_class {
req =
req.header(HeaderName::from_static(constants::X_AMZ_STORAGE_CLASS), v);