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: 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 uint8 credential_slot, 42 bool fin, 43 bool unidirectional, 44 const SpdyHeaderBlock& headers) = 0; 45 46 // Called after all the header data for SYN_REPLY control frame is received. 47 virtual void OnSynReply(SpdyStreamId stream_id, 48 bool fin, 49 const SpdyHeaderBlock& headers) = 0; 50 51 // Called after all the header data for HEADERS control frame is received. 52 virtual void OnHeaders(SpdyStreamId stream_id, 53 bool fin, 54 const SpdyHeaderBlock& headers) = 0; 55 56 // Called when data is received. 57 // |stream_id| The stream receiving data. 58 // |data| A buffer containing the data received. 59 // |len| The length of the data buffer (at most 2^24 - 1 for SPDY/3, 60 // but 2^16 - 1 - 8 for SPDY/4). 61 // When the other side has finished sending data on this stream, 62 // this method will be called with a zero-length buffer. 63 virtual void OnStreamFrameData(SpdyStreamId stream_id, 64 const char* data, 65 size_t len, 66 bool fin) = 0; 67 68 // Called when a SETTINGS frame is received. 69 // |clear_persisted| True if the respective flag is set on the SETTINGS frame. 70 virtual void OnSettings(bool clear_persisted) = 0; 71 72 // Called when an individual setting within a SETTINGS frame has been parsed 73 // and validated. 74 virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0; 75 76 // Called when a PING frame has been parsed. 77 virtual void OnPing(uint32 unique_id) = 0; 78 79 // Called when a RST_STREAM frame has been parsed. 80 virtual void OnRstStream(SpdyStreamId stream_id, 81 SpdyRstStreamStatus status) = 0; 82 83 // Called when a GOAWAY frame has been parsed. 84 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, 85 SpdyGoAwayStatus status) = 0; 86 87 // Called when a WINDOW_UPDATE frame has been parsed. 88 virtual void OnWindowUpdate(SpdyStreamId stream_id, 89 uint32 delta_window_size) = 0; 90 91 // Called when a PUSH_PROMISE frame has been parsed. 92 virtual void OnPushPromise(SpdyStreamId stream_id, 93 SpdyStreamId promised_stream_id) = 0; 94 95 protected: 96 virtual ~BufferedSpdyFramerVisitorInterface() {} 97 98 private: 99 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface); 100 }; 101 102 class NET_EXPORT_PRIVATE BufferedSpdyFramer 103 : public SpdyFramerVisitorInterface { 104 public: 105 BufferedSpdyFramer(SpdyMajorVersion version, 106 bool enable_compression); 107 virtual ~BufferedSpdyFramer(); 108 109 // Sets callbacks to be called from the buffered spdy framer. A visitor must 110 // be set, or else the framer will likely crash. It is acceptable for the 111 // visitor to do nothing. If this is called multiple times, only the last 112 // visitor will be used. 113 void set_visitor(BufferedSpdyFramerVisitorInterface* visitor); 114 115 // Set debug callbacks to be called from the framer. The debug visitor is 116 // completely optional and need not be set in order for normal operation. 117 // If this is called multiple times, only the last visitor will be used. 118 void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor); 119 120 // SpdyFramerVisitorInterface 121 virtual void OnError(SpdyFramer* spdy_framer) OVERRIDE; 122 virtual void OnSynStream(SpdyStreamId stream_id, 123 SpdyStreamId associated_stream_id, 124 SpdyPriority priority, 125 uint8 credential_slot, 126 bool fin, 127 bool unidirectional) OVERRIDE; 128 virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE; 129 virtual void OnHeaders(SpdyStreamId stream_id, bool fin) OVERRIDE; 130 virtual bool OnCredentialFrameData(const char* frame_data, 131 size_t len) OVERRIDE; 132 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id, 133 const char* header_data, 134 size_t len) OVERRIDE; 135 virtual void OnStreamFrameData(SpdyStreamId stream_id, 136 const char* data, 137 size_t len, 138 bool fin) OVERRIDE; 139 virtual void OnSettings(bool clear_persisted) OVERRIDE; 140 virtual void OnSetting( 141 SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE; 142 virtual void OnPing(uint32 unique_id) OVERRIDE; 143 virtual void OnRstStream(SpdyStreamId stream_id, 144 SpdyRstStreamStatus status) OVERRIDE; 145 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, 146 SpdyGoAwayStatus status) OVERRIDE; 147 virtual void OnWindowUpdate(SpdyStreamId stream_id, 148 uint32 delta_window_size) OVERRIDE; 149 virtual void OnPushPromise(SpdyStreamId stream_id, 150 SpdyStreamId promised_stream_id) OVERRIDE; 151 virtual void OnDataFrameHeader(SpdyStreamId stream_id, 152 size_t length, 153 bool fin) OVERRIDE; 154 155 // SpdyFramer methods. 156 size_t ProcessInput(const char* data, size_t len); 157 int protocol_version(); 158 void Reset(); 159 SpdyFramer::SpdyError error_code() const; 160 SpdyFramer::SpdyState state() const; 161 bool MessageFullyRead(); 162 bool HasError(); 163 SpdyFrame* CreateSynStream(SpdyStreamId stream_id, 164 SpdyStreamId associated_stream_id, 165 SpdyPriority priority, 166 uint8 credential_slot, 167 SpdyControlFlags flags, 168 bool compressed, 169 const SpdyHeaderBlock* headers); 170 SpdyFrame* CreateSynReply(SpdyStreamId stream_id, 171 SpdyControlFlags flags, 172 bool compressed, 173 const SpdyHeaderBlock* headers); 174 SpdyFrame* CreateRstStream(SpdyStreamId stream_id, 175 SpdyRstStreamStatus status) const; 176 SpdyFrame* CreateSettings(const SettingsMap& values) const; 177 SpdyFrame* CreatePingFrame(uint32 unique_id) const; 178 SpdyFrame* CreateGoAway( 179 SpdyStreamId last_accepted_stream_id, 180 SpdyGoAwayStatus status) const; 181 SpdyFrame* CreateHeaders(SpdyStreamId stream_id, 182 SpdyControlFlags flags, 183 bool compressed, 184 const SpdyHeaderBlock* headers); 185 SpdyFrame* CreateWindowUpdate( 186 SpdyStreamId stream_id, 187 uint32 delta_window_size) const; 188 SpdyFrame* CreateCredentialFrame( 189 const SpdyCredential& credential) const; 190 SpdyFrame* CreateDataFrame(SpdyStreamId stream_id, 191 const char* data, 192 uint32 len, 193 SpdyDataFlags flags); 194 195 // Serialize a frame of unknown type. 196 SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) { 197 return spdy_framer_.SerializeFrame(frame); 198 } 199 200 SpdyPriority GetHighestPriority() const; 201 202 size_t GetDataFrameMinimumSize() const { 203 return spdy_framer_.GetDataFrameMinimumSize(); 204 } 205 206 size_t GetControlFrameHeaderSize() const { 207 return spdy_framer_.GetControlFrameHeaderSize(); 208 } 209 210 size_t GetSynStreamMinimumSize() const { 211 return spdy_framer_.GetSynStreamMinimumSize(); 212 } 213 214 size_t GetFrameMinimumSize() const { 215 return spdy_framer_.GetFrameMinimumSize(); 216 } 217 218 size_t GetFrameMaximumSize() const { 219 return spdy_framer_.GetFrameMaximumSize(); 220 } 221 222 size_t GetDataFrameMaximumPayload() const { 223 return spdy_framer_.GetDataFrameMaximumPayload(); 224 } 225 226 int frames_received() const { return frames_received_; } 227 228 private: 229 // The size of the header_buffer_. 230 enum { kHeaderBufferSize = 32 * 1024 }; 231 232 void InitHeaderStreaming(SpdyStreamId stream_id); 233 234 SpdyFramer spdy_framer_; 235 BufferedSpdyFramerVisitorInterface* visitor_; 236 237 // Header block streaming state: 238 char header_buffer_[kHeaderBufferSize]; 239 size_t header_buffer_used_; 240 bool header_buffer_valid_; 241 SpdyStreamId header_stream_id_; 242 int frames_received_; 243 244 // Collection of fields from control frames that we need to 245 // buffer up from the spdy framer. 246 struct ControlFrameFields { 247 SpdyFrameType type; 248 SpdyStreamId stream_id; 249 SpdyStreamId associated_stream_id; 250 SpdyPriority priority; 251 uint8 credential_slot; 252 bool fin; 253 bool unidirectional; 254 }; 255 scoped_ptr<ControlFrameFields> control_frame_fields_; 256 257 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer); 258 }; 259 260 } // namespace net 261 262 #endif // NET_SPDY_BUFFERED_SPDY_FRAMER_H_ 263