Utils.cc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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 <sstream>
  18. #include <stdlib.h>
  19. #include <alibabacloud/core/Utils.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. {
  31. #ifdef _WIN32
  32. char *data;
  33. UUID uuidhandle;
  34. UuidCreate(&uuidhandle);
  35. UuidToString(&uuidhandle, reinterpret_cast<RPC_CSTR *>(&data));
  36. std::string uuid(data);
  37. RpcStringFree(reinterpret_cast<RPC_CSTR *>(&data));
  38. return uuid;
  39. #else
  40. uuid_t uu;
  41. uuid_generate(uu);
  42. char buf[36];
  43. uuid_unparse(uu, buf);
  44. return buf;
  45. #endif
  46. }
  47. std::string AlibabaCloud::UrlEncode(const std::string &src)
  48. {
  49. CURL *curl = curl_easy_init();
  50. char *output = curl_easy_escape(curl, src.c_str(), src.size());
  51. std::string result(output);
  52. curl_free(output);
  53. curl_easy_cleanup(curl);
  54. return result;
  55. }
  56. std::string AlibabaCloud::UrlDecode(const std::string &src)
  57. {
  58. CURL *curl = curl_easy_init();
  59. int outlength = 0;
  60. char *output = curl_easy_unescape(curl, src.c_str(), src.size(), &outlength);
  61. std::string result(output, outlength);
  62. curl_free(output);
  63. curl_easy_cleanup(curl);
  64. return result;
  65. }
  66. std::string AlibabaCloud::ComputeContentMD5(const char *data, size_t size)
  67. {
  68. #ifdef _WIN32
  69. HCRYPTPROV hProv = 0;
  70. HCRYPTHASH hHash = 0;
  71. BYTE pbHash[16];
  72. DWORD dwDataLen = 16;
  73. CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
  74. CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
  75. CryptHashData(hHash, (BYTE *)(data), size, 0);
  76. CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwDataLen, 0);
  77. CryptDestroyHash(hHash);
  78. CryptReleaseContext(hProv, 0);
  79. DWORD dlen = 0;
  80. CryptBinaryToString(pbHash, dwDataLen,
  81. CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &dlen);
  82. char *dest = new char[dlen];
  83. CryptBinaryToString(pbHash, dwDataLen,
  84. CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, dest, &dlen);
  85. std::string ret = std::string(dest, dlen);
  86. delete dest;
  87. return ret;
  88. #else
  89. unsigned char md[MD5_DIGEST_LENGTH];
  90. MD5(reinterpret_cast<const unsigned char *>(data), size,
  91. (unsigned char *)&md);
  92. char encodedData[100];
  93. EVP_EncodeBlock(reinterpret_cast<unsigned char *>(encodedData), md,
  94. MD5_DIGEST_LENGTH);
  95. return encodedData;
  96. #endif
  97. }
  98. void AlibabaCloud::StringReplace(std::string &src, const std::string &s1,
  99. const std::string &s2)
  100. {
  101. std::string::size_type pos = 0;
  102. while ((pos = src.find(s1, pos)) != std::string::npos)
  103. {
  104. src.replace(pos, s1.length(), s2);
  105. pos += s2.length();
  106. }
  107. }
  108. std::string AlibabaCloud::HttpMethodToString(HttpRequest::Method method)
  109. {
  110. switch (method)
  111. {
  112. case HttpRequest::Method::Head:
  113. return "HEAD";
  114. break;
  115. case HttpRequest::Method::Post:
  116. return "POST";
  117. break;
  118. case HttpRequest::Method::Put:
  119. return "PUT";
  120. break;
  121. case HttpRequest::Method::Delete:
  122. return "DELETE";
  123. break;
  124. case HttpRequest::Method::Connect:
  125. return "CONNECT";
  126. break;
  127. case HttpRequest::Method::Options:
  128. return "OPTIONS";
  129. break;
  130. case HttpRequest::Method::Patch:
  131. return "PATCH";
  132. break;
  133. case HttpRequest::Method::Trace:
  134. return "TRACE";
  135. break;
  136. case HttpRequest::Method::Get:
  137. default:
  138. return "GET";
  139. break;
  140. }
  141. }
  142. std::string AlibabaCloud::canonicalizedQuery(
  143. const std::map<std::string, std::string> &params)
  144. {
  145. if (params.empty())
  146. return std::string();
  147. std::stringstream ss;
  148. for (const auto &p : params)
  149. {
  150. std::string key = UrlEncode(p.first);
  151. StringReplace(key, "+", "%20");
  152. StringReplace(key, "*", "%2A");
  153. StringReplace(key, "%7E", "~");
  154. std::string value = UrlEncode(p.second);
  155. StringReplace(value, "+", "%20");
  156. StringReplace(value, "*", "%2A");
  157. StringReplace(value, "%7E", "~");
  158. ss << "&" << key << "=" << value;
  159. }
  160. return ss.str().substr(1);
  161. }
  162. std::string AlibabaCloud::canonicalizedHeaders(
  163. const HttpMessage::HeaderCollection &headers)
  164. {
  165. std::map<std::string, std::string> materials;
  166. for (const auto &p : headers)
  167. {
  168. std::string key = p.first;
  169. std::transform(key.begin(), key.end(), key.begin(), ::tolower);
  170. if (key.find("x-acs-") != 0)
  171. continue;
  172. std::string value = p.second;
  173. StringReplace(value, "\t", " ");
  174. StringReplace(value, "\n", " ");
  175. StringReplace(value, "\r", " ");
  176. StringReplace(value, "\f", " ");
  177. materials[key] = value;
  178. }
  179. if (materials.empty())
  180. return std::string();
  181. std::stringstream ss;
  182. for (const auto &p : materials)
  183. ss << p.first << ":" << p.second << "\n";
  184. return ss.str();
  185. }
  186. std::string AlibabaCloud::GetEnv(const std::string env)
  187. {
  188. #ifdef _WIN32
  189. char *buf = nullptr;
  190. size_t sz = 0;
  191. if (_dupenv_s(&buf, &sz, env.c_str()) == 0 && buf != nullptr)
  192. {
  193. std::string var(buf);
  194. free(buf);
  195. return var;
  196. }
  197. else
  198. {
  199. if (buf)
  200. {
  201. free(buf);
  202. }
  203. return std::string();
  204. }
  205. #else
  206. char *var = getenv(env.c_str());
  207. if (var)
  208. {
  209. return std::string(var);
  210. }
  211. return std::string();
  212. #endif
  213. }
  214. std::string AlibabaCloud::MapToJson(const std::map<std::string, std::string> &maps)
  215. {
  216. Json::Value jsonObject;
  217. for (std::map<std::string, std::string>::const_iterator iter = maps.begin(); iter != maps.end(); ++iter)
  218. {
  219. jsonObject[iter->first] = iter->second;
  220. }
  221. return jsonObject.toStyledString();
  222. }
  223. std::map<std::string, std::string> AlibabaCloud::JsonToMap(const std::string &json)
  224. {
  225. Json::Reader reader;
  226. Json::Value value;
  227. std::map<std::string, std::string> maps;
  228. if (json.length() > 0)
  229. {
  230. if (reader.parse(json, value))
  231. {
  232. Json::Value::Members members = value.getMemberNames();
  233. for (Json::Value::Members::iterator it = members.begin(); it != members.end(); it++)
  234. {
  235. Json::ValueType vt = value[*it].type();
  236. switch (vt)
  237. {
  238. case Json::stringValue:
  239. {
  240. maps.insert(std::pair<std::string, std::string>(*it, value[*it].asString()));
  241. break;
  242. }
  243. case Json::intValue:
  244. {
  245. int inttmp = value[*it].asInt();
  246. maps.insert(std::pair<std::string, std::string>(*it, std::to_string(inttmp)));
  247. break;
  248. }
  249. case Json::arrayValue:
  250. {
  251. std::string strid;
  252. for (unsigned int i = 0; i < value[*it].size(); i++)
  253. {
  254. strid += value[*it][i].asString();
  255. strid += ",";
  256. }
  257. if (!strid.empty())
  258. {
  259. strid = strid.substr(0, strid.size() - 1);
  260. }
  261. maps.insert(std::pair<std::string, std::string>(*it, strid));
  262. break;
  263. }
  264. default:
  265. {
  266. break;
  267. }
  268. }
  269. }
  270. }
  271. }
  272. return maps;
  273. }