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