mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
update Curl.cpp
This commit is contained in:
parent
effa850337
commit
9510e06a26
1 changed files with 52 additions and 53 deletions
|
|
@ -23,27 +23,27 @@ static size_t write_callback(
|
||||||
return size * nmemb;
|
return size * nmemb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ProcessingRequest {
|
||||||
|
CURL* curl;
|
||||||
|
HttpRequest request;
|
||||||
|
std::vector<char> buffer;
|
||||||
|
};
|
||||||
|
|
||||||
class CurlRequests : public Requests {
|
class CurlRequests : public Requests {
|
||||||
CURLM* multiHandle;
|
CURLM* multiHandle;
|
||||||
CURL* curl;
|
std::vector<std::unique_ptr<ProcessingRequest>> requests;
|
||||||
|
|
||||||
size_t totalUpload = 0;
|
size_t totalUpload = 0;
|
||||||
size_t totalDownload = 0;
|
size_t totalDownload = 0;
|
||||||
|
|
||||||
OnResponse onResponse;
|
|
||||||
OnReject onReject;
|
|
||||||
std::vector<char> buffer;
|
|
||||||
std::string url;
|
|
||||||
|
|
||||||
std::queue<HttpRequest> requests;
|
|
||||||
public:
|
public:
|
||||||
CurlRequests(CURLM* multiHandle, CURL* curl)
|
CurlRequests(CURLM* multiHandle) : multiHandle(multiHandle) {
|
||||||
: multiHandle(multiHandle), curl(curl) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~CurlRequests() {
|
virtual ~CurlRequests() {
|
||||||
curl_multi_remove_handle(multiHandle, curl);
|
for (auto& entry : requests) {
|
||||||
curl_easy_cleanup(curl);
|
curl_multi_remove_handle(multiHandle, entry->curl);
|
||||||
|
curl_easy_cleanup(entry->curl);
|
||||||
|
}
|
||||||
curl_multi_cleanup(multiHandle);
|
curl_multi_cleanup(multiHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,17 +52,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void processRequest(HttpRequest request) {
|
void processRequest(HttpRequest request) {
|
||||||
if (!url.empty()) {
|
auto curl = curl_easy_init();
|
||||||
requests.push(request);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
onResponse = request.onResponse;
|
|
||||||
onReject = request.onReject;
|
|
||||||
url = request.url;
|
|
||||||
|
|
||||||
buffer.clear();
|
auto entry = std::make_unique<ProcessingRequest>();
|
||||||
|
entry->curl = curl;
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
curl_easy_setopt(curl, CURLOPT_URL, request.url.c_str());
|
||||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, request.method.c_str());
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, request.method.c_str());
|
||||||
|
|
||||||
curl_slist* hs = nullptr;
|
curl_slist* hs = nullptr;
|
||||||
|
|
@ -80,7 +75,7 @@ public:
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);
|
||||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, request.followLocation);
|
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, request.followLocation);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &entry->buffer);
|
||||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.81.0");
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.81.0");
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
|
|
@ -97,12 +92,13 @@ public:
|
||||||
CURLMcode res = curl_multi_perform(multiHandle, &running);
|
CURLMcode res = curl_multi_perform(multiHandle, &running);
|
||||||
if (res != CURLM_OK) {
|
if (res != CURLM_OK) {
|
||||||
auto message = curl_multi_strerror(res);
|
auto message = curl_multi_strerror(res);
|
||||||
logger.error() << message << " (" << url << ")";
|
logger.error() << message << " (" << request.url << ")";
|
||||||
if (onReject) {
|
if (request.onReject) {
|
||||||
onReject(HTTP_BAD_GATEWAY, {});
|
request.onReject(HTTP_BAD_GATEWAY, {});
|
||||||
}
|
}
|
||||||
url = "";
|
|
||||||
}
|
}
|
||||||
|
entry->request = std::move(request);
|
||||||
|
requests.push_back(std::move(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void update() override {
|
void update() override {
|
||||||
|
|
@ -112,15 +108,24 @@ public:
|
||||||
CURLMcode res = curl_multi_perform(multiHandle, &running);
|
CURLMcode res = curl_multi_perform(multiHandle, &running);
|
||||||
if (res != CURLM_OK) {
|
if (res != CURLM_OK) {
|
||||||
auto message = curl_multi_strerror(res);
|
auto message = curl_multi_strerror(res);
|
||||||
logger.error() << message << " (" << url << ")";
|
logger.error() << message;
|
||||||
if (onReject) {
|
|
||||||
onReject(HTTP_BAD_GATEWAY, {});
|
|
||||||
}
|
|
||||||
curl_multi_remove_handle(multiHandle, curl);
|
|
||||||
url = "";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((msg = curl_multi_info_read(multiHandle, &messagesLeft)) != nullptr) {
|
if ((msg = curl_multi_info_read(multiHandle, &messagesLeft)) != nullptr) {
|
||||||
|
auto curl = msg->easy_handle;
|
||||||
|
auto found = std::find_if(
|
||||||
|
requests.begin(), requests.end(),
|
||||||
|
[curl](const std::unique_ptr<ProcessingRequest>& entry) {
|
||||||
|
return entry->curl == curl;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (found == requests.end()) {
|
||||||
|
logger.error() << "could not find request for cURL handle";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& entry = *found;
|
||||||
|
auto& req = entry->request;
|
||||||
|
|
||||||
if(msg->msg == CURLMSG_DONE) {
|
if(msg->msg == CURLMSG_DONE) {
|
||||||
curl_multi_remove_handle(multiHandle, curl);
|
curl_multi_remove_handle(multiHandle, curl);
|
||||||
}
|
}
|
||||||
|
|
@ -135,15 +140,15 @@ public:
|
||||||
if (!curl_easy_getinfo(curl, CURLINFO_HEADER_SIZE, &size)) {
|
if (!curl_easy_getinfo(curl, CURLINFO_HEADER_SIZE, &size)) {
|
||||||
totalDownload += size;
|
totalDownload += size;
|
||||||
}
|
}
|
||||||
totalDownload += buffer.size();
|
totalDownload += entry->buffer.size();
|
||||||
if (onResponse) {
|
if (req.onResponse) {
|
||||||
onResponse(std::move(buffer));
|
req.onResponse(std::move(entry->buffer));
|
||||||
}
|
}
|
||||||
} else if (response == 0) {
|
} else if (response == 0) {
|
||||||
auto message = std::string(curl_easy_strerror(result));
|
auto message = std::string(curl_easy_strerror(result));
|
||||||
logger.error() << message << " (" << url << ")";
|
logger.error() << message << " (" << req.url << ")";
|
||||||
if (onReject) {
|
if (req.onReject) {
|
||||||
onReject(
|
req.onReject(
|
||||||
response,
|
response,
|
||||||
std::vector<char>(
|
std::vector<char>(
|
||||||
message.data(), message.data() + message.size()
|
message.data(), message.data() + message.size()
|
||||||
|
|
@ -152,21 +157,15 @@ public:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error()
|
logger.error()
|
||||||
<< "response code " << response << " (" << url << ")"
|
<< "response code " << response << " (" << req.url << ")"
|
||||||
<< (buffer.empty()
|
<< (entry->buffer.empty()
|
||||||
? ""
|
? ""
|
||||||
: std::to_string(buffer.size()) + " byte(s)");
|
: std::to_string(entry->buffer.size()) + " byte(s)");
|
||||||
totalDownload += buffer.size();
|
totalDownload += entry->buffer.size();
|
||||||
if (onReject) {
|
if (req.onReject) {
|
||||||
onReject(response, std::move(buffer));
|
req.onReject(response, std::move(entry->buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
url = "";
|
|
||||||
}
|
|
||||||
if (url.empty() && !requests.empty()) {
|
|
||||||
auto request = std::move(requests.front());
|
|
||||||
requests.pop();
|
|
||||||
processRequest(std::move(request));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,14 +180,14 @@ public:
|
||||||
static std::unique_ptr<CurlRequests> create() {
|
static std::unique_ptr<CurlRequests> create() {
|
||||||
auto curl = curl_easy_init();
|
auto curl = curl_easy_init();
|
||||||
if (curl == nullptr) {
|
if (curl == nullptr) {
|
||||||
throw std::runtime_error("could not initialzie cURL");
|
throw std::runtime_error("could not initialize cURL");
|
||||||
}
|
}
|
||||||
auto multiHandle = curl_multi_init();
|
auto multiHandle = curl_multi_init();
|
||||||
if (multiHandle == nullptr) {
|
if (multiHandle == nullptr) {
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
throw std::runtime_error("could not initialzie cURL-multi");
|
throw std::runtime_error("could not initialize cURL-multi");
|
||||||
}
|
}
|
||||||
return std::make_unique<CurlRequests>(multiHandle, curl);
|
return std::make_unique<CurlRequests>(multiHandle);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue