1 // Copyright (c) 2012 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 NET_SPDY_BUFFERED_SPDY_FRAMER_H_ 6 #define NET_SPDY_BUFFERED_SPDY_FRAMER_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/gtest_prod_util.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "net/base/net_export.h" 14 #include "net/socket/next_proto.h" 15 #include "net/spdy/spdy_framer.h" 16 #include "net/spdy/spdy_header_block.h" 17 #include "net/spdy/spdy_protocol.h" 18 19 namespace net { 20 21 // Returns the SPDY major version corresponding to the given NextProto 22 // value, which must represent a SPDY-like protocol. 23 NET_EXPORT_PRIVATE SpdyMajorVersion NextProtoToSpdyMajorVersion( 24 NextProto next_proto); 25 26 class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface { 27 public: BufferedSpdyFramerVisitorInterface()28 BufferedSpdyFramerVisitorInterface() {} 29 30 // Called if an error is detected in the SpdyFrame protocol. 31 virtual void OnError(SpdyFramer::SpdyError error_code) = 0; 32 33 // Called if an error is detected in a SPDY stream. 34 virtual void OnStreamError(SpdyStreamId stream_id, 35 const std::string& description) = 0; 36 37 // Called after all the header data for SYN_STREAM control frame is received. 38 virtual void OnSynStream(SpdyStreamId stream_id, 39 SpdyStreamId associated_stream_id, 40 SpdyPriority priority, 41 bool fin, 42 bool unidirectional, 43 const SpdyHeaderBlock& headers) = 0; 44 45 // Called after all the header data for SYN_REPLY control frame is received. 46 virtual void OnSynReply(SpdyStreamId stream_id, 47 bool fin, 48 const SpdyHeaderBlock& headers) = 0; 49 50 // Called after all the header data for HEADERS control frame is received. 51 virtual void OnHeaders(SpdyStreamId stream_id, 52 bool fin, 53 const SpdyHeaderBlock& headers) = 0; 54 55 // Called when a data frame header is received. 56 virtual void OnDataFrameHeader(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^24 - 1 for SPDY/3, 64 // but 2^16 - 1 - 8 for SPDY/4). 65 // When the other side has finished sending data on this stream, 66 // this method will be called with a zero-length buffer. 67 virtual void OnStreamFrameData(SpdyStreamId stream_id, 68 const char* data, 69 size_t len, 70 bool fin) = 0; 71 72 // Called when a SETTINGS frame is received. 73 // |clear_persisted| True if the respective flag is set on the SETTINGS frame. 74 virtual void OnSettings(bool clear_persisted) = 0; 75 76 // Called when an individual setting within a SETTINGS frame has been parsed 77 // and validated. 78 virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0; 79 80 // Called when a SETTINGS frame is received with the ACK flag set. OnSettingsAck()81 virtual void OnSettingsAck() {} 82 83 // Called at the completion of parsing SETTINGS id and value tuples. OnSettingsEnd()84 virtual void OnSettingsEnd() {} 85 86 // Called when a PING frame has been parsed. 87 virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0; 88 89 // Called when a RST_STREAM frame has been parsed. 90 virtual void OnRstStream(SpdyStreamId stream_id, 91 SpdyRstStreamStatus status) = 0; 92 93 // Called when a GOAWAY frame has been parsed. 94 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, 95 SpdyGoAwayStatus status) = 0; 96 97 // Called when a WINDOW_UPDATE frame has been parsed. 98 virtual void OnWindowUpdate(SpdyStreamId stream_id, 99 uint32 delta_window_size) = 0; 100 101 // Called when a PUSH_PROMISE frame has been parsed. 102 virtual void OnPushPromise(SpdyStreamId stream_id, 103 SpdyStreamId promised_stream_id, 104 const SpdyHeaderBlock& headers) = 0; 105 106 // Called when a frame type we don't recognize is received. 107 // Return true if this appears to be a valid extension frame, false otherwise. 108 // We distinguish between extension frames and nonsense by checking 109 // whether the stream id is valid. 110 virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) = 0; 111 112 protected: ~BufferedSpdyFramerVisitorInterface()113 virtual ~BufferedSpdyFramerVisitorInterface() {} 114 115 private: 116 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface); 117 }; 118 119 class NET_EXPORT_PRIVATE BufferedSpdyFramer 120 : public SpdyFramerVisitorInterface { 121 public: 122 BufferedSpdyFramer(SpdyMajorVersion version, 123 bool enable_compression); 124 virtual ~BufferedSpdyFramer(); 125 126 // Sets callbacks to be called from the buffered spdy framer. A visitor must 127 // be set, or else the framer will likely crash. It is acceptable for the 128 // visitor to do nothing. If this is called multiple times, only the last 129 // visitor will be used. 130 void set_visitor(BufferedSpdyFramerVisitorInterface* visitor); 131 132 // Set debug callbacks to be called from the framer. The debug visitor is 133 // completely optional and need not be set in order for normal operation. 134 // If this is called multiple times, only the last visitor will be used. 135 void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor); 136 137 // SpdyFramerVisitorInterface 138 virtual void OnError(SpdyFramer* spdy_framer) OVERRIDE; 139 virtual void OnSynStream(SpdyStreamId stream_id, 140 SpdyStreamId associated_stream_id, 141 SpdyPriority priority, 142 bool fin, 143 bool unidirectional) OVERRIDE; 144 virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE; 145 virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) OVERRIDE; 146 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id, 147 const char* header_data, 148 size_t len) OVERRIDE; 149 virtual void OnStreamFrameData(SpdyStreamId stream_id, 150 const char* data, 151 size_t len, 152 bool fin) OVERRIDE; 153 virtual void OnSettings(bool clear_persisted) OVERRIDE; 154 virtual void OnSetting( 155 SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE; 156 virtual void OnSettingsAck() OVERRIDE; 157 virtual void OnSettingsEnd() OVERRIDE; 158 virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE; 159 virtual void OnRstStream(SpdyStreamId stream_id, 160 SpdyRstStreamStatus status) OVERRIDE; 161 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, 162 SpdyGoAwayStatus status) OVERRIDE; 163 virtual void OnWindowUpdate(SpdyStreamId stream_id, 164 uint32 delta_window_size) OVERRIDE; 165 virtual void OnPushPromise(SpdyStreamId stream_id, 166 SpdyStreamId promised_stream_id, 167 bool end) OVERRIDE; 168 virtual void OnDataFrameHeader(SpdyStreamId stream_id, 169 size_t length, 170 bool fin) OVERRIDE; 171 virtual void OnContinuation(SpdyStreamId stream_id, bool end) OVERRIDE; 172 virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) OVERRIDE; 173 174 // SpdyFramer methods. 175 size_t ProcessInput(const char* data, size_t len); 176 SpdyMajorVersion protocol_version(); 177 void Reset(); 178 SpdyFramer::SpdyError error_code() const; 179 SpdyFramer::SpdyState state() const; 180 bool MessageFullyRead(); 181 bool HasError(); 182 SpdyFrame* CreateSynStream(SpdyStreamId stream_id, 183 SpdyStreamId associated_stream_id, 184 SpdyPriority priority, 185 SpdyControlFlags flags, 186 const SpdyHeaderBlock* headers); 187 SpdyFrame* CreateSynReply(SpdyStreamId stream_id, 188 SpdyControlFlags flags, 189 const SpdyHeaderBlock* headers); 190 SpdyFrame* CreateRstStream(SpdyStreamId stream_id, 191 SpdyRstStreamStatus status) const; 192 SpdyFrame* CreateSettings(const SettingsMap& values) const; 193 SpdyFrame* CreatePingFrame(uint32 unique_id, bool is_ack) const; 194 SpdyFrame* CreateGoAway( 195 SpdyStreamId last_accepted_stream_id, 196 SpdyGoAwayStatus status) const; 197 SpdyFrame* CreateHeaders(SpdyStreamId stream_id, 198 SpdyControlFlags flags, 199 const SpdyHeaderBlock* headers); 200 SpdyFrame* CreateWindowUpdate( 201 SpdyStreamId stream_id, 202 uint32 delta_window_size) const; 203 SpdyFrame* CreateDataFrame(SpdyStreamId stream_id, 204 const char* data, 205 uint32 len, 206 SpdyDataFlags flags); 207 SpdyFrame* CreatePushPromise(SpdyStreamId stream_id, 208 SpdyStreamId promised_stream_id, 209 const SpdyHeaderBlock* headers); 210 211 // Serialize a frame of unknown type. SerializeFrame(const SpdyFrameIR & frame)212 SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) { 213 return spdy_framer_.SerializeFrame(frame); 214 } 215 216 SpdyPriority GetHighestPriority() const; 217 GetDataFrameMinimumSize()218 size_t GetDataFrameMinimumSize() const { 219 return spdy_framer_.GetDataFrameMinimumSize(); 220 } 221 GetControlFrameHeaderSize()222 size_t GetControlFrameHeaderSize() const { 223 return spdy_framer_.GetControlFrameHeaderSize(); 224 } 225 GetSynStreamMinimumSize()226 size_t GetSynStreamMinimumSize() const { 227 return spdy_framer_.GetSynStreamMinimumSize(); 228 } 229 GetFrameMinimumSize()230 size_t GetFrameMinimumSize() const { 231 return spdy_framer_.GetFrameMinimumSize(); 232 } 233 GetFrameMaximumSize()234 size_t GetFrameMaximumSize() const { 235 return spdy_framer_.GetFrameMaximumSize(); 236 } 237 GetDataFrameMaximumPayload()238 size_t GetDataFrameMaximumPayload() const { 239 return spdy_framer_.GetDataFrameMaximumPayload(); 240 } 241 frames_received()242 int frames_received() const { return frames_received_; } 243 244 private: 245 // The size of the header_buffer_. 246 enum { kHeaderBufferSize = 32 * 1024 }; 247 248 void InitHeaderStreaming(SpdyStreamId stream_id); 249 250 SpdyFramer spdy_framer_; 251 BufferedSpdyFramerVisitorInterface* visitor_; 252 253 // Header block streaming state: 254 char header_buffer_[kHeaderBufferSize]; 255 size_t header_buffer_used_; 256 bool header_buffer_valid_; 257 SpdyStreamId header_stream_id_; 258 int frames_received_; 259 260 // Collection of fields from control frames that we need to 261 // buffer up from the spdy framer. 262 struct ControlFrameFields { 263 SpdyFrameType type; 264 SpdyStreamId stream_id; 265 SpdyStreamId associated_stream_id; 266 SpdyStreamId promised_stream_id; 267 SpdyPriority priority; 268 uint8 credential_slot; 269 bool fin; 270 bool unidirectional; 271 }; 272 scoped_ptr<ControlFrameFields> control_frame_fields_; 273 274 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer); 275 }; 276 277 } // namespace net 278 279 #endif // NET_SPDY_BUFFERED_SPDY_FRAMER_H_ 280