From 344e778177d829bdf3028ceaa99ad940938c2298 Mon Sep 17 00:00:00 2001 From: JinmingHu Date: Mon, 9 Nov 2020 14:59:14 +0800 Subject: [PATCH] Storage uses Core::Encode (#855) * use Core::Encode * fix bug * remove % --- .../azure-storage-common/src/crypt.cpp | 102 ++++++------------ 1 file changed, 35 insertions(+), 67 deletions(-) diff --git a/sdk/storage/azure-storage-common/src/crypt.cpp b/sdk/storage/azure-storage-common/src/crypt.cpp index 9a74ec2a2..40f0471a3 100644 --- a/sdk/storage/azure-storage-common/src/crypt.cpp +++ b/sdk/storage/azure-storage-common/src/crypt.cpp @@ -15,91 +15,59 @@ #include #endif +#include #include #include +#include "azure/core/http/http.hpp" #include "azure/storage/common/storage_common.hpp" namespace Azure { namespace Storage { namespace Details { - static const char* c_unreserved - = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~"; static const char* c_subdelimiters = "!$&'()*+,;="; - const char* c_hex = "0123456789ABCDEF"; std::string UrlEncodeQueryParameter(const std::string& value) { - const static std::vector shouldEncodeTable = []() { - std::string queryCharacters - = std::string(c_unreserved) + std::string(c_subdelimiters) + "%/:@?"; - - std::vector ret(256, true); - for (char c : queryCharacters) - { - ret[c] = false; - } - // we also encode % and + - ret['%'] = true; - ret['+'] = true; - // Surprisingly, '=' also needs to be encoded because Azure Storage server side is so - // strict. We are applying this function to query key and value respectively, so this won't - // affect that = used to separate key and query. - ret['='] = true; - return ret; + const static std::string c_doNotEncodeCharacters = []() { + // Core::Http::Url::Encode won't encode unreserved characters. + std::string doNotEncodeCharacters = c_subdelimiters; + doNotEncodeCharacters += "/:@?"; + doNotEncodeCharacters.erase( + std::remove_if( + doNotEncodeCharacters.begin(), + doNotEncodeCharacters.end(), + [](char x) { + // we also encode + + // Surprisingly, '=' also needs to be encoded because Azure Storage server side is + // so strict. We are applying this function to query key and value respectively, + // so this won't affect that = used to separate key and query. + return x == '+' || x == '='; + }), + doNotEncodeCharacters.end()); + return doNotEncodeCharacters; }(); - - std::string encoded; - for (char c : value) - { - unsigned char uc = c; - if (shouldEncodeTable[uc]) - { - encoded += '%'; - encoded += c_hex[(uc >> 4) & 0x0f]; - encoded += c_hex[uc & 0x0f]; - } - else - { - encoded += c; - } - } - return encoded; + return Core::Http::Url::Encode(value, c_doNotEncodeCharacters); } std::string UrlEncodePath(const std::string& value) { - const static std::vector shouldEncodeTable = []() { - std::string pathCharacters - = std::string(c_unreserved) + std::string(c_subdelimiters) + "%/:@"; - - std::vector ret(256, true); - for (char c : pathCharacters) - { - ret[c] = false; - } - // we also encode % and + - ret['%'] = true; - ret['+'] = true; - return ret; + const static std::string c_doNotEncodeCharacters = []() { + // Core::Http::Url::Encode won't encode unreserved characters. + std::string doNotEncodeCharacters = c_subdelimiters; + doNotEncodeCharacters += "/:@"; + doNotEncodeCharacters.erase( + std::remove_if( + doNotEncodeCharacters.begin(), + doNotEncodeCharacters.end(), + [](char x) { + // we also encode + + return x == '+'; + }), + doNotEncodeCharacters.end()); + return doNotEncodeCharacters; }(); - - std::string encoded; - for (char c : value) - { - unsigned char uc = c; - if (shouldEncodeTable[uc]) - { - encoded += '%'; - encoded += c_hex[(uc >> 4) & 0x0f]; - encoded += c_hex[uc & 0x0f]; - } - else - { - encoded += c; - } - } - return encoded; + return Core::Http::Url::Encode(value, c_doNotEncodeCharacters); } } // namespace Details