diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index aba03063ce73..4a3f3427f8a4 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -399,7 +399,10 @@ impl Accessor for GcsBackend { } async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> { - let resp = self.core.gcs_get_object(path, args.range()).await?; + let resp = self + .core + .gcs_get_object(path, args.range(), args.if_match(), args.if_none_match()) + .await?; if resp.status().is_success() { let meta = parse_into_metadata(path, resp.headers())?; diff --git a/core/src/services/gcs/core.rs b/core/src/services/gcs/core.rs index 907d0ef4ac1e..f1b30698883b 100644 --- a/core/src/services/gcs/core.rs +++ b/core/src/services/gcs/core.rs @@ -15,14 +15,12 @@ // specific language governing permissions and limitations // under the License. -use std::fmt::Debug; -use std::fmt::Formatter; -use std::fmt::Write; - use backon::ExponentialBuilder; use backon::Retryable; use bytes::{Bytes, BytesMut}; use http::header::CONTENT_TYPE; +use http::header::IF_MATCH; +use http::header::IF_NONE_MATCH; use http::header::{CONTENT_LENGTH, CONTENT_RANGE}; use http::Request; use http::Response; @@ -31,6 +29,9 @@ use reqsign::GoogleCredentialLoader; use reqsign::GoogleSigner; use reqsign::GoogleToken; use reqsign::GoogleTokenLoader; +use std::fmt::Debug; +use std::fmt::Formatter; +use std::fmt::Write; use super::uri::percent_encode_path; use crate::raw::*; @@ -97,6 +98,8 @@ impl GcsCore { &self, path: &str, range: BytesRange, + if_match: Option<&str>, + if_none_match: Option<&str>, ) -> Result> { let p = build_abs_path(&self.root, path); @@ -109,6 +112,12 @@ impl GcsCore { let mut req = Request::get(&url); + if let Some(if_match) = if_match { + req = req.header(IF_MATCH, if_match); + } + if let Some(if_none_match) = if_none_match { + req = req.header(IF_NONE_MATCH, if_none_match); + } if !range.is_full() { req = req.header(http::header::RANGE, range.to_header()); } @@ -124,8 +133,10 @@ impl GcsCore { &self, path: &str, range: BytesRange, + if_match: Option<&str>, + if_none_match: Option<&str>, ) -> Result> { - let mut req = self.gcs_get_object_request(path, range)?; + let mut req = self.gcs_get_object_request(path, range, if_match, if_none_match)?; self.sign(&mut req).await?; self.send(req).await