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 "P_Net.h" 27 28 #include "HTTP2.h" 29 30 /** 31 Incoming HTTP/2 Frame 32 */ 33 class Http2Frame 34 { 35 public: _hdr(h)36 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: Http2TxFrame(const Http2FrameHeader & h)55 Http2TxFrame(const Http2FrameHeader &h) : _hdr(h) {} ~Http2TxFrame()56 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: Http2DataFrame(Http2StreamId stream_id,uint8_t flags,IOBufferReader * r,uint32_t l)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 { 77 } 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: Http2HeadersFrame(Http2StreamId stream_id,uint8_t flags,uint8_t * h,uint32_t l)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 { 97 } 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: Http2PriorityFrame(Http2StreamId stream_id,uint8_t flags,Http2Priority p)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 { 117 } 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: Http2RstStreamFrame(Http2StreamId stream_id,uint32_t e)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 { 134 } 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: Http2SettingsFrame(Http2StreamId stream_id,uint8_t flags)148 Http2SettingsFrame(Http2StreamId stream_id, uint8_t flags) : Http2TxFrame({0, HTTP2_FRAME_TYPE_SETTINGS, flags, stream_id}) {} Http2SettingsFrame(Http2StreamId stream_id,uint8_t flags,Http2SettingsParameter * p,uint32_t s)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 { 154 } 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: Http2PushPromiseFrame(Http2StreamId stream_id,uint8_t flags,Http2PushPromise p,uint8_t * h,uint32_t l)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 { 177 } 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: Http2PingFrame(Http2StreamId stream_id,uint8_t flags,const uint8_t * data)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 { 196 } 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: Http2GoawayFrame(Http2Goaway p)212 Http2GoawayFrame(Http2Goaway p) 213 : Http2TxFrame({HTTP2_GOAWAY_LEN, HTTP2_FRAME_TYPE_GOAWAY, HTTP2_FRAME_NO_FLAG, HTTP2_CONNECTION_CONTROL_STRTEAM}), _params(p) 214 { 215 } 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: Http2WindowUpdateFrame(Http2StreamId stream_id,uint32_t w)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 { 232 } 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: Http2ContinuationFrame(Http2StreamId stream_id,uint8_t flags,uint8_t * h,uint32_t l)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 { 249 } 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 }; 257