1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtNetwork module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QNETWORKREPLYHTTPIMPL_P_H
41#define QNETWORKREPLYHTTPIMPL_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists for the convenience
48// of the Network Access API. This header file may change from
49// version to version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <QtNetwork/private/qtnetworkglobal_p.h>
55#include "qnetworkrequest.h"
56#include "qnetworkreply.h"
57
58#include "QtCore/qpointer.h"
59#include "QtCore/qdatetime.h"
60#include "QtCore/qsharedpointer.h"
61#include "QtCore/qscopedpointer.h"
62#include "QtCore/qtimer.h"
63#include "qatomic.h"
64
65#include <QtNetwork/QNetworkCacheMetaData>
66#include <private/qhttpnetworkrequest_p.h>
67#include <private/qnetworkreply_p.h>
68#include <QtNetwork/QNetworkProxy>
69#include <QtNetwork/QNetworkSession> // ### Qt6: Remove include
70
71#ifndef QT_NO_SSL
72#include <QtNetwork/QSslConfiguration>
73#endif
74
75QT_REQUIRE_CONFIG(http);
76
77QT_BEGIN_NAMESPACE
78
79class QIODevice;
80
81class QNetworkReplyHttpImplPrivate;
82class QNetworkReplyHttpImpl: public QNetworkReply
83{
84 Q_OBJECT
85public:
86 QNetworkReplyHttpImpl(QNetworkAccessManager* const, const QNetworkRequest&, QNetworkAccessManager::Operation&, QIODevice* outgoingData);
87 virtual ~QNetworkReplyHttpImpl();
88
89 void close() override;
90 void abort() override;
91 qint64 bytesAvailable() const override;
92 bool isSequential () const override;
93 qint64 size() const override;
94 qint64 readData(char*, qint64) override;
95 void setReadBufferSize(qint64 size) override;
96 bool canReadLine () const override;
97
98 Q_DECLARE_PRIVATE(QNetworkReplyHttpImpl)
99 Q_PRIVATE_SLOT(d_func(), void _q_startOperation())
100 Q_PRIVATE_SLOT(d_func(), bool start(const QNetworkRequest &))
101 Q_PRIVATE_SLOT(d_func(), void _q_cacheLoadReadyRead())
102 Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData())
103 Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished())
104 Q_PRIVATE_SLOT(d_func(), void _q_transferTimedOut())
105#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section
106 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected())
107 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed())
108 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State))
109 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies))
110#endif
111 Q_PRIVATE_SLOT(d_func(), void _q_finished())
112 Q_PRIVATE_SLOT(d_func(), void _q_error(QNetworkReply::NetworkError, const QString &))
113
114 // From reply
115 Q_PRIVATE_SLOT(d_func(), void replyDownloadData(QByteArray))
116 Q_PRIVATE_SLOT(d_func(), void replyFinished())
117 Q_PRIVATE_SLOT(d_func(), void replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >,
118 int, QString, bool, QSharedPointer<char>,
119 qint64, qint64, bool))
120 Q_PRIVATE_SLOT(d_func(), void replyDownloadProgressSlot(qint64,qint64))
121 Q_PRIVATE_SLOT(d_func(), void httpAuthenticationRequired(const QHttpNetworkRequest &, QAuthenticator *))
122 Q_PRIVATE_SLOT(d_func(), void httpError(QNetworkReply::NetworkError, const QString &))
123#ifndef QT_NO_SSL
124 Q_PRIVATE_SLOT(d_func(), void replyEncrypted())
125 Q_PRIVATE_SLOT(d_func(), void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *))
126 Q_PRIVATE_SLOT(d_func(), void replySslConfigurationChanged(const QSslConfiguration&))
127 Q_PRIVATE_SLOT(d_func(), void replyPreSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *))
128#endif
129#ifndef QT_NO_NETWORKPROXY
130 Q_PRIVATE_SLOT(d_func(), void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth))
131#endif
132
133 Q_PRIVATE_SLOT(d_func(), void resetUploadDataSlot(bool *r))
134 Q_PRIVATE_SLOT(d_func(), void wantUploadDataSlot(qint64))
135 Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64,qint64))
136 Q_PRIVATE_SLOT(d_func(), void uploadByteDeviceReadyReadSlot())
137 Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64))
138 Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose())
139 Q_PRIVATE_SLOT(d_func(), void _q_metaDataChanged())
140 Q_PRIVATE_SLOT(d_func(), void onRedirected(const QUrl &, int, int))
141 Q_PRIVATE_SLOT(d_func(), void followRedirect())
142
143#ifndef QT_NO_SSL
144protected:
145 void ignoreSslErrors() override;
146 void ignoreSslErrorsImplementation(const QList<QSslError> &errors) override;
147 void setSslConfigurationImplementation(const QSslConfiguration &configuration) override;
148 void sslConfigurationImplementation(QSslConfiguration &configuration) const override;
149#endif
150
151signals:
152 // To HTTP thread:
153 void startHttpRequest();
154 void abortHttpRequest();
155 void readBufferSizeChanged(qint64 size);
156 void readBufferFreed(qint64 size);
157
158 void startHttpRequestSynchronously();
159
160 void haveUploadData(const qint64 pos, const QByteArray &dataArray, bool dataAtEnd, qint64 dataSize);
161};
162
163class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate
164{
165#if QT_CONFIG(bearermanagement) // ### Qt6: Remove section
166 bool startWaitForSession(QSharedPointer<QNetworkSession> &session);
167#endif
168
169public:
170
171 static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio);
172
173 QNetworkReplyHttpImplPrivate();
174 ~QNetworkReplyHttpImplPrivate();
175
176 bool start(const QNetworkRequest &newHttpRequest);
177 void _q_startOperation();
178
179 void _q_cacheLoadReadyRead();
180
181 void _q_bufferOutgoingData();
182 void _q_bufferOutgoingDataFinished();
183
184 void _q_cacheSaveDeviceAboutToClose();
185
186 void _q_transferTimedOut();
187 void setupTransferTimeout();
188
189#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section
190 void _q_networkSessionConnected();
191 void _q_networkSessionFailed();
192 void _q_networkSessionStateChanged(QNetworkSession::State);
193 void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies);
194#endif
195 void _q_finished();
196
197 void finished();
198 void error(QNetworkReply::NetworkError code, const QString &errorString);
199 void _q_error(QNetworkReply::NetworkError code, const QString &errorString);
200 void _q_metaDataChanged();
201
202 void checkForRedirect(const int statusCode);
203
204 // incoming from user
205 QNetworkAccessManager *manager;
206 QNetworkAccessManagerPrivate *managerPrivate;
207 QHttpNetworkRequest httpRequest; // There is also a copy in the HTTP thread
208 bool synchronous;
209
210 State state;
211
212 // from http thread
213 int statusCode;
214 QString reasonPhrase;
215
216 // upload
217 QNonContiguousByteDevice* createUploadByteDevice();
218 QSharedPointer<QNonContiguousByteDevice> uploadByteDevice;
219 qint64 uploadByteDevicePosition;
220 bool uploadDeviceChoking; // if we couldn't readPointer() any data at the moment
221 QIODevice *outgoingData;
222 QSharedPointer<QRingBuffer> outgoingDataBuffer;
223 void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal); // dup?
224 void onRedirected(const QUrl &redirectUrl, int httpStatus, int maxRedirectsRemainig);
225 void followRedirect();
226 qint64 bytesUploaded;
227
228
229 // cache
230 void createCache();
231 void completeCacheSave();
232 void setCachingEnabled(bool enable);
233 bool isCachingEnabled() const;
234 bool isCachingAllowed() const;
235 void initCacheSaveDevice();
236 QIODevice *cacheLoadDevice;
237 bool loadingFromCache;
238
239 QIODevice *cacheSaveDevice;
240 bool cacheEnabled; // is this for saving?
241
242
243 QUrl urlForLastAuthentication;
244#ifndef QT_NO_NETWORKPROXY
245 QNetworkProxy lastProxyAuthentication;
246#endif
247
248
249 bool migrateBackend();
250 bool canResume() const;
251 void setResumeOffset(quint64 offset);
252 quint64 resumeOffset;
253 qint64 preMigrationDownloaded;
254
255 qint64 bytesDownloaded;
256 qint64 bytesBuffered;
257
258 QTimer *transferTimeout;
259
260 // Only used when the "zero copy" style is used.
261 // Please note that the whole "zero copy" download buffer API is private right now. Do not use it.
262 qint64 downloadBufferReadPosition;
263 qint64 downloadBufferCurrentSize;
264 QSharedPointer<char> downloadBufferPointer;
265 char* downloadZerocopyBuffer;
266
267 // Will be increased by HTTP thread:
268 QSharedPointer<QAtomicInt> pendingDownloadDataEmissions;
269 QSharedPointer<QAtomicInt> pendingDownloadProgressEmissions;
270
271
272#ifndef QT_NO_SSL
273 QScopedPointer<QSslConfiguration> sslConfiguration;
274 bool pendingIgnoreAllSslErrors;
275 QList<QSslError> pendingIgnoreSslErrorsList;
276#endif
277
278 QNetworkRequest redirectRequest;
279
280 bool loadFromCacheIfAllowed(QHttpNetworkRequest &httpRequest);
281 void invalidateCache();
282 bool sendCacheContents(const QNetworkCacheMetaData &metaData);
283 QNetworkCacheMetaData fetchCacheMetaData(const QNetworkCacheMetaData &metaData) const;
284
285
286 void postRequest(const QNetworkRequest& newHttpRequest);
287 QNetworkAccessManager::Operation getRedirectOperation(QNetworkAccessManager::Operation currentOp, int httpStatus);
288 QNetworkRequest createRedirectRequest(const QNetworkRequest &originalRequests, const QUrl &url, int maxRedirectsRemainig);
289 bool isHttpRedirectResponse() const;
290
291public:
292 // From HTTP thread:
293 void replyDownloadData(QByteArray);
294 void replyFinished();
295 void replyDownloadMetaData(const QList<QPair<QByteArray,QByteArray> > &, int, const QString &,
296 bool, QSharedPointer<char>, qint64, qint64, bool);
297 void replyDownloadProgressSlot(qint64,qint64);
298 void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
299 void httpError(QNetworkReply::NetworkError error, const QString &errorString);
300#ifndef QT_NO_SSL
301 void replyEncrypted();
302 void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
303 void replySslConfigurationChanged(const QSslConfiguration &newSslConfiguration);
304 void replyPreSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *);
305#endif
306#ifndef QT_NO_NETWORKPROXY
307 void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth);
308#endif
309
310 // From QNonContiguousByteDeviceThreadForwardImpl in HTTP thread:
311 void resetUploadDataSlot(bool *r);
312 void wantUploadDataSlot(qint64);
313 void sentUploadDataSlot(qint64, qint64);
314
315 // From user's QNonContiguousByteDevice
316 void uploadByteDeviceReadyReadSlot();
317
318 Q_DECLARE_PUBLIC(QNetworkReplyHttpImpl)
319};
320
321QT_END_NAMESPACE
322
323#endif
324

source code of qtbase/src/network/access/qnetworkreplyhttpimpl_p.h