]> git.sur5r.net Git - minitube/blob - lib/http/src/http.cpp
New upstream version 3.9.1
[minitube] / lib / http / src / http.cpp
1 #include "http.h"
2
3 #include "networkhttpreply.h"
4
5 namespace {
6
7 QNetworkAccessManager *networkAccessManager() {
8     static thread_local QNetworkAccessManager *nam = [] {
9         auto nam = new QNetworkAccessManager();
10 #if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
11         nam->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
12 #endif
13         return nam;
14     }();
15     return nam;
16 }
17
18 int defaultReadTimeout = 10000;
19 int defaultMaxRetries = 3;
20 } // namespace
21
22 Http::Http()
23     : requestHeaders(getDefaultRequestHeaders()), readTimeout(defaultReadTimeout),
24       maxRetries(defaultMaxRetries) {}
25
26 void Http::setRequestHeaders(const QMap<QByteArray, QByteArray> &headers) {
27     requestHeaders = headers;
28 }
29
30 QMap<QByteArray, QByteArray> &Http::getRequestHeaders() {
31     return requestHeaders;
32 }
33
34 void Http::addRequestHeader(const QByteArray &name, const QByteArray &value) {
35     requestHeaders.insert(name, value);
36 }
37
38 void Http::setReadTimeout(int timeout) {
39     readTimeout = timeout;
40 }
41
42 Http &Http::instance() {
43     static Http i;
44     return i;
45 }
46
47 const QMap<QByteArray, QByteArray> &Http::getDefaultRequestHeaders() {
48     static const QMap<QByteArray, QByteArray> defaultRequestHeaders = [] {
49         QMap<QByteArray, QByteArray> h;
50         h.insert("Accept-Charset", "utf-8");
51         h.insert("Connection", "Keep-Alive");
52         return h;
53     }();
54     return defaultRequestHeaders;
55 }
56
57 void Http::setDefaultReadTimeout(int timeout) {
58     defaultReadTimeout = timeout;
59 }
60
61 QNetworkReply *Http::networkReply(const HttpRequest &req) {
62     QNetworkRequest request(req.url);
63
64     QMap<QByteArray, QByteArray> &headers = requestHeaders;
65     if (!req.headers.isEmpty()) headers = req.headers;
66
67     QMap<QByteArray, QByteArray>::const_iterator it;
68     for (it = headers.constBegin(); it != headers.constEnd(); ++it)
69         request.setRawHeader(it.key(), it.value());
70
71     if (req.offset > 0)
72         request.setRawHeader("Range", QStringLiteral("bytes=%1-").arg(req.offset).toUtf8());
73
74     QNetworkAccessManager *manager = networkAccessManager();
75
76     QNetworkReply *networkReply = nullptr;
77     switch (req.operation) {
78     case QNetworkAccessManager::GetOperation:
79         networkReply = manager->get(request);
80         break;
81
82     case QNetworkAccessManager::HeadOperation:
83         networkReply = manager->head(request);
84         break;
85
86     case QNetworkAccessManager::PostOperation:
87         networkReply = manager->post(request, req.body);
88         break;
89
90     case QNetworkAccessManager::PutOperation:
91         networkReply = manager->put(request, req.body);
92         break;
93
94     case QNetworkAccessManager::DeleteOperation:
95         networkReply = manager->deleteResource(request);
96         break;
97
98     default:
99         qWarning() << "Unknown operation:" << req.operation;
100     }
101
102     return networkReply;
103 }
104
105 HttpReply *Http::request(const HttpRequest &req) {
106     return new NetworkHttpReply(req, *this);
107 }
108
109 HttpReply *Http::request(const QUrl &url,
110                          QNetworkAccessManager::Operation operation,
111                          const QByteArray &body,
112                          uint offset) {
113     HttpRequest req;
114     req.url = url;
115     req.operation = operation;
116     req.body = body;
117     req.offset = offset;
118     return request(req);
119 }
120
121 HttpReply *Http::get(const QUrl &url) {
122     return request(url, QNetworkAccessManager::GetOperation);
123 }
124
125 HttpReply *Http::head(const QUrl &url) {
126     return request(url, QNetworkAccessManager::HeadOperation);
127 }
128
129 HttpReply *Http::post(const QUrl &url, const QMap<QString, QString> &params) {
130     QByteArray body;
131     QMapIterator<QString, QString> i(params);
132     while (i.hasNext()) {
133         i.next();
134         body += QUrl::toPercentEncoding(i.key()) + '=' + QUrl::toPercentEncoding(i.value()) + '&';
135     }
136     HttpRequest req;
137     req.url = url;
138     req.operation = QNetworkAccessManager::PostOperation;
139     req.body = body;
140     req.headers = requestHeaders;
141     req.headers.insert("Content-Type", "application/x-www-form-urlencoded");
142     return request(req);
143 }
144
145 HttpReply *Http::post(const QUrl &url, const QByteArray &body, const QByteArray &contentType) {
146     HttpRequest req;
147     req.url = url;
148     req.operation = QNetworkAccessManager::PostOperation;
149     req.body = body;
150     req.headers = requestHeaders;
151     QByteArray cType = contentType;
152     if (cType.isEmpty()) cType = "application/x-www-form-urlencoded";
153     req.headers.insert("Content-Type", cType);
154     return request(req);
155 }
156
157
158 HttpReply *Http::put(const QUrl &url, const QByteArray &body, const QByteArray &contentType) {
159         HttpRequest req;
160         req.url = url;
161         req.operation = QNetworkAccessManager::PutOperation;
162         req.body = body;
163         req.headers = requestHeaders;
164         QByteArray cType = contentType;
165         if (cType.isEmpty()) cType = "application/x-www-form-urlencoded";
166         req.headers.insert("Content-Type", cType);
167         return request(req);
168 }
169
170
171 HttpReply *Http::deleteResource(const QUrl &url) {
172         HttpRequest req;
173         req.url = url;
174         req.operation = QNetworkAccessManager::DeleteOperation;
175         req.headers = requestHeaders;
176         return request(req);
177 }
178
179 int Http::getMaxRetries() const {
180     return maxRetries;
181 }
182
183 void Http::setMaxRetries(int value) {
184     maxRetries = value;
185 }