CurlClient.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. #include "StdAfx.h"
  2. #include "CurlClient.h"
  3. #include "curl/curl.h"
  4. #include "curl/easy.h"
  5. #include "curl/curlver.h"
  6. #include "CharEncoding.h"
  7. CCurlClient::CCurlClient(void)
  8. {
  9. m_bDebug = TRUE;
  10. }
  11. CCurlClient::~CCurlClient(void)
  12. {
  13. // 释放curl的全局对象;
  14. curl_global_cleanup();
  15. }
  16. INT CCurlClient::Initialize()
  17. {
  18. // 初始化全局调用模式;
  19. CURLcode res = ::curl_global_init( CURL_GLOBAL_ALL );
  20. if( CURLE_OK != res )
  21. {
  22. fprintf( stderr, "curl_global_init failed: %d \n", res );
  23. return -1;
  24. }
  25. return 0;
  26. }
  27. static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)
  28. {
  29. if(itype == CURLINFO_TEXT)
  30. {
  31. TRACE("[TEXT]%s\n", pData);
  32. }
  33. else if(itype == CURLINFO_HEADER_IN)
  34. {
  35. TRACE("[HEADER_IN]%s\n", pData);
  36. }
  37. else if(itype == CURLINFO_HEADER_OUT)
  38. {
  39. TRACE("[HEADER_OUT]%s\n", pData);
  40. }
  41. else if(itype == CURLINFO_DATA_IN)
  42. {
  43. TRACE("[DATA_IN]%s\n", pData);
  44. }
  45. else if(itype == CURLINFO_DATA_OUT)
  46. {
  47. TRACE("[DATA_OUT]%s\n", pData);
  48. }
  49. return 0;
  50. }
  51. size_t CCurlClient::OnWriteData(const void *ptr, size_t size, size_t nmemb, std::string *stream)
  52. {
  53. if( NULL == stream || NULL == ptr )
  54. return -1;
  55. stream->append((char*)ptr, size * nmemb);
  56. return nmemb;
  57. }
  58. int CCurlClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse)
  59. {
  60. CURLcode res;
  61. CURL* curl = curl_easy_init();
  62. if(NULL == curl)
  63. {
  64. return CURLE_FAILED_INIT;
  65. }
  66. if(m_bDebug)
  67. {// 是否开启调试日志输出;
  68. curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  69. curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
  70. }
  71. // 设置URL地址;
  72. curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
  73. // 设置POST方式;
  74. curl_easy_setopt(curl, CURLOPT_POST, 1);
  75. // 设置POST参数;
  76. curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());
  77. // 设置回调函数-读取;
  78. curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
  79. // 设置回调函数-写入;
  80. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
  81. // 设置回调函数-写入的缓存区;
  82. curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
  83. // 设置(多线程下,只是尽量减少)无签名;
  84. curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  85. // 设置连接超时值(单位毫秒);
  86. curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30000);
  87. // 设置操作超时值(单位毫秒);
  88. curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30000);
  89. // 执行POST提交;
  90. res = curl_easy_perform(curl);
  91. // 释放资源;
  92. curl_easy_cleanup(curl);
  93. return res;
  94. }
  95. int CCurlClient::Post(IN LPCTSTR lpUrl, IN LPCTSTR lpPost, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen)
  96. {
  97. if ( lpUrl == NULL || lpPost == NULL )
  98. return CURLE_FAILED_INIT;
  99. string strUrl;
  100. string strPost;
  101. string strResponse;
  102. #ifdef UNICODE
  103. CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl);
  104. CharEncoding::UNICODE2ASCII((LPWCH)lpPost, strPost);
  105. int res = Post(strUrl, strPost, strResponse) ;
  106. if ( CURLE_OK == res )
  107. {
  108. CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen);
  109. return CURLE_OK;
  110. }
  111. return res;
  112. #else
  113. strUrl = lpUrl;
  114. strPost = lpPost;
  115. int res = Post(strUrl, strPost, strResponse) ;
  116. if ( CURLE_OK == res )
  117. {
  118. sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str());
  119. return CURLE_OK;
  120. }
  121. return res;
  122. #endif
  123. }
  124. int CCurlClient::Post(IN CString& strUrl, IN CString& strPost, OUT CString& strResponse)
  125. {
  126. if ( strUrl.IsEmpty() || strPost.IsEmpty() )
  127. return CURLE_FAILED_INIT;
  128. string url;
  129. string post;
  130. string response;
  131. #ifdef UNICODE
  132. CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url);
  133. CharEncoding::UNICODE2ASCII((LPWCH)strPost.GetString(), post);
  134. int res = Post(url, post, response) ;
  135. if ( CURLE_OK == res )
  136. {
  137. WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str());
  138. if ( pResult )
  139. {
  140. strResponse = pResult;
  141. delete []pResult;
  142. pResult = NULL;
  143. return CURLE_OK;
  144. }
  145. }
  146. return res;
  147. #else
  148. url = strUrl.GetString();
  149. post = strPost.GetString();
  150. int res = Post(url, post, response) ;
  151. if ( CURLE_OK == res )
  152. {
  153. strResponse = response.c_str();
  154. return CURLE_OK;
  155. }
  156. return res;
  157. #endif
  158. }
  159. int CCurlClient::Get(const std::string & strUrl, std::string & strResponse)
  160. {
  161. CURLcode res;
  162. CURL* curl = curl_easy_init();
  163. if(NULL == curl)
  164. {
  165. return CURLE_FAILED_INIT;
  166. }
  167. if(m_bDebug)
  168. {
  169. curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  170. curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
  171. }
  172. // 设置URL地址;
  173. curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
  174. // 设置回调函数-读取;
  175. curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
  176. // 设置回调函数-写入;
  177. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
  178. // 设置回调函数-写入的缓存区;
  179. curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
  180. /**
  181. * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。
  182. * 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。
  183. */
  184. // 设置(多线程下,只是尽量减少)无签名;
  185. curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  186. // 设置连接超时值;
  187. curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,5000);
  188. // 设置超时值;
  189. curl_easy_setopt(curl,CURLOPT_TIMEOUT,5000);
  190. res = curl_easy_perform(curl);
  191. curl_easy_cleanup(curl);
  192. return res;
  193. }
  194. int CCurlClient::Get(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen)
  195. {
  196. if ( lpUrl == NULL )
  197. return CURLE_FAILED_INIT;
  198. string strUrl;
  199. string strResponse;
  200. #ifdef UNICODE
  201. CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl);
  202. int res = Get(strUrl, strResponse) ;
  203. if ( CURLE_OK == res )
  204. {
  205. CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen);
  206. return CURLE_OK;
  207. }
  208. return res;
  209. #else
  210. strUrl = lpUrl;
  211. int res = Get(strUrl, strResponse) ;
  212. if ( CURLE_OK == res )
  213. {
  214. sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str());
  215. return CURLE_OK;
  216. }
  217. return res;
  218. #endif
  219. }
  220. int CCurlClient::Get(IN CString& strUrl, OUT CString& strResponse)
  221. {
  222. if ( strUrl.IsEmpty() )
  223. return CURLE_FAILED_INIT;
  224. string url;
  225. string post;
  226. string response;
  227. #ifdef UNICODE
  228. CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url);
  229. int res = Get(url, response) ;
  230. if ( CURLE_OK == res )
  231. {
  232. WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str());
  233. if ( pResult )
  234. {
  235. strResponse = pResult;
  236. delete []pResult;
  237. pResult = NULL;
  238. return CURLE_OK;
  239. }
  240. }
  241. return res;
  242. #else
  243. url = strUrl.GetString();
  244. int res = Get(url, response) ;
  245. if ( CURLE_OK == res )
  246. {
  247. strResponse = response.c_str();
  248. return CURLE_OK;
  249. }
  250. return res;
  251. #endif
  252. }
  253. int CCurlClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath)
  254. {
  255. CURLcode res;
  256. CURL* curl = curl_easy_init();
  257. if(NULL == curl)
  258. {
  259. return CURLE_FAILED_INIT;
  260. }
  261. if(m_bDebug)
  262. {
  263. curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  264. curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
  265. }
  266. // 设置URL地址;
  267. curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
  268. // 设置POST提交方式;
  269. curl_easy_setopt(curl, CURLOPT_POST, 1);
  270. // 设置POST参数;
  271. curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());
  272. // 设置回调函数-读取;
  273. curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
  274. // 设置回调函数-写入;
  275. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
  276. // 设置回调函数-写入的缓存区;
  277. curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
  278. // 设置;
  279. curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  280. if(NULL == pCaPath || pCaPath[0] == '\0')
  281. {
  282. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
  283. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
  284. }
  285. else
  286. {
  287. //缺省情况就是PEM,所以无需设置,另外支持DER
  288. //curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
  289. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);
  290. curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);
  291. }
  292. // 设置连接超时值;
  293. curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,5000);
  294. // 设置超时值;
  295. curl_easy_setopt(curl,CURLOPT_TIMEOUT,5000);
  296. // 执行POST提交;
  297. res = curl_easy_perform(curl);
  298. // 释放资源;
  299. curl_easy_cleanup(curl);
  300. return res;
  301. }
  302. int CCurlClient::Posts(IN LPCTSTR lpUrl, IN LPCTSTR lpPost, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath /* = NULL */)
  303. {
  304. if ( lpUrl == NULL || lpPost == NULL )
  305. return CURLE_FAILED_INIT;
  306. string strUrl;
  307. string strPost;
  308. string strCapath;
  309. string strResponse;
  310. #ifdef UNICODE
  311. CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl);
  312. CharEncoding::UNICODE2ASCII((LPWCH)lpPost, strPost);
  313. CharEncoding::UNICODE2ASCII((LPWCH)lpCaPath, strCapath);
  314. int res = Posts(strUrl, strPost, strResponse, strCapath.c_str()) ;
  315. if ( CURLE_OK == res )
  316. {
  317. CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen);
  318. return CURLE_OK;
  319. }
  320. return res;
  321. #else
  322. strUrl = lpUrl;
  323. strPost = lpPost;
  324. strCapath = lpCaPath;
  325. int res = Posts(strUrl, strPost, strResponse, strCapath.c_str()) ;
  326. if ( CURLE_OK == res )
  327. {
  328. sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str());
  329. return CURLE_OK;
  330. }
  331. return res;
  332. #endif
  333. }
  334. int CCurlClient::Posts(IN CString& strUrl, IN CString& strPost, OUT CString& strResponse, IN const CString& strCaPath /* = _T("") */)
  335. {
  336. if ( strUrl.IsEmpty() || strPost.IsEmpty() )
  337. return CURLE_FAILED_INIT;
  338. string url;
  339. string post;
  340. string capth;
  341. string response;
  342. #ifdef UNICODE
  343. CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url);
  344. CharEncoding::UNICODE2ASCII((LPWCH)strPost.GetString(), post);
  345. CharEncoding::UNICODE2ASCII((LPWCH)strCaPath.GetString(), capth);
  346. int res = Posts(url, post, response, capth.c_str()) ;
  347. if ( CURLE_OK == res )
  348. {
  349. WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str());
  350. if ( pResult )
  351. {
  352. strResponse = pResult;
  353. delete []pResult;
  354. pResult = NULL;
  355. return CURLE_OK;
  356. }
  357. }
  358. return res;
  359. #else
  360. url = strUrl.GetString();
  361. post = strPost.GetString();
  362. capth = strCaPath.GetString();
  363. int res = Posts(url, post, response, capth.c_str()) ;
  364. if ( CURLE_OK == res )
  365. {
  366. strResponse = response.c_str();
  367. return CURLE_OK;
  368. }
  369. return res;
  370. #endif
  371. }
  372. int CCurlClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath)
  373. {
  374. CURLcode res;
  375. CURL* curl = curl_easy_init();
  376. if(NULL == curl)
  377. {
  378. return CURLE_FAILED_INIT;
  379. }
  380. if(m_bDebug)
  381. {
  382. curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  383. curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
  384. }
  385. curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
  386. curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
  387. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
  388. curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);
  389. curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  390. if(NULL == pCaPath || pCaPath[0] == '\0')
  391. {
  392. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
  393. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
  394. }
  395. else
  396. {
  397. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);
  398. curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);
  399. }
  400. curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);
  401. curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
  402. res = curl_easy_perform(curl);
  403. curl_easy_cleanup(curl);
  404. return res;
  405. }
  406. int CCurlClient::Gets(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath /* = NULL */)
  407. {
  408. if ( lpUrl == NULL )
  409. return CURLE_FAILED_INIT;
  410. string strUrl;
  411. string strCapath;
  412. string strResponse;
  413. #ifdef UNICODE
  414. CharEncoding::UNICODE2ASCII((LPWCH)lpUrl, strUrl);
  415. CharEncoding::UNICODE2ASCII((LPWCH)lpCaPath, strCapath);
  416. int res = Gets(strUrl, strResponse, strCapath.c_str()) ;
  417. if ( CURLE_OK == res )
  418. {
  419. CharEncoding::ASCII2UNICODE(strResponse.c_str(), (LPWCH)lpResponse, nMaxlen);
  420. return CURLE_OK;
  421. }
  422. return res;
  423. #else
  424. strUrl = lpUrl;
  425. strCapath = lpCaPath;
  426. int res = Gets(strUrl, strResponse, strCapath.c_str()) ;
  427. if ( CURLE_OK == res )
  428. {
  429. sprintf_s(lpResponse, nMaxlen, "%s", strResponse.c_str());
  430. return CURLE_OK;
  431. }
  432. return res;
  433. #endif
  434. }
  435. int CCurlClient::Gets(IN CString& strUrl, OUT CString& strResponse, IN const CString& strCaPath /* = _T("") */)
  436. {
  437. if ( strUrl.IsEmpty() )
  438. return CURLE_FAILED_INIT;
  439. string url;
  440. string post;
  441. string capth;
  442. string response;
  443. #ifdef UNICODE
  444. CharEncoding::UNICODE2ASCII((LPWCH)strUrl.GetString(), url);
  445. CharEncoding::UNICODE2ASCII((LPWCH)strCaPath.GetString(), capth);
  446. int res = Gets(url, response, capth.c_str()) ;
  447. if ( CURLE_OK == res )
  448. {
  449. WCHAR* pResult = CharEncoding::ASCII2UNICODE(response.c_str());
  450. if ( pResult )
  451. {
  452. strResponse = pResult;
  453. delete []pResult;
  454. pResult = NULL;
  455. return CURLE_OK;
  456. }
  457. }
  458. return res;
  459. #else
  460. url = strUrl.GetString();
  461. capth = strCaPath.GetString();
  462. int res = Gets(url, response, capth.c_str()) ;
  463. if ( CURLE_OK == res )
  464. {
  465. strResponse = response.c_str();
  466. return CURLE_OK;
  467. }
  468. return res;
  469. #endif
  470. }
  471. void CCurlClient::SetDebug(bool bDebug)
  472. {
  473. m_bDebug = bDebug;
  474. }