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