cutelyst 4.3.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 auto it = streams.constBegin();
80 while (it != streams.constEnd()) {
81 // If we deleteLater the context, there might
82 // be an event that tries to finalize the request
83 // and it will encounter a null context pointer
84 delete it.value()->context;
85 delete it.value();
86 ++it;
87 }
88 streams.clear();
89
90 headersBuffer.clear();
91 maxStreamId = 0;
92 streamForContinuation = 0;
93 dataSent = 0;
94 windowSize = 65535;
95 settingsInitialWindowSize = 65535;
96 canPush = false;
97 }
98
99 quint32 stream_id = 0;
100 quint32 pktsize = 0;
101
102 QByteArray headersBuffer;
103 HPack *hpack = nullptr;
104 quint64 streamForContinuation = 0;
105 quint32 maxStreamId = 0;
106 qint32 dataSent = 0;
107 qint32 windowSize = 65535;
108 qint32 settingsInitialWindowSize = 65535;
109 quint32 settingsMaxFrameSize = 16384;
110 quint8 processing = 0;
111 bool canPush = true;
112
114};
115
116class ProtocolHttp2 final : public Protocol
117{
118public:
119 explicit ProtocolHttp2(Server *wsgi);
120 ~ProtocolHttp2() override;
121
122 Type type() const override;
123
124 void parse(Cutelyst::Socket *sock, QIODevice *io) const override final;
125
126 ProtocolData *createData(Cutelyst::Socket *sock) const override final;
127
128 int parseSettings(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
129 int parseData(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
130 int parseHeaders(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
131 int parsePriority(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
132 int parsePing(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
133 int parseRstStream(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
134 int parseWindowUpdate(ProtoRequestHttp2 *request, QIODevice *io, const H2Frame &fr) const;
135
136 int sendGoAway(QIODevice *io, quint32 lastStreamId, quint32 error) const;
137 int sendRstStream(QIODevice *io, quint32 streamId, quint32 error) const;
138 int sendSettings(QIODevice *io, const std::vector<std::pair<quint16, quint32>> &settings) const;
139 int sendSettingsAck(QIODevice *io) const;
140 int sendPing(QIODevice *io, quint8 flags, const char *data = nullptr, qint32 dataLen = 0) const;
141 int sendData(QIODevice *io,
142 quint32 streamId,
143 qint32 flags,
144 const char *data,
145 qint32 dataLen) const;
146 int sendFrame(QIODevice *io,
147 quint8 type,
148 quint8 flags = 0,
149 quint32 streamId = 0,
150 const char *data = nullptr,
151 qint32 dataLen = 0) const;
152
153 void queueStream(Cutelyst::Socket *socket, H2Stream *stream) const;
154
155 bool
156 upgradeH2C(Cutelyst::Socket *socket, QIODevice *io, const Cutelyst::EngineRequest &request);
157
158public:
159 quint32 m_maxFrameSize;
160 qint32 m_headerTableSize;
161};
162
163} // namespace Cutelyst
164
165#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()