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