From 1bd625a613a180a340ec7c9d08e9050ddd498446 Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Sat, 17 May 2025 19:42:09 -0400 Subject: [PATCH] rgw_cksum: select checksum algo from only a checksum trailer header When the checksum payload will be sent in trailer section, a typed checksum header name will be one of the values of x-amz-trailer. Signed-off-by: Matt Benjamin --- src/rgw/rgw_cksum.h | 4 ++-- src/rgw/rgw_cksum_pipe.h | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/rgw/rgw_cksum.h b/src/rgw/rgw_cksum.h index c4e2cca682c..95f8d08c738 100644 --- a/src/rgw/rgw_cksum.h +++ b/src/rgw/rgw_cksum.h @@ -289,12 +289,12 @@ namespace rgw { namespace cksum { static inline const std::optional no_cksum{std::nullopt}; /* XXX would like std::string view */ - static inline std::string to_string(const Type type) { + static inline std::string_view to_string(const Type type) { const auto& ckd = Cksum::checksums[uint16_t(type)]; return ckd.name; } - static inline std::string to_uc_string(const Type type) { + static inline std::string_view to_uc_string(const Type type) { const auto& ckd = Cksum::checksums[uint16_t(type)]; return ckd.name_uc; } diff --git a/src/rgw/rgw_cksum_pipe.h b/src/rgw/rgw_cksum_pipe.h index f442f67d78e..1e08431b9e8 100644 --- a/src/rgw/rgw_cksum_pipe.h +++ b/src/rgw/rgw_cksum_pipe.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include "common/split.h" #include "rgw_cksum.h" #include "rgw_cksum_digest.h" #include "rgw_common.h" @@ -78,6 +78,20 @@ namespace rgw::putobj { return cksum_hdr_t(hk, hv); } } + /* look for a trailing checksum */ + auto hv = env.get("HTTP_X_AMZ_TRAILER"); + if (hv) { + auto kv = ceph::split(hv, ","); + for (auto k = kv.begin(); k != kv.end(); k = std::next(k)) { + /* a checksum trailer resembles "x-amz-checksum-crc32" and + * we need "CRC32", for known checksum types */ + auto type = cksum::parse_cksum_type_hdr(*k); + if (type != cksum::Type::none) { + return cksum_hdr_t("HTTP_X_AMZ_CHECKSUM_ALGORITHM", + cksum::to_uc_string(type).data()); + } + } + } /* for requests not sending a trailer, we could just have (golang sdk v2) * a checksum header and payload */ for (const auto& ck_desc : cksum::Cksum::checksums) { @@ -131,8 +145,7 @@ namespace rgw::putobj { for (int16_t ix = int16_t(cksum::Type::crc32); ix <= uint16_t(cksum::Type::blake3); ++ix) { cksum_type = cksum::Type(ix); - auto hk = fmt::format("HTTP_X_AMZ_CHECKSUM_{}", - boost::to_upper_copy(to_string(cksum_type))); + auto hk = fmt::format("HTTP_X_AMZ_CHECKSUM_{}", to_uc_string(cksum_type)); auto hv = env.get(hk.c_str()); if (hv) { return -- 2.39.5