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
qhttpnetworkconnection_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 QHTTPNETWORKCONNECTION_H
6#define QHTTPNETWORKCONNECTION_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of the Network Access API. This header file may change from
14// version to version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtNetwork/private/qtnetworkglobal_p.h>
20#include <QtNetwork/qnetworkrequest.h>
21#include <QtNetwork/qnetworkreply.h>
22#include <QtNetwork/qabstractsocket.h>
23
24#include <qhttp2configuration.h>
25
26#include <private/qobject_p.h>
27#include <qauthenticator.h>
28#include <qnetworkproxy.h>
29#include <qbuffer.h>
30#include <qtimer.h>
31#include <qsharedpointer.h>
32
33#include <private/qhttpnetworkheader_p.h>
34#include <private/qhttpnetworkrequest_p.h>
35#include <private/qhttpnetworkreply_p.h>
36#include <private/http2protocol_p.h>
37
38#include <private/qhttpnetworkconnectionchannel_p.h>
39#include <private/qtcpkeepaliveconfiguration_p.h>
40
41#include <utility>
42
44
45QT_BEGIN_NAMESPACE
46
47class QHttpNetworkRequest;
48class QHttpNetworkReply;
50class QByteArray;
51class QHostInfo;
52#ifndef QT_NO_SSL
53class QSslConfiguration;
54class QSslContext;
55#endif // !QT_NO_SSL
56
58class Q_NETWORK_EXPORT QHttpNetworkConnection : public QObject
59{
60 Q_OBJECT
61public:
62
63 enum ConnectionType {
64 ConnectionTypeHTTP,
65 ConnectionTypeHTTP2,
66 ConnectionTypeHTTP2Direct
67 };
68
69 QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80,
70 bool encrypt = false, bool isLocalSocket = false,
71 QObject *parent = nullptr,
72 ConnectionType connectionType = ConnectionTypeHTTP);
73 ~QHttpNetworkConnection();
74
75 //The hostname to which this is connected to.
76 QString hostName() const;
77 //The HTTP port in use.
78 quint16 port() const;
79
80 //add a new HTTP request through this connection
81 QHttpNetworkReply* sendRequest(const QHttpNetworkRequest &request);
82 void fillHttp2Queue();
83
84#ifndef QT_NO_NETWORKPROXY
85 //set the proxy for this connection
86 void setCacheProxy(const QNetworkProxy &networkProxy);
87 QNetworkProxy cacheProxy() const;
88 void setTransparentProxy(const QNetworkProxy &networkProxy);
89 QNetworkProxy transparentProxy() const;
90#endif
91
92 bool isSsl() const;
93
94 QHttpNetworkConnectionChannel *channels() const;
95
96 ConnectionType connectionType() const;
97 void setConnectionType(ConnectionType type);
98
99 QHttp2Configuration http2Parameters() const;
100 void setHttp2Parameters(const QHttp2Configuration &params);
101
102 QTcpKeepAliveConfiguration tcpKeepAliveParameters() const;
103 void setTcpKeepAliveParameters(QTcpKeepAliveConfiguration config);
104
105#ifndef QT_NO_SSL
106 void setSslConfiguration(const QSslConfiguration &config);
107 void ignoreSslErrors(int channel = -1);
108 void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1);
109 std::shared_ptr<QSslContext> sslContext() const;
110 void setSslContext(std::shared_ptr<QSslContext> context);
111#endif
112
113 void preConnectFinished();
114
115 QString peerVerifyName() const;
116 void setPeerVerifyName(const QString &peerName);
117
118public slots:
119 void onlineStateChanged(bool isOnline);
120
121private:
122 Q_DECLARE_PRIVATE(QHttpNetworkConnection)
123 Q_DISABLE_COPY_MOVE(QHttpNetworkConnection)
124 friend class QHttpThreadDelegate;
125 friend class QHttpNetworkReply;
126 friend class QHttpNetworkReplyPrivate;
127 friend class QHttpNetworkConnectionChannel;
128 friend class QHttp2ProtocolHandler;
129 friend class QHttpProtocolHandler;
130
131 Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
132 Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo))
133 Q_PRIVATE_SLOT(d_func(), void _q_connectDelayedChannel())
134};
135
136
137// private classes
138typedef std::pair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
139
140
142{
143 Q_DECLARE_PUBLIC(QHttpNetworkConnection)
145public:
146 // Note: Only used from auto tests, normal usage is via QHttp1Configuration
147 static constexpr int defaultHttpChannelCount = 6;
148 static const int defaultPipelineLength;
149 static const int defaultRePipelineLength;
150
155
163
164 QHttpNetworkConnectionPrivate(quint16 connectionCount, const QString &hostName, quint16 port,
165 bool encrypt, bool isLocalSocket,
166 QHttpNetworkConnection::ConnectionType type);
168 void init();
169
170 void pauseConnection();
171 void resumeConnection();
174
175 enum { ChunkSize = 4096 };
176
177 int indexOf(QIODevice *socket) const;
178
179 QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request);
180 void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke
181 void fillHttp2Queue();
182 bool dequeueRequest(QIODevice *socket);
183 void prepareRequest(HttpMessagePair &request);
184 void updateChannel(int i, const HttpMessagePair &messagePair);
185 QHttpNetworkRequest predictNextRequest() const;
186 QHttpNetworkReply* predictNextRequestsReply() const;
187
188 void fillPipeline(QIODevice *socket);
189 bool fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel);
190
191 // read more HTTP body after the next event loop spin
192 void readMoreLater(QHttpNetworkReply *reply);
193
194 void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy);
195
196 void startHostInfoLookup();
198 void networkLayerDetected(QAbstractSocket::NetworkLayerProtocol protocol);
199
200 // private slots
201 void _q_startNextRequest(); // send the next request from the queue
202
203 void _q_hostLookupFinished(const QHostInfo &info);
205
206 void createAuthorization(QIODevice *socket, QHttpNetworkRequest &request);
207
208 QString errorDetail(QNetworkReply::NetworkError errorCode, QIODevice *socket,
209 const QString &extraDetail = QString());
210
211 void removeReply(QHttpNetworkReply *reply);
212
213 QString hostName;
217 bool delayIpv4 = true;
218
219 // Number of channels we are trying to use at the moment:
221 // The total number of channels we reserved:
222 const int channelCount;
224 QHttpNetworkConnectionChannel * const channels; // parallel connections to the server
225 bool shouldEmitChannelError(QIODevice *socket);
226
227 qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const;
228 qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const;
229
230
231 void emitReplyError(QIODevice *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode);
232 bool handleAuthenticateChallenge(QIODevice *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
237 static ParseRedirectResult parseRedirectResponse(QHttpNetworkReply *reply);
238 // Used by the HTTP1 code-path
239 QUrl parseRedirectResponse(QIODevice *socket, QHttpNetworkReply *reply);
240
241#ifndef QT_NO_NETWORKPROXY
243 void emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth);
244#endif
245
246 //The request queues
249
251
253
254#ifndef QT_NO_SSL
256#endif
257
258 QHttp2Configuration http2Parameters;
259
261
263
265};
266
267
268
269QT_END_NAMESPACE
270
271#endif
qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const
bool shouldEmitChannelError(QIODevice *socket)
void createAuthorization(QIODevice *socket, QHttpNetworkRequest &request)
void emitReplyError(QIODevice *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode)
QTcpKeepAliveConfiguration tcpKeepAliveConfiguration
QUrl parseRedirectResponse(QIODevice *socket, QHttpNetworkReply *reply)
QHttpNetworkRequest predictNextRequest() const
void prepareRequest(HttpMessagePair &request)
NetworkLayerPreferenceState networkLayerState
void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy)
std::shared_ptr< QSslContext > sslContext
void networkLayerDetected(QAbstractSocket::NetworkLayerProtocol protocol)
void requeueRequest(const HttpMessagePair &pair)
QList< HttpMessagePair > lowPriorityQueue
void removeReply(QHttpNetworkReply *reply)
void _q_hostLookupFinished(const QHostInfo &info)
QHttpNetworkReply * predictNextRequestsReply() const
QList< HttpMessagePair > highPriorityQueue
void updateChannel(int i, const HttpMessagePair &messagePair)
bool handleAuthenticateChallenge(QIODevice *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend)
QHttpNetworkReply * queueRequest(const QHttpNetworkRequest &request)
QHttpNetworkConnectionChannel *const channels
void readMoreLater(QHttpNetworkReply *reply)
int indexOf(QIODevice *socket) const
qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const
static ParseRedirectResult parseRedirectResponse(QHttpNetworkReply *reply)
Combined button and popup list for selecting options.
QT_REQUIRE_CONFIG(http)
std::pair< QHttpNetworkRequest, QHttpNetworkReply * > HttpMessagePair