This is an automated email from the ASF dual-hosted git repository.
kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new f36c238fd02 GH-50148: [C++] Add Content-Encoding support to S3
filesystem metadata (#50167)
f36c238fd02 is described below
commit f36c238fd0284bb0c499f67177665d993af436a2
Author: alytantawyy <[email protected]>
AuthorDate: Wed Sep 30 20:15:47 2026 -0700
GH-50148: [C++] Add Content-Encoding support to S3 filesystem metadata
(#50167)
### Rationale for this change
The S3 filesystem metadata handling supported headers such as
`Content-Type`,
`Content-Language`, `Cache-Control`, and `Expires`, but omitted
`Content-Encoding`.
As a result, `Content-Encoding` was not propagated when writing S3 object
metadata, and it was also not returned when reading metadata back.
### What changes are included in this PR?
- add `Content-Encoding` to S3 object metadata extraction
- add `Content-Encoding` to the S3 metadata setter whitelist
- reuse the existing string metadata setter for `Content-Encoding`
- extend the S3 metadata round-trip test to cover explicit and default
`Content-Encoding` metadata
### Are these changes tested?
Yes.
```text
./cpp/build-s3-system/debug/arrow-s3fs-test
--gtest_filter=TestS3FS.OpenOutputStreamMetadata
```
* GitHub Issue: #50148
Authored-by: alytantawyy <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
cpp/src/arrow/filesystem/s3fs.cc | 2 ++
cpp/src/arrow/filesystem/s3fs_test.cc | 10 ++++++----
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/cpp/src/arrow/filesystem/s3fs.cc b/cpp/src/arrow/filesystem/s3fs.cc
index 1c6763a4aee..76b1ce61614 100644
--- a/cpp/src/arrow/filesystem/s3fs.cc
+++ b/cpp/src/arrow/filesystem/s3fs.cc
@@ -1361,6 +1361,7 @@ std::shared_ptr<const KeyValueMetadata>
GetObjectMetadata(const ObjectResult& re
md->Append("Content-Length", ToChars(result.GetContentLength()));
push("Cache-Control", result.GetCacheControl());
+ push("Content-Encoding", result.GetContentEncoding());
push("Content-Type", result.GetContentType());
push("Content-Language", result.GetContentLanguage());
push("ETag", result.GetETag());
@@ -1379,6 +1380,7 @@ struct ObjectMetadataSetter {
static std::unordered_map<std::string, Setter> GetSetters() {
return {{"ACL", CannedACLSetter()},
{"Cache-Control", StringSetter(&ObjectRequest::SetCacheControl)},
+ {"Content-Encoding",
StringSetter(&ObjectRequest::SetContentEncoding)},
{"Content-Type", ContentTypeSetter()},
{"Content-Language",
StringSetter(&ObjectRequest::SetContentLanguage)},
{"Expires", DateTimeSetter(&ObjectRequest::SetExpires)}};
diff --git a/cpp/src/arrow/filesystem/s3fs_test.cc
b/cpp/src/arrow/filesystem/s3fs_test.cc
index 114701b6d44..06d25287a4f 100644
--- a/cpp/src/arrow/filesystem/s3fs_test.cc
+++ b/cpp/src/arrow/filesystem/s3fs_test.cc
@@ -1655,8 +1655,9 @@ TEST_F(TestS3FS, OpenOutputStreamMetadata) {
testing::IsSupersetOf(implicit_metadata->sorted_pairs()));
// Create new file with explicit metadata
- auto metadata = KeyValueMetadata::Make({"Content-Type", "Expires"},
- {"x-arrow/test6",
"2016-02-05T20:08:35Z"});
+ auto metadata =
+ KeyValueMetadata::Make({"Content-Encoding", "Content-Type", "Expires"},
+ {"gzip", "x-arrow/test6",
"2016-02-05T20:08:35Z"});
AssertMetadataRoundtrip("bucket/mdfile1", metadata,
testing::IsSupersetOf(metadata->sorted_pairs()));
@@ -1666,8 +1667,9 @@ TEST_F(TestS3FS, OpenOutputStreamMetadata) {
AssertMetadataRoundtrip("bucket/mdfile2", metadata, testing::_);
// Create new file with default metadata
- auto default_metadata = KeyValueMetadata::Make({"Content-Type",
"Content-Language"},
- {"image/png", "fr_FR"});
+ auto default_metadata =
+ KeyValueMetadata::Make({"Content-Encoding", "Content-Type",
"Content-Language"},
+ {"br", "image/png", "fr_FR"});
options_.default_metadata = default_metadata;
MakeFileSystem();
// (null, then empty metadata argument)