From: Radoslaw Zarzynski Date: Fri, 19 May 2017 15:21:10 +0000 (+0200) Subject: rgw: use preallocated std::strings when concatenating in AWSv4. X-Git-Tag: v12.1.0~155^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e8dd37aac26696f5df5240fa6d301d303b673b2a;p=ceph.git rgw: use preallocated std::strings when concatenating in AWSv4. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index 8b291ce25e56..88b1c2bd00d2 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -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(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(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(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; diff --git a/src/rgw/rgw_string.h b/src/rgw/rgw_string.h index 6bc529cb8604..5fa10885470a 100644 --- a/src/rgw/rgw_string.h +++ b/src/rgw/rgw_string.h @@ -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 +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