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 75 QT_REQUIRE_CONFIG(http); 76 77 QT_BEGIN_NAMESPACE 78 79 class QIODevice; 80 81 class QNetworkReplyHttpImplPrivate; 82 class QNetworkReplyHttpImpl: public QNetworkReply 83 { 84 Q_OBJECT 85 public: 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 144 protected: 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 151 signals: 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 163 class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate 164 { 165 #if QT_CONFIG(bearermanagement) // ### Qt6: Remove section 166 bool startWaitForSession(QSharedPointer<QNetworkSession> &session); 167 #endif 168 169 public: 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 291 public: 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 321 QT_END_NAMESPACE 322 323 #endif 324