Mercurial > minori
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 290:9347e2eaf6e5 | 291:9a88e1725fd2 |
|---|---|
| 11 static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { | 11 static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { |
| 12 reinterpret_cast<QByteArray*>(userdata)->append(reinterpret_cast<char*>(contents), size * nmemb); | 12 reinterpret_cast<QByteArray*>(userdata)->append(reinterpret_cast<char*>(contents), size * nmemb); |
| 13 return size * nmemb; | 13 return size * nmemb; |
| 14 } | 14 } |
| 15 | 15 |
| 16 QByteArray Get(const std::string& url, const std::vector<std::string>& headers) { | 16 QByteArray Request(const std::string& url, const std::vector<std::string>& headers, const std::string& data, Type type) { |
| 17 struct curl_slist* list = NULL; | 17 struct curl_slist* list = NULL; |
| 18 QByteArray userdata; | 18 QByteArray userdata; |
| 19 | 19 |
| 20 CURL* curl = curl_easy_init(); | 20 CURL* curl = curl_easy_init(); |
| 21 if (curl) { | 21 if (curl) { |
| 22 for (const std::string& h : headers) { | 22 for (const std::string& h : headers) |
| 23 list = curl_slist_append(list, h.c_str()); | 23 list = curl_slist_append(list, h.c_str()); |
| 24 } | 24 |
| 25 curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | 25 curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); |
| 26 if (type == Type::Post) | |
| 27 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); | |
| 26 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); | 28 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); |
| 27 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &userdata); | 29 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &userdata); |
| 28 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback); | 30 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback); |
| 29 /* Use system certs... useful on Windows. */ | 31 /* Use system certs... useful on Windows. */ |
| 30 curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); | 32 curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); |
| 36 std::cerr << "curl_easy_perform(curl) failed!: " << curl_easy_strerror(res) << std::endl; | 38 std::cerr << "curl_easy_perform(curl) failed!: " << curl_easy_strerror(res) << std::endl; |
| 37 } | 39 } |
| 38 return userdata; | 40 return userdata; |
| 39 } | 41 } |
| 40 | 42 |
| 41 QByteArray Post(const std::string& url, const std::string& data, const std::vector<std::string>& headers) { | 43 /* this function is static */ |
| 44 size_t RequestThread::WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { | |
| 45 RequestThread* thread = reinterpret_cast<RequestThread*>(userdata); | |
| 46 | |
| 47 const std::lock_guard<std::mutex> lock(thread->callback_data_mutex_); | |
| 48 | |
| 49 /* stop writing, then! */ | |
| 50 if (thread->cancelled_) | |
| 51 return CURL_WRITEFUNC_ERROR; | |
| 52 | |
| 53 /* else, continue on as normal */ | |
| 54 thread->array_.append(reinterpret_cast<char*>(contents), size * nmemb); | |
| 55 return size * nmemb; | |
| 56 } | |
| 57 | |
| 58 RequestThread::RequestThread(Type type, QObject* parent) : QThread(parent) { | |
| 59 SetType(type); | |
| 60 } | |
| 61 | |
| 62 RequestThread::RequestThread(const std::string& url, const std::vector<std::string>& headers, | |
| 63 const std::string& data, Type type, QObject* parent) | |
| 64 : QThread(parent) { | |
| 65 SetUrl(url); | |
| 66 SetData(data); | |
| 67 SetHeaders(headers); | |
| 68 SetType(type); | |
| 69 } | |
| 70 | |
| 71 RequestThread::~RequestThread() { | |
| 72 /* block until the function can safely exit. | |
| 73 * | |
| 74 * this sucks. find out a better way to do this, which will probably | |
| 75 * be to put all of the threads in a pool */ | |
| 76 Stop(); | |
| 77 wait(); | |
| 78 } | |
| 79 | |
| 80 void RequestThread::SetUrl(const std::string& url) { | |
| 81 url_ = url; | |
| 82 } | |
| 83 | |
| 84 void RequestThread::SetHeaders(const std::vector<std::string>& headers) { | |
| 85 headers_ = headers; | |
| 86 } | |
| 87 | |
| 88 void RequestThread::SetData(const std::string& data) { | |
| 89 data_ = data; | |
| 90 } | |
| 91 | |
| 92 void RequestThread::SetType(Type type) { | |
| 93 type_ = type; | |
| 94 } | |
| 95 | |
| 96 void RequestThread::run() { | |
| 42 struct curl_slist* list = NULL; | 97 struct curl_slist* list = NULL; |
| 43 QByteArray userdata; | |
| 44 | 98 |
| 45 CURL* curl = curl_easy_init(); | 99 CURL* curl = curl_easy_init(); |
| 46 if (curl) { | 100 if (curl) { |
| 47 for (const std::string& h : headers) { | 101 curl_easy_setopt(curl, CURLOPT_URL, url_.c_str()); |
| 102 | |
| 103 if (type_ == Type::Post) | |
| 104 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data_.c_str()); | |
| 105 | |
| 106 for (const std::string& h : headers_) | |
| 48 list = curl_slist_append(list, h.c_str()); | 107 list = curl_slist_append(list, h.c_str()); |
| 49 } | |
| 50 curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | |
| 51 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); | |
| 52 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); | 108 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); |
| 53 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &userdata); | 109 |
| 54 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback); | 110 curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); |
| 111 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RequestThread::WriteCallback); | |
| 112 | |
| 55 /* Use system certs... useful on Windows. */ | 113 /* Use system certs... useful on Windows. */ |
| 56 curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); | 114 curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); |
| 57 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // threading | 115 |
| 116 /* does something with threading, don't remember what though */ | |
| 117 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); | |
| 118 | |
| 58 CURLcode res = curl_easy_perform(curl); | 119 CURLcode res = curl_easy_perform(curl); |
| 59 session.IncrementRequests(); | 120 session.IncrementRequests(); |
| 60 curl_easy_cleanup(curl); | 121 curl_easy_cleanup(curl); |
| 61 if (res != CURLE_OK) | 122 |
| 123 callback_data_mutex_.lock(); | |
| 124 if (res != CURLE_OK && !(res == CURLE_WRITE_ERROR && cancelled_)) | |
| 62 std::cerr << "curl_easy_perform(curl) failed!: " << curl_easy_strerror(res) << std::endl; | 125 std::cerr << "curl_easy_perform(curl) failed!: " << curl_easy_strerror(res) << std::endl; |
| 126 callback_data_mutex_.unlock(); | |
| 63 } | 127 } |
| 64 return userdata; | 128 |
| 129 emit ReceivedData(array_); | |
| 130 array_.clear(); | |
| 131 } | |
| 132 | |
| 133 void RequestThread::Stop() { | |
| 134 const std::lock_guard<std::mutex> lock(callback_data_mutex_); | |
| 135 cancelled_ = true; | |
| 65 } | 136 } |
| 66 | 137 |
| 67 } // namespace HTTP | 138 } // namespace HTTP |
