Utils.cc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * Copyright 1999-2019 Alibaba Cloud All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <algorithm>
  17. #include <alibabacloud/core/Utils.h>
  18. #include <sstream>
  19. #include <stdlib.h>
  20. #ifdef _WIN32
  21. #include <Windows.h>
  22. #else
  23. #include <openssl/hmac.h>
  24. #include <openssl/md5.h>
  25. #include <uuid/uuid.h>
  26. #endif
  27. #include <curl/curl.h>
  28. #include <json/json.h>
  29. std::string AlibabaCloud::GenerateUuid() {
  30. #ifdef _WIN32
  31. char *data;
  32. UUID uuidhandle;
  33. UuidCreate(&uuidhandle);
  34. UuidToString(&uuidhandle, reinterpret_cast<RPC_CSTR *>(&data));
  35. std::string uuid(data);
  36. RpcStringFree(reinterpret_cast<RPC_CSTR *>(&data));
  37. return uuid;
  38. #else
  39. uuid_t uu;
  40. uuid_generate(uu);
  41. char buf[36];
  42. uuid_unparse(uu, buf);
  43. return buf;
  44. #endif
  45. }
  46. std::string AlibabaCloud::UrlEncode(const std::string &src) {
  47. CURL *curl = curl_easy_init();
  48. char *output = curl_easy_escape(curl, src.c_str(), src.size());
  49. std::string result(output);
  50. curl_free(output);
  51. curl_easy_cleanup(curl);
  52. return result;
  53. }
  54. std::string AlibabaCloud::UrlDecode(const std::string &src) {
  55. CURL *curl = curl_easy_init();
  56. int outlength = 0;
  57. char *output = curl_easy_unescape(curl, src.c_str(), src.size(), &outlength);
  58. std::string result(output, outlength);
  59. curl_free(output);
  60. curl_easy_cleanup(curl);
  61. return result;
  62. }
  63. std::string AlibabaCloud::ComputeContentMD5(const char *data, size_t size) {
  64. #ifdef _WIN32
  65. HCRYPTPROV hProv = 0;
  66. HCRYPTHASH hHash = 0;
  67. BYTE pbHash[16];
  68. DWORD dwDataLen = 16;
  69. CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
  70. CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
  71. CryptHashData(hHash, (BYTE *)(data), size, 0);
  72. CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwDataLen, 0);
  73. CryptDestroyHash(hHash);
  74. CryptReleaseContext(hProv, 0);
  75. DWORD dlen = 0;
  76. CryptBinaryToString(pbHash, dwDataLen,
  77. CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &dlen);
  78. char *dest = new char[dlen];
  79. CryptBinaryToString(pbHash, dwDataLen,
  80. CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, dest, &dlen);
  81. std::string ret = std::string(dest, dlen);
  82. delete dest;
  83. return ret;
  84. #else
  85. unsigned char md[MD5_DIGEST_LENGTH];
  86. MD5(reinterpret_cast<const unsigned char *>(data), size,
  87. (unsigned char *)&md);
  88. char encodedData[100];
  89. EVP_EncodeBlock(reinterpret_cast<unsigned char *>(encodedData), md,
  90. MD5_DIGEST_LENGTH);
  91. return encodedData;
  92. #endif
  93. }
  94. void AlibabaCloud::StringReplace(std::string &src, const std::string &s1,
  95. const std::string &s2) {
  96. std::string::size_type pos = 0;
  97. while ((pos = src.find(s1, pos)) != std::string::npos) {
  98. src.replace(pos, s1.length(), s2);
  99. pos += s2.length();
  100. }
  101. }
  102. std::string AlibabaCloud::HttpMethodToString(HttpRequest::Method method) {
  103. switch (method) {
  104. case HttpRequest::Method::Head:
  105. return "HEAD";
  106. break;
  107. case HttpRequest::Method::Post:
  108. return "POST";
  109. break;
  110. case HttpRequest::Method::Put:
  111. return "PUT";
  112. break;
  113. case HttpRequest::Method::Delete:
  114. return "DELETE";
  115. break;
  116. case HttpRequest::Method::Connect:
  117. return "CONNECT";
  118. break;
  119. case HttpRequest::Method::Options:
  120. return "OPTIONS";
  121. break;
  122. case HttpRequest::Method::Patch:
  123. return "PATCH";
  124. break;
  125. case HttpRequest::Method::Trace:
  126. return "TRACE";
  127. break;
  128. case HttpRequest::Method::Get:
  129. default:
  130. return "GET";
  131. break;
  132. }
  133. }
  134. std::string AlibabaCloud::canonicalizedQuery(
  135. const std::map<std::string, std::string> &params) {
  136. if (params.empty())
  137. return std::string();
  138. std::stringstream ss;
  139. for (const auto &p : params) {
  140. std::string key = UrlEncode(p.first);
  141. StringReplace(key, "+", "%20");
  142. StringReplace(key, "*", "%2A");
  143. StringReplace(key, "%7E", "~");
  144. std::string value = UrlEncode(p.second);
  145. StringReplace(value, "+", "%20");
  146. StringReplace(value, "*", "%2A");
  147. StringReplace(value, "%7E", "~");
  148. ss << "&" << key << "=" << value;
  149. }
  150. return ss.str().substr(1);
  151. }
  152. std::string AlibabaCloud::canonicalizedHeaders(
  153. const HttpMessage::HeaderCollection &headers) {
  154. std::map<std::string, std::string> materials;
  155. for (const auto &p : headers) {
  156. std::string key = p.first;
  157. std::transform(key.begin(), key.end(), key.begin(), ::tolower);
  158. if (key.find("x-acs-") != 0)
  159. continue;
  160. std::string value = p.second;
  161. StringReplace(value, "\t", " ");
  162. StringReplace(value, "\n", " ");
  163. StringReplace(value, "\r", " ");
  164. StringReplace(value, "\f", " ");
  165. materials[key] = value;
  166. }
  167. if (materials.empty())
  168. return std::string();
  169. std::stringstream ss;
  170. for (const auto &p : materials)
  171. ss << p.first << ":" << p.second << "\n";
  172. return ss.str();
  173. }
  174. std::string AlibabaCloud::GetEnv(const std::string env) {
  175. #ifdef _WIN32
  176. char *buf = nullptr;
  177. size_t sz = 0;
  178. if (_dupenv_s(&buf, &sz, env.c_str()) == 0 && buf != nullptr) {
  179. std::string var(buf);
  180. free(buf);
  181. return var;
  182. } else {
  183. if (buf) {
  184. free(buf);
  185. }
  186. return std::string();
  187. }
  188. #else
  189. char *var = getenv(env.c_str());
  190. if (var) {
  191. return std::string(var);
  192. }
  193. return std::string();
  194. #endif
  195. }
  196. std::string
  197. AlibabaCloud::MapToJson(const std::map<std::string, std::string> &maps) {
  198. Json::Value jsonObject;
  199. Json::FastWriter writer;
  200. for (std::map<std::string, std::string>::const_iterator iter = maps.begin();
  201. iter != maps.end(); ++iter) {
  202. jsonObject[iter->first] = iter->second;
  203. }
  204. std::string unformat_str = writer.write(jsonObject);
  205. return unformat_str.substr(0, unformat_str.length() - 1);
  206. }
  207. std::map<std::string, std::string>
  208. AlibabaCloud::JsonToMap(const std::string &json) {
  209. Json::Reader reader;
  210. Json::Value value;
  211. std::map<std::string, std::string> maps;
  212. if (json.length() > 0) {
  213. if (reader.parse(json, value)) {
  214. Json::Value::Members members = value.getMemberNames();
  215. for (Json::Value::Members::iterator it = members.begin();
  216. it != members.end(); ++it) {
  217. Json::ValueType vt = value[*it].type();
  218. switch (vt) {
  219. case Json::stringValue: {
  220. maps.insert(
  221. std::pair<std::string, std::string>(*it, value[*it].asString()));
  222. break;
  223. }
  224. case Json::intValue: {
  225. int inttmp = value[*it].asInt();
  226. maps.insert(
  227. std::pair<std::string, std::string>(*it, std::to_string(inttmp)));
  228. break;
  229. }
  230. case Json::arrayValue: {
  231. std::string strid;
  232. for (unsigned int i = 0; i < value[*it].size(); i++) {
  233. strid += value[*it][i].asString();
  234. strid += ",";
  235. }
  236. if (!strid.empty()) {
  237. strid = strid.substr(0, strid.size() - 1);
  238. }
  239. maps.insert(std::pair<std::string, std::string>(*it, strid));
  240. break;
  241. }
  242. default: {
  243. break;
  244. }
  245. }
  246. }
  247. }
  248. }
  249. return maps;
  250. }