cutelyst 5.0.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
protocolhttp2.h
1/*
2 * SPDX-FileCopyrightText: (C) 2018 Daniel Nicoletti <dantti12@gmail.com>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#ifndef PROTOCOLHTTP2_H
6#define PROTOCOLHTTP2_H
7
8#include "hpack.h"
9#include "protocol.h"
10#include "socket.h"
11
12#include <context.h>
13#include <enginerequest.h>
14
15#include <QObject>
16
17// namespace Cutelyst {
18// class Headers;
19// }
20
21class QEventLoop;
22namespace Cutelyst {
23
25{
26public:
27 quint32 len;
28 quint32 streamId;
29 quint8 type;
30 quint8 flags;
31};
32
35{
36public:
37 enum State { Idle, Open, HalfClosed, Closed };
38 H2Stream(quint32 streamId, qint32 initialWindowSize, ProtoRequestHttp2 *protoRequestH2);
39 ~H2Stream() override;
40
41 qint64 doWrite(const char *data, qint64 len) override final;
42
43 bool writeHeaders(quint16 status, const Cutelyst::Headers &headers) override final;
44
45 void processingFinished() override final;
46
47 void windowUpdated();
48
49 QEventLoop *loop = nullptr;
50 QByteArray scheme;
51 ProtoRequestHttp2 *protoRequest;
52 quint32 streamId;
53 qint32 windowSize = 65535;
54 qint64 contentLength = -1;
55 qint32 dataSent = 0;
56 qint64 consumedData = 0;
57 quint8 state = Idle;
58 bool gotPath = false;
59};
60
61class ProtoRequestHttp2 final : public ProtocolData
62{
63 Q_GADGET
64public:
65 ProtoRequestHttp2(Cutelyst::Socket *sock, int bufferSize);
66 ~ProtoRequestHttp2() override;
67
68 void setupNewConnection(Cutelyst::Socket *sock) override final;
69
70 inline void resetData() override final
71 {
72 ProtocolData::resetData();
73
74 stream_id = 0;
75 pktsize = 0;
76 delete hpack;
77 hpack = nullptr;
78
79 for (const auto &stream : std::as_const(streams)) {
80 // If we deleteLater the context, there might
81 // be an event that tries to finalize the request
82 // and it will encounter a null context pointer
83 delete stream->context;
84 delete stream;
85 }
86
87 streams.clear();
88
89 headersBuffer.clear();
90 maxStreamId = 0;
91 streamForContinuation = 0;
92 dataSent = 0;
93 windowSize = 65535;
94 settingsInitialWindowSize = 65535;
95 canPush = false;
96 }
97
98 quint32 stream_id = 0;
99 quint32 pktsize = 0;
100
101 QByteArray headersBuffer;
102 HPack *hpack = nullptr;
103 quint64 streamForContinuation = 0;
104 quint32 maxStreamId = 0;
105 qint32 dataSent = 0;
106 qint32 windowSize = 65535;
107 qint32 settingsInitialWindowSize = 65535;
108 quint32 settingsMaxFrameSize = 16384;
109 quint8 processing = 0;
110 bool canPush = true;
111
113};
114
115class ProtocolHttp2 final : public Protocol
116{
117public:
118 explicit ProtocolHttp2(Server *wsgi);
119 ~ProtocolHttp2() override;
120
121 Type type() const override;
122
123 void parse(Cutelyst::Socket *sock, QIODevice *io) const override final;
124
125 ProtocolData *createData(Cutelyst::Socket *sock) const override final;
126
127 int parseSettings(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
128 int parseData(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
129 int parseHeaders(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
130 int parsePriority(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
131 int parsePing(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
132 int parseRstStream(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
133 int parseWindowUpdate(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
134
135 int sendGoAway(QIODevice *io, quint32 lastStreamId, quint32 error) const;
136 int sendRstStream(QIODevice *io, quint32 streamId, quint32 error) const;
137 int sendSettings(QIODevice *io, const std::vector<std::pair<quint16, quint32>> &settings) const;
138 int sendSettingsAck(QIODevice *io) const;
139 int sendPing(QIODevice *io, quint8 flags, const char *data = nullptr, qint32 dataLen = 0) const;
140 int sendData(QIODevice *io,
141 quint32 streamId,
142 qint32 flags,
143 const char *data,
144 qint32 dataLen) const;
145 int sendFrame(QIODevice *io,
146 quint8 type,
147 quint8 flags = 0,
148 quint32 streamId = 0,
149 const char *data = nullptr,
150 qint32 dataLen = 0) const;
151
152 void queueStream(Cutelyst::Socket *socket, H2Stream *stream) const;
153
154 bool
155 upgradeH2C(Cutelyst::Socket *socket, QIODevice *io, const Cutelyst::EngineRequest &request);
156
157public:
158 quint32 m_maxFrameSize;
159 qint32 m_headerTableSize;
160};
161
162} // namespace Cutelyst
163
164#endif // PROTOCOLHTTP2_H
qint64 doWrite(const char *data, qint64 len) override final
void processingFinished() override final
bool writeHeaders(quint16 status, const Cutelyst::Headers &headers) override final
Container for HTTP headers.
Definition headers.h:24
Implements a web server.
Definition server.h:60
The Cutelyst namespace holds all public Cutelyst API.
void clear()