设为首页 加入收藏

TOP

C++使用libcurl做HttpClient
2014-11-13 11:26:48 】 浏览:2433
Tags:使用 libcurl HttpClient

 当使用C++做HTTP客户端时,目前通用的做法就是使用libcurl。其官方网站的地址是http://curl.haxx.se/,该网站主要提供了Curl和libcurl。Curl是命令行工具,用于完成FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP的命令的请求及接收回馈。libcurl提供给开发者,用于使用C++跨平台的开发各种网络协议的请求及响应。里面的文档非常齐全,不过都是英文的。

    本文提供最简单的demo使用libcurl开发HttpClient。主要包括同步的HTTP GET、HTTP POST、HTTPS GET、HTTPS POST。

    下载libcurl包,如果使用Linux平台,建议下载源文件编译;如果使用Windows平台,建议下载Win32 - MSVC,下载地址是:http://curl.haxx.se/download.html

  1. #ifndef __HTTP_CURL_H__  

  2. #define __HTTP_CURL_H__  

  3.   

  4. #include <string>  

  5.   

  6. class CHttpClient  

  7. {  

  8. public:  

  9.     CHttpClient(void);  

  10.     ~CHttpClient(void);  

  11.   

  12. public:  

  13.     /** 

  14.     * @brief HTTP POST请求 

  15.     * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com 

  16.     * @param strPost 输入参数,使用如下格式para1=val1¶2=val2&… 

  17.     * @param strResponse 输出参数,返回的内容 

  18.     * @return 返回是否Post成功 

  19.     */  

  20.     int Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse);  

  21.   

  22.     /** 

  23.     * @brief HTTP GET请求 

  24.     * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com 

  25.     * @param strResponse 输出参数,返回的内容 

  26.     * @return 返回是否Post成功 

  27.     */  

  28.     int Get(const std::string & strUrl, std::string & strResponse);  

  29.   

  30.     /** 

  31.     * @brief HTTPS POST请求,无证书版本 

  32.     * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com 

  33.     * @param strPost 输入参数,使用如下格式para1=val1¶2=val2&… 

  34.     * @param strResponse 输出参数,返回的内容 

  35.     * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. 

  36.     * @return 返回是否Post成功 

  37.     */  

  38.     int Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath = NULL);  

  39.   

  40.     /** 

  41.     * @brief HTTPS GET请求,无证书版本 

  42.     * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com 

  43.     * @param strResponse 输出参数,返回的内容 

  44.     * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. 

  45.     * @return 返回是否Post成功 

  46.     */  

  47.     int Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL);  

  48.   

  49. public:  

  50.     void SetDebug(bool bDebug);  

  51.   

  52. private:  

  53.     bool m_bDebug;  

  54. };  

  55.   

  56. #endif  


  1. #include "httpclient.h"  

  2. #include "curl/curl.h"  

  3. #include <string>  

  4.   

  5. CHttpClient::CHttpClient(void) :   

  6. m_bDebug(false)  

  7. {  

  8.   

  9. }  

  10.   

  11. CHttpClient::~CHttpClient(void)  

  12. {  

  13.   

  14. }  

  15.   

  16. static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)  

  17. {  

  18.     if(itype == CURLINFO_TEXT)  

  19.     {  

  20.         //printf("[TEXT]%s\n", pData);  

  21.     }  

  22.     else if(itype == CURLINFO_HEADER_IN)  

  23.     {  

  24.         printf("[HEADER_IN]%s\n", pData);  

  25.     }  

  26.     else if(itype == CURLINFO_HEADER_OUT)  

  27.     {  

  28.         printf("[HEADER_OUT]%s\n", pData);  

  29.     }  

  30.     else if(itype == CURLINFO_DATA_IN)  

  31.     {  

  32.         printf("[DATA_IN]%s\n", pData);  

  33.     }  

  34.     else if(itype == CURLINFO_DATA_OUT)  

  35.     {  

  36.         printf("[DATA_OUT]%s\n", pData);  

  37.     }  

  38.     return 0;  

  39. }  

  40.   

  41. static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)  

  42. {  

  43.     std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid);  

  44.     if( NULL == str || NULL == buffer )  

  45.     {  

  46.         return -1;  

  47.     }  

  48.   

  49.     char* pData = (char*)buffer;  

  50.     str->append(pData, size * nmemb);  

  51.     return nmemb;  

  52. }  

  53.   

  54. int CHttpClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse)  

  55. {  

  56.     CURLcode res;  

  57.     CURL* curl = curl_easy_init();  

  58.     if(NULL == curl)  

  59.     {  

  60.         return CURLE_FAILED_INIT;  

  61.     }  

  62.     if(m_bDebug)  

  63.     {  

  64.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  

  65.         curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  

  66.     }  

  67.     curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  

  68.     curl_easy_setopt(curl, CURLOPT_POST, 1);  

  69.     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  

  70.     curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  

  71.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  

  72.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  

  73.     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  

  74.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  

  75.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  

  76.     res = curl_easy_perform(curl);  

  77.     curl_easy_cleanup(curl);  

  78.     return res;  

  79. }  

  80.   

  81. int CHttpClient::Get(const std::string & strUrl, std::string & strResponse)  

  82. {  

  83.     CURLcode res;  

  84.     CURL* curl = curl_easy_init();  

  85.     if(NULL == curl)  

  86.     {  

  87.         return CURLE_FAILED_INIT;  

  88.     }  

  89.     if(m_bDebug)  

  90.     {  

  91.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  

  92.         curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  

  93.     }  

  94. <pre name="code" class="cpp">   curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  

  95.     curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  

  96.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  

  97.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  

  98.     /** 

  99.     * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。 

  100.     * 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。 

  101.     */  

  102.     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  

  103.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  

  104.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  

  105.     res = curl_easy_perform(curl);  

  106.     curl_easy_cleanup(curl);  

  107.     return res;  

  108. }  

  109.   

  110. int CHttpClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath)  

  111. {  

  112.     CURLcode res;  

  113.     CURL* curl = curl_easy_init();  

  114.     if(NULL == curl)  

  115.     {  

  116.         return CURLE_FAILED_INIT;  

  117.     }  

  118.     if(m_bDebug)  

  119.     {  

  120.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  

  121.         curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  

  122.     }  

  123.     curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  

  124.     curl_easy_setopt(curl, CURLOPT_POST, 1);  

  125.     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  

  126.     curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  

  127.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  

  128.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  

  129.     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  

  130.     if(NULL == pCaPath)  

  131.     {  

  132.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);  

  133.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);  

  134.     }  

  135.     else  

  136.     {  

  137.         //缺省情况就是PEM,所以无需设置,另外支持DER  

  138.         //curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");  

  139.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);  

  140.         curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);  

  141.     }  

  142.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  

  143.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  

  144.     res = curl_easy_perform(curl);  

  145.     curl_easy_cleanup(curl);  

  146.     return res;  

  147. }  

  148.   

  149. int CHttpClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath)  

  150. {  

  151.     CURLcode res;  

  152.     CURL* curl = curl_easy_init();  

  153.     if(NULL == curl)  

  154.     {  

  155.         return CURLE_FAILED_INIT;  

  156.     }  

  157.     if(m_bDebug)  

  158.     {  

  159.         curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  

  160.         curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  

  161.     }  

  162.     curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  

  163.     curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  

  164.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  

  165.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  

  166.     curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  

  167.     if(NULL == pCaPath)  

  168.     {  

  169.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);  

  170.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);  

  171.     }  

  172.     else  

  173.     {  

  174.         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);  

  175.         curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);  

  176.     }  

  177.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  

  178.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  

  179.     res = curl_easy_perform(curl);  

  180.     curl_easy_cleanup(curl);  

  181.     return res;  

  182. }  

  183.   

  184. ///////////////////////////////////////////////////////////////////////////////////////////////  

  185.   

  186. void CHttpClient::SetDebug(bool bDebug)  

  187. {  

  188.     m_bDebug = bDebug;  

  189. }  

  190. </pre><p></p>  

  191. <pre></pre>  

  192. <br>  

  193. <br>  

  194. <p></p>  

  195. <br>  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇没有了 下一篇TCP为什么三次握手过程

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目