xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/spdy/core/http2_frame_decoder_adapter.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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