// ==========================================================================
// Author: Yee Hsu
// Date: 6/7/2011
//
// Desc: HttpClient implements a simple HTTP Client using cURL.
// Demonstrates a simple usage of the powerful cURL library to
// do simple HTTP request.
// ==========================================================================
#include "StdAfx.h"
#include "HttpClient.h"
HttpClient::HttpClient()
{
if (!m_initialize)
{
if (curl_global_init(CURL_GLOBAL_ALL) == CURLE_OK)
m_initialize=true;
}
}
HttpClient::~HttpClient()
{
if (m_initialize)
{
curl_global_cleanup();
}
m_initialize = false;
}
int HttpClient::StringWriter(char *data, size_t size, size_t nmemb, string *buffer)
{
int result = 0;
if (data)
{
buffer->append(data, size * nmemb);
result = size * nmemb;
}
return result;
}
int HttpClient::StreamWriter(char *data, size_t size, size_t nmemb, std::ostream *fs)
{
int result = 0;
if (data)
{
string buffer(data, size * nmemb);
(*fs) << buffer;
result = size * nmemb;
}
return result;
}
string HttpClient::PostFieldsToString(PostFields const& params)
{
CURL *curl = NULL;
string query;
if (curl = curl_easy_init())
{
for (PostFields::const_iterator iter = params.begin(); iter != params.end(); ++iter)
{
char *enc = NULL;
if (iter != params.begin())
{
query.append("&");
}
const string& key = iter->first;
const string& val = iter->second;
if (enc = curl_easy_escape(curl, val.c_str(), val.size()))
{
query.append(key);
query.append("=");
query.append(enc);
curl_free(enc);
}
}
curl_easy_cleanup(curl);
}
return query;
}
bool HttpClient::SetCurlEasyOpts(CURL* curl, DownloadTask& task) const
{
char err[CURL_ERROR_SIZE] = {0};
if (curl)
{
if (!task.params.empty())
{
string data = this->PostFieldsToString(task.params);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, data.c_str());
}
if (task.request_timeout > 0)
curl_easy_setopt(curl, CURLOPT_TIMEOUT, task.request_timeout);
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, err);
curl_easy_setopt(curl, CURLOPT_URL, task.url.c_str());
curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, StringWriter);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &task.resp_content);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, task.connect_timeout);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_USERAGENT, task.agent.c_str());
curl_easy_setopt(curl, CURLOPT_REFERER, task.referer.c_str());
curl_easy_setopt(curl, CURLOPT_USERNAME, task.username.c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, task.password.c_str());
return true;
}
return false;
}
bool HttpClient::Request( DownloadTask& task ) const
{
bool bret = false;
CURL* curl = NULL;
if (curl = curl_easy_init())
{
this->SetCurlEasyOpts(curl, task);
if (curl_easy_perform(curl) == CURLE_OK)
bret = true;
curl_easy_cleanup(curl);
}
return bret;
}
bool HttpClient::GetRequest( DownloadTask& task ) const
{
bool bret = false;
CURL* curl = NULL;
if (curl = curl_easy_init())
{
task.params.clear();
this->SetCurlEasyOpts(curl, task);
if (curl_easy_perform(curl) == CURLE_OK)
bret = true;
curl_easy_cleanup(curl);
}
return bret;
}
bool HttpClient::PostRequest( DownloadTask& task ) const
{
bool bret = false;
CURL* curl = NULL;
if (curl = curl_easy_init())
{
if (task.params.empty())
{
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, "");
}
this->SetCurlEasyOpts(curl, task);
if (curl_easy_perform(curl) == CURLE_OK)
bret = true;
curl_easy_cleanup(curl);
}
return bret;
}