QUICHE team | 82dee2f | 2019-01-18 12:35:12 -0500 | [diff] [blame] | 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 QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_ |
| 6 | #define QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_ |
| 7 | |
| 8 | #include <stddef.h> |
| 9 | |
| 10 | #include <cstdint> |
| 11 | #include <memory> |
bnc | 4790400 | 2019-08-16 11:49:48 -0700 | [diff] [blame] | 12 | #include <string> |
QUICHE team | 82dee2f | 2019-01-18 12:35:12 -0500 | [diff] [blame] | 13 | |
| 14 | #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder.h" |
| 15 | #include "net/third_party/quiche/src/http2/platform/api/http2_optional.h" |
| 16 | #include "net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h" |
| 17 | #include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h" |
| 18 | #include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h" |
| 19 | #include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h" |
| 20 | #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" |
| 21 | #include "net/third_party/quiche/src/spdy/platform/api/spdy_string_piece.h" |
| 22 | |
| 23 | namespace spdy { |
| 24 | |
| 25 | class SpdyFramerVisitorInterface; |
| 26 | class ExtensionVisitorInterface; |
| 27 | |
| 28 | } // namespace spdy |
| 29 | |
| 30 | // TODO(dahollings): Perform various renames/moves suggested in cl/164660364. |
| 31 | |
| 32 | namespace http2 { |
| 33 | |
| 34 | // Adapts SpdyFramer interface to use Http2FrameDecoder. |
| 35 | class SPDY_EXPORT_PRIVATE Http2DecoderAdapter |
| 36 | : public http2::Http2FrameDecoderListener { |
| 37 | public: |
| 38 | // HTTP2 states. |
| 39 | enum SpdyState { |
| 40 | SPDY_ERROR, |
| 41 | SPDY_READY_FOR_FRAME, // Framer is ready for reading the next frame. |
| 42 | SPDY_FRAME_COMPLETE, // Framer has finished reading a frame, need to reset. |
| 43 | SPDY_READING_COMMON_HEADER, |
| 44 | SPDY_CONTROL_FRAME_PAYLOAD, |
| 45 | SPDY_READ_DATA_FRAME_PADDING_LENGTH, |
| 46 | SPDY_CONSUME_PADDING, |
| 47 | SPDY_IGNORE_REMAINING_PAYLOAD, |
| 48 | SPDY_FORWARD_STREAM_FRAME, |
| 49 | SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, |
| 50 | SPDY_CONTROL_FRAME_HEADER_BLOCK, |
| 51 | SPDY_GOAWAY_FRAME_PAYLOAD, |
| 52 | SPDY_SETTINGS_FRAME_HEADER, |
| 53 | SPDY_SETTINGS_FRAME_PAYLOAD, |
| 54 | SPDY_ALTSVC_FRAME_PAYLOAD, |
| 55 | SPDY_EXTENSION_FRAME_PAYLOAD, |
| 56 | }; |
| 57 | |
| 58 | // Framer error codes. |
| 59 | enum SpdyFramerError { |
| 60 | SPDY_NO_ERROR, |
| 61 | SPDY_INVALID_STREAM_ID, // Stream ID is invalid |
| 62 | SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. |
| 63 | SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. |
| 64 | SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. |
| 65 | SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. |
| 66 | SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. |
| 67 | SPDY_COMPRESS_FAILURE, // There was an error compressing. |
| 68 | SPDY_GOAWAY_FRAME_CORRUPT, // GOAWAY frame could not be parsed. |
| 69 | SPDY_RST_STREAM_FRAME_CORRUPT, // RST_STREAM frame could not be parsed. |
| 70 | SPDY_INVALID_PADDING, // HEADERS or DATA frame padding invalid |
| 71 | SPDY_INVALID_DATA_FRAME_FLAGS, // Data frame has invalid flags. |
| 72 | SPDY_INVALID_CONTROL_FRAME_FLAGS, // Control frame has invalid flags. |
| 73 | SPDY_UNEXPECTED_FRAME, // Frame received out of order. |
| 74 | SPDY_INTERNAL_FRAMER_ERROR, // SpdyFramer was used incorrectly. |
| 75 | SPDY_INVALID_CONTROL_FRAME_SIZE, // Control frame not sized to spec |
| 76 | SPDY_OVERSIZED_PAYLOAD, // Payload size was too large |
| 77 | |
| 78 | LAST_ERROR, // Must be the last entry in the enum. |
| 79 | }; |
| 80 | |
| 81 | // For debugging. |
| 82 | static const char* StateToString(int state); |
| 83 | static const char* SpdyFramerErrorToString(SpdyFramerError spdy_framer_error); |
| 84 | |
| 85 | Http2DecoderAdapter(); |
| 86 | ~Http2DecoderAdapter() override; |
| 87 | |
| 88 | // Set callbacks to be called from the framer. A visitor must be set, or |
| 89 | // else the framer will likely crash. It is acceptable for the visitor |
| 90 | // to do nothing. If this is called multiple times, only the last visitor |
| 91 | // will be used. |
| 92 | void set_visitor(spdy::SpdyFramerVisitorInterface* visitor); |
| 93 | spdy::SpdyFramerVisitorInterface* visitor() const { return visitor_; } |
| 94 | |
| 95 | // Set extension callbacks to be called from the framer or decoder. Optional. |
| 96 | // If called multiple times, only the last visitor will be used. |
| 97 | void set_extension_visitor(spdy::ExtensionVisitorInterface* visitor); |
QUICHE team | f4e0588 | 2019-06-18 12:43:27 -0700 | [diff] [blame] | 98 | spdy::ExtensionVisitorInterface* extension_visitor() const { |
| 99 | return extension_; |
| 100 | } |
QUICHE team | 82dee2f | 2019-01-18 12:35:12 -0500 | [diff] [blame] | 101 | |
| 102 | // Set debug callbacks to be called from the framer. The debug visitor is |
| 103 | // completely optional and need not be set in order for normal operation. |
| 104 | // If this is called multiple times, only the last visitor will be used. |
| 105 | void set_debug_visitor(spdy::SpdyFramerDebugVisitorInterface* debug_visitor); |
| 106 | spdy::SpdyFramerDebugVisitorInterface* debug_visitor() const { |
| 107 | return debug_visitor_; |
| 108 | } |
| 109 | |
| 110 | // Set debug callbacks to be called from the HPACK decoder. |
| 111 | void SetDecoderHeaderTableDebugVisitor( |
| 112 | std::unique_ptr<spdy::HpackHeaderTable::DebugVisitorInterface> visitor); |
| 113 | |
| 114 | // Sets whether or not ProcessInput returns after finishing a frame, or |
| 115 | // continues processing additional frames. Normally ProcessInput processes |
| 116 | // all input, but this method enables the caller (and visitor) to work with |
| 117 | // a single frame at a time (or that portion of the frame which is provided |
| 118 | // as input). Reset() does not change the value of this flag. |
| 119 | void set_process_single_input_frame(bool v); |
| 120 | bool process_single_input_frame() const { |
| 121 | return process_single_input_frame_; |
| 122 | } |
| 123 | |
| 124 | // Decode the |len| bytes of encoded HTTP/2 starting at |*data|. Returns |
| 125 | // the number of bytes consumed. It is safe to pass more bytes in than |
| 126 | // may be consumed. Should process (or otherwise buffer) as much as |
| 127 | // available, unless process_single_input_frame is true. |
| 128 | size_t ProcessInput(const char* data, size_t len); |
| 129 | |
| 130 | // Reset the decoder (used just for tests at this time). |
| 131 | void Reset(); |
| 132 | |
| 133 | // Current state of the decoder. |
| 134 | SpdyState state() const; |
| 135 | |
| 136 | // Current error code (NO_ERROR if state != ERROR). |
| 137 | SpdyFramerError spdy_framer_error() const; |
| 138 | |
| 139 | // Has any frame header looked like the start of an HTTP/1.1 (or earlier) |
| 140 | // response? Used to detect if a backend/server that we sent a request to |
| 141 | // has responded with an HTTP/1.1 (or earlier) response. |
| 142 | bool probable_http_response() const; |
| 143 | |
| 144 | // Returns the estimate of dynamically allocated memory in bytes. |
| 145 | size_t EstimateMemoryUsage() const; |
| 146 | |
| 147 | spdy::HpackDecoderAdapter* GetHpackDecoder(); |
| 148 | |
| 149 | bool HasError() const; |
| 150 | |
| 151 | private: |
| 152 | bool OnFrameHeader(const Http2FrameHeader& header) override; |
| 153 | void OnDataStart(const Http2FrameHeader& header) override; |
| 154 | void OnDataPayload(const char* data, size_t len) override; |
| 155 | void OnDataEnd() override; |
| 156 | void OnHeadersStart(const Http2FrameHeader& header) override; |
| 157 | void OnHeadersPriority(const Http2PriorityFields& priority) override; |
| 158 | void OnHpackFragment(const char* data, size_t len) override; |
| 159 | void OnHeadersEnd() override; |
| 160 | void OnPriorityFrame(const Http2FrameHeader& header, |
| 161 | const Http2PriorityFields& priority) override; |
| 162 | void OnContinuationStart(const Http2FrameHeader& header) override; |
| 163 | void OnContinuationEnd() override; |
| 164 | void OnPadLength(size_t trailing_length) override; |
| 165 | void OnPadding(const char* padding, size_t skipped_length) override; |
| 166 | void OnRstStream(const Http2FrameHeader& header, |
| 167 | Http2ErrorCode http2_error_code) override; |
| 168 | void OnSettingsStart(const Http2FrameHeader& header) override; |
| 169 | void OnSetting(const Http2SettingFields& setting_fields) override; |
| 170 | void OnSettingsEnd() override; |
| 171 | void OnSettingsAck(const Http2FrameHeader& header) override; |
| 172 | void OnPushPromiseStart(const Http2FrameHeader& header, |
| 173 | const Http2PushPromiseFields& promise, |
| 174 | size_t total_padding_length) override; |
| 175 | void OnPushPromiseEnd() override; |
| 176 | void OnPing(const Http2FrameHeader& header, |
| 177 | const Http2PingFields& ping) override; |
| 178 | void OnPingAck(const Http2FrameHeader& header, |
| 179 | const Http2PingFields& ping) override; |
| 180 | void OnGoAwayStart(const Http2FrameHeader& header, |
| 181 | const Http2GoAwayFields& goaway) override; |
| 182 | void OnGoAwayOpaqueData(const char* data, size_t len) override; |
| 183 | void OnGoAwayEnd() override; |
| 184 | void OnWindowUpdate(const Http2FrameHeader& header, |
| 185 | uint32_t increment) override; |
| 186 | void OnAltSvcStart(const Http2FrameHeader& header, |
| 187 | size_t origin_length, |
| 188 | size_t value_length) override; |
| 189 | void OnAltSvcOriginData(const char* data, size_t len) override; |
| 190 | void OnAltSvcValueData(const char* data, size_t len) override; |
| 191 | void OnAltSvcEnd() override; |
| 192 | void OnUnknownStart(const Http2FrameHeader& header) override; |
| 193 | void OnUnknownPayload(const char* data, size_t len) override; |
| 194 | void OnUnknownEnd() override; |
| 195 | void OnPaddingTooLong(const Http2FrameHeader& header, |
| 196 | size_t missing_length) override; |
| 197 | void OnFrameSizeError(const Http2FrameHeader& header) override; |
| 198 | |
| 199 | size_t ProcessInputFrame(const char* data, size_t len); |
| 200 | |
| 201 | void DetermineSpdyState(DecodeStatus status); |
| 202 | void ResetBetweenFrames(); |
| 203 | |
| 204 | // ResetInternal is called from the constructor, and during tests, but not |
| 205 | // otherwise (i.e. not between every frame). |
| 206 | void ResetInternal(); |
| 207 | |
| 208 | void set_spdy_state(SpdyState v); |
| 209 | |
| 210 | void SetSpdyErrorAndNotify(SpdyFramerError error); |
| 211 | |
| 212 | const Http2FrameHeader& frame_header() const; |
| 213 | |
| 214 | uint32_t stream_id() const; |
| 215 | Http2FrameType frame_type() const; |
| 216 | |
| 217 | size_t remaining_total_payload() const; |
| 218 | |
| 219 | bool IsReadingPaddingLength(); |
| 220 | bool IsSkippingPadding(); |
| 221 | bool IsDiscardingPayload(); |
| 222 | // Called from OnXyz or OnXyzStart methods to decide whether it is OK to |
| 223 | // handle the callback. |
| 224 | bool IsOkToStartFrame(const Http2FrameHeader& header); |
| 225 | bool HasRequiredStreamId(uint32_t stream_id); |
| 226 | |
| 227 | bool HasRequiredStreamId(const Http2FrameHeader& header); |
| 228 | |
| 229 | bool HasRequiredStreamIdZero(uint32_t stream_id); |
| 230 | |
| 231 | bool HasRequiredStreamIdZero(const Http2FrameHeader& header); |
| 232 | |
| 233 | void ReportReceiveCompressedFrame(const Http2FrameHeader& header); |
| 234 | |
| 235 | void CommonStartHpackBlock(); |
| 236 | |
| 237 | // SpdyFramer calls HandleControlFrameHeadersData even if there are zero |
| 238 | // fragment bytes in the first frame, so do the same. |
| 239 | void MaybeAnnounceEmptyFirstHpackFragment(); |
| 240 | void CommonHpackFragmentEnd(); |
| 241 | |
| 242 | // The most recently decoded frame header; invalid after we reached the end |
| 243 | // of that frame. |
| 244 | Http2FrameHeader frame_header_; |
| 245 | |
| 246 | // If decoding an HPACK block that is split across multiple frames, this holds |
| 247 | // the frame header of the HEADERS or PUSH_PROMISE that started the block. |
| 248 | Http2FrameHeader hpack_first_frame_header_; |
| 249 | |
| 250 | // Amount of trailing padding. Currently used just as an indicator of whether |
| 251 | // OnPadLength has been called. |
| 252 | Http2Optional<size_t> opt_pad_length_; |
| 253 | |
| 254 | // Temporary buffers for the AltSvc fields. |
bnc | 4790400 | 2019-08-16 11:49:48 -0700 | [diff] [blame] | 255 | std::string alt_svc_origin_; |
| 256 | std::string alt_svc_value_; |
QUICHE team | 82dee2f | 2019-01-18 12:35:12 -0500 | [diff] [blame] | 257 | |
| 258 | // Listener used if we transition to an error state; the listener ignores all |
| 259 | // the callbacks. |
| 260 | Http2FrameDecoderNoOpListener no_op_listener_; |
| 261 | |
| 262 | spdy::SpdyFramerVisitorInterface* visitor_ = nullptr; |
| 263 | spdy::SpdyFramerDebugVisitorInterface* debug_visitor_ = nullptr; |
| 264 | |
| 265 | // If non-null, unknown frames and settings are passed to the extension. |
| 266 | spdy::ExtensionVisitorInterface* extension_ = nullptr; |
| 267 | |
| 268 | // The HPACK decoder to be used for this adapter. User is responsible for |
| 269 | // clearing if the adapter is to be used for another connection. |
| 270 | std::unique_ptr<spdy::HpackDecoderAdapter> hpack_decoder_ = nullptr; |
| 271 | |
| 272 | // The HTTP/2 frame decoder. Accessed via a unique_ptr to allow replacement |
| 273 | // (e.g. in tests) when Reset() is called. |
| 274 | std::unique_ptr<Http2FrameDecoder> frame_decoder_; |
| 275 | |
| 276 | // Next frame type expected. Currently only used for CONTINUATION frames, |
| 277 | // but could be used for detecting whether the first frame is a SETTINGS |
| 278 | // frame. |
| 279 | // TODO(jamessyng): Provide means to indicate that decoder should require |
| 280 | // SETTINGS frame as the first frame. |
| 281 | Http2FrameType expected_frame_type_; |
| 282 | |
| 283 | // Attempt to duplicate the SpdyState and SpdyFramerError values that |
| 284 | // SpdyFramer sets. Values determined by getting tests to pass. |
| 285 | SpdyState spdy_state_; |
| 286 | SpdyFramerError spdy_framer_error_; |
| 287 | |
| 288 | // The limit on the size of received HTTP/2 payloads as specified in the |
| 289 | // SETTINGS_MAX_FRAME_SIZE advertised to peer. |
| 290 | size_t recv_frame_size_limit_ = spdy::kHttp2DefaultFramePayloadLimit; |
| 291 | |
| 292 | // Has OnFrameHeader been called? |
| 293 | bool decoded_frame_header_ = false; |
| 294 | |
| 295 | // Have we recorded an Http2FrameHeader for the current frame? |
| 296 | // We only do so if the decoder will make multiple callbacks for |
| 297 | // the frame; for example, for PING frames we don't make record |
| 298 | // the frame header, but for ALTSVC we do. |
| 299 | bool has_frame_header_ = false; |
| 300 | |
| 301 | // Have we recorded an Http2FrameHeader for the current HPACK block? |
| 302 | // True only for multi-frame HPACK blocks. |
| 303 | bool has_hpack_first_frame_header_ = false; |
| 304 | |
| 305 | // Has OnHeaders() already been called for current HEADERS block? Only |
| 306 | // meaningful between OnHeadersStart and OnHeadersPriority. |
| 307 | bool on_headers_called_; |
| 308 | |
| 309 | // Has OnHpackFragment() already been called for current HPACK block? |
| 310 | // SpdyFramer will pass an empty buffer to the HPACK decoder if a HEADERS |
| 311 | // or PUSH_PROMISE has no HPACK data in it (e.g. a HEADERS frame with only |
| 312 | // padding). Detect that condition and replicate the behavior using this |
| 313 | // field. |
| 314 | bool on_hpack_fragment_called_; |
| 315 | |
| 316 | // Have we seen a frame header that appears to be an HTTP/1 response? |
| 317 | bool latched_probable_http_response_ = false; |
| 318 | |
| 319 | // Is expected_frame_type_ set? |
| 320 | bool has_expected_frame_type_ = false; |
| 321 | |
| 322 | // Is the current frame payload destined for |extension_|? |
| 323 | bool handling_extension_payload_ = false; |
| 324 | |
| 325 | bool process_single_input_frame_ = false; |
| 326 | }; |
| 327 | |
| 328 | } // namespace http2 |
| 329 | |
| 330 | namespace spdy { |
| 331 | |
| 332 | // Http2DecoderAdapter will use the given visitor implementing this |
| 333 | // interface to deliver event callbacks as frames are decoded. |
| 334 | // |
| 335 | // Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE) |
| 336 | // are processed in fashion that allows the decompressed header block to be |
| 337 | // delivered in chunks to the visitor. |
| 338 | // The following steps are followed: |
| 339 | // 1. OnHeaders, or OnPushPromise is called. |
| 340 | // 2. OnHeaderFrameStart is called; visitor is expected to return an instance |
| 341 | // of SpdyHeadersHandlerInterface that will receive the header key-value |
| 342 | // pairs. |
| 343 | // 3. OnHeaderFrameEnd is called, indicating that the full header block has |
| 344 | // been delivered for the control frame. |
| 345 | // During step 2, if the visitor is not interested in accepting the header data, |
| 346 | // it should return a no-op implementation of SpdyHeadersHandlerInterface. |
| 347 | class SPDY_EXPORT_PRIVATE SpdyFramerVisitorInterface { |
| 348 | public: |
| 349 | virtual ~SpdyFramerVisitorInterface() {} |
| 350 | |
| 351 | // Called if an error is detected in the SpdyFrame protocol. |
| 352 | virtual void OnError(http2::Http2DecoderAdapter::SpdyFramerError error) = 0; |
| 353 | |
| 354 | // Called when the common header for a frame is received. Validating the |
| 355 | // common header occurs in later processing. |
| 356 | virtual void OnCommonHeader(SpdyStreamId /*stream_id*/, |
| 357 | size_t /*length*/, |
| 358 | uint8_t /*type*/, |
| 359 | uint8_t /*flags*/) {} |
| 360 | |
| 361 | // Called when a data frame header is received. The frame's data |
| 362 | // payload will be provided via subsequent calls to |
| 363 | // OnStreamFrameData(). |
| 364 | virtual void OnDataFrameHeader(SpdyStreamId stream_id, |
| 365 | size_t length, |
| 366 | bool fin) = 0; |
| 367 | |
| 368 | // Called when data is received. |
| 369 | // |stream_id| The stream receiving data. |
| 370 | // |data| A buffer containing the data received. |
| 371 | // |len| The length of the data buffer. |
| 372 | virtual void OnStreamFrameData(SpdyStreamId stream_id, |
| 373 | const char* data, |
| 374 | size_t len) = 0; |
| 375 | |
| 376 | // Called when the other side has finished sending data on this stream. |
| 377 | // |stream_id| The stream that was receiving data. |
| 378 | virtual void OnStreamEnd(SpdyStreamId stream_id) = 0; |
| 379 | |
| 380 | // Called when padding length field is received on a DATA frame. |
| 381 | // |stream_id| The stream receiving data. |
| 382 | // |value| The value of the padding length field. |
danzh | 8f3a576 | 2019-06-25 13:43:51 -0700 | [diff] [blame] | 383 | virtual void OnStreamPadLength(SpdyStreamId /*stream_id*/, size_t /*value*/) { |
| 384 | } |
QUICHE team | 82dee2f | 2019-01-18 12:35:12 -0500 | [diff] [blame] | 385 | |
| 386 | // Called when padding is received (the trailing octets, not pad_len field) on |
| 387 | // a DATA frame. |
| 388 | // |stream_id| The stream receiving data. |
| 389 | // |len| The number of padding octets. |
| 390 | virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0; |
| 391 | |
| 392 | // Called just before processing the payload of a frame containing header |
| 393 | // data. Should return an implementation of SpdyHeadersHandlerInterface that |
| 394 | // will receive headers for stream |stream_id|. The caller will not take |
| 395 | // ownership of the headers handler. The same instance should remain live |
| 396 | // and be returned for all header frames comprising a logical header block |
| 397 | // (i.e. until OnHeaderFrameEnd() is called). |
| 398 | virtual SpdyHeadersHandlerInterface* OnHeaderFrameStart( |
| 399 | SpdyStreamId stream_id) = 0; |
| 400 | |
| 401 | // Called after processing the payload of a frame containing header data. |
| 402 | virtual void OnHeaderFrameEnd(SpdyStreamId stream_id) = 0; |
| 403 | |
| 404 | // Called when a RST_STREAM frame has been parsed. |
| 405 | virtual void OnRstStream(SpdyStreamId stream_id, |
| 406 | SpdyErrorCode error_code) = 0; |
| 407 | |
| 408 | // Called when a SETTINGS frame is received. |
| 409 | virtual void OnSettings() {} |
| 410 | |
| 411 | // Called when a complete setting within a SETTINGS frame has been parsed. |
| 412 | // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec. |
| 413 | virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0; |
| 414 | |
| 415 | // Called when a SETTINGS frame is received with the ACK flag set. |
| 416 | virtual void OnSettingsAck() {} |
| 417 | |
| 418 | // Called before and after parsing SETTINGS id and value tuples. |
| 419 | virtual void OnSettingsEnd() = 0; |
| 420 | |
| 421 | // Called when a PING frame has been parsed. |
| 422 | virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0; |
| 423 | |
| 424 | // Called when a GOAWAY frame has been parsed. |
| 425 | virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, |
| 426 | SpdyErrorCode error_code) = 0; |
| 427 | |
| 428 | // Called when a HEADERS frame is received. |
| 429 | // Note that header block data is not included. See OnHeaderFrameStart(). |
| 430 | // |stream_id| The stream receiving the header. |
| 431 | // |has_priority| Whether or not the headers frame included a priority value, |
| 432 | // and stream dependency info. |
| 433 | // |weight| If |has_priority| is true, then weight (in the range [1, 256]) |
| 434 | // for the receiving stream, otherwise 0. |
| 435 | // |parent_stream_id| If |has_priority| is true the parent stream of the |
| 436 | // receiving stream, else 0. |
| 437 | // |exclusive| If |has_priority| is true the exclusivity of dependence on the |
| 438 | // parent stream, else false. |
| 439 | // |fin| Whether FIN flag is set in frame headers. |
| 440 | // |end| False if HEADERs frame is to be followed by a CONTINUATION frame, |
| 441 | // or true if not. |
| 442 | virtual void OnHeaders(SpdyStreamId stream_id, |
| 443 | bool has_priority, |
| 444 | int weight, |
| 445 | SpdyStreamId parent_stream_id, |
| 446 | bool exclusive, |
| 447 | bool fin, |
| 448 | bool end) = 0; |
| 449 | |
| 450 | // Called when a WINDOW_UPDATE frame has been parsed. |
| 451 | virtual void OnWindowUpdate(SpdyStreamId stream_id, |
| 452 | int delta_window_size) = 0; |
| 453 | |
| 454 | // Called when a goaway frame opaque data is available. |
| 455 | // |goaway_data| A buffer containing the opaque GOAWAY data chunk received. |
| 456 | // |len| The length of the header data buffer. A length of zero indicates |
| 457 | // that the header data block has been completely sent. |
| 458 | // When this function returns true the visitor indicates that it accepted |
| 459 | // all of the data. Returning false indicates that that an error has |
| 460 | // occurred while processing the data. Default implementation returns true. |
| 461 | virtual bool OnGoAwayFrameData(const char* goaway_data, size_t len); |
| 462 | |
| 463 | // Called when a PUSH_PROMISE frame is received. |
| 464 | // Note that header block data is not included. See OnHeaderFrameStart(). |
| 465 | virtual void OnPushPromise(SpdyStreamId stream_id, |
| 466 | SpdyStreamId promised_stream_id, |
| 467 | bool end) = 0; |
| 468 | |
| 469 | // Called when a CONTINUATION frame is received. |
| 470 | // Note that header block data is not included. See OnHeaderFrameStart(). |
| 471 | virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0; |
| 472 | |
| 473 | // Called when an ALTSVC frame has been parsed. |
| 474 | virtual void OnAltSvc( |
| 475 | SpdyStreamId /*stream_id*/, |
| 476 | SpdyStringPiece /*origin*/, |
| 477 | const SpdyAltSvcWireFormat::AlternativeServiceVector& /*altsvc_vector*/) { |
| 478 | } |
| 479 | |
| 480 | // Called when a PRIORITY frame is received. |
| 481 | // |stream_id| The stream to update the priority of. |
| 482 | // |parent_stream_id| The parent stream of |stream_id|. |
| 483 | // |weight| Stream weight, in the range [1, 256]. |
| 484 | // |exclusive| Whether |stream_id| should be an only child of |
| 485 | // |parent_stream_id|. |
| 486 | virtual void OnPriority(SpdyStreamId stream_id, |
| 487 | SpdyStreamId parent_stream_id, |
| 488 | int weight, |
| 489 | bool exclusive) = 0; |
| 490 | |
| 491 | // Called when a frame type we don't recognize is received. |
| 492 | // Return true if this appears to be a valid extension frame, false otherwise. |
| 493 | // We distinguish between extension frames and nonsense by checking |
| 494 | // whether the stream id is valid. |
| 495 | virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0; |
| 496 | }; |
| 497 | |
| 498 | class SPDY_EXPORT_PRIVATE ExtensionVisitorInterface { |
| 499 | public: |
| 500 | virtual ~ExtensionVisitorInterface() {} |
| 501 | |
| 502 | // Called when SETTINGS are received, including non-standard SETTINGS. |
| 503 | virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0; |
| 504 | |
| 505 | // Called when non-standard frames are received. |
| 506 | virtual bool OnFrameHeader(SpdyStreamId stream_id, |
| 507 | size_t length, |
| 508 | uint8_t type, |
| 509 | uint8_t flags) = 0; |
| 510 | |
| 511 | // The payload for a single frame may be delivered as multiple calls to |
| 512 | // OnFramePayload. Since the length field is passed in OnFrameHeader, there is |
| 513 | // no explicit indication of the end of the frame payload. |
| 514 | virtual void OnFramePayload(const char* data, size_t len) = 0; |
| 515 | }; |
| 516 | |
| 517 | } // namespace spdy |
| 518 | |
| 519 | #endif // QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_ |