]> git.apps.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)
committerMatt Benjamin <mbenjamin@redhat.com>
Thu, 12 Jun 2025 17:35:27 +0000 (13:35 -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
Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
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 c27f8fe91989df93522d8558d9d72d548fffe1ae..92124499a7a4b2dd2e27a101d076731035ab9285 100644 (file)
@@ -3137,8 +3137,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()))};
@@ -4540,8 +4539,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) {
@@ -4666,8 +4664,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) {