105 lines
3.3 KiB
C++
Executable File
105 lines
3.3 KiB
C++
Executable File
#include "CurlHandler.hpp"
|
|
|
|
CurlHandler::CurlHandler()
|
|
: initialRes{}, initialCurl(curl_easy_init(), curl_easy_cleanup) {
|
|
}
|
|
|
|
CurlHandler::~CurlHandler() {
|
|
for (auto &t: v)
|
|
t.join();
|
|
}
|
|
|
|
void CurlHandler::configure(const ParametersProvider::settings &sett) {
|
|
url.append("imaps://");
|
|
url += sett.imapS;
|
|
url += "/INBOX?ALL";
|
|
setts = sett;
|
|
|
|
setupCurl(initialCurl.get(), initialChunk, url);
|
|
}
|
|
|
|
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;
|
|
|
|
// 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)
|
|
v.emplace_back(&CurlHandler::query, this, std::ref(*i), count++);
|
|
|
|
return &decodedMessages;
|
|
}
|
|
|
|
void CurlHandler::query(std::string &c, size_t count) {
|
|
std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> localCurl(curl_easy_init(), curl_easy_cleanup);
|
|
CURLcode localCode;
|
|
c.erase(std::remove(c.begin(), c.end(), '\r'), c.end());
|
|
c.erase(std::remove(c.begin(), c.end(), '\n'), c.end());
|
|
setupCurl(localCurl.get(), decodedMessages[count], url + c);
|
|
|
|
localCode = curl_easy_perform(localCurl.get());
|
|
if (localCode != CURLE_OK) {
|
|
// ...
|
|
}
|
|
|
|
emit threadFinished(count, std::stoi(c));
|
|
}
|
|
|
|
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());
|
|
|
|
curl_easy_setopt(ptr, CURLOPT_PORT, setts.port);
|
|
curl_easy_setopt(ptr, CURLOPT_TIMEOUT, curlTimeoutSeconds);
|
|
|
|
// The callback function will receive the string ref as its userdata
|
|
// and therefore save the data there.
|
|
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);
|
|
|
|
// Necessary on some servers
|
|
curl_easy_setopt(ptr, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
|
|
|
curl_easy_setopt(ptr, CURLOPT_URL, ur.c_str());
|
|
|
|
#ifdef DEBUG
|
|
curl_easy_setopt(ptr, CURLOPT_VERBOSE, 1L);
|
|
#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;
|
|
auto *mem = static_cast<std::string *> (userdata);
|
|
mem->append(data, realSize);
|
|
return realSize;
|
|
}
|