最近有个需求,需要用c++请求下我自己的服务器,周末看了一下怎么发起http请求。
官方文档见:
官网的demo是基于c的,我用的时候报错了。下面是我写的get/post的方法,同步执行。
cpp
namespace yeshen_http
{
struct MemoryStruct
{
char *memory;
size_t size;
};
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
void *ptr = realloc(mem->memory, mem->size + realsize + 1);
if (!ptr)
{
std::cout << "not enough memory (realloc returned NULL)" << std::endl;
return 0;
}
mem->memory = (char *)ptr;
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
static const char *get_url = "https://yeshen.org";
}
int HTTP::get(const char *url, std::string &response)
{
CURL *curl = curl_easy_init();
struct yeshen_http::MemoryStruct chunk;
chunk.memory = (char *)malloc(1);
chunk.size = 0;
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, yeshen_http::WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
CURLcode res = curl_easy_perform(curl);
int retCode = -1;
if (res != CURLE_OK)
{
std::cerr << "curl_easy_perform() failed:" << curl << curl_easy_strerror(res) << std::endl;
}
else if (chunk.size == 0)
{
std::cout << (unsigned long)chunk.size << " bytes retrieved" << std::endl;
}
else
{
std::cout << (unsigned long)chunk.size << " bytes retrieved" << std::endl;
response = chunk.memory;
retCode = 0;
}
free(chunk.memory);
curl_easy_cleanup(curl);
return retCode;
}
return -1;
}
int HTTP::post(const char *url, const std::string &data)
{
CURL *curl = curl_easy_init();
if (curl)
{
const char *data_str = data.c_str();
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data_str);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(data_str));
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
std::cerr << "curl_easy_perform() failed:" << curl_easy_strerror(res) << std::endl;
return -1;
}
curl_easy_cleanup(curl);
return 0;
}
return -1;
}
cmake部分的处理
cmake
target_link_libraries(${YESHEN_TARGET_NAME} PRIVATE
libcurl.so
)