CHttpClient 用于表示一个基于 C++ 和libcurl 的 HTTP 客户端

   CHttpClient 用于表示一个基于 C++ 的 HTTP 客户端,它内部使用了 libcurl 来实现 HTTP 请求的发送和接收。libcurl 是一个强大的库,支持多种协议,包括 HTTP、HTTPS、FTP 等,并且提供了丰富的 API 来定制请求。

        该类封装了 libcurl 的基本功能,用于发送 GET 和 POST 请求。请注意,这个假设你已经有了 libcurl 的开发环境配置好,并且你的项目能够链接到 libcurl

        

#ifndef __HTTP_CURL_H__  
#define __HTTP_CURL_H__  

#include <string>
#include "curl.h" 



class CHttpClient  
{  
public:  
    CHttpClient(void);  
    ~CHttpClient(void);  
  
public:  
    /** 
    * @brief HTTP POST请求 
    * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com 
    * @param strPost 输入参数,使用如下格式para1=val1?2=val2&… 
    * @param strResponse 输出参数,返回的内容 
    * @return 返回是否Post成功 
    */  
    int Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse, bool bSaveCook = false);  

    /** 
    * @brief HTTP GET请求 
    * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com 
    * @param strResponse 输出参数,返回的内容 
    * @return 返回是否Post成功 
    */  
    int Get(const std::string & strUrl, std::string & strResponse);  
  
    /** 
    * @brief HTTPS POST请求,无证书版本 
    * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com 
    * @param strPost 输入参数,使用如下格式para1=val1?2=val2&… 
    * @param strResponse 输出参数,返回的内容 
    * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. 
    * @return 返回是否Post成功 
    */  
    int Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath = NULL);  
  
    /** 
    * @brief HTTPS GET请求,无证书版本 
    * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com 
    * @param strResponse 输出参数,返回的内容 
    * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. 
    * @return 返回是否Post成功 
    */  
    int Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL);  
  
    int Put(const std::string& strUrl, const std::string& strPut, std::string &strResponse);
public:  
    void SetDebug(bool bDebug);  
  
private:  
    bool m_bDebug;  
};  
  
#endif  
#include "HttpClient.h"  
#include "curl/curl.h"  
#include <string>  
#include "curl//easy.h"
 
CHttpClient::CHttpClient(void) :   
m_bDebug(false)  
{  
  
}  
  
CHttpClient::~CHttpClient(void)  
{  
  
}  
  
static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)  
{  
    if(itype == CURLINFO_TEXT)  
    {  
        //printf("[TEXT]%s\n", pData);  
    }  
    else if(itype == CURLINFO_HEADER_IN)  
    {  
        printf("[HEADER_IN]%s\n", pData);  
    }  
    else if(itype == CURLINFO_HEADER_OUT)  
    {  
        printf("[HEADER_OUT]%s\n", pData);  
    }  
    else if(itype == CURLINFO_DATA_IN)  
    {  
        printf("[DATA_IN]%s\n", pData);  
    }  
    else if(itype == CURLINFO_DATA_OUT)  
    {  
        printf("[DATA_OUT]%s\n", pData);  
    }  
    return 0;  
}  
  
static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)  
{  
    std::string* str = (std::string*)lpVoid;  
    if( NULL == str || NULL == buffer )  
    {  
        return -1;  
    }  
  
    char* pData = (char*)buffer;  
    str->append(pData, size * nmemb);
    return nmemb;  
}  

int CHttpClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse, bool bSaveCook)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if(m_bDebug)  
    {  
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    curl_easy_setopt(curl, CURLOPT_POST, 1);  
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    //curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
	curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookies.txt");

    struct curl_slist *slist = NULL;
    slist = curl_slist_append(slist, "Expect:");        //防止Expect:100-Continue
	slist = curl_slist_append(slist, "Content-Type:application/json");
	slist = curl_slist_append(slist, "charset:utf-8");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);  //set head

	if ( bSaveCook )
	{
		curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookies.txt");
	}
    res = curl_easy_perform(curl);  
    curl_easy_cleanup(curl);  
    return res;  
}  

int CHttpClient::Get(const std::string & strUrl, std::string & strResponse)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if(m_bDebug)  
    {
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  

	std::string strUrlTmp ;

#ifdef _LINUX_
	std::string strParam;
	std::string::size_type nPos = strUrl.find("?");
	if ( nPos != std::string::npos )
	{
		strParam = strUrl.substr(strUrl.find("?")+1);
		char * escape_control = curl_escape(strParam.c_str(), strParam.size());
		strParam = escape_control;
		curl_free(escape_control);

		strUrlTmp = strUrl.substr(0, strUrl.find("?")+1) + strParam;
	}
	else
	{
		strUrlTmp = strUrl;
	}
#else
	strUrlTmp = strUrl;
#endif

	curl_easy_setopt(curl, CURLOPT_URL, strUrlTmp.c_str());  
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    /** 
    * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。 
    * 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。 
    */  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    //curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
	curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1); //这个很重要,curl 有个重用机制,访问的链接不会立即释放,如果访问过于平凡的可能会导致服务器端口被沾满,无法访问的情况(CURLE_COULDNT_CONNECT /* 7 */ 这个是返回的错误码)
	curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "E:\\cookies.txt");
	
	struct curl_slist *slist = NULL;
	slist = curl_slist_append(slist, "Accept:application/json");
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); //set head

    res = curl_easy_perform(curl);  
    curl_easy_cleanup(curl);

    return res;  
}  
  
int CHttpClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if(m_bDebug)  
    {  
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    curl_easy_setopt(curl, CURLOPT_POST, 1);  
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    if(NULL == pCaPath)  
    {  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);  
    }  
    else  
    {  
        //缺省情况就是PEM,所以无需设置,另外支持DER  
        //curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);  
        curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);  
    }  
    //curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);  
    res = curl_easy_perform(curl);  
    curl_easy_cleanup(curl);  
    return res;  
}  
  
int CHttpClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if(m_bDebug)  
    {  
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    if(NULL == pCaPath)  
    {  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);  
    }  
    else  
    {  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);  
        curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);  
    }  
    //curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
	curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1); //这个很重要,curl 有个重用机制,访问的链接不会立即释放,如果访问过于平凡的可能会导致服务器端口被沾满,无法访问的情况(CURLE_COULDNT_CONNECT /* 7 */ 这个是返回的错误码)
	res = curl_easy_perform(curl);  
    curl_easy_cleanup(curl);  
    return res;  
}

int CHttpClient::Put(const std::string& strUrl, const std::string& strPut, std::string &strResponse)
{
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if (NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if (m_bDebug)  
    {  
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  

    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); 
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPut.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strPut.length());
 
    struct curl_slist *slist = NULL;
    slist = curl_slist_append(slist, "Content-Type: XXXX");
    slist = curl_slist_append(slist, "Accept:XXXX");
    slist = curl_slist_append(slist, "XXXX");
    slist = curl_slist_append(slist, "Expect:");        //防止Expect:100-Continue
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);  //set head

    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  

    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    //curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);  

    res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);
    return res;
}

///  
  
void CHttpClient::SetDebug(bool bDebug)  
{  
    m_bDebug = bDebug;  
}  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值