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