1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qhttpnetworkrequest_p.h"
5#include "private/qnoncontiguousbytedevice_p.h"
6
7QT_BEGIN_NAMESPACE
8
9QT_IMPL_METATYPE_EXTERN(QHttpNetworkRequest)
10
11QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op,
12 QHttpNetworkRequest::Priority pri, const QUrl &newUrl)
13 : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(nullptr),
14 autoDecompress(false), pipeliningAllowed(false), http2Allowed(true),
15 http2Direct(false), withCredentials(true), preConnect(false), redirectCount(0),
16 redirectPolicy(QNetworkRequest::ManualRedirectPolicy)
17{
18}
19
20QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other) // = default
21 : QHttpNetworkHeaderPrivate(other),
22 operation(other.operation),
23 customVerb(other.customVerb),
24 priority(other.priority),
25 uploadByteDevice(other.uploadByteDevice),
26 autoDecompress(other.autoDecompress),
27 pipeliningAllowed(other.pipeliningAllowed),
28 http2Allowed(other.http2Allowed),
29 http2Direct(other.http2Direct),
30 h2cAllowed(other.h2cAllowed),
31 withCredentials(other.withCredentials),
32 ssl(other.ssl),
33 preConnect(other.preConnect),
34 needResendWithCredentials(other.needResendWithCredentials),
35 redirectCount(other.redirectCount),
36 redirectPolicy(other.redirectPolicy),
37 peerVerifyName(other.peerVerifyName)
38{
39}
40
41QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate()
42{
43}
44
45bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &other) const
46{
47 return QHttpNetworkHeaderPrivate::operator==(other)
48 && (operation == other.operation)
49 && (priority == other.priority)
50 && (uploadByteDevice == other.uploadByteDevice)
51 && (autoDecompress == other.autoDecompress)
52 && (pipeliningAllowed == other.pipeliningAllowed)
53 && (http2Allowed == other.http2Allowed)
54 && (http2Direct == other.http2Direct)
55 && (h2cAllowed == other.h2cAllowed)
56 // we do not clear the customVerb in setOperation
57 && (operation != QHttpNetworkRequest::Custom || (customVerb == other.customVerb))
58 && (withCredentials == other.withCredentials)
59 && (ssl == other.ssl)
60 && (preConnect == other.preConnect)
61 && (redirectPolicy == other.redirectPolicy)
62 && (peerVerifyName == other.peerVerifyName)
63 && (needResendWithCredentials == other.needResendWithCredentials)
64 ;
65}
66
67QByteArray QHttpNetworkRequest::methodName() const
68{
69 switch (d->operation) {
70 case QHttpNetworkRequest::Get:
71 return "GET";
72 case QHttpNetworkRequest::Head:
73 return "HEAD";
74 case QHttpNetworkRequest::Post:
75 return "POST";
76 case QHttpNetworkRequest::Options:
77 return "OPTIONS";
78 case QHttpNetworkRequest::Put:
79 return "PUT";
80 case QHttpNetworkRequest::Delete:
81 return "DELETE";
82 case QHttpNetworkRequest::Trace:
83 return "TRACE";
84 case QHttpNetworkRequest::Connect:
85 return "CONNECT";
86 case QHttpNetworkRequest::Custom:
87 return d->customVerb;
88 default:
89 break;
90 }
91 return QByteArray();
92}
93
94QByteArray QHttpNetworkRequest::uri(bool throughProxy) const
95{
96 QUrl::FormattingOptions format(QUrl::RemoveFragment | QUrl::RemoveUserInfo | QUrl::FullyEncoded);
97
98 // for POST, query data is sent as content
99 if (d->operation == QHttpNetworkRequest::Post && !d->uploadByteDevice)
100 format |= QUrl::RemoveQuery;
101 // for requests through proxy, the Request-URI contains full url
102 if (!throughProxy)
103 format |= QUrl::RemoveScheme | QUrl::RemoveAuthority;
104 QUrl copy = d->url;
105 if (copy.path().isEmpty())
106 copy.setPath(QStringLiteral("/"));
107 else
108 format |= QUrl::NormalizePathSegments;
109 QByteArray uri = copy.toEncoded(options: format);
110 return uri;
111}
112
113QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy)
114{
115 const QHttpHeaders headers = request.header();
116 QByteArray ba;
117 ba.reserve(asize: 40 + headers.size() * 25); // very rough lower bound estimation
118
119 ba += request.methodName();
120 ba += ' ';
121 ba += request.uri(throughProxy);
122
123 ba += " HTTP/";
124 ba += QByteArray::number(request.majorVersion());
125 ba += '.';
126 ba += QByteArray::number(request.minorVersion());
127 ba += "\r\n";
128
129 for (qsizetype i = 0; i < headers.size(); ++i) {
130 ba += headers.nameAt(i);
131 ba += ": ";
132 ba += headers.valueAt(i);
133 ba += "\r\n";
134 }
135 if (request.d->operation == QHttpNetworkRequest::Post) {
136 // add content type, if not set in the request
137 if (request.headerField(name: "content-type").isEmpty() && ((request.d->uploadByteDevice && request.d->uploadByteDevice->size() > 0) || request.d->url.hasQuery())) {
138 //Content-Type is mandatory. We can't say anything about the encoding, but x-www-form-urlencoded is the most likely to work.
139 //This warning indicates a bug in application code not setting a required header.
140 //Note that if using QHttpMultipart, the content-type is set in QNetworkAccessManagerPrivate::prepareMultipart already
141 qWarning(msg: "content-type missing in HTTP POST, defaulting to application/x-www-form-urlencoded. Use QNetworkRequest::setHeader() to fix this problem.");
142 ba += "Content-Type: application/x-www-form-urlencoded\r\n";
143 }
144 if (!request.d->uploadByteDevice && request.d->url.hasQuery()) {
145 QByteArray query = request.d->url.query(QUrl::FullyEncoded).toLatin1();
146 ba += "Content-Length: ";
147 ba += QByteArray::number(query.size());
148 ba += "\r\n\r\n";
149 ba += query;
150 } else {
151 ba += "\r\n";
152 }
153 } else {
154 ba += "\r\n";
155 }
156 return ba;
157}
158
159
160// QHttpNetworkRequest
161
162QHttpNetworkRequest::QHttpNetworkRequest(const QUrl &url, Operation operation, Priority priority)
163 : d(new QHttpNetworkRequestPrivate(operation, priority, url))
164{
165}
166
167QHttpNetworkRequest::QHttpNetworkRequest(const QHttpNetworkRequest &other)
168 : QHttpNetworkHeader(other), d(other.d)
169{
170}
171
172QHttpNetworkRequest::~QHttpNetworkRequest()
173{
174}
175
176QUrl QHttpNetworkRequest::url() const
177{
178 return d->url;
179}
180void QHttpNetworkRequest::setUrl(const QUrl &url)
181{
182 d->url = url;
183}
184
185bool QHttpNetworkRequest::isSsl() const
186{
187 return d->ssl;
188}
189void QHttpNetworkRequest::setSsl(bool s)
190{
191 d->ssl = s;
192}
193
194bool QHttpNetworkRequest::isPreConnect() const
195{
196 return d->preConnect;
197}
198void QHttpNetworkRequest::setPreConnect(bool preConnect)
199{
200 d->preConnect = preConnect;
201}
202
203bool QHttpNetworkRequest::isFollowRedirects() const
204{
205 return d->redirectPolicy != QNetworkRequest::ManualRedirectPolicy;
206}
207
208void QHttpNetworkRequest::setRedirectPolicy(QNetworkRequest::RedirectPolicy policy)
209{
210 d->redirectPolicy = policy;
211}
212
213QNetworkRequest::RedirectPolicy QHttpNetworkRequest::redirectPolicy() const
214{
215 return d->redirectPolicy;
216}
217
218int QHttpNetworkRequest::redirectCount() const
219{
220 return d->redirectCount;
221}
222
223void QHttpNetworkRequest::setRedirectCount(int count)
224{
225 d->redirectCount = count;
226}
227
228qint64 QHttpNetworkRequest::contentLength() const
229{
230 return d->contentLength();
231}
232
233void QHttpNetworkRequest::setContentLength(qint64 length)
234{
235 d->setContentLength(length);
236}
237
238QHttpHeaders QHttpNetworkRequest::header() const
239{
240 return d->parser.headers();
241}
242
243QByteArray QHttpNetworkRequest::headerField(QByteArrayView name, const QByteArray &defaultValue) const
244{
245 return d->headerField(name, defaultValue);
246}
247
248void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArray &data)
249{
250 d->setHeaderField(name, data);
251}
252
253void QHttpNetworkRequest::prependHeaderField(const QByteArray &name, const QByteArray &data)
254{
255 d->prependHeaderField(name, data);
256}
257
258void QHttpNetworkRequest::clearHeaders()
259{
260 d->clearHeaders();
261}
262
263QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other)
264{
265 QHttpNetworkHeader::operator=(other);
266 d = other.d;
267 return *this;
268}
269
270bool QHttpNetworkRequest::operator==(const QHttpNetworkRequest &other) const
271{
272 return d->operator==(other: *other.d);
273}
274
275QHttpNetworkRequest::Operation QHttpNetworkRequest::operation() const
276{
277 return d->operation;
278}
279
280void QHttpNetworkRequest::setOperation(Operation operation)
281{
282 d->operation = operation;
283}
284
285QByteArray QHttpNetworkRequest::customVerb() const
286{
287 return d->customVerb;
288}
289
290void QHttpNetworkRequest::setCustomVerb(const QByteArray &customVerb)
291{
292 d->customVerb = customVerb;
293}
294
295QHttpNetworkRequest::Priority QHttpNetworkRequest::priority() const
296{
297 return d->priority;
298}
299
300void QHttpNetworkRequest::setPriority(Priority priority)
301{
302 d->priority = priority;
303}
304
305bool QHttpNetworkRequest::isPipeliningAllowed() const
306{
307 return d->pipeliningAllowed;
308}
309
310void QHttpNetworkRequest::setPipeliningAllowed(bool b)
311{
312 d->pipeliningAllowed = b;
313}
314
315bool QHttpNetworkRequest::isHTTP2Allowed() const
316{
317 return d->http2Allowed;
318}
319
320void QHttpNetworkRequest::setHTTP2Allowed(bool b)
321{
322 d->http2Allowed = b;
323}
324
325bool QHttpNetworkRequest::isHTTP2Direct() const
326{
327 return d->http2Direct;
328}
329
330void QHttpNetworkRequest::setHTTP2Direct(bool b)
331{
332 d->http2Direct = b;
333}
334
335bool QHttpNetworkRequest::isH2cAllowed() const
336{
337 return d->h2cAllowed;
338}
339
340void QHttpNetworkRequest::setH2cAllowed(bool b)
341{
342 d->h2cAllowed = b;
343}
344
345bool QHttpNetworkRequest::withCredentials() const
346{
347 return d->withCredentials;
348}
349
350void QHttpNetworkRequest::setWithCredentials(bool b)
351{
352 d->withCredentials = b;
353}
354
355void QHttpNetworkRequest::setUploadByteDevice(QNonContiguousByteDevice *bd)
356{
357 d->uploadByteDevice = bd;
358}
359
360QNonContiguousByteDevice* QHttpNetworkRequest::uploadByteDevice() const
361{
362 return d->uploadByteDevice;
363}
364
365int QHttpNetworkRequest::majorVersion() const
366{
367 return 1;
368}
369
370int QHttpNetworkRequest::minorVersion() const
371{
372 return 1;
373}
374
375QString QHttpNetworkRequest::peerVerifyName() const
376{
377 return d->peerVerifyName;
378}
379
380void QHttpNetworkRequest::setPeerVerifyName(const QString &peerName)
381{
382 d->peerVerifyName = peerName;
383}
384
385QString QHttpNetworkRequest::fullLocalServerName() const
386{
387 return d->fullLocalServerName;
388}
389
390void QHttpNetworkRequest::setFullLocalServerName(const QString &fullServerName)
391{
392 d->fullLocalServerName = fullServerName;
393}
394
395QT_END_NAMESPACE
396
397

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/network/access/qhttpnetworkrequest.cpp