使用CURL封装HttpClient

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

using std::string;

class HttpClient
{
public:
    static size_t WriteData(char *data, size_t block_size, size_t block_count, string *response)
    {
        if(data == NULL) return 0;
        
        size_t len = block_size * block_count;
        response->append(data, len);
        return len;
    }

    static size_t WriteFile(char *data, size_t block_size, size_t block_count, FILE *file)
    {
        if(data == NULL) return 0;
        
        size_t len = block_size * block_count;
        fwrite(data, len, 1, file);	
        return len;
    }

    HttpClient():m_pcurl(NULL)
    {
        m_pcurl = curl_easy_init();
    }

    ~HttpClient()
    {
        curl_easy_cleanup(m_pcurl);
    }
    
    string Error() {return m_error;}
    string Header() {return m_header;}
    string Response() {return m_response;}
    long HttpCode(){return m_response_code;}

    bool Get(const string &url, int timeout)
    {
        return Request(url, "", "get", timeout);
    }

    bool Put(const string &url, const string &request, int timeout)
    {
        return Request(url, request, "put", timeout);
    }

    bool Post(const string &url, const string &request, int timeout)
    {
        return Request(url, request, "post", timeout);
    }

    bool Delete(const string &url, int timeout)
    {
        return Request(url, "", "delete",timeout);
    }

    bool Save( const std::string &url, const char *filename, int timeout)
    {
        m_error = "";
        m_response_code = 0;

        FILE* file = fopen(filename, "wb");

        curl_easy_reset(m_pcurl);
        curl_easy_setopt(m_pcurl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(m_pcurl, CURLOPT_WRITEFUNCTION, WriteFile);
        curl_easy_setopt(m_pcurl, CURLOPT_WRITEDATA, file);
        curl_easy_setopt(m_pcurl, CURLOPT_FOLLOWLOCATION, 1);
        curl_easy_setopt(m_pcurl, CURLOPT_NOSIGNAL, 1);
        curl_easy_setopt(m_pcurl, CURLOPT_TIMEOUT, timeout);

        CURLcode rc = curl_easy_perform(m_pcurl);
        fclose(file);
        if(rc != CURLE_OK)
        {
            m_error =  string(curl_easy_strerror(rc));
            return false;
        }

        rc = curl_easy_getinfo(m_pcurl, CURLINFO_RESPONSE_CODE , &m_response_code); 
        if(rc != CURLE_OK)
        {
            m_error =  string(curl_easy_strerror(rc));
            return false;
        }

        return true;
    }

private:
    bool Request(const string &url, const string &request, string method, int timeout)
    {
        m_error = "";
        m_response_code = 0;
        m_response.clear();
        m_header.clear();

        curl_easy_reset(m_pcurl);
        curl_easy_setopt(m_pcurl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(m_pcurl, CURLOPT_NOSIGNAL, 1);
        curl_easy_setopt(m_pcurl, CURLOPT_TIMEOUT, timeout);
        curl_easy_setopt(m_pcurl, CURLOPT_WRITEFUNCTION, WriteData);
        curl_easy_setopt(m_pcurl, CURLOPT_WRITEDATA, &m_response);
        curl_easy_setopt(m_pcurl, CURLOPT_HEADERFUNCTION, WriteData);
        curl_easy_setopt(m_pcurl, CURLOPT_WRITEHEADER, &m_header);
        if(method == "get")
        {
            curl_easy_setopt(m_pcurl, CURLOPT_HTTPGET, 1);
        }
        else if(method == "post")
        {
            curl_easy_setopt(m_pcurl, CURLOPT_POST, 1L);
            curl_easy_setopt(m_pcurl, CURLOPT_POSTFIELDSIZE, request.length());
            curl_easy_setopt(m_pcurl, CURLOPT_POSTFIELDS, request.c_str());
        }
        else if(method == "put")
        {
            curl_easy_setopt(m_pcurl, CURLOPT_CUSTOMREQUEST, "PUT");
            curl_easy_setopt(m_pcurl, CURLOPT_POSTFIELDSIZE, request.length());
            curl_easy_setopt(m_pcurl, CURLOPT_POSTFIELDS, request.c_str());
        }
        else if(method == "delete")
        {
            curl_easy_setopt(m_pcurl, CURLOPT_CUSTOMREQUEST, "DELETE");
        }
        else
        {
            m_error = "method not support: " + method;
            return false;
        }

        CURLcode rc = curl_easy_perform(m_pcurl);
        if(rc != CURLE_OK)
        {
            m_error =  string(curl_easy_strerror(rc));
            return false;
        }

        rc = curl_easy_getinfo(m_pcurl, CURLINFO_RESPONSE_CODE , &m_response_code); 
        if(rc != CURLE_OK)
        {
            m_error =  string(curl_easy_strerror(rc));
            return false;
        }

        return true;
    }
    

private:
    CURL  *m_pcurl;
    string m_error;
    string m_header;
    string m_response;
    long   m_response_code;
};


以上是使用curl封装的HttpClient;工作中使用过的,默认支持长连接。
遇到过的curl缺陷与陷阱
1、对url中的空格是不进行编码的
解决方法:使用时需要对空格进行替换为:”%20”.
2、跟服务器交互时,如果跟服务失去连接会导致僵尸(阻塞在poll)
解决方式:可以设置一个超时时间

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值