]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: recognize checksum from x-amz-checksum-{type} alone
authorMatt Benjamin <mbenjamin@redhat.com>
Sat, 17 May 2025 19:52:20 +0000 (15:52 -0400)
committerThomas Serlin <tserlin@redhat.com>
Mon, 22 Sep 2025 19:18:18 +0000 (15:18 -0400)
Some SDKs may send x-amz-checksum-algorithm or
x-amz-sdk-checksum-algorithm regardless as well, but those are
only required if the checksum header is in the trailer section.

Fixes: https://tracker.ceph.com/issues/71350
Resolves: rhbz#2392604

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
(cherry picked from commit 572289a2c7fb1cceebef7fefdec032ba95418cf4)

src/rgw/rgw_cksum.h
src/rgw/rgw_cksum_pipe.h
src/rgw/rgw_rest_s3.cc

index 70836e7c6bacd5876592810d4765f0ea8f180984..c4e2cca682c7f886214d665b4f8074716f861c9c 100644 (file)
@@ -60,6 +60,7 @@ namespace rgw { namespace cksum {
   public:
     const Type type;
     const char* name;
+    const char* name_uc;
     const uint16_t digest_size;
     const uint16_t armored_size;
     const uint16_t flags;
@@ -68,9 +69,9 @@ namespace rgw { namespace cksum {
       return sz / 3 * 4 + 4;
     }
 
-    constexpr Desc(Type _type, const char* _name, uint16_t _size,
-                  uint16_t _flags)
-      : type(_type), name(_name),
+    constexpr Desc(Type _type, const char* _name, const char* _name_uc,
+                  uint16_t _size, uint16_t _flags)
+      : type(_type), name(_name), name_uc(_name_uc),
        digest_size(_size),
        armored_size(to_armored_size(digest_size)),
        flags(_flags)
@@ -87,15 +88,15 @@ namespace rgw { namespace cksum {
   public:
     static constexpr std::array<Desc, 9> checksums =
     {
-      Desc(Type::none, "none", 0, FLAG_NONE),
-      Desc(Type::crc32, "crc32", 4, FLAG_AWS_CKSUM|FLAG_CRC),
-      Desc(Type::crc32c, "crc32c", 4, FLAG_AWS_CKSUM|FLAG_CRC),
-      Desc(Type::xxh3, "xxh3", 8, FLAG_NONE),
-      Desc(Type::sha1, "sha1", 20, FLAG_AWS_CKSUM),
-      Desc(Type::sha256, "sha256", 32, FLAG_AWS_CKSUM),
-      Desc(Type::sha512, "sha512", 64, FLAG_NONE),
-      Desc(Type::blake3, "blake3", 32, FLAG_NONE),
-      Desc(Type::crc64nvme, "crc64nvme", 8, FLAG_AWS_CKSUM|FLAG_CRC),
+      Desc(Type::none, "none", "NONE", 0, FLAG_NONE),
+      Desc(Type::crc32, "crc32", "CRC32", 4, FLAG_AWS_CKSUM|FLAG_CRC),
+      Desc(Type::crc32c, "crc32c", "CRC32C", 4, FLAG_AWS_CKSUM|FLAG_CRC),
+      Desc(Type::xxh3, "xxh3", "XXH3", 8, FLAG_NONE),
+      Desc(Type::sha1, "sha1", "SHA1", 20, FLAG_AWS_CKSUM),
+      Desc(Type::sha256, "sha256", "SHA256", 32, FLAG_AWS_CKSUM),
+      Desc(Type::sha512, "sha512", "SHA512", 64, FLAG_NONE),
+      Desc(Type::blake3, "blake3", "BLAKE3", 32, FLAG_NONE),
+      Desc(Type::crc64nvme, "crc64nvme", "CRC64NVME", 8, FLAG_AWS_CKSUM|FLAG_CRC),
     };
 
     static constexpr uint16_t max_digest_size = 64;
@@ -148,6 +149,10 @@ namespace rgw { namespace cksum {
       return (Cksum::checksums[uint16_t(type)]).name;
     }
 
+    const char* uc_type_string() const {
+      return (Cksum::checksums[uint16_t(type)]).name_uc;
+    }
+
     const bool aws() const {
       return (Cksum::checksums[uint16_t(type)]).aws();
     }
@@ -187,8 +192,7 @@ namespace rgw { namespace cksum {
     }
 
     std::string element_name() const {
-      std::string ts{type_string()};
-      return fmt::format("Checksum{}", boost::to_upper_copy(ts));
+      return fmt::format("Checksum{}", uc_type_string());
     }
 
     std::string_view raw() const {
@@ -290,6 +294,11 @@ namespace rgw { namespace cksum {
     return ckd.name;
   }
 
+  static inline std::string to_uc_string(const Type type) {
+    const auto& ckd = Cksum::checksums[uint16_t(type)];
+    return ckd.name_uc;
+  }
+
   static inline Type parse_cksum_type(const char* name)
   {
     for (const auto& ck : Cksum::checksums) {
index da79d17cdac531e672125dac524b1779a6b7c722..f442f67d78e4d2405441242c7658249ccf2735cc 100644 (file)
@@ -78,6 +78,15 @@ namespace rgw::putobj {
        return cksum_hdr_t(hk, hv);
       }
     }
+    /* 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) {
+      auto aws_hdr_name = fmt::format("HTTP_X_AMZ_CHECKSUM_{}", ck_desc.name_uc);
+      auto hv = env.get(aws_hdr_name.c_str());
+      if (hv) {
+       return cksum_hdr_t("HTTP_X_AMZ_CHECKSUM_ALGORITHM", ck_desc.name_uc);
+      }
+    }
     return cksum_hdr_t(nullptr, nullptr);
   } /* cksum_algorithm_hdr */
 
index 18cdfad4c88ef7a86fd9d94d6fdf7e85d05c1bc7..34e8100d4375185d79e88399fd5b56786c93a23a 100644 (file)
@@ -3133,8 +3133,7 @@ int RGWPostObj_ObjStore_S3::get_params(optional_yield y)
     auto& k = p.first;
     auto cksum_type =  rgw::cksum::parse_cksum_type_hdr(k);
     if (cksum_type != rgw::cksum::Type::none) {
-      put_prop("HTTP_X_AMZ_CHECKSUM_ALGORITHM",
-              boost::to_upper_copy(to_string(cksum_type)));
+      put_prop("HTTP_X_AMZ_CHECKSUM_ALGORITHM", to_uc_string(cksum_type));
       bufferlist& d = p.second.data;
       std::string v {
        rgw_trim_whitespace(std::string_view(d.c_str(), d.length()))};
@@ -4541,8 +4540,7 @@ void RGWInitMultipart_ObjStore_S3::send_response()
     dump_header_if_nonempty(s, "x-amz-abort-rule-id", rule_id);
   }
   if (cksum_algo != rgw::cksum::Type::none) {
-    dump_header(s, "x-amz-checksum-algorithm",
-               boost::to_upper_copy(to_string(cksum_algo)));
+    dump_header(s, "x-amz-checksum-algorithm", to_uc_string(cksum_algo));
   }
   end_header(s, this, to_mime_type(s->format));
   if (op_ret == 0) {
@@ -4667,8 +4665,7 @@ void RGWListMultipart_ObjStore_S3::send_response()
        Container element that identifies who initiated the multipart upload. If the initiator is an AWS account, this element provides the same information as the Owner element. If the initiator is an IAM User, this element provides the user ARN and display name, see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html */
 
     if (cksum && cksum->aws()) {
-      s->formatter->dump_string("ChecksumAlgorithm",
-                               boost::to_upper_copy(std::string(cksum->type_string())));
+      s->formatter->dump_string("ChecksumAlgorithm", cksum->uc_type_string());
     }
 
     for (; iter != upload->get_parts().end(); ++iter) {