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 157 spdy::HpackDecoderAdapter* GetHpackDecoder(); GetHpackDecoder()158 const spdy::HpackDecoderAdapter* GetHpackDecoder() const { 159 return hpack_decoder_.get(); 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. User is responsible for 294 // clearing if the adapter is to be used for another connection. 295 std::unique_ptr<spdy::HpackDecoderAdapter> hpack_decoder_; 296 297 // The HTTP/2 frame decoder. 298 Http2FrameDecoder frame_decoder_; 299 300 // Next frame type expected. Currently only used for CONTINUATION frames, 301 // but could be used for detecting whether the first frame is a SETTINGS 302 // frame. 303 // TODO(jamessynge): Provide means to indicate that decoder should require 304 // SETTINGS frame as the first frame. 305 Http2FrameType expected_frame_type_; 306 307 // Attempt to duplicate the SpdyState and SpdyFramerError values that 308 // SpdyFramer sets. Values determined by getting tests to pass. 309 SpdyState spdy_state_ = SpdyState::SPDY_READY_FOR_FRAME; 310 SpdyFramerError spdy_framer_error_ = SpdyFramerError::SPDY_NO_ERROR; 311 312 // The limit on the size of received HTTP/2 payloads as specified in the 313 // SETTINGS_MAX_FRAME_SIZE advertised to peer. 314 size_t max_frame_size_ = spdy::kHttp2DefaultFramePayloadLimit; 315 316 // Has OnFrameHeader been called? 317 bool decoded_frame_header_ = false; 318 319 // Have we recorded an Http2FrameHeader for the current frame? 320 // We only do so if the decoder will make multiple callbacks for 321 // the frame; for example, for PING frames we don't make record 322 // the frame header, but for ALTSVC we do. 323 bool has_frame_header_ = false; 324 325 // Have we recorded an Http2FrameHeader for the current HPACK block? 326 // True only for multi-frame HPACK blocks. 327 bool has_hpack_first_frame_header_ = false; 328 329 // Has OnHeaders() already been called for current HEADERS block? Only 330 // meaningful between OnHeadersStart and OnHeadersPriority. 331 bool on_headers_called_ = false; 332 333 // Has OnHpackFragment() already been called for current HPACK block? 334 // SpdyFramer will pass an empty buffer to the HPACK decoder if a HEADERS 335 // or PUSH_PROMISE has no HPACK data in it (e.g. a HEADERS frame with only 336 // padding). Detect that condition and replicate the behavior using this 337 // field. 338 bool on_hpack_fragment_called_ = false; 339 340 // Have we seen a frame header that appears to be an HTTP/1 response? 341 bool latched_probable_http_response_ = false; 342 343 // Is expected_frame_type_ set? 344 bool has_expected_frame_type_ = false; 345 346 // Is the current frame payload destined for |extension_|? 347 bool handling_extension_payload_ = false; 348 }; 349 350 } // namespace http2 351 352 namespace spdy { 353 354 // Http2DecoderAdapter will use the given visitor implementing this 355 // interface to deliver event callbacks as frames are decoded. 356 // 357 // Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE) 358 // are processed in fashion that allows the decompressed header block to be 359 // delivered in chunks to the visitor. 360 // The following steps are followed: 361 // 1. OnHeaders, or OnPushPromise is called. 362 // 2. OnHeaderFrameStart is called; visitor is expected to return an instance 363 // of SpdyHeadersHandlerInterface that will receive the header key-value 364 // pairs. 365 // 3. OnHeaderFrameEnd is called, indicating that the full header block has 366 // been delivered for the control frame. 367 // During step 2, if the visitor is not interested in accepting the header data, 368 // it should return a no-op implementation of SpdyHeadersHandlerInterface. 369 class QUICHE_EXPORT SpdyFramerVisitorInterface { 370 public: ~SpdyFramerVisitorInterface()371 virtual ~SpdyFramerVisitorInterface() {} 372 373 // Called if an error is detected in the SpdyFrame protocol. 374 virtual void OnError(http2::Http2DecoderAdapter::SpdyFramerError error, 375 std::string detailed_error) = 0; 376 377 // Called when the common header for a frame is received. Validating the 378 // common header occurs in later processing. OnCommonHeader(SpdyStreamId,size_t,uint8_t,uint8_t)379 virtual void OnCommonHeader(SpdyStreamId /*stream_id*/, size_t /*length*/, 380 uint8_t /*type*/, uint8_t /*flags*/) {} 381 382 // Called when a data frame header is received. The frame's data payload will 383 // be provided via subsequent calls to OnStreamFrameData(). 384 // |stream_id| The stream receiving data. 385 // |length| The length of the payload in this DATA frame. Includes the length 386 // of the data itself and potential padding. 387 // |fin| Whether the END_STREAM flag is set in the frame header. 388 virtual void OnDataFrameHeader(SpdyStreamId stream_id, size_t length, 389 bool fin) = 0; 390 391 // Called when data is received. 392 // |stream_id| The stream receiving data. 393 // |data| A buffer containing the data received. 394 // |len| The length of the data buffer. 395 virtual void OnStreamFrameData(SpdyStreamId stream_id, const char* data, 396 size_t len) = 0; 397 398 // Called when the other side has finished sending data on this stream. 399 // |stream_id| The stream that was receiving data. 400 virtual void OnStreamEnd(SpdyStreamId stream_id) = 0; 401 402 // Called when padding length field is received on a DATA frame. 403 // |stream_id| The stream receiving data. 404 // |value| The value of the padding length field. OnStreamPadLength(SpdyStreamId,size_t)405 virtual void OnStreamPadLength(SpdyStreamId /*stream_id*/, size_t /*value*/) { 406 } 407 408 // Called when padding is received (the trailing octets, not pad_len field) on 409 // a DATA frame. 410 // |stream_id| The stream receiving data. 411 // |len| The number of padding octets. 412 virtual void OnStreamPadding(SpdyStreamId stream_id, size_t len) = 0; 413 414 // Called just before processing the payload of a frame containing header 415 // data. Should return an implementation of SpdyHeadersHandlerInterface that 416 // will receive headers for stream |stream_id|. The caller will not take 417 // ownership of the headers handler. The same instance should remain live 418 // and be returned for all header frames comprising a logical header block 419 // (i.e. until OnHeaderFrameEnd() is called). 420 virtual SpdyHeadersHandlerInterface* OnHeaderFrameStart( 421 SpdyStreamId stream_id) = 0; 422 423 // Called after processing the payload of a frame containing header data. 424 virtual void OnHeaderFrameEnd(SpdyStreamId stream_id) = 0; 425 426 // Called when a RST_STREAM frame has been parsed. 427 virtual void OnRstStream(SpdyStreamId stream_id, 428 SpdyErrorCode error_code) = 0; 429 430 // Called when a SETTINGS frame is received. OnSettings()431 virtual void OnSettings() {} 432 433 // Called when a complete setting within a SETTINGS frame has been parsed. 434 // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec. 435 virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0; 436 437 // Called when a SETTINGS frame is received with the ACK flag set. OnSettingsAck()438 virtual void OnSettingsAck() {} 439 440 // Called before and after parsing SETTINGS id and value tuples. 441 virtual void OnSettingsEnd() = 0; 442 443 // Called when a PING frame has been parsed. 444 virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0; 445 446 // Called when a GOAWAY frame has been parsed. 447 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, 448 SpdyErrorCode error_code) = 0; 449 450 // Called when a HEADERS frame is received. 451 // Note that header block data is not included. See OnHeaderFrameStart(). 452 // |stream_id| The stream receiving the header. 453 // |payload_length| The length of the payload in this HEADERS frame. Includes 454 // the length of the encoded header block and potential padding. 455 // |has_priority| Whether or not the headers frame included a priority value, 456 // and stream dependency info. 457 // |weight| If |has_priority| is true, then weight (in the range [1, 256]) 458 // for the receiving stream, otherwise 0. 459 // |parent_stream_id| If |has_priority| is true the parent stream of the 460 // receiving stream, else 0. 461 // |exclusive| If |has_priority| is true the exclusivity of dependence on the 462 // parent stream, else false. 463 // |fin| Whether the END_STREAM flag is set in the frame header. 464 // |end| False if HEADERs frame is to be followed by a CONTINUATION frame, 465 // or true if not. 466 virtual void OnHeaders(SpdyStreamId stream_id, size_t payload_length, 467 bool has_priority, int weight, 468 SpdyStreamId parent_stream_id, bool exclusive, 469 bool fin, bool end) = 0; 470 471 // Called when a WINDOW_UPDATE frame has been parsed. 472 virtual void OnWindowUpdate(SpdyStreamId stream_id, 473 int delta_window_size) = 0; 474 475 // Called when a goaway frame opaque data is available. 476 // |goaway_data| A buffer containing the opaque GOAWAY data chunk received. 477 // |len| The length of the header data buffer. A length of zero indicates 478 // that the header data block has been completely sent. 479 // When this function returns true the visitor indicates that it accepted 480 // all of the data. Returning false indicates that that an error has 481 // occurred while processing the data. Default implementation returns true. 482 virtual bool OnGoAwayFrameData(const char* goaway_data, size_t len); 483 484 // Called when a PUSH_PROMISE frame is received. 485 // Note that header block data is not included. See OnHeaderFrameStart(). 486 virtual void OnPushPromise(SpdyStreamId stream_id, 487 SpdyStreamId promised_stream_id, bool end) = 0; 488 489 // Called when a CONTINUATION frame is received. 490 // Note that header block data is not included. See OnHeaderFrameStart(). 491 // |stream_id| The stream receiving the CONTINUATION. 492 // |payload_length| The length of the payload in this CONTINUATION frame. 493 // |end| True if this CONTINUATION frame will not be followed by another 494 // CONTINUATION frame. 495 virtual void OnContinuation(SpdyStreamId stream_id, size_t payload_length, 496 bool end) = 0; 497 498 // Called when an ALTSVC frame has been parsed. OnAltSvc(SpdyStreamId,absl::string_view,const SpdyAltSvcWireFormat::AlternativeServiceVector &)499 virtual void OnAltSvc( 500 SpdyStreamId /*stream_id*/, absl::string_view /*origin*/, 501 const SpdyAltSvcWireFormat::AlternativeServiceVector& /*altsvc_vector*/) { 502 } 503 504 // Called when a PRIORITY frame is received. 505 // |stream_id| The stream to update the priority of. 506 // |parent_stream_id| The parent stream of |stream_id|. 507 // |weight| Stream weight, in the range [1, 256]. 508 // |exclusive| Whether |stream_id| should be an only child of 509 // |parent_stream_id|. 510 virtual void OnPriority(SpdyStreamId stream_id, SpdyStreamId parent_stream_id, 511 int weight, bool exclusive) = 0; 512 513 // Called when a PRIORITY_UPDATE frame is received on stream 0. 514 // |prioritized_stream_id| is the Prioritized Stream ID and 515 // |priority_field_value| is the Priority Field Value 516 // parsed from the frame payload. 517 virtual void OnPriorityUpdate(SpdyStreamId prioritized_stream_id, 518 absl::string_view priority_field_value) = 0; 519 520 // Called when a frame type we don't recognize is received. 521 // Return true if this appears to be a valid extension frame, false otherwise. 522 // We distinguish between extension frames and nonsense by checking 523 // whether the stream id is valid. 524 // TODO(b/239060116): Remove this callback altogether. 525 virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0; 526 527 // Called when the common header for a non-standard frame is received. If the 528 // `length` is nonzero, the frame's payload will be provided via subsequent 529 // calls to OnUnknownFramePayload(). 530 // |stream_id| The stream receiving the non-standard frame. 531 // |length| The length of the payload of the frame. 532 // |type| The type of the frame. This type is non-standard. 533 // |flags| The flags of the frame. 534 virtual void OnUnknownFrameStart(SpdyStreamId stream_id, size_t length, 535 uint8_t type, uint8_t flags) = 0; 536 537 // Called when a non-empty payload chunk for a non-standard frame is received. 538 // The payload for a single frame may be delivered as multiple calls to 539 // OnUnknownFramePayload(). Since the length field is passed in 540 // OnUnknownFrameStart(), there is no explicit indication of the end of the 541 // frame payload. 542 // |stream_id| The stream receiving the non-standard frame. 543 // |payload| The payload chunk, which will be non-empty. 544 virtual void OnUnknownFramePayload(SpdyStreamId stream_id, 545 absl::string_view payload) = 0; 546 }; 547 548 class QUICHE_EXPORT ExtensionVisitorInterface { 549 public: ~ExtensionVisitorInterface()550 virtual ~ExtensionVisitorInterface() {} 551 552 // Called when non-standard SETTINGS are received. 553 virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0; 554 555 // Called when non-standard frames are received. 556 virtual bool OnFrameHeader(SpdyStreamId stream_id, size_t length, 557 uint8_t type, uint8_t flags) = 0; 558 559 // The payload for a single frame may be delivered as multiple calls to 560 // OnFramePayload. Since the length field is passed in OnFrameHeader, there is 561 // no explicit indication of the end of the frame payload. 562 virtual void OnFramePayload(const char* data, size_t len) = 0; 563 }; 564 565 } // namespace spdy 566 567 #endif // QUICHE_SPDY_CORE_HTTP2_FRAME_DECODER_ADAPTER_H_ 568