annotate src/core/http.cc @ 313:3775ffa15ba4

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