2024-04-25 14:14:01 +08:00
|
|
|
|
#include "Request.h"
|
|
|
|
|
|
#include "Response.h"
|
|
|
|
|
|
#include "curl/curl.h"
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
|
#include <exception>
|
|
|
|
|
|
#include <new>
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
namespace
|
|
|
|
|
|
{
|
|
|
|
|
|
static size_t
|
|
|
|
|
|
WriteMemoryCallback(char *contents, size_t size, size_t nmemb, void *userp)
|
|
|
|
|
|
{
|
|
|
|
|
|
size_t realsize = size * nmemb;
|
|
|
|
|
|
std::string *str = (std::string *)userp;
|
|
|
|
|
|
if (realsize)
|
|
|
|
|
|
{
|
|
|
|
|
|
str->append(contents);
|
|
|
|
|
|
}
|
|
|
|
|
|
return realsize;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
Request::Request() : mCurl(NULL),
|
|
|
|
|
|
mHeaders(NULL),
|
|
|
|
|
|
mVerbose(false),
|
|
|
|
|
|
mValid(true)
|
|
|
|
|
|
{
|
|
|
|
|
|
mCurl = curl_easy_init();
|
|
|
|
|
|
if (!mCurl)
|
|
|
|
|
|
{
|
|
|
|
|
|
mValid = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Request::~Request()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (mCurl)
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_easy_cleanup(mCurl);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (mHeaders)
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_slist_free_all((struct curl_slist *)mHeaders);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Request::setClientCertificate(const std::string &cerPath, const std::string &keyPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!mValid)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
mCert = cerPath;
|
|
|
|
|
|
mKey = keyPath;
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_SSLCERT, cerPath.data());
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_SSLKEY, keyPath.data());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Request::setVerbose(bool verbose)
|
|
|
|
|
|
{
|
|
|
|
|
|
mVerbose = verbose;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Response Request::post(const std::string &url, const std::string &body,
|
|
|
|
|
|
const std::unordered_map<std::string, std::string> &headers)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!mValid)
|
|
|
|
|
|
{
|
|
|
|
|
|
return Response::ErrorResponse("http handle not valid!");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (url.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
return Response::ErrorResponse("post error, url is empty!");
|
|
|
|
|
|
}
|
|
|
|
|
|
int protocolIdx = url.find_first_of("http");
|
|
|
|
|
|
if (protocolIdx < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return Response::ErrorResponse("not http protocal find in the url!");
|
|
|
|
|
|
}
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_URL, url.data());
|
|
|
|
|
|
// https设置
|
|
|
|
|
|
if (url.length() > protocolIdx + 5 && url[protocolIdx + 4] == 's')
|
|
|
|
|
|
{
|
|
|
|
|
|
// 避免使用本地ca
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
|
|
|
|
// 关于host名验证,便于直接使用ip地址访问!!!
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYHOST, 0L);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_POST, 1L);
|
|
|
|
|
|
// CURLOPT_POSTFIELDS 不可以为空不然会有问题
|
|
|
|
|
|
if (body.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_POSTFIELDS, "");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_POSTFIELDS, body.data());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// set headers
|
|
|
|
|
|
if (!headers.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto item : headers)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::string header;
|
|
|
|
|
|
header.append(item.first);
|
|
|
|
|
|
header.append(": ");
|
|
|
|
|
|
header.append(item.second);
|
|
|
|
|
|
mHeaders = curl_slist_append((struct curl_slist *)mHeaders, header.data());
|
|
|
|
|
|
}
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaders);
|
|
|
|
|
|
}
|
|
|
|
|
|
Response resp;
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, (void *)&(resp.getContent()));
|
|
|
|
|
|
|
2024-07-31 10:51:57 +08:00
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_TIMEOUT, 6L);
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_CONNECTTIMEOUT, 6L);
|
2024-04-25 14:14:01 +08:00
|
|
|
|
if (mVerbose)
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_easy_setopt(mCurl, CURLOPT_VERBOSE, 1L);
|
|
|
|
|
|
}
|
|
|
|
|
|
CURLcode res;
|
|
|
|
|
|
/* Perform the request, res will get the return code */
|
|
|
|
|
|
res = curl_easy_perform(mCurl);
|
|
|
|
|
|
|
|
|
|
|
|
if (mHeaders)
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_slist_free_all((struct curl_slist *)mHeaders);
|
|
|
|
|
|
mHeaders = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
/* Check for errors */
|
|
|
|
|
|
if (res != CURLE_OK)
|
|
|
|
|
|
{
|
|
|
|
|
|
char buffer[4096] = {0};
|
|
|
|
|
|
sprintf(buffer, "post failed because do curl_easy_perform() failed:%s \n", curl_easy_strerror(res));
|
|
|
|
|
|
return Response::ErrorResponse(buffer);
|
|
|
|
|
|
}
|
|
|
|
|
|
long response_code;
|
|
|
|
|
|
curl_easy_getinfo(mCurl, CURLINFO_RESPONSE_CODE, &response_code);
|
|
|
|
|
|
resp.setHttpCode(response_code);
|
|
|
|
|
|
return std::move(resp);
|
|
|
|
|
|
}
|
|
|
|
|
|
void Request::Init()
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_global_init(CURL_GLOBAL_ALL);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Request::Dispose()
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_global_cleanup();
|
|
|
|
|
|
}
|