Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qhttp2protocolhandler_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
4#ifndef QHTTP2PROTOCOLHANDLER_P_H
5#define QHTTP2PROTOCOLHANDLER_P_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 <private/qhttpnetworkconnectionchannel_p.h>
19#include <private/qabstractprotocolhandler_p.h>
20#include <private/qhttpnetworkrequest_p.h>
21
23
24#include <private/http2protocol_p.h>
25#include <private/http2streams_p.h>
26#include <private/http2frames_p.h>
27#include <private/hpacktable_p.h>
28#include <private/hpack_p.h>
29
30#include <QtCore/qnamespace.h>
31#include <QtCore/qbytearray.h>
32#include <QtCore/qglobal.h>
33#include <QtCore/qobject.h>
34#include <QtCore/qflags.h>
35#include <QtCore/qhash.h>
36
37#include <vector>
38#include <limits>
39#include <deque>
40#include <set>
41
43
45
47{
49
50public:
52
55
58
61
62private slots:
63 void _q_uploadDataReadyRead();
64 void _q_replyDestroyed(QObject* reply);
65 void _q_uploadDataDestroyed(QObject* uploadData);
66
67private:
68 using Stream = Http2::Stream;
69
70 void _q_readyRead() override;
71 Q_INVOKABLE void _q_receiveReply() override;
72 Q_INVOKABLE bool sendRequest() override;
73
74 bool sendClientPreface();
75 bool sendSETTINGS_ACK();
76 bool sendHEADERS(Stream &stream);
77 bool sendDATA(Stream &stream);
78 Q_INVOKABLE bool sendWINDOW_UPDATE(quint32 streamID, quint32 delta);
79 bool sendRST_STREAM(quint32 streamID, quint32 errorCoder);
80 bool sendGOAWAY(quint32 errorCode);
81
82 void handleDATA();
83 void handleHEADERS();
84 void handlePRIORITY();
85 void handleRST_STREAM();
86 void handleSETTINGS();
87 void handlePUSH_PROMISE();
88 void handlePING();
89 void handleGOAWAY();
90 void handleWINDOW_UPDATE();
91 void handleCONTINUATION();
92
93 void handleContinuedHEADERS();
94
95 bool acceptSetting(Http2::Settings identifier, quint32 newValue);
96
97 void handleAuthorization(Stream &stream);
98 void updateStream(Stream &stream, const HPack::HttpHeader &headers,
100 void updateStream(Stream &stream, const Http2::Frame &dataFrame,
102 void finishStream(Stream &stream, Qt::ConnectionType connectionType = Qt::DirectConnection);
103 // Error code send by a peer (GOAWAY/RST_STREAM):
104 void finishStreamWithError(Stream &stream, quint32 errorCode);
105 // Locally encountered error:
106 void finishStreamWithError(Stream &stream, QNetworkReply::NetworkError error,
107 const QString &message);
108
109 // Stream's lifecycle management:
110 quint32 createNewStream(const HttpMessagePair &message, bool uploadDone = false);
111 void addToSuspended(Stream &stream);
112 void markAsReset(quint32 streamID);
113 quint32 popStreamToResume();
114 void removeFromSuspended(quint32 streamID);
115 void deleteActiveStream(quint32 streamID);
116 bool streamWasReset(quint32 streamID) const;
117
118 bool prefaceSent = false;
119 // In the current implementation we send
120 // SETTINGS only once, immediately after
121 // the client's preface 24-byte message.
122 bool waitingForSettingsACK = false;
123
124 inline static const quint32 maxAcceptableTableSize = 16 * HPack::FieldLookupTable::DefaultSize;
125 // HTTP/2 4.3: Header compression is stateful. One compression context and
126 // one decompression context are used for the entire connection.
127 HPack::Decoder decoder;
128 HPack::Encoder encoder;
129
130 QHash<QObject *, int> streamIDs;
131 QHash<quint32, Stream> activeStreams;
132 std::deque<quint32> suspendedStreams[3]; // 3 for priorities: High, Normal, Low.
133 inline static const std::deque<quint32>::size_type maxRecycledStreams = 10000;
134 std::deque<quint32> recycledStreams;
135
136 // Peer's max frame size (this min is the default value
137 // we start with, that can be updated by SETTINGS frame):
138 quint32 maxFrameSize = Http2::minPayloadLimit;
139
140 Http2::FrameReader frameReader;
141 Http2::Frame inboundFrame;
142 Http2::FrameWriter frameWriter;
143 // Temporary storage to assemble HEADERS' block
144 // from several CONTINUATION frames ...
145 bool continuationExpected = false;
146 std::vector<Http2::Frame> continuedFrames;
147
148 // Control flow:
149
150 // This is how many concurrent streams our peer allows us, 100 is the
151 // initial value, can be updated by the server's SETTINGS frame(s):
152 quint32 maxConcurrentStreams = Http2::maxConcurrentStreams;
153 // While we allow sending SETTTINGS_MAX_CONCURRENT_STREAMS to limit our peer,
154 // it's just a hint and we do not actually enforce it (and we can continue
155 // sending requests and creating streams while maxConcurrentStreams allows).
156
157 // This is our (client-side) maximum possible receive window size, we set
158 // it in a ctor from QHttp2Configuration, it does not change after that.
159 // The default is 64Kb:
160 qint32 maxSessionReceiveWindowSize = Http2::defaultSessionWindowSize;
161
162 // Our session current receive window size, updated in a ctor from
163 // QHttp2Configuration. Signed integer since it can become negative
164 // (it's still a valid window size).
165 qint32 sessionReceiveWindowSize = Http2::defaultSessionWindowSize;
166 // Our per-stream receive window size, default is 64 Kb, will be updated
167 // from QHttp2Configuration. Again, signed - can become negative.
168 qint32 streamInitialReceiveWindowSize = Http2::defaultSessionWindowSize;
169
170 // These are our peer's receive window sizes, they will be updated by the
171 // peer's SETTINGS and WINDOW_UPDATE frames, defaults presumed to be 64Kb.
172 qint32 sessionSendWindowSize = Http2::defaultSessionWindowSize;
173 qint32 streamInitialSendWindowSize = Http2::defaultSessionWindowSize;
174
175 // Our peer's header size limitations. It's unlimited by default, but can
176 // be changed via peer's SETTINGS frame.
177 quint32 maxHeaderListSize = (std::numeric_limits<quint32>::max)();
178 // While we can send SETTINGS_MAX_HEADER_LIST_SIZE value (our limit on
179 // the headers size), we never enforce it, it's just a hint to our peer.
180
181 Q_INVOKABLE void resumeSuspendedStreams();
182 // Our stream IDs (all odd), the first valid will be 1.
183 quint32 nextID = 1;
184 quint32 allocateStreamID();
185 bool validPeerStreamID() const;
186 bool goingAway = false;
187 bool pushPromiseEnabled = false;
188 quint32 lastPromisedID = Http2::connectionStreamID;
189 QHash<QString, Http2::PushPromise> promisedData;
190 bool tryReserveStream(const Http2::Frame &pushPromiseFrame,
191 const HPack::HttpHeader &requestHeader);
192 void resetPromisedStream(const Http2::Frame &pushPromiseFrame,
193 Http2::Http2Error reason);
194 void initReplyFromPushPromise(const HttpMessagePair &message,
195 const QString &cacheKey);
196 // Errors:
197 void connectionError(Http2::Http2Error errorCode,
198 const char *message);
199 void closeSession();
200};
201
203
204#endif
IOBluetoothL2CAPChannel * channel
QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *channel)
Q_INVOKABLE void handleConnectionClosure()
Q_INVOKABLE void _q_receiveReply() override
QHttp2ProtocolHandler & operator=(const QHttp2ProtocolHandler &rhs)=delete
Q_INVOKABLE bool sendRequest() override
Q_INVOKABLE void ensureClientPrefaceSent()
QHttp2ProtocolHandler(QHttp2ProtocolHandler &&rhs)=delete
QHttp2ProtocolHandler(const QHttp2ProtocolHandler &rhs)=delete
NetworkError
Indicates all possible error conditions found during the processing of the request.
\inmodule QtCore
Definition qobject.h:103
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
std::vector< HeaderField > HttpHeader
Definition hpack_p.h:33
@ maxConcurrentStreams
@ defaultSessionWindowSize
@ connectionStreamID
@ minPayloadLimit
Combined button and popup list for selecting options.
ConnectionType
@ DirectConnection
DBusConnection const char DBusError * error
EGLStreamKHR stream
QPair< QHttpNetworkRequest, QHttpNetworkReply * > HttpMessagePair
static QByteArray cacheKey(Args &&...args)
GLuint GLsizei const GLchar * message
#define QT_REQUIRE_CONFIG(feature)
#define Q_OBJECT
#define Q_INVOKABLE
#define slots
unsigned int quint32
Definition qtypes.h:50
int qint32
Definition qtypes.h:49
QNetworkReply * reply