4#ifndef HTTP2CONNECTION_P_H
5#define HTTP2CONNECTION_P_H
18#include <private/qtnetworkglobal_p.h>
20#include <QtCore/qobject.h>
21#include <QtCore/qhash.h>
22#include <QtCore/qvarlengtharray.h>
23#include <QtCore/qxpfunctional.h>
24#include <QtNetwork/qhttp2configuration.h>
25#include <QtNetwork/qtcpsocket.h>
27#include <private/http2protocol_p.h>
28#include <private/http2streams_p.h>
29#include <private/http2frames_p.h>
30#include <private/hpack_p.h>
39template <
typename T,
typename Err>
42 static_assert(!std::is_same_v<T, Err>,
"T and Err must be different types");
52 m_data = std::move(
value);
62 m_data = std::move(
error);
73 return std::get<T>(m_data);
78 return std::get<Err>(m_data);
80 bool ok() const noexcept {
return std::holds_alternative<T>(m_data); }
82 bool has_error() const noexcept {
return std::holds_alternative<Err>(m_data); }
83 void clear() noexcept { m_data.reset(); }
86 std::variant<T, Err> m_data;
96 enum class State { Idle, ReservedRemote, Open, HalfClosedLocal, HalfClosedRemote, Closed };
98 constexpr static
quint8 DefaultPriority = 127;
103 quint32 streamID() const noexcept {
return m_streamID; }
106 bool isUploadBlocked() const noexcept;
107 bool isUploadingDATA() const noexcept {
return m_uploadByteDevice !=
nullptr; }
109 bool isActive() const noexcept {
return m_state != State::Closed && m_state != State::Idle; }
111 bool wasReset() const noexcept {
return m_RST_STREAM_code.has_value(); }
132 bool sendRST_STREAM(
quint32 errorCode);
134 quint8 priority = DefaultPriority);
137 void sendWINDOW_UPDATE(
quint32 delta);
140 void maybeResumeUpload();
141 void uploadDeviceReadChannelFinished();
142 void uploadDeviceDestroyed();
150 return qobject_cast<QHttp2Connection *>(parent());
153 enum class StateTransition {
161 void transitionState(StateTransition transition);
162 void internalSendDATA();
163 void finishSendDATA();
166 void handleHEADERS(Http2::FrameFlags frameFlags,
const HPack::HttpHeader &headers);
167 void handleRST_STREAM(
const Http2::Frame &inboundFrame);
168 void handleWINDOW_UPDATE(
const Http2::Frame &inboundFrame);
171 void finishWithError(
quint32 errorCode);
177 bool m_endStreamAfterDATA =
false;
178 std::optional<quint32> m_RST_STREAM_code;
184 State m_state = State::Idle;
186 bool m_isReserved =
false;
196 MaxConcurrentStreamsReached,
204 PongSignatureIdentical,
205 PongSignatureChanged,
219 [[nodiscard]] QH2Expected<QHttp2Stream *, CreateStreamError> createStream();
224 if (
quint32 id = m_promisedStreams.value(streamKey, 0);
id)
225 return m_streams.value(
id);
250 void handleReadyRead();
251 void handleConnectionClosure();
255 [[nodiscard]]
QIODevice *getSocket()
const {
return qobject_cast<QIODevice *>(parent()); }
257 QH2Expected<QHttp2Stream *, QHttp2Connection::CreateStreamError> createStreamInternal();
260 bool isInvalidStream(
quint32 streamID)
noexcept;
261 bool streamWasReset(
quint32 streamID)
noexcept;
268 qsizetype numActiveRemoteStreams() const noexcept;
269 qsizetype numActiveLocalStreams() const noexcept;
271 bool sendClientPreface();
273 bool sendServerPreface();
274 bool serverCheckClientPreface();
276 bool sendGOAWAY(
quint32 errorCode);
277 bool sendSETTINGS_ACK();
280 void handleHEADERS();
281 void handlePRIORITY();
282 void handleRST_STREAM();
283 void handleSETTINGS();
284 void handlePUSH_PROMISE();
287 void handleWINDOW_UPDATE();
288 void handleCONTINUATION();
290 void handleContinuedHEADERS();
292 bool acceptSetting(
Http2::Settings identifier,
quint32 newValue);
294 bool readClientPreface();
298 enum class
Type {
Client, Server } m_connectionType = Type::Client;
300 bool waitingForSettingsACK =
false;
309 QHash<quint32, QPointer<QHttp2Stream>> m_streams;
310 QHash<QUrl, quint32> m_promisedStreams;
311 QVarLengthArray<quint32> m_resetStreamIDs;
312 std::optional<QByteArray> m_lastPingSignature = std::nullopt;
325 bool continuationExpected =
false;
326 std::vector<Http2::Frame> continuedFrames;
357 quint32 m_maxHeaderListSize = (std::numeric_limits<quint32>::max)();
361 bool m_upgradedConnection =
false;
362 bool m_goingAway =
false;
363 bool pushPromiseEnabled =
false;
367 bool m_waitingForClientPreface =
false;
IOBluetoothDevice * device
bool has_error() const noexcept
QH2Expected & operator=(T &&value)
QH2Expected(const T &value)
bool has_value() const noexcept
QH2Expected & operator=(Err &&error)
QH2Expected(const Err &error)
QH2Expected & operator=(const T &value)
QH2Expected & operator=(const Err &error)
The QHttp2Configuration class controls HTTP/2 parameters and settings.
void receivedGOAWAY(quint32 errorCode, quint32 lastStreamID)
This signal is emitted when the connection has received a GOAWAY frame.
bool isGoingAway() const noexcept
Returns true if the connection is in the process of being closed, or false otherwise.
void pingFrameRecived(QHttp2Connection::PingState state)
QHttp2Stream * promisedStream(const QUrl &streamKey) const
Returns a pointer to the stream that was promised with the given streamKey, if any.
void errorOccurred(Http2::Http2Error errorCode, const QString &errorString)
This signal is emitted when the connection has encountered an error.
void connectionClosed()
This signal is emitted when the connection has been closed.
void settingsFrameReceived()
This signal is emitted when the connection has received a SETTINGS frame.
quint32 maxConcurrentStreams() const noexcept
Returns the maximum number of concurrent streams we are allowed to have active at any given time.
void close()
This sends a GOAWAY frame on the connection stream, gracefully closing the connection.
bool isUpgradedConnection() const noexcept
Returns true if this connection was created as a result of an HTTP/1 upgrade to HTTP/2,...
void errorReceived()
This signal is emitted when the connection has received an error.
void newIncomingStream(QHttp2Stream *stream)
This signal is emitted when a new stream is received from the remote peer.
void newPromisedStream(QHttp2Stream *stream)
This signal is emitted when the remote peer has promised a new stream.
quint32 maxHeaderListSize() const noexcept
Returns the maximum size of the header which the peer is willing to accept.
bool isActive() const noexcept
Returns true if the stream has been opened and is not yet closed.
void dataReceived(const QByteArray &data, bool endStream)
This signal is emitted when the stream has received a DATA frame from the remote peer.
void stateChanged(QHttp2Stream::State newState)
This signal is emitted when the state of the stream changes.
State state() const noexcept
Returns the current state of the stream.
quint32 RST_STREAM_code() const noexcept
Returns the HTTP/2 error code if the stream was reset by the remote peer.
bool isPromisedStream() const noexcept
Returns true if the stream was promised by the remote peer.
void uploadDeviceError(const QString &errorString)
This signal is emitted if the upload device encounters an error while sending data.
void uploadBlocked()
This signal is emitted when the stream is unable to send more data because the remote peer's receive ...
void bytesWritten(qint64 bytesWritten)
This signal is emitted when the stream has written bytesWritten bytes to the network.
HPack::HttpHeader receivedHeaders() const noexcept
Returns the headers received from the remote peer, if any.
bool wasReset() const noexcept
Returns true if the stream was reset by the remote peer.
void promisedStreamReceived(quint32 newStreamID)
This signal is emitted when the remote peer has promised a new stream with the given newStreamID.
void uploadFinished()
This signal is emitted when the stream has finished sending all the data from the upload device.
void headersUpdated()
This signal may be emitted if a new HEADERS frame was received after already processing a previous HE...
void errorOccurred(quint32 errorCode, const QString &errorString)
This signal is emitted when the stream has encountered an error.
void headersReceived(const HPack::HttpHeader &headers, bool endStream)
This signal is emitted when the remote peer has sent a HEADERS frame, and potentially some CONTINUATI...
QByteDataBuffer downloadBuffer() const noexcept
Returns the buffer containing the data received from the remote peer.
\inmodule QtCore \reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
std::vector< HeaderField > HttpHeader
@ defaultSessionWindowSize
const qint32 maxSessionReceiveWindowSize((quint32(1)<< 31) - 1)
Combined button and popup list for selecting options.
DBusConnection * connection
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLsizei GLuint GLint * bytesWritten
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLsizei const GLchar * message
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask