From 8c083c35a57806a87d7c02a70aeab3a44374614c Mon Sep 17 00:00:00 2001 From: Yuang Gao Date: Thu, 28 May 2026 22:16:54 -0700 Subject: [PATCH] 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. --- bindings/python/tests/test_read.py | 6 +++++- core/services/http/src/backend.rs | 4 ++++ core/services/http/src/core.rs | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/bindings/python/tests/test_read.py b/bindings/python/tests/test_read.py index f8987e1a78b8..17f7a1ddd652 100644 --- a/bindings/python/tests/test_read.py +++ b/bindings/python/tests/test_read.py @@ -258,7 +258,11 @@ 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", + "delete", + "read_with_if_modified_since", + "read_with_if_unmodified_since", ) def test_sync_conditional_reads(service_name, operator): path = f"random_file_{str(uuid4())}" diff --git a/core/services/http/src/backend.rs b/core/services/http/src/backend.rs index 56ba41b62be5..5f44e01b965d 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 b8ae55657814..a98a37c5fcab 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()) }