-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHttp2Frame.h
190 lines (155 loc) · 4.04 KB
/
Http2Frame.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/**
* Http 2.0 Frame implement from frame.py
*
* Created by lihuanqian 12/17/2024
*
* Copyright (c) lihuanqian. All rights reserved.
*
*/
#pragma once
#include <vector>
#include <map>
static constexpr uint32_t HTTP2_HEAD_SIZE = 9;
static const std::vector<uint8_t> HTTP2_MAGIC = {
'P', 'R', 'I', ' ', '*', ' ', 'H', 'T', 'T', 'P', '/', '2', '.', '0', '\r', '\n',
'\r', '\n', 'S', 'M', '\r', '\n', '\r', '\n'
};
class Http2Frame
{
public:
Http2Frame(uint32_t streamId, uint8_t flags, uint8_t type);
virtual ~Http2Frame() {}
/** serialize all data */
virtual std::vector<uint8_t> serialize();
/** serialize head data */
virtual std::vector<uint8_t> serializeHead();
/** serialize body data */
virtual std::vector<uint8_t> serializeBody() = 0;
protected:
uint32_t m_streamId;
uint8_t m_flags;
uint8_t m_type;
uint32_t m_bodyLen;
};
/**
* @brief Setting Frame
*/
class Http2SettingsFrame : public Http2Frame
{
public:
// The flags defined for SETTINGS frames.
static constexpr uint8_t FLAG_ACK = 0x01;
// The type byte defined for SETTINGS frames.
static constexpr uint8_t TYPE = 0x04;
// Stream association (no stream in SETTINGS frames)
static constexpr uint32_t STREAM_ASSOC_NO_STREAM = 0;
// The known settings
enum SettingOption : uint16_t
{
HEADER_TABLE_SIZE = 0x01,
ENABLE_PUSH = 0x02,
MAX_CONCURRENT_STREAMS = 0x03,
INITIAL_WINDOW_SIZE = 0x04,
MAX_FRAME_SIZE = 0x05,
MAX_HEADER_LIST_SIZE = 0x06,
ENABLE_CONNECT_PROTOCOL = 0x08
};
using SettingsMap = std::map<SettingOption, uint32_t>;
Http2SettingsFrame(uint8_t flags = 0, uint32_t streamID = STREAM_ASSOC_NO_STREAM, const SettingsMap& settings = {});
public:
std::vector<uint8_t> serializeBody() override;
SettingsMap m_settings;
};
/**
* @brief Window Update Frame
*/
class Http2WindowUpdateFrame : public Http2Frame
{
public:
static constexpr uint8_t TYPE = 0x08;
Http2WindowUpdateFrame(uint32_t streamId, uint32_t windowIncrement);
std::vector<uint8_t> serializeBody() override;
private:
uint32_t m_windowIncrement;
};
/**
* @brief Headers Frame
*/
class Http2HeadersFrame : public Http2Frame
{
public:
static constexpr uint8_t TYPE = 0x01;
// Flags
enum Flags : uint8_t
{
END_STREAM = 0x01,
END_HEADERS = 0x04,
PADDED = 0x08,
PRIORITY = 0x20
};
Http2HeadersFrame(
uint32_t streamId,
const std::vector<uint8_t>& headerBlock,
Flags flags,
uint8_t padLength = 0,
uint32_t dependsOn = 0,
uint8_t weight = 0);
std::vector<uint8_t> serializeBody() override;
private:
std::vector<uint8_t> m_headerBlock;
uint8_t m_padLength;
uint32_t m_dependsOn;
uint8_t m_weight;
};
/**
* @brief Data Frame
*/
class Http2DataFrame : public Http2Frame
{
public:
static constexpr uint8_t TYPE = 0x00;
Http2DataFrame(uint32_t streamId, const std::vector<uint8_t>& data, uint8_t padLength = 0);
std::vector<uint8_t> serializeBody() override;
private:
std::vector<uint8_t> m_data;
uint8_t m_padLength;
};
/**
* ------------- --------------
* | Size 3byte || Type 1byte |
* ------------- --------------
* -------------
* | Flags 1byte |
* -------------
* -----------------------------
* | Stream id 4byte |
* -----------------------------
* -----------------------------
* | Data |
* -----------------------------
*/
class Http2FrameHeadParser
{
public:
enum FrameType
{
None,
HeadFrame,
SettingFrame,
DataFrame,
WindowsUpdateFrame,
UnkownFrame
};
Http2FrameHeadParser(const std::vector<uint8_t>& frameHead);
void setFrameHead(const std::vector<uint8_t>& frameHead);
/** get frame type */
FrameType getFrameType();
/** get data size */
uint32_t getDataSize();
/** get flags */
uint8_t getFlags();
/** get stream id */
uint32_t getStreamId();
private:
std::vector<uint8_t> m_data;
};