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 |