Coverage Report

Created: 2026-04-07 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/trafficserver/include/proxy/http2/Http2Frame.h
Line
Count
Source
1
/** @file
2
3
  Http2Frame
4
5
  @section license License
6
7
  Licensed to the Apache Software Foundation (ASF) under one
8
  or more contributor license agreements.  See the NOTICE file
9
  distributed with this work for additional information
10
  regarding copyright ownership.  The ASF licenses this file
11
  to you under the Apache License, Version 2.0 (the
12
  "License"); you may not use this file except in compliance
13
  with the License.  You may obtain a copy of the License at
14
15
      http://www.apache.org/licenses/LICENSE-2.0
16
17
  Unless required by applicable law or agreed to in writing, software
18
  distributed under the License is distributed on an "AS IS" BASIS,
19
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
  See the License for the specific language governing permissions and
21
  limitations under the License.
22
 */
23
24
#pragma once
25
26
#include "iocore/eventsystem/IOBuffer.h"
27
28
#include "proxy/http2/HTTP2.h"
29
30
/**
31
   Incoming HTTP/2 Frame
32
 */
33
class Http2Frame
34
{
35
public:
36
0
  Http2Frame(const Http2FrameHeader &h, IOBufferReader *r, bool e = false) : _hdr(h), _ioreader(r), _from_early_data(e) {}
37
38
  // Accessor
39
  IOBufferReader         *reader() const;
40
  const Http2FrameHeader &header() const;
41
  bool                    is_from_early_data() const;
42
43
private:
44
  Http2FrameHeader _hdr;
45
  IOBufferReader  *_ioreader        = nullptr;
46
  bool             _from_early_data = false;
47
};
48
49
/**
50
   Outgoing HTTP/2 Frame
51
 */
52
class Http2TxFrame
53
{
54
public:
55
0
  Http2TxFrame(const Http2FrameHeader &h) : _hdr(h) {}
56
0
  virtual ~Http2TxFrame() {}
57
58
  // Don't allocate on heap
59
  void *operator new(std::size_t)   = delete;
60
  void *operator new[](std::size_t) = delete;
61
62
  virtual int64_t write_to(MIOBuffer *iobuffer) const = 0;
63
64
protected:
65
  Http2FrameHeader _hdr;
66
};
67
68
/**
69
   DATA Frame
70
 */
71
class Http2DataFrame : public Http2TxFrame
72
{
73
public:
74
  Http2DataFrame(Http2StreamId stream_id, uint8_t flags, IOBufferReader *r, uint32_t l)
75
    : Http2TxFrame({l, HTTP2_FRAME_TYPE_DATA, flags, stream_id}), _reader(r), _payload_len(l)
76
0
  {
77
0
  }
78
79
  int64_t write_to(MIOBuffer *iobuffer) const override;
80
81
private:
82
  IOBufferReader *_reader      = nullptr;
83
  uint32_t        _payload_len = 0;
84
};
85
86
/**
87
   HEADERS Frame
88
89
   TODO: support priority info & padding using Http2HeadersParameter
90
 */
91
class Http2HeadersFrame : public Http2TxFrame
92
{
93
public:
94
  Http2HeadersFrame(Http2StreamId stream_id, uint8_t flags, uint8_t *h, uint32_t l)
95
    : Http2TxFrame({l, HTTP2_FRAME_TYPE_HEADERS, flags, stream_id}), _hdr_block(h), _hdr_block_len(l)
96
0
  {
97
0
  }
98
99
  int64_t write_to(MIOBuffer *iobuffer) const override;
100
101
private:
102
  uint8_t *_hdr_block     = nullptr;
103
  uint32_t _hdr_block_len = 0;
104
};
105
106
/**
107
   PRIORITY Frame
108
109
   TODO: implement xmit function
110
 */
111
class Http2PriorityFrame : public Http2TxFrame
112
{
113
public:
114
  Http2PriorityFrame(Http2StreamId stream_id, uint8_t flags, Http2Priority p)
115
    : Http2TxFrame({HTTP2_PRIORITY_LEN, HTTP2_FRAME_TYPE_PRIORITY, flags, stream_id}), _params(p)
116
0
  {
117
0
  }
118
119
  int64_t write_to(MIOBuffer *iobuffer) const override;
120
121
private:
122
  Http2Priority _params;
123
};
124
125
/**
126
   RST_STREAM Frame
127
 */
128
class Http2RstStreamFrame : public Http2TxFrame
129
{
130
public:
131
  Http2RstStreamFrame(Http2StreamId stream_id, uint32_t e)
132
    : Http2TxFrame({HTTP2_RST_STREAM_LEN, HTTP2_FRAME_TYPE_RST_STREAM, HTTP2_FRAME_NO_FLAG, stream_id}), _error_code(e)
133
0
  {
134
0
  }
135
136
  int64_t write_to(MIOBuffer *iobuffer) const override;
137
138
private:
139
  uint32_t _error_code;
140
};
141
142
/**
143
   SETTINGS Frame
144
 */
145
class Http2SettingsFrame : public Http2TxFrame
146
{
147
public:
148
0
  Http2SettingsFrame(Http2StreamId stream_id, uint8_t flags) : Http2TxFrame({0, HTTP2_FRAME_TYPE_SETTINGS, flags, stream_id}) {}
149
  Http2SettingsFrame(Http2StreamId stream_id, uint8_t flags, Http2SettingsParameter *p, uint32_t s)
150
    : Http2TxFrame({static_cast<uint32_t>(HTTP2_SETTINGS_PARAMETER_LEN) * s, HTTP2_FRAME_TYPE_SETTINGS, flags, stream_id}),
151
      _params(p),
152
      _psize(s)
153
0
  {
154
0
  }
155
156
  int64_t write_to(MIOBuffer *iobuffer) const override;
157
158
private:
159
  Http2SettingsParameter *_params = nullptr;
160
  uint32_t                _psize  = 0;
161
};
162
163
/**
164
   PUSH_PROMISE Frame
165
166
   TODO: support padding
167
 */
168
class Http2PushPromiseFrame : public Http2TxFrame
169
{
170
public:
171
  Http2PushPromiseFrame(Http2StreamId stream_id, uint8_t flags, Http2PushPromise p, uint8_t *h, uint32_t l)
172
    : Http2TxFrame({l + static_cast<uint32_t>(sizeof(Http2StreamId)), HTTP2_FRAME_TYPE_PUSH_PROMISE, flags, stream_id}),
173
      _params(p),
174
      _hdr_block(h),
175
      _hdr_block_len(l)
176
0
  {
177
0
  }
178
179
  int64_t write_to(MIOBuffer *iobuffer) const override;
180
181
private:
182
  Http2PushPromise _params;
183
  uint8_t         *_hdr_block     = nullptr;
184
  uint32_t         _hdr_block_len = 0;
185
};
186
187
/**
188
   PING Frame
189
 */
190
class Http2PingFrame : public Http2TxFrame
191
{
192
public:
193
  Http2PingFrame(Http2StreamId stream_id, uint8_t flags, const uint8_t *data)
194
    : Http2TxFrame({HTTP2_PING_LEN, HTTP2_FRAME_TYPE_PING, flags, stream_id}), _opaque_data(data)
195
0
  {
196
0
  }
197
198
  int64_t write_to(MIOBuffer *iobuffer) const override;
199
200
private:
201
  const uint8_t *_opaque_data;
202
};
203
204
/**
205
   GOAWAY Frame
206
207
   TODO: support Additional Debug Data
208
 */
209
class Http2GoawayFrame : public Http2TxFrame
210
{
211
public:
212
  Http2GoawayFrame(Http2Goaway p)
213
    : Http2TxFrame({HTTP2_GOAWAY_LEN, HTTP2_FRAME_TYPE_GOAWAY, HTTP2_FRAME_NO_FLAG, HTTP2_CONNECTION_CONTROL_STREAM}), _params(p)
214
0
  {
215
0
  }
216
217
  int64_t write_to(MIOBuffer *iobuffer) const override;
218
219
private:
220
  Http2Goaway _params;
221
};
222
223
/**
224
   WINDOW_UPDATE Frame
225
 */
226
class Http2WindowUpdateFrame : public Http2TxFrame
227
{
228
public:
229
  Http2WindowUpdateFrame(Http2StreamId stream_id, uint32_t w)
230
    : Http2TxFrame({HTTP2_WINDOW_UPDATE_LEN, HTTP2_FRAME_TYPE_WINDOW_UPDATE, HTTP2_FRAME_NO_FLAG, stream_id}), _window(w)
231
0
  {
232
0
  }
233
234
  int64_t write_to(MIOBuffer *iobuffer) const override;
235
236
private:
237
  uint32_t _window = 0;
238
};
239
240
/**
241
   CONTINUATION Frame
242
 */
243
class Http2ContinuationFrame : public Http2TxFrame
244
{
245
public:
246
  Http2ContinuationFrame(Http2StreamId stream_id, uint8_t flags, uint8_t *h, uint32_t l)
247
    : Http2TxFrame({l, HTTP2_FRAME_TYPE_CONTINUATION, flags, stream_id}), _hdr_block(h), _hdr_block_len(l)
248
0
  {
249
0
  }
250
251
  int64_t write_to(MIOBuffer *iobuffer) const override;
252
253
private:
254
  uint8_t *_hdr_block     = nullptr;
255
  uint32_t _hdr_block_len = 0;
256
};