| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef NET_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_ | |
| 6 #define NET_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_ | |
| 7 | |
| 8 // Http2FrameDecoderListener is the interface which the HTTP/2 decoder uses | |
| 9 // to report the decoded frames to a listener. | |
| 10 // | |
| 11 // The general design is to assume that the listener will copy the data it needs | |
| 12 // (e.g. frame headers) and will keep track of the implicit state of the | |
| 13 // decoding process (i.e. the decoder maintains just the information it needs in | |
| 14 // order to perform the decoding). Therefore, the parameters are just those with | |
| 15 // (potentially) new data, not previously provided info about the current frame. | |
| 16 // | |
| 17 // The calls are described as if they are made in quick succession, i.e. one | |
| 18 // after another, but of course the decoder needs input to decode, and the | |
| 19 // decoder will only call the listener once the necessary input has been | |
| 20 // provided. For example: OnDataStart can only be called once the 9 bytes of | |
| 21 // of an HTTP/2 common frame header have been received. The decoder will call | |
| 22 // the listener methods as soon as possible to avoid almost all buffering. | |
| 23 // | |
| 24 // The listener interface is designed so that it is possible to exactly | |
| 25 // reconstruct the serialized frames, with the exception of reserved bits, | |
| 26 // including in the frame header's flags and stream_id fields, which will have | |
| 27 // been cleared before the methods below are called. | |
| 28 | |
| 29 #include <stddef.h> | |
| 30 | |
| 31 #include <type_traits> | |
| 32 | |
| 33 #include "net/http2/http2_constants.h" | |
| 34 #include "net/http2/http2_structures.h" | |
| 35 | |
| 36 namespace net { | |
| 37 | |
| 38 // TODO(jamessynge): Consider sorting the methods by frequency of call, if that | |
| 39 // helps at all. | |
| 40 class Http2FrameDecoderListener { | |
| 41 public: | |
| 42 Http2FrameDecoderListener() {} | |
| 43 virtual ~Http2FrameDecoderListener() {} | |
| 44 | |
| 45 // Called once the common frame header has been decoded for any frame, and | |
| 46 // before any of the methods below, which will also be called. This method is | |
| 47 // included in this interface only for the purpose of supporting SpdyFramer | |
| 48 // semantics via an adapter. This is the only method that has a non-void | |
| 49 // return type, and this is just so that Http2FrameDecoderAdapter (called | |
| 50 // from SpdyFramer) can more readily pass existing tests that expect decoding | |
| 51 // to stop if the headers alone indicate an error. Return false to stop | |
| 52 // decoding just after decoding the header, else return true to continue | |
| 53 // decoding. | |
| 54 // TODO(jamessynge): Remove OnFrameHeader once done with supporting | |
| 55 // SpdyFramer's exact states. | |
| 56 virtual bool OnFrameHeader(const Http2FrameHeader& header) = 0; | |
| 57 | |
| 58 ////////////////////////////////////////////////////////////////////////////// | |
| 59 | |
| 60 // Called once the common frame header has been decoded for a DATA frame, | |
| 61 // before examining the frame's payload, after which: | |
| 62 // OnPadLength will be called if header.IsPadded() is true, i.e. if the | |
| 63 // PADDED flag is set; | |
| 64 // OnDataPayload will be called as the non-padding portion of the payload | |
| 65 // is available until all of it has been provided; | |
| 66 // OnPadding will be called if the frame is padded AND the Pad Length field | |
| 67 // is greater than zero; | |
| 68 // OnDataEnd will be called last. If the frame is unpadded and has no | |
| 69 // payload, then this will be called immediately after OnDataStart. | |
| 70 virtual void OnDataStart(const Http2FrameHeader& header) = 0; | |
| 71 | |
| 72 // Called when the next non-padding portion of a DATA frame's payload is | |
| 73 // received. | |
| 74 // |data| The start of |len| bytes of data. | |
| 75 // |len| The length of the data buffer. Maybe zero in some cases, which does | |
| 76 // not mean anything special. | |
| 77 virtual void OnDataPayload(const char* data, size_t len) = 0; | |
| 78 | |
| 79 // Called after an entire DATA frame has been received. | |
| 80 // If header.IsEndStream() == true, this is the last data for the stream. | |
| 81 virtual void OnDataEnd() = 0; | |
| 82 | |
| 83 // Called once the common frame header has been decoded for a HEADERS frame, | |
| 84 // before examining the frame's payload, after which: | |
| 85 // OnPadLength will be called if header.IsPadded() is true, i.e. if the | |
| 86 // PADDED flag is set; | |
| 87 // OnHeadersPriority will be called if header.HasPriority() is true, i.e. if | |
| 88 // the frame has the PRIORITY flag; | |
| 89 // OnHpackFragment as the remainder of the non-padding payload is available | |
| 90 // until all if has been provided; | |
| 91 // OnPadding will be called if the frame is padded AND the Pad Length field | |
| 92 // is greater than zero; | |
| 93 // OnHeadersEnd will be called last; If the frame is unpadded and has no | |
| 94 // payload, then this will be called immediately after OnHeadersStart; | |
| 95 // OnHeadersEnd indicates the end of the HPACK block only if the frame | |
| 96 // header had the END_HEADERS flag set, else the END_HEADERS should be | |
| 97 // looked for on a subsequent CONTINUATION frame. | |
| 98 virtual void OnHeadersStart(const Http2FrameHeader& header) = 0; | |
| 99 | |
| 100 // Called when a HEADERS frame is received with the PRIORITY flag set and | |
| 101 // the priority fields have been decoded. | |
| 102 virtual void OnHeadersPriority( | |
| 103 const Http2PriorityFields& priority_fields) = 0; | |
| 104 | |
| 105 // Called when a fragment (i.e. some or all of an HPACK Block) is received; | |
| 106 // this may be part of a HEADERS, PUSH_PROMISE or CONTINUATION frame. | |
| 107 // |data| The start of |len| bytes of data. | |
| 108 // |len| The length of the data buffer. Maybe zero in some cases, which does | |
| 109 // not mean anything special, except that it simplified the decoder. | |
| 110 virtual void OnHpackFragment(const char* data, size_t len) = 0; | |
| 111 | |
| 112 // Called after an entire HEADERS frame has been received. The frame is the | |
| 113 // end of the HEADERS if the END_HEADERS flag is set; else there should be | |
| 114 // CONTINUATION frames after this frame. | |
| 115 virtual void OnHeadersEnd() = 0; | |
| 116 | |
| 117 // Called when an entire PRIORITY frame has been decoded. | |
| 118 virtual void OnPriorityFrame(const Http2FrameHeader& header, | |
| 119 const Http2PriorityFields& priority_fields) = 0; | |
| 120 | |
| 121 // Called once the common frame header has been decoded for a CONTINUATION | |
| 122 // frame, before examining the frame's payload, after which: | |
| 123 // OnHpackFragment as the frame's payload is available until all of it | |
| 124 // has been provided; | |
| 125 // OnContinuationEnd will be called last; If the frame has no payload, | |
| 126 // then this will be called immediately after OnContinuationStart; | |
| 127 // the HPACK block is at an end if and only if the frame header passed | |
| 128 // to OnContinuationStart had the END_HEADERS flag set. | |
| 129 virtual void OnContinuationStart(const Http2FrameHeader& header) = 0; | |
| 130 | |
| 131 // Called after an entire CONTINUATION frame has been received. The frame is | |
| 132 // the end of the HEADERS if the END_HEADERS flag is set. | |
| 133 virtual void OnContinuationEnd() = 0; | |
| 134 | |
| 135 // Called when Pad Length field has been read. Applies to DATA and HEADERS | |
| 136 // frames. For PUSH_PROMISE frames, the Pad Length + 1 is provided in the | |
| 137 // OnPushPromiseStart call as total_padding_length. | |
| 138 virtual void OnPadLength(size_t pad_length) = 0; | |
| 139 | |
| 140 // Called when padding is skipped over. | |
| 141 virtual void OnPadding(const char* padding, size_t skipped_length) = 0; | |
| 142 | |
| 143 // Called when an entire RST_STREAM frame has been decoded. | |
| 144 // This is the only callback for RST_STREAM frames. | |
| 145 virtual void OnRstStream(const Http2FrameHeader& header, | |
| 146 Http2ErrorCode error_code) = 0; | |
| 147 | |
| 148 // Called once the common frame header has been decoded for a SETTINGS frame | |
| 149 // without the ACK flag, before examining the frame's payload, after which: | |
| 150 // OnSetting will be called in turn for each pair of settings parameter and | |
| 151 // value found in the payload; | |
| 152 // OnSettingsEnd will be called last; If the frame has no payload, | |
| 153 // then this will be called immediately after OnSettingsStart. | |
| 154 // The frame header is passed so that the caller can check the stream_id, | |
| 155 // which should be zero, but that hasn't been checked by the decoder. | |
| 156 virtual void OnSettingsStart(const Http2FrameHeader& header) = 0; | |
| 157 | |
| 158 // Called for each setting parameter and value within a SETTINGS frame. | |
| 159 virtual void OnSetting(const Http2SettingFields& setting_fields) = 0; | |
| 160 | |
| 161 // Called after parsing the complete payload of SETTINGS frame (non-ACK). | |
| 162 virtual void OnSettingsEnd() = 0; | |
| 163 | |
| 164 // Called when an entire SETTINGS frame, with the ACK flag, has been decoded. | |
| 165 virtual void OnSettingsAck(const Http2FrameHeader& header) = 0; | |
| 166 | |
| 167 // Called just before starting to process the HPACK block of a PUSH_PROMISE | |
| 168 // frame. The Pad Length field has already been decoded at this point, so | |
| 169 // OnPadLength will not be called; note that total_padding_length is Pad | |
| 170 // Length + 1. After OnPushPromiseStart: | |
| 171 // OnHpackFragment as the remainder of the non-padding payload is available | |
| 172 // until all if has been provided; | |
| 173 // OnPadding will be called if the frame is padded AND the Pad Length field | |
| 174 // is greater than zero (i.e. total_padding_length > 1); | |
| 175 // OnPushPromiseEnd will be called last; If the frame is unpadded and has no | |
| 176 // payload, then this will be called immediately after OnPushPromiseStart. | |
| 177 virtual void OnPushPromiseStart(const Http2FrameHeader& header, | |
| 178 const Http2PushPromiseFields& promise, | |
| 179 size_t total_padding_length) = 0; | |
| 180 | |
| 181 // Called after all of the HPACK block fragment and padding of a PUSH_PROMISE | |
| 182 // has been decoded and delivered to the listener. This call indicates the end | |
| 183 // of the HPACK block if and only if the frame header had the END_HEADERS flag | |
| 184 // set (i.e. header.IsEndHeaders() is true); otherwise the next block must be | |
| 185 // a CONTINUATION frame with the same stream id (not the same promised stream | |
| 186 // id). | |
| 187 virtual void OnPushPromiseEnd() = 0; | |
| 188 | |
| 189 // Called when an entire PING frame, without the ACK flag, has been decoded. | |
| 190 virtual void OnPing(const Http2FrameHeader& header, | |
| 191 const Http2PingFields& ping) = 0; | |
| 192 | |
| 193 // Called when an entire PING frame, with the ACK flag, has been decoded. | |
| 194 virtual void OnPingAck(const Http2FrameHeader& header, | |
| 195 const Http2PingFields& ping) = 0; | |
| 196 | |
| 197 // Called after parsing a GOAWAY frame's header and fixed size fields, after | |
| 198 // which: | |
| 199 // OnGoAwayOpaqueData will be called as opaque data of the payload becomes | |
| 200 // available to the decoder, until all of it has been provided to the | |
| 201 // listener; | |
| 202 // OnGoAwayEnd will be called last, after all the opaque data has been | |
| 203 // provided to the listener; if there is no opaque data, then OnGoAwayEnd | |
| 204 // will be called immediately after OnGoAwayStart. | |
| 205 virtual void OnGoAwayStart(const Http2FrameHeader& header, | |
| 206 const Http2GoAwayFields& goaway) = 0; | |
| 207 | |
| 208 // Called when the next portion of a GOAWAY frame's payload is received. | |
| 209 // |data| The start of |len| bytes of opaque data. | |
| 210 // |len| The length of the opaque data buffer. Maybe zero in some cases, | |
| 211 // which does not mean anything special. | |
| 212 virtual void OnGoAwayOpaqueData(const char* data, size_t len) = 0; | |
| 213 | |
| 214 // Called after finishing decoding all of a GOAWAY frame. | |
| 215 virtual void OnGoAwayEnd() = 0; | |
| 216 | |
| 217 // Called when an entire WINDOW_UPDATE frame has been decoded. The | |
| 218 // window_size_increment is required to be non-zero, but that has not been | |
| 219 // checked. If header.stream_id==0, the connection's flow control window is | |
| 220 // being increased, else the specified stream's flow control is being | |
| 221 // increased. | |
| 222 virtual void OnWindowUpdate(const Http2FrameHeader& header, | |
| 223 uint32_t window_size_increment) = 0; | |
| 224 | |
| 225 // Called when an ALTSVC frame header and origin length have been parsed. | |
| 226 // Either or both lengths may be zero. After OnAltSvcStart: | |
| 227 // OnAltSvcOriginData will be called until all of the (optional) Origin | |
| 228 // has been provided; | |
| 229 // OnAltSvcValueData will be called until all of the Alt-Svc-Field-Value | |
| 230 // has been provided; | |
| 231 // OnAltSvcEnd will called last, after all of the origin and | |
| 232 // Alt-Svc-Field-Value have been delivered to the listener. | |
| 233 virtual void OnAltSvcStart(const Http2FrameHeader& header, | |
| 234 size_t origin_length, | |
| 235 size_t value_length) = 0; | |
| 236 | |
| 237 // Called when decoding the (optional) origin of an ALTSVC; | |
| 238 // the field is uninterpreted. | |
| 239 virtual void OnAltSvcOriginData(const char* data, size_t len) = 0; | |
| 240 | |
| 241 // Called when decoding the Alt-Svc-Field-Value of an ALTSVC; | |
| 242 // the field is uninterpreted. | |
| 243 virtual void OnAltSvcValueData(const char* data, size_t len) = 0; | |
| 244 | |
| 245 // Called after decoding all of a ALTSVC frame and providing to the listener | |
| 246 // via the above methods. | |
| 247 virtual void OnAltSvcEnd() = 0; | |
| 248 | |
| 249 // Called when the common frame header has been decoded, but the frame type | |
| 250 // is unknown, after which: | |
| 251 // OnUnknownPayload is called as the payload of the frame is provided to the | |
| 252 // decoder, until all of the payload has been decoded; | |
| 253 // OnUnknownEnd will called last, after the entire frame of the unknown type | |
| 254 // has been decoded and provided to the listener. | |
| 255 virtual void OnUnknownStart(const Http2FrameHeader& header) = 0; | |
| 256 | |
| 257 // Called when the payload of an unknown frame type is received. | |
| 258 // |data| A buffer containing the data received. | |
| 259 // |len| The length of the data buffer. | |
| 260 virtual void OnUnknownPayload(const char* data, size_t len) = 0; | |
| 261 | |
| 262 // Called after decoding all of the payload of an unknown frame type. | |
| 263 virtual void OnUnknownEnd() = 0; | |
| 264 | |
| 265 ////////////////////////////////////////////////////////////////////////////// | |
| 266 // Below here are events indicating a problem has been detected during | |
| 267 // decoding (i.e. the received frames are malformed in some way). | |
| 268 | |
| 269 // Padding field (uint8) has a value that is too large (i.e. the amount of | |
| 270 // padding is greater than the remainder of the payload that isn't required). | |
| 271 // From RFC Section 6.1, DATA: | |
| 272 // If the length of the padding is the length of the frame payload or | |
| 273 // greater, the recipient MUST treat this as a connection error | |
| 274 // (Section 5.4.1) of type PROTOCOL_ERROR. | |
| 275 // The same is true for HEADERS and PUSH_PROMISE. | |
| 276 virtual void OnPaddingTooLong(const Http2FrameHeader& header, | |
| 277 size_t missing_length) = 0; | |
| 278 | |
| 279 // Frame size error. Depending upon the effected frame, this may or may not | |
| 280 // require terminating the connection, though that is probably the best thing | |
| 281 // to do. | |
| 282 // From RFC Section 4.2, Frame Size: | |
| 283 // An endpoint MUST send an error code of FRAME_SIZE_ERROR if a frame | |
| 284 // exceeds the size defined in SETTINGS_MAX_FRAME_SIZE, exceeds any limit | |
| 285 // defined for the frame type, or is too small to contain mandatory frame | |
| 286 // data. A frame size error in a frame that could alter the state of the | |
| 287 // the entire connection MUST be treated as a connection error | |
| 288 // (Section 5.4.1); this includes any frame carrying a header block | |
| 289 // (Section 4.3) (that is, HEADERS, PUSH_PROMISE, and CONTINUATION), | |
| 290 // SETTINGS, and any frame with a stream identifier of 0. | |
| 291 virtual void OnFrameSizeError(const Http2FrameHeader& header) = 0; | |
| 292 }; | |
| 293 | |
| 294 // Do nothing for each call. Useful for ignoring a frame that is invalid. | |
| 295 class Http2FrameDecoderNoOpListener : public Http2FrameDecoderListener { | |
| 296 public: | |
| 297 Http2FrameDecoderNoOpListener() {} | |
| 298 ~Http2FrameDecoderNoOpListener() override {} | |
| 299 | |
| 300 // TODO(jamessynge): Remove OnFrameHeader once done with supporting | |
| 301 // SpdyFramer's exact states. | |
| 302 bool OnFrameHeader(const Http2FrameHeader& header) override; | |
| 303 | |
| 304 void OnDataStart(const Http2FrameHeader& header) override {} | |
| 305 void OnDataPayload(const char* data, size_t len) override {} | |
| 306 void OnDataEnd() override {} | |
| 307 void OnHeadersStart(const Http2FrameHeader& header) override {} | |
| 308 void OnHeadersPriority(const Http2PriorityFields& priority) override {} | |
| 309 void OnHpackFragment(const char* data, size_t len) override {} | |
| 310 void OnHeadersEnd() override {} | |
| 311 void OnPriorityFrame(const Http2FrameHeader& header, | |
| 312 const Http2PriorityFields& priority) override {} | |
| 313 void OnContinuationStart(const Http2FrameHeader& header) override {} | |
| 314 void OnContinuationEnd() override {} | |
| 315 void OnPadLength(size_t trailing_length) override {} | |
| 316 void OnPadding(const char* padding, size_t skipped_length) override {} | |
| 317 void OnRstStream(const Http2FrameHeader& header, | |
| 318 Http2ErrorCode error_code) override {} | |
| 319 void OnSettingsStart(const Http2FrameHeader& header) override {} | |
| 320 void OnSetting(const Http2SettingFields& setting_fields) override {} | |
| 321 void OnSettingsEnd() override {} | |
| 322 void OnSettingsAck(const Http2FrameHeader& header) override {} | |
| 323 void OnPushPromiseStart(const Http2FrameHeader& header, | |
| 324 const Http2PushPromiseFields& promise, | |
| 325 size_t total_padding_length) override {} | |
| 326 void OnPushPromiseEnd() override {} | |
| 327 void OnPing(const Http2FrameHeader& header, | |
| 328 const Http2PingFields& ping) override {} | |
| 329 void OnPingAck(const Http2FrameHeader& header, | |
| 330 const Http2PingFields& ping) override {} | |
| 331 void OnGoAwayStart(const Http2FrameHeader& header, | |
| 332 const Http2GoAwayFields& goaway) override {} | |
| 333 void OnGoAwayOpaqueData(const char* data, size_t len) override {} | |
| 334 void OnGoAwayEnd() override {} | |
| 335 void OnWindowUpdate(const Http2FrameHeader& header, | |
| 336 uint32_t increment) override {} | |
| 337 void OnAltSvcStart(const Http2FrameHeader& header, | |
| 338 size_t origin_length, | |
| 339 size_t value_length) override {} | |
| 340 void OnAltSvcOriginData(const char* data, size_t len) override {} | |
| 341 void OnAltSvcValueData(const char* data, size_t len) override {} | |
| 342 void OnAltSvcEnd() override {} | |
| 343 void OnUnknownStart(const Http2FrameHeader& header) override {} | |
| 344 void OnUnknownPayload(const char* data, size_t len) override {} | |
| 345 void OnUnknownEnd() override {} | |
| 346 void OnPaddingTooLong(const Http2FrameHeader& header, | |
| 347 size_t missing_length) override {} | |
| 348 void OnFrameSizeError(const Http2FrameHeader& header) override {} | |
| 349 }; | |
| 350 | |
| 351 static_assert(!std::is_abstract<Http2FrameDecoderNoOpListener>(), | |
| 352 "Http2FrameDecoderNoOpListener ought to be concrete."); | |
| 353 | |
| 354 } // namespace net | |
| 355 | |
| 356 #endif // NET_HTTP2_DECODER_HTTP2_FRAME_DECODER_LISTENER_H_ | |
| OLD | NEW |