#include <string>
#include "curl/curl.h"
#include <iostream>
using std::cout;
using std::endl;
using std::string;
struct Global_initializer {
Global_initializer() {
curl_global_init(CURL_GLOBAL_ALL);
}
~Global_initializer() {
curl_global_cleanup();
}
};
class Curl_client {
const static Global_initializer gi;
string url;
CURL *curl;
CURLcode res;
struct curl_slist *header_list = nullptr;
static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)
{
std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid);
if (NULL == str || NULL == buffer)
{
return -1;
}
char* pData = (char*)buffer;
str->append(pData, size * nmemb);
return nmemb;
}
static int debug_callback(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)
{
// can't see plainly if Data is gzip encoded
printf("[DATA_IN]%s\n", pData);
}
else if (itype == CURLINFO_DATA_OUT)
{
//printf("[DATA_OUT]%s\n", pData);
}
return 0;
}
public:
static bool debug;
string resp;
long resp_code;
Curl_client(string url) {
this->url = url;
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp);
if (debug) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debug_callback);
}
}
~Curl_client() {
curl_easy_cleanup(curl);
if (header_list) curl_slist_free_all(header_list);
}
CURLcode get() {
resp.clear();
if (header_list) curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
cout << "visit " << url << " failed: " <<
curl_easy_strerror(res) << endl;
}
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp_code);
return res;
}
CURLcode post(const string& post_data = string()) {
resp.clear();
header_list = curl_slist_append(header_list, "Expect:"); // remove 100 continue
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data.c_str());
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
cout << "visit " << url << " failed: " <<
curl_easy_strerror(res) << endl;
}
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp_code);
return res;
}
Curl_client& enable_debug() {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debug_callback);
return *this;
}
Curl_client& set_proxy(const string& proxy) {
curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str());
return *this;
}
Curl_client& ignore_ssl_cert() {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
return *this;
}
template<typename T>
Curl_client& setopt(CURLoption option, T value) {
curl_easy_setopt(curl, option, value);
return *this;
}
Curl_client& append_header(const string& header) {
header_list = curl_slist_append(header_list, header.c_str());
return *this;
}
Curl_client& remove_header(const string& header) {
append_header(header + ':');
return *this;
}
// accept "identity" "deflate" "gzip"
Curl_client& set_encoding(const char* encode) {
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, encode);
return *this;
}
};
const Global_initializer Curl_client::gi{};
bool Curl_client::debug{ false };