Files
GUI/src/recon/Request.cpp

155 lines
3.9 KiB
C++
Raw Normal View History

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()));
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();
}