1 /*
2 * Copyright (C) 2016-2018 Daniel Nicoletti <dantti12@gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #ifndef PROTOCOL_H
19 #define PROTOCOL_H
20
21 #include <QObject>
22 #include <QDebug>
23
24 class QIODevice;
25
26 namespace Cutelyst {
27
28 class Server;
29 class Socket;
30 class Protocol;
31 class ProtocolData
32 {
33 Q_GADGET
34 public:
35 ProtocolData(Socket *sock, int bufferSize);
36 virtual ~ProtocolData();
37
38 enum HeaderConnection {
39 HeaderConnectionNotSet = 0,
40 HeaderConnectionKeep,
41 HeaderConnectionClose,
42 HeaderConnectionUpgrade
43 };
44 Q_ENUM(HeaderConnection)
45
46 enum ParserState {
47 MethodLine = 0,
48 HeaderLine,
49 ContentBody,
50 H2Frames
51 };
Q_ENUM(ParserState)52 Q_ENUM(ParserState)
53
54 inline virtual void resetData() {
55 connState = MethodLine;
56 buf_size = 0;
57 headerConnection = HeaderConnectionNotSet;
58 headerHost = false;
59 X_Forwarded_For = false;
60 X_Forwarded_Host = false;
61 X_Forwarded_Proto = false;
62 }
63
socketDisconnected()64 virtual void socketDisconnected() {}
65 virtual void setupNewConnection(Socket *sock) = 0;
66
67 qint64 contentLength = 0;
68 Socket *sock;//temporary
69 QIODevice *io;
70 ProtocolData *upgradedFrom = nullptr;
71 int buf_size = 0;
72 ParserState connState = MethodLine;
73 HeaderConnection headerConnection = HeaderConnectionNotSet;
74 char *buffer;
75 bool headerHost = false;
76 bool X_Forwarded_For = false;
77 bool X_Forwarded_Host = false;
78 bool X_Forwarded_Proto = false;
79 };
80
81 class Protocol
82 {
83 Q_GADGET
84 public:
85 enum Type {
86 Unknown,
87 Http11,
88 Http2,
89 FastCGI1
90 };
91 Q_ENUM(Type)
92
93 Protocol(Server *wsgi);
94 virtual ~Protocol();
95
96 virtual Type type() const;
97
98 virtual void parse(Socket *sock, QIODevice *io) const = 0;
99
100 virtual ProtocolData *createData(Socket *sock) const = 0;
101
102 QIODevice *createBody(qint64 contentLength) const;
103
104 qint64 m_postBufferSize;
105 qint64 m_postBuffering;
106 int m_bufferSize;
107 char *m_postBuffer;
108 };
109
net_be64(const char * buf)110 inline quint64 net_be64(const char *buf) {
111 quint64 ret = 0;
112 auto src = reinterpret_cast<const quint64 *>(buf);
113 auto ptr = reinterpret_cast<quint8 *>(&ret);
114 ptr[0] = static_cast<quint8>((*src >> 56) & 0xff);
115 ptr[1] = static_cast<quint8>((*src >> 48) & 0xff);
116 ptr[2] = static_cast<quint8>((*src >> 40) & 0xff);
117 ptr[3] = static_cast<quint8>((*src >> 32) & 0xff);
118 ptr[4] = static_cast<quint8>((*src >> 24) & 0xff);
119 ptr[5] = static_cast<quint8>((*src >> 16) & 0xff);
120 ptr[6] = static_cast<quint8>((*src >> 8) & 0xff);
121 ptr[7] = static_cast<quint8>(*src & 0xff);
122 return ret;
123 }
124
net_be32(const char * buf)125 inline quint32 net_be32(const char *buf) {
126 quint32 ret = 0;
127 auto src = reinterpret_cast<const quint32 *>(buf);
128 auto ptr = reinterpret_cast<quint8 *>(&ret);
129 ptr[0] = static_cast<quint8>((*src >> 24) & 0xff);
130 ptr[1] = static_cast<quint8>((*src >> 16) & 0xff);
131 ptr[2] = static_cast<quint8>((*src >> 8) & 0xff);
132 ptr[3] = static_cast<quint8>(*src & 0xff);
133 return ret;
134 }
135
net_be24(const char * buf)136 inline quint32 net_be24(const char *buf) {
137 quint32 ret = 0;
138 auto src = reinterpret_cast<const quint32 *>(buf);
139 auto ptr = reinterpret_cast<quint8 *>(&ret);
140 ptr[0] = static_cast<quint8>((*src >> 16) & 0xff);
141 ptr[1] = static_cast<quint8>((*src >> 8) & 0xff);
142 ptr[2] = static_cast<quint8>(*src & 0xff);
143 return ret;
144 }
145
net_be16(const char * buf)146 inline quint16 net_be16(const char *buf) {
147 quint16 ret = 0;
148 auto src = reinterpret_cast<const quint16 *>(buf);
149 auto ptr = reinterpret_cast<quint8 *>(&ret);
150 ptr[0] = static_cast<quint8>((*src >> 8) & 0xff);
151 ptr[1] = static_cast<quint8>(*src & 0xff);
152 return ret;
153 }
154
155 }
156
157 #endif // PROTOCOL_H
158