使用CURL封装HttpClient

来源:互联网 发布:淘宝卖点卡 编辑:程序博客网 时间:2024/05/16 16:17
#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;    }    CHttpClient():m_pcurl(NULL)    {    m_pcurl = curl_easy_init();    }    ~CHttpClient()    {    curl_easy_cleanup(m_pcurl);    }    bool Get(const string& url, string &response, int timeout)    {        return Request(url, "", "get", response, timeout);    }    bool Put(const string &url, const string &request, string &response, int timeout)    {        return Request(url, request, "put", response, timeout);    }    bool Post(const string& url, const string &request, string &response, int timeout)    {        return Request(url, request, "post", response, timeout);    }    bool Delete(const string &url, string &response, int timeout)    {        return Request(url, "", "delete", response, timeout);    }    bool Save( const std::string& url, const char *filename, int timeout)    {        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, string &response, int timeout)    {        m_response_code = 0;        response.clear();response.reserve(64 * 1024);        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, &response);        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        {            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;    long   m_response_code;};

以上是使用curl封装的HttpClient;工作中使用过的,默认支持长连接。

遇到过的curl缺陷与陷阱

1、对url中的空格是不进行编码的

解决方法:使用时需要对空格进行替换为:”%20”.

2、跟服务器交互时,如果跟服务失去连接会导致僵尸(阻塞在poll)

解决方式:可以设置一个超时时间


0 0