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

alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs-object-store.git


The following commit(s) were added to refs/heads/main by this push:
     new da88a75  Add storage class for aws, gcp, and azure (#456)
da88a75 is described below

commit da88a756b09fb2694c4a70aa6ac12fabf31cfe26
Author: Matthew Turner <[email protected]>
AuthorDate: Sat Sep 13 09:01:59 2025 -0400

    Add storage class for aws, gcp, and azure (#456)
    
    * Add storage class for aws and gcp
    
    * Add azure storage class attribute
    
    * Update attribute docs
    
    * Update http client
---
 src/attributes.rs   | 8 ++++++++
 src/aws/client.rs   | 2 ++
 src/azure/client.rs | 2 ++
 src/gcp/client.rs   | 2 ++
 src/http/client.rs  | 4 ++++
 5 files changed, 18 insertions(+)

diff --git a/src/attributes.rs b/src/attributes.rs
index 11cf27c..cac5b36 100644
--- a/src/attributes.rs
+++ b/src/attributes.rs
@@ -45,6 +45,14 @@ pub enum Attribute {
     ///
     /// See 
[Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)
     CacheControl,
+    /// Specifies the storage class of the object.
+    ///
+    /// See [AWS](https://aws.amazon.com/s3/storage-classes/),
+    /// [GCP](https://cloud.google.com/storage/docs/storage-classes), and
+    /// 
[Azure](https://learn.microsoft.com/en-us/rest/api/storageservices/set-blob-tier).
  
+    /// `StorageClass` is used as the name for this attribute because 2 of the 
3 storage providers
+    /// use that name
+    StorageClass,
     /// Specifies a user-defined metadata field for the object
     ///
     /// The String is a user-defined key
diff --git a/src/aws/client.rs b/src/aws/client.rs
index a99db15..913859d 100644
--- a/src/aws/client.rs
+++ b/src/aws/client.rs
@@ -61,6 +61,7 @@ const VERSION_HEADER: &str = "x-amz-version-id";
 const SHA256_CHECKSUM: &str = "x-amz-checksum-sha256";
 const USER_DEFINED_METADATA_HEADER_PREFIX: &str = "x-amz-meta-";
 const ALGORITHM: &str = "x-amz-checksum-algorithm";
+const STORAGE_CLASS: &str = "x-amz-storage-class";
 
 /// A specialized `Error` for object store-related errors
 #[derive(Debug, thiserror::Error)]
@@ -373,6 +374,7 @@ impl Request<'_> {
                     has_content_type = true;
                     builder.header(CONTENT_TYPE, v.as_ref())
                 }
+                Attribute::StorageClass => builder.header(STORAGE_CLASS, 
v.as_ref()),
                 Attribute::Metadata(k_suffix) => builder.header(
                     
&format!("{USER_DEFINED_METADATA_HEADER_PREFIX}{k_suffix}"),
                     v.as_ref(),
diff --git a/src/azure/client.rs b/src/azure/client.rs
index c7440a0..1e96aac 100644
--- a/src/azure/client.rs
+++ b/src/azure/client.rs
@@ -48,6 +48,7 @@ use std::time::Duration;
 use url::Url;
 
 const VERSION_HEADER: &str = "x-ms-version-id";
+const ACCESS_TIER_HEADER: &str = "x-ms-access-tier";
 const USER_DEFINED_METADATA_HEADER_PREFIX: &str = "x-ms-meta-";
 static MS_CACHE_CONTROL: HeaderName = 
HeaderName::from_static("x-ms-blob-cache-control");
 static MS_CONTENT_TYPE: HeaderName = 
HeaderName::from_static("x-ms-blob-content-type");
@@ -242,6 +243,7 @@ impl PutRequest<'_> {
                     has_content_type = true;
                     builder.header(&MS_CONTENT_TYPE, v.as_ref())
                 }
+                Attribute::StorageClass => builder.header(ACCESS_TIER_HEADER, 
v.as_ref()),
                 Attribute::Metadata(k_suffix) => builder.header(
                     
&format!("{USER_DEFINED_METADATA_HEADER_PREFIX}{k_suffix}"),
                     v.as_ref(),
diff --git a/src/gcp/client.rs b/src/gcp/client.rs
index a988cc4..47af709 100644
--- a/src/gcp/client.rs
+++ b/src/gcp/client.rs
@@ -51,6 +51,7 @@ use std::sync::Arc;
 const VERSION_HEADER: &str = "x-goog-generation";
 const DEFAULT_CONTENT_TYPE: &str = "application/octet-stream";
 const USER_DEFINED_METADATA_HEADER_PREFIX: &str = "x-goog-meta-";
+const STORAGE_CLASS: &str = "x-goog-storage-class";
 
 static VERSION_MATCH: HeaderName = 
HeaderName::from_static("x-goog-if-generation-match");
 
@@ -201,6 +202,7 @@ impl Request<'_> {
                     has_content_type = true;
                     builder.header(CONTENT_TYPE, v.as_ref())
                 }
+                Attribute::StorageClass => builder.header(STORAGE_CLASS, 
v.as_ref()),
                 Attribute::Metadata(k_suffix) => builder.header(
                     
&format!("{USER_DEFINED_METADATA_HEADER_PREFIX}{k_suffix}"),
                     v.as_ref(),
diff --git a/src/http/client.rs b/src/http/client.rs
index 272f7c6..d08e9fa 100644
--- a/src/http/client.rs
+++ b/src/http/client.rs
@@ -196,6 +196,10 @@ impl Client {
                         has_content_type = true;
                         builder.header(CONTENT_TYPE, v.as_ref())
                     }
+                    Attribute::StorageClass => {
+                        tracing::warn!("StorageClass attribute not supported 
on HTTP client as header key is unknown");
+                        builder
+                    }
                     // Ignore metadata attributes
                     Attribute::Metadata(_) => builder,
                 };

Reply via email to