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
4#ifndef QHTTPNETWORKREPLY_H
5#define QHTTPNETWORKREPLY_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of the Network Access API. This header file may change from
13// version to version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtNetwork/private/qtnetworkglobal_p.h>
19
20#include <qplatformdefs.h>
21
22#include <QtNetwork/qtcpsocket.h>
23// it's safe to include these even if SSL support is not enabled
24#include <QtNetwork/qsslsocket.h>
25#include <QtNetwork/qsslerror.h>
26
27#include <QtNetwork/qnetworkrequest.h>
28#include <QtNetwork/qnetworkreply.h>
29#include <qbuffer.h>
30
31#include <private/qobject_p.h>
32#include <private/qhttpnetworkheader_p.h>
33#include <private/qhttpnetworkrequest_p.h>
34#include <private/qauthenticator_p.h>
35#include <private/qringbuffer_p.h>
36#include <private/qbytedata_p.h>
37
38#ifndef QT_NO_NETWORKPROXY
39Q_MOC_INCLUDE(<QtNetwork/QNetworkProxy>)
40#endif
41Q_MOC_INCLUDE(<QtNetwork/QAuthenticator>)
42
43#include <private/qdecompresshelper_p.h>
44
45QT_REQUIRE_CONFIG(http);
46
47QT_BEGIN_NAMESPACE
48
49class QHttpNetworkConnection;
50class QHttpNetworkConnectionChannel;
51class QHttpNetworkRequest;
52class QHttpNetworkConnectionPrivate;
53class QHttpNetworkReplyPrivate;
54class Q_AUTOTEST_EXPORT QHttpNetworkReply : public QObject, public QHttpNetworkHeader
55{
56 Q_OBJECT
57public:
58
59 explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = nullptr);
60 virtual ~QHttpNetworkReply();
61
62 QUrl url() const override;
63 void setUrl(const QUrl &url) override;
64
65 int majorVersion() const override;
66 int minorVersion() const override;
67 void setMajorVersion(int version);
68 void setMinorVersion(int version);
69
70 qint64 contentLength() const override;
71 void setContentLength(qint64 length) override;
72
73 QList<QPair<QByteArray, QByteArray> > header() const override;
74 QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const override;
75 void setHeaderField(const QByteArray &name, const QByteArray &data) override;
76 void appendHeaderField(const QByteArray &name, const QByteArray &data);
77 void parseHeader(const QByteArray &header); // used for testing
78
79 QHttpNetworkRequest request() const;
80 void setRequest(const QHttpNetworkRequest &request);
81
82 int statusCode() const;
83 void setStatusCode(int code);
84
85 QString errorString() const;
86 void setErrorString(const QString &error);
87
88 QNetworkReply::NetworkError errorCode() const;
89
90 QString reasonPhrase() const;
91 void setReasonPhrase(const QString &reason);
92
93 qint64 bytesAvailable() const;
94 qint64 bytesAvailableNextBlock() const;
95 bool readAnyAvailable() const;
96 QByteArray readAny();
97 QByteArray readAll();
98 QByteArray read(qint64 amount);
99 qint64 sizeNextBlock();
100 void setDownstreamLimited(bool t);
101 void setReadBufferSize(qint64 size);
102
103 bool supportsUserProvidedDownloadBuffer();
104 void setUserProvidedDownloadBuffer(char*);
105 char* userProvidedDownloadBuffer();
106
107 void abort();
108
109 bool isAborted() const;
110 bool isFinished() const;
111
112 bool isPipeliningUsed() const;
113 bool isHttp2Used() const;
114 void setHttp2WasUsed(bool h2Used);
115 qint64 removedContentLength() const;
116
117 bool isRedirecting() const;
118
119 QHttpNetworkConnection* connection();
120
121 QUrl redirectUrl() const;
122 void setRedirectUrl(const QUrl &url);
123
124 static bool isHttpRedirect(int statusCode);
125
126 bool isCompressed() const;
127
128#ifndef QT_NO_SSL
129 QSslConfiguration sslConfiguration() const;
130 void setSslConfiguration(const QSslConfiguration &config);
131 void ignoreSslErrors();
132 void ignoreSslErrors(const QList<QSslError> &errors);
133
134Q_SIGNALS:
135 void encrypted();
136 void sslErrors(const QList<QSslError> &errors);
137 void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator);
138#endif
139
140Q_SIGNALS:
141 void socketStartedConnecting();
142 void requestSent();
143 void readyRead();
144 void finished();
145 void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString());
146 void headerChanged();
147 void dataReadProgress(qint64 done, qint64 total);
148 void dataSendProgress(qint64 done, qint64 total);
149 void cacheCredentials(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
150#ifndef QT_NO_NETWORKPROXY
151 void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
152#endif
153 void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *authenticator);
154 void redirected(const QUrl &url, int httpStatus, int maxRedirectsRemaining);
155private:
156 Q_DECLARE_PRIVATE(QHttpNetworkReply)
157 friend class QHttpSocketEngine;
158 friend class QHttpNetworkConnection;
159 friend class QHttpNetworkConnectionPrivate;
160 friend class QHttpNetworkConnectionChannel;
161 friend class QHttp2ProtocolHandler;
162 friend class QHttpProtocolHandler;
163 friend class QSpdyProtocolHandler;
164};
165
166
167class Q_AUTOTEST_EXPORT QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate
168{
169public:
170 QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl());
171 ~QHttpNetworkReplyPrivate();
172 qint64 readStatus(QAbstractSocket *socket);
173 bool parseStatus(const QByteArray &status);
174 qint64 readHeader(QAbstractSocket *socket);
175 void parseHeader(const QByteArray &header);
176 void appendHeaderField(const QByteArray &name, const QByteArray &data);
177 qint64 readBody(QAbstractSocket *socket, QByteDataBuffer *out);
178 qint64 readBodyVeryFast(QAbstractSocket *socket, char *b);
179 qint64 readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb);
180 bool findChallenge(bool forProxy, QByteArray &challenge) const;
181 void clear();
182 void clearHttpLayerInformation();
183
184 qint64 readReplyBodyRaw(QAbstractSocket *in, QByteDataBuffer *out, qint64 size);
185 qint64 readReplyBodyChunked(QAbstractSocket *in, QByteDataBuffer *out);
186 qint64 getChunkSize(QAbstractSocket *in, qint64 *chunkSize);
187
188 bool isRedirecting() const;
189 bool shouldEmitSignals();
190 bool expectContent();
191 void eraseData();
192
193 qint64 bytesAvailable() const;
194 bool isChunked();
195 bool isConnectionCloseEnabled();
196
197 bool isCompressed() const;
198 void removeAutoDecompressHeader();
199
200 enum ReplyState {
201 NothingDoneState,
202 ReadingStatusState,
203 ReadingHeaderState,
204 ReadingDataState,
205 AllDoneState,
206 SPDYSYNSent,
207 SPDYUploading,
208 SPDYHalfClosed,
209 SPDYClosed,
210 Aborted
211 } state;
212
213 QHttpNetworkRequest request;
214 bool ssl;
215 QString errorString;
216 qint64 bodyLength;
217 qint64 contentRead;
218 qint64 totalProgress;
219 QByteArray fragment; // used for header, status, chunk header etc, not for reply data
220 bool chunkedTransferEncoding;
221 bool connectionCloseEnabled;
222 bool forceConnectionCloseEnabled;
223 bool lastChunkRead;
224 qint64 currentChunkSize;
225 qint64 currentChunkRead;
226 qint64 readBufferMaxSize;
227 qint64 totallyUploadedData; // HTTP/2
228 qint64 removedContentLength;
229 QPointer<QHttpNetworkConnection> connection;
230 QPointer<QHttpNetworkConnectionChannel> connectionChannel;
231 QNetworkReply::NetworkError httpErrorCode = QNetworkReply::NoError;
232
233 bool autoDecompress;
234
235 QByteDataBuffer responseData; // uncompressed body
236 bool requestIsPrepared;
237
238 bool pipeliningUsed;
239 bool h2Used;
240 bool downstreamLimited;
241
242 char* userProvidedDownloadBuffer;
243 QUrl redirectUrl;
244};
245
246
247
248
249QT_END_NAMESPACE
250
251#endif // QHTTPNETWORKREPLY_H
252

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