xref: /aosp_15_r20/external/cronet/net/spdy/buffered_spdy_framer.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
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 NET_SPDY_BUFFERED_SPDY_FRAMER_H_
6 #define NET_SPDY_BUFFERED_SPDY_FRAMER_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <string>
13 #include <string_view>
14 
15 #include "base/memory/raw_ptr.h"
16 #include "base/time/time.h"
17 #include "net/base/net_export.h"
18 #include "net/log/net_log_source.h"
19 #include "net/spdy/header_coalescer.h"
20 #include "net/third_party/quiche/src/quiche/spdy/core/http2_frame_decoder_adapter.h"
21 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
22 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_alt_svc_wire_format.h"
23 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
24 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
25 
26 namespace net {
27 
28 class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
29  public:
30   BufferedSpdyFramerVisitorInterface() = default;
31 
32   BufferedSpdyFramerVisitorInterface(
33       const BufferedSpdyFramerVisitorInterface&) = delete;
34   BufferedSpdyFramerVisitorInterface& operator=(
35       const BufferedSpdyFramerVisitorInterface&) = delete;
36 
37   // Called if an error is detected in the spdy::SpdySerializedFrame protocol.
38   virtual void OnError(
39       http2::Http2DecoderAdapter::SpdyFramerError spdy_framer_error) = 0;
40 
41   // Called if an error is detected in a HTTP2 stream.
42   virtual void OnStreamError(spdy::SpdyStreamId stream_id,
43                              const std::string& description) = 0;
44 
45   // Called after all the header data for HEADERS control frame is received.
46   virtual void OnHeaders(spdy::SpdyStreamId stream_id,
47                          bool has_priority,
48                          int weight,
49                          spdy::SpdyStreamId parent_stream_id,
50                          bool exclusive,
51                          bool fin,
52                          spdy::Http2HeaderBlock headers,
53                          base::TimeTicks recv_first_byte_time) = 0;
54 
55   // Called when a data frame header is received.
56   virtual void OnDataFrameHeader(spdy::SpdyStreamId stream_id,
57                                  size_t length,
58                                  bool fin) = 0;
59 
60   // Called when data is received.
61   // |stream_id| The stream receiving data.
62   // |data| A buffer containing the data received.
63   // |len| The length of the data buffer (at most 2^16 - 1 - 8).
64   virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
65                                  const char* data,
66                                  size_t len) = 0;
67 
68   // Called when the other side has finished sending data on this stream.
69   // |stream_id| The stream that was receivin data.
70   virtual void OnStreamEnd(spdy::SpdyStreamId stream_id) = 0;
71 
72   // Called when padding is received (padding length field or padding octets).
73   // |stream_id| The stream receiving data.
74   // |len| The number of padding octets.
75   virtual void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) = 0;
76 
77   // Called when a SETTINGS frame is received.
78   virtual void OnSettings() = 0;
79 
80   // Called when an individual setting within a SETTINGS frame has been parsed.
81   // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec.
82   virtual void OnSetting(spdy::SpdySettingsId id, uint32_t value) = 0;
83 
84   // Called when a SETTINGS frame is received with the ACK flag set.
85   virtual void OnSettingsAck() = 0;
86 
87   // Called at the completion of parsing SETTINGS id and value tuples.
88   virtual void OnSettingsEnd() = 0;
89 
90   // Called when a PING frame has been parsed.
91   virtual void OnPing(spdy::SpdyPingId unique_id, bool is_ack) = 0;
92 
93   // Called when a RST_STREAM frame has been parsed.
94   virtual void OnRstStream(spdy::SpdyStreamId stream_id,
95                            spdy::SpdyErrorCode error_code) = 0;
96 
97   // Called when a GOAWAY frame has been parsed.
98   virtual void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
99                         spdy::SpdyErrorCode error_code,
100                         std::string_view debug_data) = 0;
101 
102   // Called when a WINDOW_UPDATE frame has been parsed.
103   virtual void OnWindowUpdate(spdy::SpdyStreamId stream_id,
104                               int delta_window_size) = 0;
105 
106   // Called when a PUSH_PROMISE frame has been parsed.
107   virtual void OnPushPromise(spdy::SpdyStreamId stream_id,
108                              spdy::SpdyStreamId promised_stream_id,
109                              spdy::Http2HeaderBlock headers) = 0;
110 
111   // Called when an ALTSVC frame has been parsed.
112   virtual void OnAltSvc(
113       spdy::SpdyStreamId stream_id,
114       std::string_view origin,
115       const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector&
116           altsvc_vector) = 0;
117 
118   // Called when a frame type we don't recognize is received.
119   // Return true if this appears to be a valid extension frame, false otherwise.
120   // We distinguish between extension frames and nonsense by checking
121   // whether the stream id is valid.
122   virtual bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
123                               uint8_t frame_type) = 0;
124 
125  protected:
126   virtual ~BufferedSpdyFramerVisitorInterface() = default;
127 };
128 
129 class NET_EXPORT_PRIVATE BufferedSpdyFramer
130     : public spdy::SpdyFramerVisitorInterface {
131  public:
132   using TimeFunc = base::TimeTicks (*)();
133 
134   BufferedSpdyFramer(uint32_t max_header_list_size,
135                      const NetLogWithSource& net_log,
136                      TimeFunc time_func = base::TimeTicks::Now);
137   BufferedSpdyFramer() = delete;
138 
139   BufferedSpdyFramer(const BufferedSpdyFramer&) = delete;
140   BufferedSpdyFramer& operator=(const BufferedSpdyFramer&) = delete;
141 
142   ~BufferedSpdyFramer() override;
143 
144   // Sets callbacks to be called from the buffered spdy framer.  A visitor must
145   // be set, or else the framer will likely crash.  It is acceptable for the
146   // visitor to do nothing.  If this is called multiple times, only the last
147   // visitor will be used.
148   void set_visitor(BufferedSpdyFramerVisitorInterface* visitor);
149 
150   // Set debug callbacks to be called from the framer. The debug visitor is
151   // completely optional and need not be set in order for normal operation.
152   // If this is called multiple times, only the last visitor will be used.
153   void set_debug_visitor(spdy::SpdyFramerDebugVisitorInterface* debug_visitor);
154 
155   // spdy::SpdyFramerVisitorInterface
156   void OnError(http2::Http2DecoderAdapter::SpdyFramerError spdy_framer_error,
157                std::string detailed_error) override;
158   void OnHeaders(spdy::SpdyStreamId stream_id,
159                  size_t payload_length,
160                  bool has_priority,
161                  int weight,
162                  spdy::SpdyStreamId parent_stream_id,
163                  bool exclusive,
164                  bool fin,
165                  bool end) override;
166   void OnStreamFrameData(spdy::SpdyStreamId stream_id,
167                          const char* data,
168                          size_t len) override;
169   void OnStreamEnd(spdy::SpdyStreamId stream_id) override;
170   void OnStreamPadLength(spdy::SpdyStreamId stream_id, size_t value) override;
171   void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) override;
172   spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
173       spdy::SpdyStreamId stream_id) override;
174   void OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) override;
175   void OnSettings() override;
176   void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
177   void OnSettingsAck() override;
178   void OnSettingsEnd() override;
179   void OnPing(spdy::SpdyPingId unique_id, bool is_ack) override;
180   void OnRstStream(spdy::SpdyStreamId stream_id,
181                    spdy::SpdyErrorCode error_code) override;
182   void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
183                 spdy::SpdyErrorCode error_code) override;
184   bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
185   void OnWindowUpdate(spdy::SpdyStreamId stream_id,
186                       int delta_window_size) override;
187   void OnPushPromise(spdy::SpdyStreamId stream_id,
188                      spdy::SpdyStreamId promised_stream_id,
189                      bool end) override;
190   void OnAltSvc(spdy::SpdyStreamId stream_id,
191                 std::string_view origin,
192                 const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector&
193                     altsvc_vector) override;
194   void OnDataFrameHeader(spdy::SpdyStreamId stream_id,
195                          size_t length,
196                          bool fin) override;
197   void OnContinuation(spdy::SpdyStreamId stream_id,
198                       size_t payload_length,
199                       bool end) override;
OnPriority(spdy::SpdyStreamId stream_id,spdy::SpdyStreamId parent_stream_id,int weight,bool exclusive)200   void OnPriority(spdy::SpdyStreamId stream_id,
201                   spdy::SpdyStreamId parent_stream_id,
202                   int weight,
203                   bool exclusive) override {}
OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,std::string_view priority_field_value)204   void OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
205                         std::string_view priority_field_value) override {}
206   bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
207                       uint8_t frame_type) override;
OnUnknownFrameStart(spdy::SpdyStreamId stream_id,size_t length,uint8_t type,uint8_t flags)208   void OnUnknownFrameStart(spdy::SpdyStreamId stream_id,
209                            size_t length,
210                            uint8_t type,
211                            uint8_t flags) override {}
OnUnknownFramePayload(spdy::SpdyStreamId stream_id,std::string_view payload)212   void OnUnknownFramePayload(spdy::SpdyStreamId stream_id,
213                              std::string_view payload) override {}
214 
215   // spdy::SpdyFramer methods.
216   size_t ProcessInput(const char* data, size_t len);
217   void UpdateHeaderDecoderTableSize(uint32_t value);
218   http2::Http2DecoderAdapter::SpdyFramerError spdy_framer_error() const;
219   http2::Http2DecoderAdapter::SpdyState state() const;
220   bool MessageFullyRead();
221   bool HasError();
222   std::unique_ptr<spdy::SpdySerializedFrame> CreateRstStream(
223       spdy::SpdyStreamId stream_id,
224       spdy::SpdyErrorCode error_code) const;
225   std::unique_ptr<spdy::SpdySerializedFrame> CreateSettings(
226       const spdy::SettingsMap& values) const;
227   std::unique_ptr<spdy::SpdySerializedFrame> CreatePingFrame(
228       spdy::SpdyPingId unique_id,
229       bool is_ack) const;
230   std::unique_ptr<spdy::SpdySerializedFrame> CreateWindowUpdate(
231       spdy::SpdyStreamId stream_id,
232       uint32_t delta_window_size) const;
233   std::unique_ptr<spdy::SpdySerializedFrame> CreateDataFrame(
234       spdy::SpdyStreamId stream_id,
235       const char* data,
236       uint32_t len,
237       spdy::SpdyDataFlags flags);
238   std::unique_ptr<spdy::SpdySerializedFrame> CreatePriority(
239       spdy::SpdyStreamId stream_id,
240       spdy::SpdyStreamId dependency_id,
241       int weight,
242       bool exclusive) const;
243 
244   // Serialize a frame of unknown type.
SerializeFrame(const spdy::SpdyFrameIR & frame)245   spdy::SpdySerializedFrame SerializeFrame(const spdy::SpdyFrameIR& frame) {
246     return spdy_framer_.SerializeFrame(frame);
247   }
248 
frames_received()249   int frames_received() const { return frames_received_; }
250 
251   // Updates the maximum size of the header encoder compression table.
252   void UpdateHeaderEncoderTableSize(uint32_t value);
253   // Returns the maximum size of the header encoder compression table.
254   uint32_t header_encoder_table_size() const;
255 
256  private:
257   spdy::SpdyFramer spdy_framer_;
258   http2::Http2DecoderAdapter deframer_;
259   raw_ptr<BufferedSpdyFramerVisitorInterface> visitor_ = nullptr;
260 
261   int frames_received_ = 0;
262 
263   // Collection of fields from control frames that we need to
264   // buffer up from the spdy framer.
265   struct ControlFrameFields {
266     ControlFrameFields();
267 
268     spdy::SpdyFrameType type;
269     spdy::SpdyStreamId stream_id = 0U;
270     spdy::SpdyStreamId associated_stream_id = 0U;
271     spdy::SpdyStreamId promised_stream_id = 0U;
272     bool has_priority = false;
273     spdy::SpdyPriority priority = 0U;
274     int weight = 0;
275     spdy::SpdyStreamId parent_stream_id = 0U;
276     bool exclusive = false;
277     bool fin = false;
278     bool unidirectional = false;
279     base::TimeTicks recv_first_byte_time;
280   };
281   std::unique_ptr<ControlFrameFields> control_frame_fields_;
282 
283   // Collection of fields of a GOAWAY frame that this class needs to buffer.
284   struct GoAwayFields {
285     spdy::SpdyStreamId last_accepted_stream_id;
286     spdy::SpdyErrorCode error_code;
287     std::string debug_data;
288   };
289   std::unique_ptr<GoAwayFields> goaway_fields_;
290 
291   std::unique_ptr<HeaderCoalescer> coalescer_;
292 
293   const uint32_t max_header_list_size_;
294   NetLogWithSource net_log_;
295   TimeFunc time_func_;
296 };
297 
298 }  // namespace net
299 
300 #endif  // NET_SPDY_BUFFERED_SPDY_FRAMER_H_
301