cutelyst 5.1.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
protocolhttp.h
1/*
2 * SPDX-FileCopyrightText: (C) 2016-2018 Daniel Nicoletti <dantti12@gmail.com>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#ifndef PROTOCOLHTTP_H
6#define PROTOCOLHTTP_H
7
8#include "protocol.h"
9#include "socket.h"
10
11#include <Cutelyst/Context>
12
13#include <QObject>
14
15namespace Cutelyst {
16class Server;
17class Socket;
19 : public ProtocolData
21{
22 Q_GADGET
23public:
24 enum class WebSocketPhase {
25 WebSocketPhaseHeaders,
26 WebSocketPhaseSize,
27 WebSocketPhaseMask,
28 WebSocketPhasePayload,
29 };
30 Q_ENUM(WebSocketPhase)
31
32 enum OpCode {
33 OpCodeContinue = 0x0,
34 OpCodeText = 0x1,
35 OpCodeBinary = 0x2,
36 OpCodeReserved3 = 0x3,
37 OpCodeReserved4 = 0x4,
38 OpCodeReserved5 = 0x5,
39 OpCodeReserved6 = 0x6,
40 OpCodeReserved7 = 0x7,
41 OpCodeClose = 0x8,
42 OpCodePing = 0x9,
43 OpCodePong = 0xA,
44 OpCodeReservedB = 0xB,
45 OpCodeReservedC = 0xC,
46 OpCodeReservedD = 0xD,
47 OpCodeReservedE = 0xE,
48 OpCodeReservedF = 0xF
49 };
50 Q_ENUM(OpCode)
51
52 enum class ChunkPhase {
53 NotChunked = 0,
54 Size,
55 Data,
56 DataCrLf,
57 Trailers,
58 };
59 Q_ENUM(ChunkPhase)
60
61 ProtoRequestHttp(Socket *sock, int bufferSize);
62 ~ProtoRequestHttp() override;
63
64 void setupNewConnection(Socket *sock) override final;
65
66 bool writeHeaders(quint16 status, const Cutelyst::Headers &headers) override final;
67
68 qint64 doWrite(const char *data, qint64 len) override final;
69 inline qint64 doWrite(const QByteArray &data) { return doWrite(data.constData(), data.size()); }
70
71 void processingFinished() override final;
72
73 bool webSocketSendTextMessage(const QString &message) override final;
74
75 bool webSocketSendBinaryMessage(const QByteArray &message) override final;
76
77 bool webSocketSendPing(const QByteArray &payload) override final;
78
79 bool webSocketClose(quint16 code, const QString &reason) override final;
80
81 inline void resetData() override final
82 {
83 ProtocolData::resetData();
84
85 // EngineRequest
86
87 // If we deleteLater the context, there might
88 // be an event that tries to finalize the request
89 // and it will encounter a null context pointer
90 delete context;
91 context = nullptr;
92 body = nullptr;
93
94 startOfRequest = TimePointSteady{};
95 status = InitialState;
96
97 websocketUpgraded = false;
98 last = 0;
99 beginLine = 0;
100 chunkPhase = ChunkPhase::NotChunked;
101 chunkBytesLeft = 0;
102
103 serverAddress = sock->serverAddress;
104 remoteAddress = sock->remoteAddress;
105 remotePort = sock->remotePort;
106 isSecure = sock->isSecure;
107 }
108
109 virtual void socketDisconnected() override final;
110
111 QByteArray websocket_message;
112 QByteArray websocket_payload;
113 quint64 websocket_payload_size = 0;
114 quint32 websocket_need = 0;
115 quint32 websocket_mask = 0;
116 int last = 0;
117 int beginLine = 0;
118 int websocket_start_of_frame = 0;
119 WebSocketPhase websocket_phase = WebSocketPhase::WebSocketPhaseHeaders;
120 ChunkPhase chunkPhase = ChunkPhase::NotChunked;
121 qint64 chunkBytesLeft = 0;
122 quint8 websocket_continue_opcode = 0;
123 quint8 websocket_finn_opcode = 0;
124 bool websocketUpgraded = false;
125
126protected:
127 bool webSocketHandshakeDo(const QByteArray &key,
128 const QByteArray &origin,
129 const QByteArray &protocol) override final;
130};
131
132class ProtocolHttp2;
134class ProtocolHttp final : public Protocol
135{
136public:
137 explicit ProtocolHttp(Server *server, ProtocolHttp2 *upgradeH2c = nullptr);
138 ~ProtocolHttp() override;
139
140 ProtocolHttp(const ProtocolHttp &) = delete;
141 ProtocolHttp &operator=(const ProtocolHttp &) = delete;
142
143 Type type() const override;
144
145 void parse(Socket *sock, QIODevice *io) const override final;
146
147 ProtocolData *createData(Socket *sock) const override final;
148
149private:
150 inline bool processRequest(Socket *sock, QIODevice *io) const;
151 inline void parseMethod(const char *ptr, const char *end, Socket *sock) const;
152 inline void parseHeader(const char *ptr, const char *end, Socket *sock) const;
153 // Returns true when the chunked body is complete and the request can run.
154 bool parseChunkedBody(Socket *sock, QIODevice *io) const;
155
156protected:
157 friend class ProtoRequestHttp;
158
159 ProtocolWebSocket *m_websocketProto;
160 ProtocolHttp2 *m_upgradeH2c;
161 bool usingFrontendProxy;
162};
163
164} // namespace Cutelyst
165
166#endif // PROTOCOLHTTP_H
TimePointSteady startOfRequest
Container for HTTP headers.
Definition headers.h:24
bool writeHeaders(quint16 status, const Cutelyst::Headers &headers) override final
qint64 doWrite(const char *data, qint64 len) override final
void processingFinished() override final
Implements a web server.
Definition server.h:60
The Cutelyst namespace holds all public Cutelyst API.
const char * constData() const const
qsizetype size() const const