Mercurial > minori
annotate src/core/http.cc @ 300:8eb0cfe59992
CI/windows: attempt to fix the build
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Mon, 13 May 2024 14:56:37 -0400 |
parents | 9a88e1725fd2 |
children | b1f625b0227c |
rev | line source |
---|---|
75 | 1 #include "core/http.h" |
2 #include "core/session.h" | |
3 #include <QByteArray> | |
4 #include <curl/curl.h> | |
258 | 5 #include <iostream> |
75 | 6 #include <string> |
7 #include <vector> | |
8 | |
9 namespace HTTP { | |
10 | |
77 | 11 static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userdata) { |
75 | 12 reinterpret_cast<QByteArray*>(userdata)->append(reinterpret_cast<char*>(contents), size * nmemb); |
13 return size * nmemb; | |
14 } | |
15 | |
291 | 16 QByteArray Request(const std::string& url, const std::vector<std::string>& headers, const std::string& data, Type type) { |
75 | 17 struct curl_slist* list = NULL; |
18 QByteArray userdata; | |
19 | |
20 CURL* curl = curl_easy_init(); | |
21 if (curl) { | |
291 | 22 for (const std::string& h : headers) |
75 | 23 list = curl_slist_append(list, h.c_str()); |
291 | 24 |
77 | 25 curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); |
291 | 26 if (type == Type::Post) |
27 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); | |
77 | 28 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); |
75 | 29 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &userdata); |
30 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &WriteCallback); | |
31 /* Use system certs... useful on Windows. */ | |
32 curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); | |
221
53211cb1e7f5
library: add initial library stuff
Paper <paper@paper.us.eu.org>
parents:
175
diff
changeset
|
33 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // threading |
75 | 34 CURLcode res = curl_easy_perform(curl); |
35 session.IncrementRequests(); | |
36 curl_easy_cleanup(curl); | |
175 | 37 if (res != CURLE_OK) |
38 std::cerr << "curl_easy_perform(curl) failed!: " << curl_easy_strerror(res) << std::endl; | |
75 | 39 } |
77 | 40 return userdata; |
75 | 41 } |
42 | |
291 | 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() { | |
77 | 97 struct curl_slist* list = NULL; |
75 | 98 |
99 CURL* curl = curl_easy_init(); | |
100 if (curl) { | |
291 | 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_) | |
75 | 107 list = curl_slist_append(list, h.c_str()); |
108 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); | |
291 | 109 |
110 curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); | |
111 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &RequestThread::WriteCallback); | |
112 | |
75 | 113 /* Use system certs... useful on Windows. */ |
114 curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); | |
291 | 115 |
116 /* does something with threading, don't remember what though */ | |
117 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); | |
118 | |
75 | 119 CURLcode res = curl_easy_perform(curl); |
120 session.IncrementRequests(); | |
121 curl_easy_cleanup(curl); | |
291 | 122 |
123 callback_data_mutex_.lock(); | |
124 if (res != CURLE_OK && !(res == CURLE_WRITE_ERROR && cancelled_)) | |
175 | 125 std::cerr << "curl_easy_perform(curl) failed!: " << curl_easy_strerror(res) << std::endl; |
291 | 126 callback_data_mutex_.unlock(); |
75 | 127 } |
291 | 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; | |
75 | 136 } |
137 | |
76 | 138 } // namespace HTTP |