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

erickguan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new e489f0bc6 feat(services/http): support if_modified_since and 
if_unmodified_since (#7636)
e489f0bc6 is described below

commit e489f0bc6b9ca842f8dfe5c9f3d9766163a2d0d6
Author: Yuang Gao <[email protected]>
AuthorDate: Sun Jun 28 00:08:09 2026 -0700

    feat(services/http): support if_modified_since and if_unmodified_since 
(#7636)
    
    * feat(services/http): support if_modified_since and if_unmodified_since
    
    Inject If-Modified-Since and If-Unmodified-Since in http_get_request
    and http_head_request, and declare the matching read/stat capabilities.
    
    Part of #5486.
    
    * test(python): drop unnecessary delete capability and cleanup
---
 bindings/python/tests/test_read.py |  7 ++++---
 core/services/http/src/backend.rs  |  4 ++++
 core/services/http/src/core.rs     | 18 ++++++++++++++++++
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/bindings/python/tests/test_read.py 
b/bindings/python/tests/test_read.py
index f8987e1a7..002be4ae2 100644
--- a/bindings/python/tests/test_read.py
+++ b/bindings/python/tests/test_read.py
@@ -258,7 +258,10 @@ async def test_async_read_not_exists(service_name, 
operator, async_operator):
 
 
 @pytest.mark.need_capability(
-    "read", "read_with_if_modified_since", "read_with_if_unmodified_since"
+    "read",
+    "write",
+    "read_with_if_modified_since",
+    "read_with_if_unmodified_since",
 )
 def test_sync_conditional_reads(service_name, operator):
     path = f"random_file_{str(uuid4())}"
@@ -282,5 +285,3 @@ def test_sync_conditional_reads(service_name, operator):
     # Should fail: file was modified after `before`
     with pytest.raises(ConditionNotMatch):
         operator.read(path, if_unmodified_since=before)
-
-    operator.delete(path)
diff --git a/core/services/http/src/backend.rs 
b/core/services/http/src/backend.rs
index 56ba41b62..5f44e01b9 100644
--- a/core/services/http/src/backend.rs
+++ b/core/services/http/src/backend.rs
@@ -133,12 +133,16 @@ impl Builder for HttpBuilder {
             stat: true,
             stat_with_if_match: true,
             stat_with_if_none_match: true,
+            stat_with_if_modified_since: true,
+            stat_with_if_unmodified_since: true,
 
             read: true,
             read_with_suffix: true,
 
             read_with_if_match: true,
             read_with_if_none_match: true,
+            read_with_if_modified_since: true,
+            read_with_if_unmodified_since: true,
 
             presign: auth.is_none(),
             presign_read: auth.is_none(),
diff --git a/core/services/http/src/core.rs b/core/services/http/src/core.rs
index b8ae55657..a98a37c5f 100644
--- a/core/services/http/src/core.rs
+++ b/core/services/http/src/core.rs
@@ -21,7 +21,9 @@ use http::Request;
 use http::Response;
 use http::header;
 use http::header::IF_MATCH;
+use http::header::IF_MODIFIED_SINCE;
 use http::header::IF_NONE_MATCH;
+use http::header::IF_UNMODIFIED_SINCE;
 
 use opendal_core::raw::*;
 use opendal_core::*;
@@ -70,6 +72,14 @@ impl HttpCore {
             req = req.header(IF_NONE_MATCH, if_none_match);
         }
 
+        if let Some(if_modified_since) = args.if_modified_since() {
+            req = req.header(IF_MODIFIED_SINCE, 
if_modified_since.format_http_date());
+        }
+
+        if let Some(if_unmodified_since) = args.if_unmodified_since() {
+            req = req.header(IF_UNMODIFIED_SINCE, 
if_unmodified_since.format_http_date());
+        }
+
         if let Some(auth) = &self.authorization {
             req = req.header(header::AUTHORIZATION, auth.clone())
         }
@@ -111,6 +121,14 @@ impl HttpCore {
             req = req.header(IF_NONE_MATCH, if_none_match);
         }
 
+        if let Some(if_modified_since) = args.if_modified_since() {
+            req = req.header(IF_MODIFIED_SINCE, 
if_modified_since.format_http_date());
+        }
+
+        if let Some(if_unmodified_since) = args.if_unmodified_since() {
+            req = req.header(IF_UNMODIFIED_SINCE, 
if_unmodified_since.format_http_date());
+        }
+
         if let Some(auth) = &self.authorization {
             req = req.header(header::AUTHORIZATION, auth.clone())
         }

Reply via email to