CHttpClient.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. #include "CHttpClient.h"
  2. #include <QFile>
  3. #include <mutex>
  4. #include <openssl/err.h>
  5. #include <openssl/ssl.h>
  6. #include <openssl/x509.h>
  7. #include <openssl/pem.h>
  8. #include <openssl/dh.h>
  9. #include <openssl/conf.h>
  10. #include <openssl/engine.h>
  11. #include <openssl/buffer.h>
  12. #include <openssl/rsa.h>
  13. std::once_flag CHttpClient::oc_init;
  14. std::once_flag CHttpClient::oc_destory;
  15. CHttpClient::CHttpClient()
  16. {
  17. m_pCurl = nullptr;
  18. m_pList = nullptr;
  19. m_nTimeOutSecord = 30;
  20. m_formpost = nullptr;
  21. m_lastptr = nullptr;
  22. std::call_once(oc_init, [&](){
  23. CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
  24. if(CURLE_OK != res)
  25. {
  26. m_sErrorMsg = "curl_global_init初始化失败";
  27. }
  28. });
  29. }
  30. CHttpClient::~CHttpClient()
  31. {
  32. std::call_once(oc_destory, [](){curl_global_cleanup();});
  33. }
  34. struct MemoryStruct
  35. {
  36. char *memory;
  37. size_t size;
  38. MemoryStruct()
  39. {
  40. memory = (char *)malloc(1);
  41. size = 0;
  42. }
  43. ~MemoryStruct()
  44. {
  45. free(memory);
  46. memory = NULL;
  47. size = 0;
  48. }
  49. };
  50. struct FileStruct
  51. {
  52. std::string fileName;
  53. FILE *pFile;
  54. size_t size;
  55. bool setFile(std::string sFileName)
  56. {
  57. QFile file(sFileName.c_str());
  58. if(file.exists())
  59. {
  60. file.remove();
  61. }
  62. pFile = fopen(sFileName.c_str(), "wb");
  63. if( pFile == NULL )
  64. {
  65. return false;
  66. }
  67. fileName = sFileName;
  68. return true;
  69. }
  70. void saveFile()
  71. {
  72. fclose(pFile);
  73. }
  74. FileStruct()
  75. {
  76. pFile = nullptr;
  77. fileName = "";
  78. size = 0;
  79. }
  80. ~FileStruct()
  81. {
  82. size = 0;
  83. }
  84. };
  85. size_t WriteFileCallback(void *ptr, size_t size, size_t nmemb, void *data)
  86. {
  87. size_t realsize = size * nmemb;
  88. FileStruct *file = (FileStruct *)data;
  89. if(file->pFile)
  90. {
  91. fwrite(ptr,realsize,1,file->pFile);
  92. file->size += realsize;
  93. }
  94. return realsize;
  95. }
  96. size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
  97. {
  98. size_t realsize = size * nmemb;
  99. MemoryStruct *mem = (MemoryStruct *)data;
  100. mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
  101. if (mem->memory)
  102. {
  103. memcpy(&(mem->memory[mem->size]), ptr, realsize);
  104. mem->size += realsize;
  105. mem->memory[mem->size] = 0;
  106. }
  107. return realsize;
  108. }
  109. void CHttpClient::setTimeOut(int nTimeOut)
  110. {
  111. m_nTimeOutSecord = nTimeOut;
  112. }
  113. void CHttpClient::addParam(std::string sKey, std::string sValue)
  114. {
  115. std::string sEncodeValue = encodeStr(sValue);
  116. if(m_sParmStr.empty())
  117. {
  118. m_sParmStr = sKey + "=" + sEncodeValue;
  119. }
  120. else
  121. {
  122. m_sParmStr = m_sParmStr + "&" + sKey + "=" + sEncodeValue;
  123. }
  124. }
  125. void CHttpClient::addHeader(std::string sKey, std::string sValue)
  126. {
  127. m_pList = curl_slist_append(m_pList, (sKey + ":" + sValue).c_str());
  128. }
  129. bool CHttpClient::post(std::string uri, std::string &sResponse, int &nResCode)
  130. {
  131. m_pCurl = curl_easy_init();
  132. if( NULL == m_pCurl)
  133. {
  134. m_sErrorMsg = "curl_easy_init初始化失败";
  135. return false;
  136. }
  137. m_pList = curl_slist_append(m_pList,"Content-Type:application/x-www-form-urlencoded;charset=UTF-8");
  138. m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8");
  139. curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList);
  140. curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord); //设置超时时长
  141. curl_easy_setopt(m_pCurl, CURLOPT_URL, uri.c_str() ); //提交表单的URL地址
  142. curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输
  143. curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向
  144. curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
  145. //将返回结果通过回调函数写到自定义的对象中
  146. MemoryStruct oDataChunk;
  147. curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk);
  148. curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  149. curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息
  150. //libcur的相关POST配置项
  151. curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L);
  152. curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, m_sParmStr.c_str());
  153. curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, m_sParmStr.size());
  154. // curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false);
  155. // curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false);
  156. sslVerify();
  157. CURLcode res = curl_easy_perform(m_pCurl);
  158. long res_code = -1;
  159. res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code);
  160. nResCode = res_code;
  161. if( res == CURLE_OK )
  162. {
  163. sResponse = std::string(oDataChunk.memory, oDataChunk.size);
  164. curl_slist_free_all(m_pList);
  165. m_pList = NULL;
  166. m_sParmStr = "";
  167. curl_easy_cleanup(m_pCurl);
  168. return true;
  169. }
  170. else
  171. {
  172. curl_slist_free_all(m_pList);
  173. m_pList = NULL;
  174. m_sParmStr = "";
  175. curl_easy_cleanup(m_pCurl);
  176. return false;
  177. }
  178. }
  179. bool CHttpClient::post(std::string uri, std::string sPostStr, std::string &sResponse, int &nResCode)
  180. {
  181. m_pCurl = curl_easy_init();
  182. if( NULL == m_pCurl)
  183. {
  184. m_sErrorMsg = "curl_easy_init初始化失败";
  185. return false;
  186. }
  187. m_pList = curl_slist_append(m_pList,"Content-Type:application/json");
  188. m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8");
  189. curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList);
  190. curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord); //设置超时时长
  191. curl_easy_setopt(m_pCurl, CURLOPT_URL, uri.c_str() ); //提交表单的URL地址
  192. curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输
  193. curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向
  194. curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
  195. //将返回结果通过回调函数写到自定义的对象中
  196. MemoryStruct oDataChunk;
  197. curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk);
  198. curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  199. curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息
  200. //libcur的相关POST配置项
  201. curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L);
  202. curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, sPostStr.c_str());
  203. curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, sPostStr.size());
  204. //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false);
  205. //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false);
  206. sslVerify();
  207. CURLcode res = curl_easy_perform(m_pCurl);
  208. long res_code = -1;
  209. res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code);
  210. nResCode = res_code;
  211. if( res == CURLE_OK )
  212. {
  213. sResponse = std::string(oDataChunk.memory, oDataChunk.size);
  214. curl_slist_free_all(m_pList);
  215. m_pList = NULL;
  216. m_sParmStr = "";
  217. curl_easy_cleanup(m_pCurl);
  218. return true;
  219. }
  220. else
  221. {
  222. curl_slist_free_all(m_pList);
  223. m_pList = NULL;
  224. m_sParmStr = "";
  225. curl_easy_cleanup(m_pCurl);
  226. return false;
  227. }
  228. }
  229. void CHttpClient::addFormDataList(FORM_DATA_TYPE nType, std::string sKey, std::vector<std::string> sValue)
  230. {
  231. curl_forms *pArray = new curl_forms[sValue.size()+1];
  232. curl_forms *temp = pArray;
  233. for (std::string sItem : sValue)
  234. {
  235. if (nType == fdt_content)
  236. {
  237. temp->option = CURLFORM_COPYCONTENTS;
  238. }
  239. else
  240. {
  241. temp->option = CURLFORM_FILE;
  242. }
  243. temp->value = sItem.c_str();
  244. temp++;
  245. }
  246. temp->option = CURLFORM_END;
  247. curl_formadd(&m_formpost, &m_lastptr,
  248. CURLFORM_COPYNAME, sKey.c_str(),
  249. CURLFORM_ARRAY, pArray, CURLFORM_END);
  250. delete [] pArray;
  251. }
  252. void CHttpClient::addFormData(FORM_DATA_TYPE nType, std::string sKey, std::string sValue)
  253. {
  254. if(nType == fdt_content)
  255. {
  256. curl_formadd(&m_formpost, &m_lastptr,
  257. CURLFORM_COPYNAME, sKey.c_str(),
  258. CURLFORM_COPYCONTENTS, sValue.c_str(), CURLFORM_END);
  259. }
  260. else
  261. {
  262. curl_formadd(&m_formpost, &m_lastptr,
  263. CURLFORM_COPYNAME, sKey.c_str(),
  264. CURLFORM_FILE, sValue.c_str(), CURLFORM_END);
  265. }
  266. }
  267. bool CHttpClient::postFormData(std::string uri, std::string &sResponse, int &nResCode)
  268. {
  269. m_pCurl = curl_easy_init();
  270. if( NULL == m_pCurl)
  271. {
  272. m_sErrorMsg = "curl_easy_init初始化失败";
  273. return false;
  274. }
  275. m_pList = curl_slist_append(m_pList,"Content-type:multipart/form-data");
  276. m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8");
  277. curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList);
  278. curl_easy_setopt(m_pCurl, CURLOPT_URL, uri.c_str() ); //提交表单的URL地址
  279. // 设置Form表单参数
  280. curl_easy_setopt(m_pCurl, CURLOPT_HTTPPOST, m_formpost);
  281. // curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输
  282. // curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向
  283. curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
  284. //将返回结果通过回调函数写到自定义的对象中
  285. MemoryStruct oDataChunk;
  286. curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk);
  287. curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  288. curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息
  289. //libcur的相关POST配置项
  290. // curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L);
  291. // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, m_sParmStr.c_str());
  292. // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, m_sParmStr.size());
  293. curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord);
  294. //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false);
  295. //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false);
  296. sslVerify();
  297. CURLcode res = curl_easy_perform(m_pCurl);
  298. long res_code = -1;
  299. res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code);
  300. nResCode = res_code;
  301. if( res == CURLE_OK )
  302. {
  303. sResponse = std::string(oDataChunk.memory, oDataChunk.size);
  304. curl_easy_cleanup(m_pCurl);
  305. curl_slist_free_all(m_pList);
  306. curl_formfree(m_formpost);
  307. m_formpost = NULL;
  308. m_lastptr = NULL;
  309. m_pList = NULL;
  310. m_sParmStr = "";
  311. return true;
  312. }
  313. else
  314. {
  315. curl_easy_cleanup(m_pCurl);
  316. curl_slist_free_all(m_pList);
  317. curl_formfree(m_formpost);
  318. m_lastptr = NULL;
  319. m_pList = NULL;
  320. m_sParmStr = "";
  321. return false;
  322. }
  323. }
  324. CURLcode CHttpClient::sslctx_function(CURL *curl, void *sslctx, void *parm)
  325. {
  326. X509 *cert = NULL;
  327. BIO *bio = NULL;
  328. BIO *kbio = NULL;
  329. RSA *rsa = NULL;
  330. int ret;
  331. const char *mypem = "-----BEGIN CERTIFICATE-----\n"
  332. "MIIDOjCCAiICBQCHhjV3MA0GCSqGSIb3DQEBBAUAMIGiMQswCQYDVQQGEwJDTjES\n"
  333. "MBAGA1UECAwJR3VhbmdEb25nMRIwEAYDVQQHDAlTaGVuWmhlbmcxEDAOBgNVBAoM\n"
  334. "B0FsaWJhYmExDTALBgNVBAsMBFByb2QxKDAmBgNVBAMMH29lLXN0dWRlbnQtY2xp\n"
  335. "ZW50LmV4YW0tY2xvdWQuY24xIDAeBgkqhkiG9w0BCQEWEWh1eXVlQHFtdGguY29t\n"
  336. "LmNuMB4XDTIxMTExMTA5MDUyM1oXDTMxMTEwOTA5MDUyM1owgaIxCzAJBgNVBAYT\n"
  337. "AkNOMRIwEAYDVQQIDAlHdWFuZ0RvbmcxEDAOBgNVBAoMB0FsaWJhYmExDTALBgNV\n"
  338. "BAsMBFByb2QxEjAQBgNVBAcMCVNoZW5aaGVuZzEoMCYGA1UEAwwfb2Utc3R1ZGVu\n"
  339. "dC1jbGllbnQuZXhhbS1jbG91ZC5jbjEgMB4GCSqGSIb3DQEJARYRaHV5dWVAcW10\n"
  340. "aC5jb20uY24wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMss/6qUMhiOdu80\n"
  341. "cyhZpkwBGO3raA+81ujwt8lEiK0idRE4dj+G6Bd6KjNJGdhQogfOgDPklv+oLxU/\n"
  342. "w4mXogHtb1DtFYPfEY72kdvEeLtRtG0gaRXN2/BJ1U6qZ+zvmhjEiqf/k5Q0HkZi\n"
  343. "hXZcADWrgPn3Dv43mUU9qvhbk9sFAgMBAAEwDQYJKoZIhvcNAQEEBQADggEBAAZa\n"
  344. "0K3mmslMCAQZWuidSA2O5tyRNT6uijKX/3UCm9NQ/Q98vMQ90cyXh2KyqNxi/L37\n"
  345. "EWPcMo1R8yuds41k8/sxSqF3A2zRs9uPTh3kYiu54dx7Z8amE31S0eh07fQs8qvp\n"
  346. "Jdi6vyARhgzNKKvvPi5hF5X03BAVdTGKaAWi2gMZMmeDuC8pjENTycixt9+usylV\n"
  347. "uB+Cheb9M/8FtJU6bKTwOyw3mYqhMK1wgKahjBSnUkp7IEXoaITDkn2Mz44xqCtN\n"
  348. "zZJ4R8wtV9uGm8HalDVaS9LWR1NPdLSkaIjtfESfjnWd4cjWOrHZ035yClab0uj4\n"
  349. "OyGCQKEQjVOot6szUP8=\n"
  350. "-----END CERTIFICATE-----";
  351. /*replace the XXX with the actual RSA key*/
  352. const char *mykey = "-----BEGIN RSA PRIVATE KEY-----\n"
  353. "MIICXgIBAAKBgQDLLP+qlDIYjnbvNHMoWaZMARjt62gPvNbo8LfJRIitInUROHY/\n"
  354. "hugXeiozSRnYUKIHzoAz5Jb/qC8VP8OJl6IB7W9Q7RWD3xGO9pHbxHi7UbRtIGkV\n"
  355. "zdvwSdVOqmfs75oYxIqn/5OUNB5GYoV2XAA1q4D59w7+N5lFPar4W5PbBQIDAQAB\n"
  356. "AoGBAK++19REZmTpbqWRN/9yNK/PzzGWDCh4z2klN8SoPJWOlbb0oQxodIBCUxiT\n"
  357. "pgCAFvgrvqeklpzEbR2zTz/IYwA+8wMVXT/V72QNygVKOohuhRYFH88LHTNOQV/X\n"
  358. "ieg6OoYz5bGvaNYHwx7kIqkeE2sBDtq89sX73bR9NWTb/n8hAkEA7XPDDHN2qdhh\n"
  359. "9xAl14L18UVTlTUK/cXZXaxNp0nmKL1jnQtHibWSUgyTDdv0vplXnqjRIk2mEtR/\n"
  360. "We3np/9mTQJBANsL0yGQrsMhAcRRHptYd4E9SrYp27L6/Oi3TGn8QNv5lawaGfCu\n"
  361. "0tat8AJfGzNgOWP16lwAz3/nns9HFVi4E5kCQQCbrGdVxGUpmPkxFt8YWX2Qflj7\n"
  362. "21inY4zMQuhuIp7IWtHx5bEy8V1KeX/3eBsO0k2FcTwa9zlH4xTTCovzsheJAkEA\n"
  363. "rEwK0NYbgUUPPLqKFqtppPDvOYaHV6txECROKPfQlLcnce4+BUGeelrq9RKWNL01\n"
  364. "p1kh9Sh2DyfDlUtWkSiJ0QJAZSLI92yo116QJz6SmU9g10pm8LSlAPa7j+1lfLvz\n"
  365. "eTIXiFpu5fbF1I1sFMuLKISSoqWPihMCIWxsE5a5i5OOuA== \n"
  366. "-----END RSA PRIVATE KEY-----";
  367. (void)curl; /* avoid warnings */
  368. (void)parm; /* avoid warnings */
  369. /* get a BIO */
  370. bio = BIO_new_mem_buf((char *)mypem, -1);
  371. if (bio == NULL) {
  372. printf("BIO_new_mem_buf failed\n");
  373. }
  374. /* use it to read the PEM formatted certificate from memory into an X509
  375. * structure that SSL can use
  376. */
  377. cert = PEM_read_bio_X509(bio, NULL, 0, NULL);
  378. if (cert == NULL) {
  379. printf("PEM_read_bio_X509 failed...\n");
  380. }
  381. /*tell SSL to use the X509 certificate*/
  382. ret = SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert);
  383. if (ret != 1) {
  384. printf("Use certificate failed\n");
  385. }
  386. /*create a bio for the RSA key*/
  387. kbio = BIO_new_mem_buf((char *)mykey, -1);
  388. if (kbio == NULL) {
  389. printf("BIO_new_mem_buf failed\n");
  390. }
  391. /*read the key bio into an RSA object*/
  392. rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL);
  393. if (rsa == NULL) {
  394. printf("Failed to create key bio\n");
  395. }
  396. /*tell SSL to use the RSA key from memory*/
  397. ret = SSL_CTX_use_RSAPrivateKey((SSL_CTX*)sslctx, rsa);
  398. if (ret != 1) {
  399. printf("Use Key failed\n");
  400. }
  401. /* free resources that have been allocated by openssl functions */
  402. if (bio)
  403. BIO_free(bio);
  404. if (kbio)
  405. BIO_free(kbio);
  406. if (rsa)
  407. RSA_free(rsa);
  408. if (cert)
  409. X509_free(cert);
  410. /* all set to go */
  411. return CURLE_OK;
  412. }
  413. void CHttpClient::sslVerify()
  414. {
  415. curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false);
  416. curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false);
  417. /*
  418. curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0);
  419. curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 2);
  420. curl_easy_setopt(m_pCurl, CURLOPT_SSLCERTTYPE, "PEM");
  421. curl_easy_setopt(m_pCurl, CURLOPT_SSLKEYTYPE, "PEM");
  422. curl_easy_setopt(m_pCurl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
  423. */
  424. }
  425. bool CHttpClient::get(std::string uri, std::string &sResponse, int &nResCode)
  426. {
  427. m_pCurl = curl_easy_init();
  428. if( NULL == m_pCurl)
  429. {
  430. m_sErrorMsg = "curl_easy_init初始化失败";
  431. return false;
  432. }
  433. m_pList = curl_slist_append(m_pList,"Content-Type:application/json");
  434. m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8");
  435. curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList);
  436. curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord); //设置超时时长
  437. std::string strUrl = "";
  438. strUrl = /*encodeURL*/(uri);
  439. curl_easy_setopt(m_pCurl, CURLOPT_URL, strUrl.c_str() ); //提交表单的URL地址
  440. curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输
  441. curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向
  442. curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
  443. //将返回结果通过回调函数写到自定义的对象中
  444. MemoryStruct oDataChunk;
  445. curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk);
  446. curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  447. curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息
  448. //libcur的相关POST配置项
  449. // curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L);
  450. // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, m_sParmStr.c_str());
  451. // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, m_sParmStr.size());
  452. sslVerify();
  453. CURLcode res = curl_easy_perform(m_pCurl);
  454. long res_code = -1;
  455. res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code);
  456. nResCode = res_code;
  457. if( res == CURLE_OK )
  458. {
  459. sResponse = std::string(oDataChunk.memory, oDataChunk.size);
  460. curl_slist_free_all(m_pList);
  461. m_pList = NULL;
  462. m_sParmStr = "";
  463. curl_easy_cleanup(m_pCurl);
  464. return true;
  465. }
  466. else
  467. {
  468. curl_slist_free_all(m_pList);
  469. m_pList = NULL;
  470. m_sParmStr = "";
  471. curl_easy_cleanup(m_pCurl);
  472. return false;
  473. }
  474. }
  475. bool CHttpClient::put(std::string uri, std::string &sResponse, int &nResCode)
  476. {
  477. m_pCurl = curl_easy_init();
  478. if (NULL == m_pCurl)
  479. {
  480. m_sErrorMsg = "curl_easy_init初始化失败";
  481. return false;
  482. }
  483. m_pList = curl_slist_append(m_pList, "Content-Type:application/json");
  484. m_pList = curl_slist_append(m_pList, "Accept-Language:zh-CN,zh;q=0.8");
  485. curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList);
  486. curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, m_nTimeOutSecord); //设置超时时长
  487. std::string strUrl = "";
  488. strUrl = uri;
  489. curl_easy_setopt(m_pCurl, CURLOPT_URL, strUrl.c_str()); //提交表单的URL地址
  490. curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输
  491. curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向
  492. curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
  493. curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息
  494. curl_easy_setopt(m_pCurl, CURLOPT_PUT, 1L);
  495. //将返回结果通过回调函数写到自定义的对象中
  496. MemoryStruct oDataChunk;
  497. curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk);
  498. curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  499. //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false);
  500. //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false);
  501. sslVerify();
  502. CURLcode res = curl_easy_perform(m_pCurl);
  503. long res_code = -1;
  504. res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code);
  505. nResCode = res_code;
  506. if (res == CURLE_OK)
  507. {
  508. sResponse = std::string(oDataChunk.memory, oDataChunk.size);
  509. }
  510. curl_slist_free_all(m_pList);
  511. m_pList = NULL;
  512. m_sParmStr = "";
  513. curl_easy_cleanup(m_pCurl);
  514. if (res == CURLE_OK)
  515. {
  516. return true;
  517. }
  518. else
  519. {
  520. return false;
  521. }
  522. }
  523. bool CHttpClient::download(std::string uri, std::string sFileName, int &nResCode)
  524. {
  525. m_pCurl = curl_easy_init();
  526. if( NULL == m_pCurl)
  527. {
  528. m_sErrorMsg = "curl_easy_init初始化失败";
  529. return false;
  530. }
  531. // m_pList = curl_slist_append(m_pList,"Content-Type:application/x-www-form-urlencoded;charset=UTF-8");
  532. // m_pList = curl_slist_append(m_pList,"Accept-Language:zh-CN,zh;q=0.8");
  533. // curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_pList);
  534. std::string strUrl = "";
  535. int nPos = uri.find_last_of(":");
  536. strUrl = uri.substr(0, nPos+1);
  537. strUrl += encodeURL(uri.substr(nPos + 1, uri.length() - nPos - 1));
  538. //myDebug()<<strUrl.c_str();
  539. curl_easy_setopt(m_pCurl, CURLOPT_URL, strUrl.c_str() ); //提交表单的URL地址
  540. curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT,m_nTimeOutSecord); //设置超时时长
  541. // curl_easy_setopt(m_pCurl, CURLOPT_HEADER, 0L); //启用时会将头文件的信息作为数据流输
  542. // curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);//允许重定向
  543. // curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
  544. //将返回结果通过回调函数写到自定义的对象中
  545. FileStruct oDataChunk;
  546. if(!oDataChunk.setFile(sFileName))
  547. {
  548. m_sErrorMsg = "创建文件失败!";
  549. return false;
  550. }
  551. curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &oDataChunk);
  552. curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteFileCallback);
  553. curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1L); //启用时会汇报所有的信息
  554. //libcur的相关POST配置项
  555. // curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L);
  556. // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, m_sParmStr.c_str());
  557. // curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, m_sParmStr.size());
  558. //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, false);
  559. //curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, false);
  560. sslVerify();
  561. CURLcode res = curl_easy_perform(m_pCurl);
  562. long res_code = -1;
  563. res = curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &res_code);
  564. nResCode = res_code;
  565. if( res == CURLE_OK && res_code == 200)
  566. {
  567. double length;
  568. res = curl_easy_getinfo(m_pCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length);
  569. fflush(oDataChunk.pFile);
  570. fseek(oDataChunk.pFile, 0, SEEK_END);
  571. long nDown = ftell(oDataChunk.pFile);
  572. oDataChunk.saveFile();
  573. curl_slist_free_all(m_pList);
  574. m_pList = NULL;
  575. m_sParmStr = "";
  576. curl_easy_cleanup(m_pCurl);
  577. if (nDown != (long)length)
  578. {
  579. nResCode = 0;
  580. if (!DeleteFileA(sFileName.c_str()))
  581. {
  582. m_sErrorMsg = GetLastError();
  583. }
  584. return false;
  585. }
  586. return true;
  587. }
  588. else
  589. {
  590. DeleteFileA(sFileName.c_str());
  591. curl_slist_free_all(m_pList);
  592. m_pList = NULL;
  593. m_sParmStr = "";
  594. curl_easy_cleanup(m_pCurl);
  595. return false;
  596. }
  597. }
  598. std::string CHttpClient::encodeStr(std::string sStr)
  599. {
  600. char* pUri = curl_easy_escape(m_pCurl, sStr.c_str(), sStr.length());
  601. std::string StrRet = pUri;
  602. curl_free(pUri);
  603. return StrRet;
  604. }
  605. std::string CHttpClient::encodeURL(std::string sUri)
  606. {
  607. std::string retUri = "";
  608. QString strUri = QString::fromLocal8Bit(sUri.c_str());
  609. QStringList uriList = strUri.split("/");
  610. for(int i = 0; i < uriList.count(); i++)
  611. {
  612. if(i == 0)
  613. {
  614. retUri = uriList[i].toStdString();
  615. }
  616. else
  617. {
  618. std::string tempStr = uriList[i].toStdString();
  619. char* pUri = curl_easy_escape(m_pCurl, tempStr.c_str(), tempStr.length());
  620. retUri += std::string("/") + pUri;
  621. curl_free(pUri);
  622. }
  623. }
  624. return retUri;
  625. }