CurlHttp.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #include "CurlHttp.h"
  2. #include <regex>
  3. #include "fmtlog.h"
  4. /* ==================================================================================
  5. * *********************************** 全局变量 *************************************
  6. * ================================================================================== */
  7. /* ==================================================================================
  8. * *********************************** 全局函数 *************************************
  9. * ================================================================================== */
  10. /**
  11. * @brief 写入回调函数
  12. *
  13. * @param contents 接收到的内容
  14. * @param size 内容大小,单位size_t
  15. * @param nmemb size_t的单位
  16. * @param userp 用户传入的接收区指针
  17. * @return size_t
  18. */
  19. static size_t WriteStringCallback(void* contents, size_t size, size_t nmemb, std::string* userStr)
  20. {
  21. size_t newLength = size * nmemb;
  22. size_t oldLength = userStr->size();
  23. try
  24. {
  25. userStr->resize(oldLength + newLength);
  26. }
  27. catch(std::bad_alloc &e)
  28. {
  29. FMTLOG_ERROR("{}", e.what());
  30. return 0;
  31. }
  32. std::copy_n((char*)contents, newLength, userStr->begin() + oldLength);
  33. return size * nmemb;
  34. }
  35. /* ==================================================================================
  36. * *********************************** 成员函数 *************************************
  37. * ================================================================================== */
  38. CurlHttp::CurlHttp()
  39. {
  40. curl_global_init(CURL_GLOBAL_DEFAULT);
  41. }
  42. CurlHttp::~CurlHttp()
  43. {
  44. curl_global_cleanup();
  45. }
  46. /**
  47. * @brief 获取信息
  48. *
  49. * @param url 网址
  50. * @param response 返回的数据
  51. * @return true
  52. * @return false
  53. */
  54. bool CurlHttp::Get(const std::string& url, std::string& response)
  55. {
  56. CURL *curl;
  57. CURLcode res;
  58. curl = curl_easy_init();
  59. if(curl == nullptr)
  60. {
  61. FMTLOG_ERROR("curl_easy_init() failed");
  62. return false;
  63. }
  64. /* 设置为Get请求 */
  65. curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
  66. /* 设置url */
  67. curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  68. /* 设置重定向,遇到3xx返回值时自动重定向 */
  69. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  70. /* 设置https协议 */
  71. curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
  72. /* 设置写入回调函数 */
  73. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteStringCallback);
  74. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
  75. /* 设置超时 */
  76. curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L);
  77. curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
  78. /* 发送请求 */
  79. bool result = true;
  80. res = curl_easy_perform(curl);
  81. if(res != CURLE_OK)
  82. {
  83. FMTLOG_ERROR("Get failed: {}, Url: {}", curl_easy_strerror(res), url);
  84. result = false;
  85. }
  86. curl_easy_cleanup(curl);
  87. return true;
  88. }
  89. /* 获取信息,带有http头 */
  90. bool CurlHttp::Get(const std::string& url, const std::vector<std::string>& vecHeader, std::string& response)
  91. {
  92. CURL *curl;
  93. CURLcode res;
  94. curl = curl_easy_init();
  95. if(curl == nullptr)
  96. {
  97. FMTLOG_ERROR("curl_easy_init() failed");
  98. return false;
  99. }
  100. /* 设置为Get请求 */
  101. curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
  102. /* 设置url */
  103. curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  104. /* 设置http头 */
  105. struct curl_slist *headers = NULL;
  106. if(!vecHeader.empty())
  107. {
  108. for(auto &header : vecHeader)
  109. {
  110. headers = curl_slist_append(headers, header.c_str());
  111. }
  112. curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  113. }
  114. /* 设置重定向,遇到3xx返回值时自动重定向 */
  115. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  116. /* 设置https协议 */
  117. curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
  118. /* 设置写入回调函数 */
  119. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteStringCallback);
  120. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
  121. /* 设置超时 */
  122. curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L);
  123. curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
  124. /* 发送请求 */
  125. bool result = true;
  126. res = curl_easy_perform(curl);
  127. if(res != CURLE_OK)
  128. {
  129. FMTLOG_ERROR("Get failed: {}, Url:{}", curl_easy_strerror(res), url);
  130. result = false;
  131. }
  132. /* 清理内存 */
  133. curl_slist_free_all(headers);
  134. curl_easy_cleanup(curl);
  135. return result;
  136. }
  137. /**
  138. * @brief 发送信息,不携带http头
  139. *
  140. * @param url
  141. * @param postData
  142. * @param response
  143. * @return true
  144. * @return false
  145. */
  146. bool CurlHttp::Post(const std::string& url, const std::string& postData, std::string& response)
  147. {
  148. CURL *curl;
  149. CURLcode res;
  150. curl = curl_easy_init();
  151. if(curl == nullptr)
  152. {
  153. FMTLOG_ERROR("curl_easy_init() failed");
  154. return false;
  155. }
  156. /* 设置用户名密码,可能有的话 */
  157. /* 设置动作功能和网址 */
  158. curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
  159. curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  160. /* 设置重定向,遇到3xx返回值时自动重定向 */
  161. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  162. /* 设置https协议 */
  163. curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
  164. /* 设置包体 */
  165. curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str());
  166. curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postData.size());
  167. /* 设置回调函数 */
  168. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteStringCallback);
  169. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
  170. /* 设置连接超时和接收数据超时 */
  171. curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L);
  172. curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
  173. /* 设置不发送任何信号,对于多线程有用 */
  174. // curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  175. /* 发送请求 */
  176. res = curl_easy_perform(curl);
  177. bool result = true;
  178. if(res != CURLE_OK)
  179. {
  180. FMTLOG_ERROR("Post failed: {}, Url: {}", curl_easy_strerror(res), url);
  181. result = false;
  182. }
  183. /* 清理curl */
  184. curl_easy_cleanup(curl);
  185. return result;
  186. }
  187. /**
  188. * @brief 发送带有Http头和包体的信息
  189. *
  190. * @param url 网址
  191. * @param vecHeader http头,vector<string>格式,每个元素为一行,
  192. * 如 User-Agent: Apifox/1.0.0 (https://apifox.com)
  193. * @param postData 发送的包体
  194. * @param response 返回的数据
  195. * @return true
  196. * @return false
  197. */
  198. bool CurlHttp::Post(const std::string& url,const std::vector<std::string>& vecHeader, const std::string& postData, std::string& response)
  199. {
  200. CURL *curl;
  201. CURLcode res;
  202. curl = curl_easy_init();
  203. if(curl == nullptr)
  204. {
  205. FMTLOG_ERROR("curl_easy_init() failed");
  206. return false;
  207. }
  208. /* 设置动作功能和网址 */
  209. curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
  210. curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  211. /* 设置重定向,遇到3xx返回值时自动重定向 */
  212. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  213. /* 设置https协议 */
  214. curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
  215. /* 设置http头 */
  216. struct curl_slist *headers = NULL;
  217. if(!vecHeader.empty())
  218. {
  219. for(auto &header : vecHeader)
  220. {
  221. headers = curl_slist_append(headers, header.c_str());
  222. }
  223. curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  224. }
  225. /* 设置包体 */
  226. curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str());
  227. curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postData.size());
  228. /* 设置回调函数 */
  229. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteStringCallback);
  230. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
  231. /* 设置连接超时和接收数据超时 */
  232. curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30L);
  233. curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
  234. /* 设置不发送任何信号,对于多线程有用 */
  235. // curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  236. /* 发送请求 */
  237. res = curl_easy_perform(curl);
  238. bool result = true;
  239. if(res != CURLE_OK)
  240. {
  241. FMTLOG_ERROR("Post failed: {}, Url: {}", curl_easy_strerror(res), url);
  242. result = false;
  243. }
  244. curl_slist_free_all(headers);
  245. /* 清理curl */
  246. curl_easy_cleanup(curl);
  247. return result;
  248. }