Mercurial > minori
diff src/core/http.cc @ 291:9a88e1725fd2
*: refactor lots of stuff
I forgot to put this into different commits, oops!
anyway, it doesn't really matter *that* much since this is an
unfinished hobby project anyway. once it starts getting stable
commit history will be more important, but for now it's not
that big of a deal
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sun, 12 May 2024 16:31:07 -0400 |
parents | 862d0d8619f6 |
children | b1f625b0227c |
line wrap: on
line diff
--- a/src/core/http.cc Wed May 08 17:32:28 2024 -0400 +++ b/src/core/http.cc Sun May 12 16:31:07 2024 -0400 @@ -13,16 +13,18 @@ return size * nmemb; } -QByteArray Get(const std::string& url, const std::vector<std::string>& headers) { +QByteArray Request(const std::string& url, const std::vector<std::string>& headers, const std::string& data, Type type) { struct curl_slist* list = NULL; QByteArray userdata; CURL* curl = curl_easy_init(); if (curl) { - for (const std::string& h : headers) { + for (const std::string& h : headers) list = curl_slist_append(list, h.c_str()); - } + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + if (type == Type::Post) + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &userdata); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback); @@ -38,30 +40,99 @@ return userdata; } -QByteArray Post(const std::string& url, const std::string& data, const std::vector<std::string>& headers) { +/* this function is static */ +size_t RequestThread::WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { + RequestThread* thread = reinterpret_cast<RequestThread*>(userdata); + + const std::lock_guard<std::mutex> lock(thread->callback_data_mutex_); + + /* stop writing, then! */ + if (thread->cancelled_) + return CURL_WRITEFUNC_ERROR; + + /* else, continue on as normal */ + thread->array_.append(reinterpret_cast<char*>(contents), size * nmemb); + return size * nmemb; +} + +RequestThread::RequestThread(Type type, QObject* parent) : QThread(parent) { + SetType(type); +} + +RequestThread::RequestThread(const std::string& url, const std::vector<std::string>& headers, + const std::string& data, Type type, QObject* parent) + : QThread(parent) { + SetUrl(url); + SetData(data); + SetHeaders(headers); + SetType(type); +} + +RequestThread::~RequestThread() { + /* block until the function can safely exit. + * + * this sucks. find out a better way to do this, which will probably + * be to put all of the threads in a pool */ + Stop(); + wait(); +} + +void RequestThread::SetUrl(const std::string& url) { + url_ = url; +} + +void RequestThread::SetHeaders(const std::vector<std::string>& headers) { + headers_ = headers; +} + +void RequestThread::SetData(const std::string& data) { + data_ = data; +} + +void RequestThread::SetType(Type type) { + type_ = type; +} + +void RequestThread::run() { struct curl_slist* list = NULL; - QByteArray userdata; CURL* curl = curl_easy_init(); if (curl) { - for (const std::string& h : headers) { + curl_easy_setopt(curl, CURLOPT_URL, url_.c_str()); + + if (type_ == Type::Post) + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data_.c_str()); + + for (const std::string& h : headers_) list = curl_slist_append(list, h.c_str()); - } - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &userdata); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback); + + curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RequestThread::WriteCallback); + /* Use system certs... useful on Windows. */ curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // threading + + /* does something with threading, don't remember what though */ + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + CURLcode res = curl_easy_perform(curl); session.IncrementRequests(); curl_easy_cleanup(curl); - if (res != CURLE_OK) + + callback_data_mutex_.lock(); + if (res != CURLE_OK && !(res == CURLE_WRITE_ERROR && cancelled_)) std::cerr << "curl_easy_perform(curl) failed!: " << curl_easy_strerror(res) << std::endl; + callback_data_mutex_.unlock(); } - return userdata; + + emit ReceivedData(array_); + array_.clear(); +} + +void RequestThread::Stop() { + const std::lock_guard<std::mutex> lock(callback_data_mutex_); + cancelled_ = true; } } // namespace HTTP