Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qhttpthreaddelegate_p.h
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
4
5#ifndef QHTTPTHREADDELEGATE_H
6#define QHTTPTHREADDELEGATE_H
7
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists for the convenience
14// of the Network Access API. This header file may change from
15// version to version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include <QtNetwork/private/qtnetworkglobal_p.h>
21#include <QObject>
22#include <QThreadStorage>
23#include <QNetworkProxy>
24#include <QSslConfiguration>
25#include <QSslError>
26#include <QList>
27#include <QNetworkReply>
32#include <QSharedPointer>
33#include "private/qnoncontiguousbytedevice_p.h"
35#include <QtNetwork/private/http2protocol_p.h>
36#include <QtNetwork/qhttpheaders.h>
38
39#include <optional>
40#ifndef QT_NO_SSL
41#include <memory>
42#endif
43
45
46QT_BEGIN_NAMESPACE
47
48class QAuthenticator;
49class QHttpNetworkReply;
50class QEventLoop;
53
55{
57public:
58 explicit QHttpThreadDelegate(QObject *parent = nullptr);
59
61
62 // incoming
63 bool ssl;
64#ifndef QT_NO_SSL
66#endif
67 QHttpNetworkRequest httpRequest;
71 // From backend, modified by us for signal compression
74#ifndef QT_NO_NETWORKPROXY
75 QNetworkProxy cacheProxy;
76 QNetworkProxy transparentProxy;
77#endif
81
82 // outgoing, Retrieved in the synchronous HTTP case
89 bool isCompressed = false;
96 QTcpKeepAliveConfiguration tcpKeepAliveParameters = {};
97
98protected:
99 // The zerocopy download buffer, if used:
101 // The QHttpNetworkConnection that is used
104 QHttpNetworkReply *httpReply;
105
106 // Used for implementing the synchronous HTTP, see startRequestSynchronously()
108
109signals:
111#ifndef QT_NO_NETWORKPROXY
112 void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
113#endif
114#ifndef QT_NO_SSL
115 void encrypted();
116 void sslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
117 void sslConfigurationChanged(const QSslConfiguration &);
118 void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *);
119#endif
122 void downloadMetaData(const QHttpHeaders &, int, const QString &, bool,
123 QSharedPointer<char>, qint64, qint64, bool, bool);
126 void error(QNetworkReply::NetworkError, const QString &);
128 void redirected(const QUrl &url, int httpStatus, int maxRedirectsRemainig);
129
130public slots:
131 // This are called via QueuedConnection from user thread
132 void startRequest();
133 void abortRequest();
134 void readBufferSizeChanged(qint64 size);
135 void readBufferFreed(qint64 size);
136
137 // This is called with a BlockingQueuedConnection from user thread
139protected slots:
140 // From QHttp*
141 void readyReadSlot();
142 void finishedSlot();
143 void finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
145 void synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
146 void headerChangedSlot();
148 void dataReadProgressSlot(qint64 done, qint64 total);
149 void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
150#ifndef QT_NO_SSL
151 void encryptedSlot();
152 void sslErrorsSlot(const QList<QSslError> &errors);
153 void preSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *authenticator);
154#endif
155
156 void synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *);
157#ifndef QT_NO_NETWORKPROXY
158 void synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &, QAuthenticator *);
159#endif
160
161protected:
162 // Cache for all the QHttpNetworkConnection objects.
163 // This is per thread.
165
166};
167
168// This QNonContiguousByteDevice is connected to the QNetworkAccessHttpBackend
169// and represents the PUT/POST data.
171{
173protected:
174 bool wantDataPending = false;
176 char *m_data = nullptr;
178 bool m_atEnd = false;
180 qint64 m_pos = 0; // to match calls of haveDataSlot with the expected position
181public:
184 m_atEnd(aE),
185 m_size(s)
186 {
187 }
188
192
193 qint64 pos() const override
194 {
195 return m_pos;
196 }
197
198 const char* readPointer(qint64 maximumLength, qint64 &len) override
199 {
200 if (m_amount > 0) {
201 len = m_amount;
202 return m_data;
203 }
204
205 if (m_atEnd) {
206 len = -1;
207 } else if (!wantDataPending) {
208 len = 0;
209 wantDataPending = true;
210 emit wantData(maximumLength);
211 } else {
212 // Do nothing, we already sent a wantData signal and wait for results
213 len = 0;
214 }
215 return nullptr;
216 }
217
218 bool advanceReadPointer(qint64 a) override
219 {
220 if (m_data == nullptr)
221 return false;
222
223 m_amount -= a;
224 m_data += a;
225 m_pos += a;
226
227 // To main thread to inform about our state. The m_pos will be sent as a sanity check.
228 emit processedData(m_pos, a);
229
230 return true;
231 }
232
233 bool atEnd() const override
234 {
235 if (m_amount > 0)
236 return false;
237 else
238 return m_atEnd;
239 }
240
242 {
243 m_amount = 0;
244 m_data = nullptr;
245 m_dataArray.clear();
246
247 if (wantDataPending) {
248 // had requested the user thread to send some data (only 1 in-flight at any moment)
249 wantDataPending = false;
250 }
251
252 // Communicate as BlockingQueuedConnection
253 bool b = false;
254 emit resetData(&b);
255 if (b) {
256 // the reset succeeded, we're at pos 0 again
257 m_pos = 0;
258 m_atEnd = false;
259 // the HTTP code will anyway abort the request if !b.
260 }
261 return b;
262 }
263
264 qint64 size() const override
265 {
266 return m_size;
267 }
268
269public slots:
270 // From user thread:
272 {
273 if (pos != m_pos) {
274 // Sometimes when re-sending a request in the qhttpnetwork* layer there is a pending haveData from the
275 // user thread on the way to us. We need to ignore it since it is the data for the wrong(later) chunk.
276 return;
277 }
278 wantDataPending = false;
279
281 m_data = const_cast<char*>(m_dataArray.constData());
283
286
287 // This will tell the HTTP code (QHttpNetworkConnectionChannel) that we have data available now
288 emit readyRead();
289 }
290
291signals:
292 // void readyRead(); in parent class
293 // void readProgress(qint64 current, qint64 total); happens in the main thread with the real bytedevice
294
295 // to main thread:
297 void processedData(qint64 pos, qint64 amount);
298 void resetData(bool *b);
299};
300
301QT_END_NAMESPACE
302
303#endif // QHTTPTHREADDELEGATE_H
The QHttp1Configuration class controls HTTP/1 parameters and settings.
void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator)
QSharedPointer< char > downloadBuffer
QHttpNetworkReply * httpReply
void readBufferSizeChanged(qint64 size)
void synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *)
void synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail=QString())
void socketStartedConnecting()
std::shared_ptr< QAtomicInt > pendingDownloadData
void sslErrorsSlot(const QList< QSslError > &errors)
QNetworkAccessCachedHttpConnection * httpConnection
void redirected(const QUrl &url, int httpStatus, int maxRedirectsRemainig)
void downloadMetaData(const QHttpHeaders &, int, const QString &, bool, QSharedPointer< char >, qint64, qint64, bool, bool)
void downloadProgress(qint64, qint64)
QHttpNetworkRequest httpRequest
void preSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *authenticator)
QHttp1Configuration http1Parameters
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)
void sslErrors(const QList< QSslError > &, bool *, QList< QSslError > *)
void error(QNetworkReply::NetworkError, const QString &)
void synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &, QAuthenticator *)
std::optional< qint64 > connectionCacheExpiryTimeoutSeconds
QTcpKeepAliveConfiguration tcpKeepAliveParameters
void finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail=QString())
std::unique_ptr< QSslConfiguration > incomingSslConfiguration
void readBufferFreed(qint64 size)
QHttp2Configuration http2Parameters
static QThreadStorage< QNetworkAccessCache * > connections
std::shared_ptr< QAtomicInt > pendingDownloadProgress
QNetworkReply::NetworkError incomingErrorCode
void downloadData(const QByteArray &)
std::shared_ptr< QNetworkAccessAuthenticationManager > authenticationManager
void dataReadProgressSlot(qint64 done, qint64 total)
void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *)
void sslConfigurationChanged(const QSslConfiguration &)
QNetworkAccessCachedHttpConnection(quint16 connectionCount, const QString &hostName, quint16 port, bool encrypt, bool isLocalSocket, QHttpNetworkConnection::ConnectionType connectionType)
qint64 size() const override
Returns the size of the complete device or -1 if unknown.
bool atEnd() const override
Returns true if everything has been read and the read pointer cannot be advanced anymore.
void processedData(qint64 pos, qint64 amount)
const char * readPointer(qint64 maximumLength, qint64 &len) override
Return a byte pointer for at most maximumLength bytes of that device.
bool advanceReadPointer(qint64 a) override
will advance the internal read pointer by amount bytes.
bool reset() override
Moves the internal read pointer back to the beginning.
\inmodule QtCore
Combined button and popup list for selecting options.
QT_REQUIRE_CONFIG(http)
static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const QUrl &url)
static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy, const QString &peerVerifyName)
static QString makeServerErrorString(int code, const QUrl &url, const QString &reasonPhrase)