1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2015 The Qt Company Ltd. 4 ** Contact: http://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 http://www.qt.io/terms-conditions. For further 15 ** information use the contact form at http://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 2.1 or version 3 as published by the Free 20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 ** following information to ensure the GNU Lesser General Public License 23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 ** 26 ** As a special exception, The Qt Company gives you certain additional 27 ** rights. These rights are described in The Qt Company LGPL Exception 28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 ** 30 ** GNU General Public License Usage 31 ** Alternatively, this file may be used under the terms of the GNU 32 ** General Public License version 3.0 as published by the Free Software 33 ** Foundation and appearing in the file LICENSE.GPL included in the 34 ** packaging of this file. Please review the following information to 35 ** ensure the GNU General Public License version 3.0 requirements will be 36 ** met: http://www.gnu.org/copyleft/gpl.html. 37 ** 38 ** $QT_END_LICENSE$ 39 ** 40 ****************************************************************************/ 41 42 #ifndef QHTTPNETWORKREPLY_H 43 #define QHTTPNETWORKREPLY_H 44 45 // 46 // W A R N I N G 47 // ------------- 48 // 49 // This file is not part of the Qt API. It exists for the convenience 50 // of the Network Access API. This header file may change from 51 // version to version without notice, or even be removed. 52 // 53 // We mean it. 54 // 55 #include <qplatformdefs.h> 56 #ifndef QT_NO_HTTP 57 58 #ifndef QT_NO_COMPRESS 59 # include <zlib.h> 60 static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header 61 // gzip flag byte 62 #define HEAD_CRC 0x02 // bit 1 set: header CRC present 63 #define EXTRA_FIELD 0x04 // bit 2 set: extra field present 64 #define ORIG_NAME 0x08 // bit 3 set: original file name present 65 #define COMMENT 0x10 // bit 4 set: file comment present 66 #define RESERVED 0xE0 // bits 5..7: reserved 67 #define CHUNK 16384 68 #endif 69 70 #include <QtNetwork/qtcpsocket.h> 71 // it's safe to include these even if SSL support is not enabled 72 #include <QtNetwork/qsslsocket.h> 73 #include <QtNetwork/qsslerror.h> 74 75 #include <QtNetwork/qnetworkrequest.h> 76 #include <QtNetwork/qnetworkreply.h> 77 #include <qbuffer.h> 78 79 #include <private/qobject_p.h> 80 #include <private/qhttpnetworkheader_p.h> 81 #include <private/qhttpnetworkrequest_p.h> 82 #include <private/qauthenticator_p.h> 83 #include <private/qringbuffer_p.h> 84 #include <private/qbytedata_p.h> 85 86 QT_BEGIN_NAMESPACE 87 88 class QHttpNetworkConnection; 89 class QHttpNetworkConnectionChannel; 90 class QHttpNetworkRequest; 91 class QHttpNetworkConnectionPrivate; 92 class QHttpNetworkReplyPrivate; 93 class Q_AUTOTEST_EXPORT QHttpNetworkReply : public QObject, public QHttpNetworkHeader 94 { 95 Q_OBJECT 96 public: 97 98 explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = 0); 99 virtual ~QHttpNetworkReply(); 100 101 QUrl url() const; 102 void setUrl(const QUrl &url); 103 104 int majorVersion() const; 105 int minorVersion() const; 106 107 qint64 contentLength() const; 108 void setContentLength(qint64 length); 109 110 QList<QPair<QByteArray, QByteArray> > header() const; 111 QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; 112 void setHeaderField(const QByteArray &name, const QByteArray &data); 113 void parseHeader(const QByteArray &header); // mainly for testing 114 115 QHttpNetworkRequest request() const; 116 void setRequest(const QHttpNetworkRequest &request); 117 118 int statusCode() const; 119 void setStatusCode(int code); 120 121 QString errorString() const; 122 void setErrorString(const QString &error); 123 124 QString reasonPhrase() const; 125 126 qint64 bytesAvailable() const; 127 qint64 bytesAvailableNextBlock() const; 128 bool readAnyAvailable() const; 129 QByteArray readAny(); 130 QByteArray readAll(); 131 QByteArray read(qint64 amount); 132 qint64 sizeNextBlock(); 133 void setDownstreamLimited(bool t); 134 void setReadBufferSize(qint64 size); 135 136 bool supportsUserProvidedDownloadBuffer(); 137 void setUserProvidedDownloadBuffer(char*); 138 char* userProvidedDownloadBuffer(); 139 140 bool isFinished() const; 141 142 bool isPipeliningUsed() const; 143 144 QHttpNetworkConnection* connection(); 145 146 #ifndef QT_NO_OPENSSL 147 QSslConfiguration sslConfiguration() const; 148 void setSslConfiguration(const QSslConfiguration &config); 149 void ignoreSslErrors(); 150 void ignoreSslErrors(const QList<QSslError> &errors); 151 152 Q_SIGNALS: 153 void sslErrors(const QList<QSslError> &errors); 154 #endif 155 156 Q_SIGNALS: 157 void readyRead(); 158 void finished(); 159 void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString()); 160 void headerChanged(); 161 // FIXME we need to change this to qint64! 162 void dataReadProgress(int done, int total); 163 void dataSendProgress(qint64 done, qint64 total); 164 void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator); 165 #ifndef QT_NO_NETWORKPROXY 166 void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); 167 #endif 168 void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator); 169 private: 170 Q_DECLARE_PRIVATE(QHttpNetworkReply) 171 friend class QHttpNetworkConnection; 172 friend class QHttpNetworkConnectionPrivate; 173 friend class QHttpNetworkConnectionChannel; 174 }; 175 176 177 class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate 178 { 179 public: 180 QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl()); 181 ~QHttpNetworkReplyPrivate(); 182 qint64 readStatus(QAbstractSocket *socket); 183 bool parseStatus(const QByteArray &status); 184 qint64 readHeader(QAbstractSocket *socket); 185 void parseHeader(const QByteArray &header); 186 qint64 readBody(QAbstractSocket *socket, QByteDataBuffer *out); 187 qint64 readBodyVeryFast(QAbstractSocket *socket, char *b); 188 qint64 readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb); 189 bool findChallenge(bool forProxy, QByteArray &challenge) const; 190 QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const; 191 void clear(); 192 void clearHttpLayerInformation(); 193 194 qint64 readReplyBodyRaw(QAbstractSocket *in, QByteDataBuffer *out, qint64 size); 195 qint64 readReplyBodyChunked(QAbstractSocket *in, QByteDataBuffer *out); 196 qint64 getChunkSize(QAbstractSocket *in, qint64 *chunkSize); 197 198 void appendUncompressedReplyData(QByteArray &qba); 199 void appendUncompressedReplyData(QByteDataBuffer &data); 200 void appendCompressedReplyData(QByteDataBuffer &data); 201 202 bool shouldEmitSignals(); 203 bool expectContent(); 204 void eraseData(); 205 206 qint64 bytesAvailable() const; 207 bool isChunked(); 208 bool isConnectionCloseEnabled(); 209 bool isGzipped(); 210 #ifndef QT_NO_COMPRESS 211 bool gzipCheckHeader(QByteArray &content, int &pos); 212 int gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated); 213 void gunzipBodyPartiallyEnd(); 214 #endif 215 void removeAutoDecompressHeader(); 216 217 enum ReplyState { 218 NothingDoneState, 219 ReadingStatusState, 220 ReadingHeaderState, 221 ReadingDataState, 222 AllDoneState 223 } state; 224 225 QHttpNetworkRequest request; 226 bool ssl; 227 int statusCode; 228 int majorVersion; 229 int minorVersion; 230 QString errorString; 231 QString reasonPhrase; 232 qint64 bodyLength; 233 qint64 contentRead; 234 qint64 totalProgress; 235 QByteArray fragment; // used for header, status, chunk header etc, not for reply data 236 bool chunkedTransferEncoding; 237 bool connectionCloseEnabled; 238 bool forceConnectionCloseEnabled; 239 bool lastChunkRead; 240 qint64 currentChunkSize; 241 qint64 currentChunkRead; 242 qint64 readBufferMaxSize; 243 QPointer<QHttpNetworkConnection> connection; 244 QPointer<QHttpNetworkConnectionChannel> connectionChannel; 245 bool initInflate; 246 bool streamEnd; 247 #ifndef QT_NO_COMPRESS 248 z_stream inflateStrm; 249 #endif 250 bool autoDecompress; 251 252 QByteDataBuffer responseData; // uncompressed body 253 QByteArray compressedData; // compressed body (temporary) 254 bool requestIsPrepared; 255 256 bool pipeliningUsed; 257 bool downstreamLimited; 258 259 char* userProvidedDownloadBuffer; 260 }; 261 262 263 264 265 QT_END_NAMESPACE 266 267 //Q_DECLARE_METATYPE(QHttpNetworkReply) 268 269 #endif // QT_NO_HTTP 270 271 272 #endif // QHTTPNETWORKREPLY_H 273