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
40#include <utility>
41
43
44QT_BEGIN_NAMESPACE
45
46class QHttpNetworkRequest;
47class QHttpNetworkReply;
49class QByteArray;
50class QHostInfo;
51#ifndef QT_NO_SSL
52class QSslConfiguration;
53class QSslContext;
54#endif // !QT_NO_SSL
55
57class Q_NETWORK_EXPORT QHttpNetworkConnection : public QObject
58{
59 Q_OBJECT
60public:
61
62 enum ConnectionType {
63 ConnectionTypeHTTP,
64 ConnectionTypeHTTP2,
65 ConnectionTypeHTTP2Direct
66 };
67
68 QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80,
69 bool encrypt = false, bool isLocalSocket = false,
70 QObject *parent = nullptr,
71 ConnectionType connectionType = ConnectionTypeHTTP);
72 ~QHttpNetworkConnection();
73
74 //The hostname to which this is connected to.
75 QString hostName() const;
76 //The HTTP port in use.
77 quint16 port() const;
78
79 //add a new HTTP request through this connection
80 QHttpNetworkReply* sendRequest(const QHttpNetworkRequest &request);
81 void fillHttp2Queue();
82
83#ifndef QT_NO_NETWORKPROXY
84 //set the proxy for this connection
85 void setCacheProxy(const QNetworkProxy &networkProxy);
86 QNetworkProxy cacheProxy() const;
87 void setTransparentProxy(const QNetworkProxy &networkProxy);
88 QNetworkProxy transparentProxy() const;
89#endif
90
91 bool isSsl() const;
92
93 QHttpNetworkConnectionChannel *channels() const;
94
95 ConnectionType connectionType() const;
96 void setConnectionType(ConnectionType type);
97
98 QHttp2Configuration http2Parameters() const;
99 void setHttp2Parameters(const QHttp2Configuration &params);
100
101#ifndef QT_NO_SSL
102 void setSslConfiguration(const QSslConfiguration &config);
103 void ignoreSslErrors(int channel = -1);
104 void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1);
105 std::shared_ptr<QSslContext> sslContext() const;
106 void setSslContext(std::shared_ptr<QSslContext> context);
107#endif
108
109 void preConnectFinished();
110
111 QString peerVerifyName() const;
112 void setPeerVerifyName(const QString &peerName);
113
114public slots:
115 void onlineStateChanged(bool isOnline);
116
117private:
118 Q_DECLARE_PRIVATE(QHttpNetworkConnection)
119 Q_DISABLE_COPY_MOVE(QHttpNetworkConnection)
120 friend class QHttpThreadDelegate;
121 friend class QHttpNetworkReply;
122 friend class QHttpNetworkReplyPrivate;
123 friend class QHttpNetworkConnectionChannel;
124 friend class QHttp2ProtocolHandler;
125 friend class QHttpProtocolHandler;
126
127 Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
128 Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo))
129 Q_PRIVATE_SLOT(d_func(), void _q_connectDelayedChannel())
130};
131
132
133// private classes
134typedef std::pair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
135
136
138{
139 Q_DECLARE_PUBLIC(QHttpNetworkConnection)
141public:
142 // Note: Only used from auto tests, normal usage is via QHttp1Configuration
143 static constexpr int defaultHttpChannelCount = 6;
144 static const int defaultPipelineLength;
145 static const int defaultRePipelineLength;
146
151
159
160 QHttpNetworkConnectionPrivate(quint16 connectionCount, const QString &hostName, quint16 port,
161 bool encrypt, bool isLocalSocket,
162 QHttpNetworkConnection::ConnectionType type);
164 void init();
165
166 void pauseConnection();
167 void resumeConnection();
170
171 enum { ChunkSize = 4096 };
172
173 int indexOf(QIODevice *socket) const;
174
175 QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request);
176 void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke
177 void fillHttp2Queue();
178 bool dequeueRequest(QIODevice *socket);
179 void prepareRequest(HttpMessagePair &request);
180 void updateChannel(int i, const HttpMessagePair &messagePair);
181 QHttpNetworkRequest predictNextRequest() const;
182 QHttpNetworkReply* predictNextRequestsReply() const;
183
184 void fillPipeline(QIODevice *socket);
185 bool fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel);
186
187 // read more HTTP body after the next event loop spin
188 void readMoreLater(QHttpNetworkReply *reply);
189
190 void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy);
191
192 void startHostInfoLookup();
194 void networkLayerDetected(QAbstractSocket::NetworkLayerProtocol protocol);
195
196 // private slots
197 void _q_startNextRequest(); // send the next request from the queue
198
199 void _q_hostLookupFinished(const QHostInfo &info);
201
202 void createAuthorization(QIODevice *socket, QHttpNetworkRequest &request);
203
204 QString errorDetail(QNetworkReply::NetworkError errorCode, QIODevice *socket,
205 const QString &extraDetail = QString());
206
207 void removeReply(QHttpNetworkReply *reply);
208
209 QString hostName;
213 bool delayIpv4 = true;
214
215 // Number of channels we are trying to use at the moment:
217 // The total number of channels we reserved:
218 const int channelCount;
220 QHttpNetworkConnectionChannel * const channels; // parallel connections to the server
221 bool shouldEmitChannelError(QIODevice *socket);
222
223 qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const;
224 qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const;
225
226
227 void emitReplyError(QIODevice *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode);
228 bool handleAuthenticateChallenge(QIODevice *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
233 static ParseRedirectResult parseRedirectResponse(QHttpNetworkReply *reply);
234 // Used by the HTTP1 code-path
235 QUrl parseRedirectResponse(QIODevice *socket, QHttpNetworkReply *reply);
236
237#ifndef QT_NO_NETWORKPROXY
239 void emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth);
240#endif
241
242 //The request queues
245
247
249
250#ifndef QT_NO_SSL
252#endif
253
254 QHttp2Configuration http2Parameters;
255
257
259};
260
261
262
263QT_END_NAMESPACE
264
265#endif
QString errorDetail(QNetworkReply::NetworkError errorCode, QIODevice *socket, const QString &extraDetail=QString())
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)
QUrl parseRedirectResponse(QIODevice *socket, QHttpNetworkReply *reply)
QHttpNetworkRequest predictNextRequest() const
void prepareRequest(HttpMessagePair &request)
QHttpNetworkConnectionPrivate(quint16 connectionCount, const QString &hostName, quint16 port, bool encrypt, bool isLocalSocket, QHttpNetworkConnection::ConnectionType type)
void emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator *auth)
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)
bool fillPipeline(QList< HttpMessagePair > &queue, QHttpNetworkConnectionChannel &channel)
int indexOf(QIODevice *socket) const
qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const
static ParseRedirectResult parseRedirectResponse(QHttpNetworkReply *reply)
QT_REQUIRE_CONFIG(http)
std::pair< QHttpNetworkRequest, QHttpNetworkReply * > HttpMessagePair