]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: use preallocated std::strings when concatenating in AWSv4.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Fri, 19 May 2017 15:21:10 +0000 (17:21 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 7 Jun 2017 10:46:21 +0000 (12:46 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_string.h

index 8b291ce25e56fddaf3c99cf5d0926de7f0022e76..88b1c2bd00d22ba42af71bcdb2ea36c9c604be77 100644 (file)
@@ -666,17 +666,20 @@ get_v4_canon_req_hash(CephContext* cct,
 {
   ldout(cct, 10) << "payload request hash = " << request_payload_hash << dendl;
 
-  const auto canonical_req = std::string()
+  const size_t total_len = http_verb.length() + canonical_uri.length() + \
+    canonical_qs.length() + canonical_hdrs.length() + signed_hdrs.length() + \
+    request_payload_hash.length() + std::strlen("\n") * 5;
+  const auto canonical_req = create_n_reserve<std::string>(total_len)
     .append(http_verb.data(), http_verb.length())
-    .append("\n")
+    .append("\n", std::strlen("\n"))
     .append(canonical_uri)
-    .append("\n")
+    .append("\n", std::strlen("\n"))
     .append(canonical_qs)
-    .append("\n")
+    .append("\n", std::strlen("\n"))
     .append(canonical_hdrs)
-    .append("\n")
+    .append("\n", std::strlen("\n"))
     .append(signed_hdrs.data(), signed_hdrs.length())
-    .append("\n")
+    .append("\n", std::strlen("\n"))
     .append(request_payload_hash.data(), request_payload_hash.length());
 
   const auto canonical_req_hash = calc_hash_sha256(canonical_req);
@@ -700,13 +703,16 @@ std::string get_v4_string_to_sign(CephContext* const cct,
                                   const sha256_digest_t& canonreq_hash)
 {
   const auto hexed_cr_hash = buf_to_hex(canonreq_hash);
-  const auto string_to_sign = std::string()
+
+  const size_t total_len = algorithm.length() + request_date.length() + \
+    credential_scope.length() + hexed_cr_hash.size() - 1 + std::strlen("\n") * 3;
+  const auto string_to_sign = create_n_reserve<std::string>(total_len)
     .append(algorithm.data(), algorithm.length())
-    .append("\n")
+    .append("\n", std::strlen("\n"))
     .append(request_date.data(), request_date.length())
-    .append("\n")
+    .append("\n", std::strlen("\n"))
     .append(credential_scope.data(), credential_scope.length())
-    .append("\n")
+    .append("\n", std::strlen("\n"))
     .append(hexed_cr_hash.data(), hexed_cr_hash.size() - 1);
 
   ldout(cct, 10) << "string to sign = "
@@ -891,17 +897,25 @@ AWSv4ComplMulti::ChunkMeta::create_next(CephContext* const cct,
 std::string
 AWSv4ComplMulti::calc_chunk_signature(const std::string& payload_hash) const
 {
-  std::string string_to_sign = "AWS4-HMAC-SHA256-PAYLOAD\n";
-
-  string_to_sign.append(date.data(), date.length());
-  string_to_sign.append("\n");
-  string_to_sign.append(credential_scope.data(), credential_scope.length());
-  string_to_sign.append("\n");
-  string_to_sign.append(prev_chunk_signature);
-  string_to_sign.append("\n");
-  string_to_sign.append(AWS4_EMPTY_PAYLOAD_HASH, strlen(AWS4_EMPTY_PAYLOAD_HASH));
-  string_to_sign.append("\n");
-  string_to_sign.append(payload_hash);
+  constexpr size_t algorithm_len = std::strlen(AWS4_HMAC_SHA256_STR);
+  constexpr size_t empty_hash_len = std::strlen(AWS4_EMPTY_PAYLOAD_HASH);
+
+  /* We want to avoid reallocations when concatenating the string_to_sign. */
+  const size_t total_len = algorithm_len + date.length() + \
+    credential_scope.length() + prev_chunk_signature.length() + \
+    empty_hash_len + payload_hash.length() + std::strlen("\n") * 5;
+  const auto string_to_sign = create_n_reserve<std::string>(total_len)
+    .append(AWS4_HMAC_SHA256_STR, algorithm_len)
+    .append("\n", std::strlen("\n"))
+    .append(date.data(), date.length())
+    .append("\n", std::strlen("\n"))
+    .append(credential_scope.data(), credential_scope.length())
+    .append("\n", std::strlen("\n"))
+    .append(prev_chunk_signature)
+    .append("\n", std::strlen("\n"))
+    .append(AWS4_EMPTY_PAYLOAD_HASH, empty_hash_len)
+    .append("\n", std::strlen("\n"))
+    .append(payload_hash);
 
   ldout(cct, 20) << "AWSv4ComplMulti: string_to_sign=\n" << string_to_sign
                  << dendl;
index 6bc529cb8604bd2206c9fad1fb9d8dacb5170d58..5fa10885470a037e45faacd6572f3a641066880a 100644 (file)
@@ -112,4 +112,17 @@ sview2cstr(const boost::string_view& sv)
   return cstr;
 }
 
+/* We need this helper function because the interface of std::string::reserve
+ * doesn't provide the chaining ability in the type append(). It's required
+ * to concatenate string without reallocations in a way const-correct manner. */
+template <class StringT>
+static inline StringT create_n_reserve(const size_t reserve_len)
+{
+  StringT ret;
+  /* I would love to see reserve() returning "basic_string&" instead of "void"
+   * in the standard library! */
+  ret.reserve(reserve_len);
+  return ret;
+}
+
 #endif