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 bool notifiedFinished = false;
106
107 // Used for implementing the synchronous HTTP, see startRequestSynchronously()
109
110signals:
112#ifndef QT_NO_NETWORKPROXY
113 void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
114#endif
115#ifndef QT_NO_SSL
116 void encrypted();
117 void sslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
118 void sslConfigurationChanged(const QSslConfiguration &);
119 void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *);
120#endif
123 void downloadMetaData(const QHttpHeaders &, int, const QString &, bool,
124 QSharedPointer<char>, qint64, qint64, bool, bool);
127 void error(QNetworkReply::NetworkError, const QString &);
129 void redirected(const QUrl &url, int httpStatus, int maxRedirectsRemainig);
130
131public slots:
132 // This are called via QueuedConnection from user thread
133 void startRequest();
134 void abortRequest();
135 void readBufferSizeChanged(qint64 size);
136 void readBufferFreed(qint64 size);
137
138 // This is called with a BlockingQueuedConnection from user thread
140protected slots:
141 // From QHttp*
142 void readyReadSlot();
143 void finishedSlot();
144 void finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
146 void synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
147 void headerChangedSlot();
149 void dataReadProgressSlot(qint64 done, qint64 total);
150 void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
151#ifndef QT_NO_SSL
152 void encryptedSlot();
153 void sslErrorsSlot(const QList<QSslError> &errors);
154 void preSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *authenticator);
155#endif
156
157 void synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *);
158#ifndef QT_NO_NETWORKPROXY
159 void synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &, QAuthenticator *);
160#endif
161
162protected:
163 // Cache for all the QHttpNetworkConnection objects.
164 // This is per thread.
166
167};
168
169// This QNonContiguousByteDevice is connected to the QNetworkAccessHttpBackend
170// and represents the PUT/POST data.
172{
174protected:
175 bool wantDataPending = false;
177 char *m_data = nullptr;
179 bool m_atEnd = false;
181 qint64 m_pos = 0; // to match calls of haveDataSlot with the expected position
182public:
185 m_atEnd(aE),
186 m_size(s)
187 {
188 }
189
193
194 qint64 pos() const override
195 {
196 return m_pos;
197 }
198
199 const char* readPointer(qint64 maximumLength, qint64 &len) override
200 {
201 if (m_amount > 0) {
202 len = m_amount;
203 return m_data;
204 }
205
206 if (m_atEnd) {
207 len = -1;
208 } else if (!wantDataPending) {
209 len = 0;
210 wantDataPending = true;
211 emit wantData(maximumLength);
212 } else {
213 // Do nothing, we already sent a wantData signal and wait for results
214 len = 0;
215 }
216 return nullptr;
217 }
218
219 bool advanceReadPointer(qint64 a) override
220 {
221 if (m_data == nullptr)
222 return false;
223
224 m_amount -= a;
225 m_data += a;
226 m_pos += a;
227
228 // To main thread to inform about our state. The m_pos will be sent as a sanity check.
229 emit processedData(m_pos, a);
230
231 return true;
232 }
233
234 bool atEnd() const override
235 {
236 if (m_amount > 0)
237 return false;
238 else
239 return m_atEnd;
240 }
241
243 {
244 m_amount = 0;
245 m_data = nullptr;
246 m_dataArray.clear();
247
248 if (wantDataPending) {
249 // had requested the user thread to send some data (only 1 in-flight at any moment)
250 wantDataPending = false;
251 }
252
253 // Communicate as BlockingQueuedConnection
254 bool b = false;
255 emit resetData(&b);
256 if (b) {
257 // the reset succeeded, we're at pos 0 again
258 m_pos = 0;
259 m_atEnd = false;
260 // the HTTP code will anyway abort the request if !b.
261 }
262 return b;
263 }
264
265 qint64 size() const override
266 {
267 return m_size;
268 }
269
270public slots:
271 // From user thread:
273 {
274 if (pos != m_pos) {
275 // Sometimes when re-sending a request in the qhttpnetwork* layer there is a pending haveData from the
276 // user thread on the way to us. We need to ignore it since it is the data for the wrong(later) chunk.
277 return;
278 }
279 wantDataPending = false;
280
282 m_data = const_cast<char*>(m_dataArray.constData());
284
287
288 // This will tell the HTTP code (QHttpNetworkConnectionChannel) that we have data available now
289 emit readyRead();
290 }
291
292signals:
293 // void readyRead(); in parent class
294 // void readProgress(qint64 current, qint64 total); happens in the main thread with the real bytedevice
295
296 // to main thread:
298 void processedData(qint64 pos, qint64 amount);
299 void resetData(bool *b);
300};
301
302QT_END_NAMESPACE
303
304#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)