Files
GUI/src/recon/Request.cpp
2024-08-01 13:29:37 +08:00

155 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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