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