emailQt/CurlHandler.cpp

105 lines
3.3 KiB
C++
Raw Permalink Normal View History

2024-03-08 12:10:58 -05:00
#include "CurlHandler.hpp"
CurlHandler::CurlHandler()
: initialRes{}, initialCurl(curl_easy_init(), curl_easy_cleanup) {
}
CurlHandler::~CurlHandler() {
for (auto &t: v)
2024-03-08 12:10:58 -05:00
t.join();
}
void CurlHandler::configure(const ParametersProvider::settings &sett) {
url.append("imaps://");
url += sett.imapS;
url += "/INBOX?ALL";
setts = sett;
2024-12-19 18:51:41 -05:00
setupCurl(initialCurl.get(), initialChunk, url);
2024-03-08 12:10:58 -05:00
}
std::vector<std::string> *CurlHandler::fetch() {
initialRes = curl_easy_perform(initialCurl.get());
if (initialRes != CURLE_OK) {
return &decodedMessages;
}
// We prepare to query the server.
url.erase(url.end() - 4, url.end());
url += "/;MAILINDEX=";
std::string temp;
std::stringstream s(initialChunk);
size_t count = 0;
while (getline(s, temp, ' ')) {
// SELECT and *
if (count < 2) {
count++;
continue;
}
messagesId.emplace_back(temp);
}
// We will query the server number by number.
// The messagesId vector contains all Email GUIDs.
v.reserve(messagesId.size());
decodedMessages.resize(messagesId.size());
count = 0;
2024-12-19 18:51:41 -05:00
// 10 messages max
// By default, even if the thread's function parameter specifies a reference,
// a copy is made. To specify that you want a reference, use std::ref.
for (auto i{messagesId.rbegin()}; i != messagesId.rbegin() + 10 && i != messagesId.rend(); ++i)
2024-03-08 12:10:58 -05:00
v.emplace_back(&CurlHandler::query, this, std::ref(*i), count++);
return &decodedMessages;
}
void CurlHandler::query(std::string &c, size_t count) {
2024-12-19 18:51:41 -05:00
std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> localCurl(curl_easy_init(), curl_easy_cleanup);
2024-03-08 12:10:58 -05:00
CURLcode localCode;
c.erase(std::remove(c.begin(), c.end(), '\r'), c.end());
c.erase(std::remove(c.begin(), c.end(), '\n'), c.end());
2024-12-19 18:51:41 -05:00
setupCurl(localCurl.get(), decodedMessages[count], url + c);
2024-03-08 12:10:58 -05:00
localCode = curl_easy_perform(localCurl.get());
if (localCode != CURLE_OK) {
// ...
}
emit threadFinished(count, std::stoi(c));
}
2024-12-19 18:51:41 -05:00
void CurlHandler::setupCurl(CURL *ptr, std::string &m, std::string const &ur) const {
curl_easy_setopt(ptr, CURLOPT_USERNAME, setts.userS.c_str());
curl_easy_setopt(ptr, CURLOPT_PASSWORD, setts.passS.c_str());
2024-03-08 12:10:58 -05:00
2024-12-19 18:51:41 -05:00
curl_easy_setopt(ptr, CURLOPT_PORT, setts.port);
curl_easy_setopt(ptr, CURLOPT_TIMEOUT, curlTimeoutSeconds);
2024-03-08 12:10:58 -05:00
// The callback function will receive the string ref as its userdata
// and therefore save the data there.
2024-12-19 18:51:41 -05:00
curl_easy_setopt(ptr, CURLOPT_USE_SSL, (long) CURLUSESSL_ALL);
curl_easy_setopt(ptr, CURLOPT_WRITEDATA, (void *) &m);
curl_easy_setopt(ptr, CURLOPT_WRITEFUNCTION, cb);
2024-03-08 12:10:58 -05:00
// Necessary on some servers
2024-12-19 18:51:41 -05:00
curl_easy_setopt(ptr, CURLOPT_USERAGENT, "libcurl-agent/1.0");
2024-03-08 12:10:58 -05:00
2024-12-19 18:51:41 -05:00
curl_easy_setopt(ptr, CURLOPT_URL, ur.c_str());
2024-03-08 12:10:58 -05:00
#ifdef DEBUG
2024-12-19 18:51:41 -05:00
curl_easy_setopt(ptr, CURLOPT_VERBOSE, 1L);
2024-03-08 12:10:58 -05:00
#else
curl_easy_setopt(ptr.get(), CURLOPT_VERBOSE, 0L);
#endif
}
size_t cb(char *data, size_t size, size_t numberOfMembers, void *userdata) {
size_t realSize = size * numberOfMembers;
2024-12-19 18:51:41 -05:00
auto *mem = static_cast<std::string *> (userdata);
2024-03-08 12:10:58 -05:00
mem->append(data, realSize);
return realSize;
}