| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef NET_SPDY_SPDY_FRAMER_H_ | 5 #ifndef NET_SPDY_SPDY_FRAMER_H_ |
| 6 #define NET_SPDY_SPDY_FRAMER_H_ | 6 #define NET_SPDY_SPDY_FRAMER_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <list> | 9 #include <list> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 class SpdyProxyClientSocketTest; | 30 class SpdyProxyClientSocketTest; |
| 31 class SpdySessionTest; | 31 class SpdySessionTest; |
| 32 class SpdyStreamTest; | 32 class SpdyStreamTest; |
| 33 class SpdyWebSocketStreamTest; | 33 class SpdyWebSocketStreamTest; |
| 34 class WebSocketJobTest; | 34 class WebSocketJobTest; |
| 35 } | 35 } |
| 36 | 36 |
| 37 namespace spdy { | 37 namespace spdy { |
| 38 | 38 |
| 39 class SpdyFramer; | 39 class SpdyFramer; |
| 40 class SpdyFramerTest; | 40 class SpdyFrameBuilder; |
| 41 class SpdyFramerSpdy2Test; |
| 42 class SpdyFramerSpdy3Test; |
| 41 | 43 |
| 42 namespace test { | 44 namespace test_spdy2 { |
| 45 |
| 43 class TestSpdyVisitor; | 46 class TestSpdyVisitor; |
| 44 void FramerSetEnableCompressionHelper(SpdyFramer* framer, bool compress); | 47 |
| 45 } // namespace test | 48 } // namespace test_spdy2 |
| 49 |
| 50 namespace test_spdy3 { |
| 51 |
| 52 class TestSpdyVisitor; |
| 53 |
| 54 } // namespace test_spdy3 |
| 46 | 55 |
| 47 // A datastructure for holding a set of headers from either a | 56 // A datastructure for holding a set of headers from either a |
| 48 // SYN_STREAM or SYN_REPLY frame. | 57 // SYN_STREAM or SYN_REPLY frame. |
| 49 typedef std::map<std::string, std::string> SpdyHeaderBlock; | 58 typedef std::map<std::string, std::string> SpdyHeaderBlock; |
| 50 | 59 |
| 60 // A datastructure for holding the ID and flag fields for SETTINGS. |
| 61 // Conveniently handles converstion to/from wire format. |
| 62 class NET_EXPORT_PRIVATE SettingsFlagsAndId { |
| 63 public: |
| 64 static SettingsFlagsAndId FromWireFormat(int version, uint32 wire); |
| 65 |
| 66 SettingsFlagsAndId() : flags_(0), id_(0) {} |
| 67 |
| 68 // TODO(hkhalil): restrict to enums instead of free-form ints. |
| 69 SettingsFlagsAndId(uint8 flags, uint32 id); |
| 70 |
| 71 uint32 GetWireFormat(int version) const; |
| 72 |
| 73 uint32 id() const { return id_; } |
| 74 uint8 flags() const { return flags_; } |
| 75 |
| 76 private: |
| 77 static void ConvertFlagsAndIdForSpdy2(uint32* val); |
| 78 |
| 79 uint8 flags_; |
| 80 uint32 id_; |
| 81 }; |
| 82 |
| 51 // A datastructure for holding a set of ID/value pairs for a SETTINGS frame. | 83 // A datastructure for holding a set of ID/value pairs for a SETTINGS frame. |
| 52 typedef std::pair<spdy::SettingsFlagsAndId, uint32> SpdySetting; | 84 typedef std::pair<SettingsFlagsAndId, uint32> SpdySetting; |
| 53 typedef std::list<SpdySetting> SpdySettings; | 85 typedef std::list<SpdySetting> SpdySettings; |
| 54 | 86 |
| 55 // A datastrcture for holding the contents of a CREDENTIAL frame. | 87 // A datastrcture for holding the contents of a CREDENTIAL frame. |
| 56 struct NET_EXPORT_PRIVATE SpdyCredential { | 88 struct NET_EXPORT_PRIVATE SpdyCredential { |
| 57 SpdyCredential(); | 89 SpdyCredential(); |
| 58 ~SpdyCredential(); | 90 ~SpdyCredential(); |
| 59 | 91 |
| 60 uint16 slot; | 92 uint16 slot; |
| 61 std::vector<std::string> certs; | 93 std::vector<std::string> certs; |
| 62 std::string proof; | 94 std::string proof; |
| 63 }; | 95 }; |
| 64 | 96 |
| 97 // Scratch space necessary for processing SETTINGS frames. |
| 98 struct NET_EXPORT_PRIVATE SpdySettingsScratch { |
| 99 SpdySettingsScratch() { Reset(); } |
| 100 |
| 101 void Reset() { |
| 102 setting_buf_len = 0; |
| 103 last_setting_id = 0; |
| 104 } |
| 105 |
| 106 // Buffer contains up to one complete key/value pair. |
| 107 char setting_buf[8]; |
| 108 |
| 109 // The amount of the buffer that is filled with valid data. |
| 110 size_t setting_buf_len; |
| 111 |
| 112 // The ID of the last setting that was processed in the current SETTINGS |
| 113 // frame. Used for detecting out-of-order or duplicate keys within a settings |
| 114 // frame. Set to 0 before first key/value pair is processed. |
| 115 uint32 last_setting_id; |
| 116 }; |
| 117 |
| 65 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. | 118 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. |
| 66 // Implement this interface to receive event callbacks as frames are | 119 // Implement this interface to receive event callbacks as frames are |
| 67 // decoded from the framer. | 120 // decoded from the framer. |
| 68 // | 121 // |
| 69 // Control frames that contain SPDY header blocks (SYN_STREAM, SYN_REPLY, and | 122 // Control frames that contain SPDY header blocks (SYN_STREAM, SYN_REPLY, and |
| 70 // HEADER) are processed in fashion that allows the decompressed header block | 123 // HEADER) are processed in fashion that allows the decompressed header block |
| 71 // to be delivered in chunks to the visitor. The following steps are followed: | 124 // to be delivered in chunks to the visitor. The following steps are followed: |
| 72 // 1. OnControl is called, with either a SpdySynStreamControlFrame, | 125 // 1. OnControl is called, with either a SpdySynStreamControlFrame, |
| 73 // SpdySynReplyControlFrame, or a SpdyHeaderControlFrame argument. | 126 // SpdySynReplyControlFrame, or a SpdyHeaderControlFrame argument. |
| 74 // 2. Repeated: OnControlFrameHeaderData is called with chunks of the | 127 // 2. Repeated: OnControlFrameHeaderData is called with chunks of the |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 // When this function returns true the visitor indicates that it accepted | 159 // When this function returns true the visitor indicates that it accepted |
| 107 // all of the data. Returning false indicates that that an unrecoverable | 160 // all of the data. Returning false indicates that that an unrecoverable |
| 108 // error has occurred, such as bad header data or resource exhaustion. | 161 // error has occurred, such as bad header data or resource exhaustion. |
| 109 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id, | 162 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id, |
| 110 const char* header_data, | 163 const char* header_data, |
| 111 size_t len) = 0; | 164 size_t len) = 0; |
| 112 | 165 |
| 113 // Called when a chunk of payload data for a credential frame is available. | 166 // Called when a chunk of payload data for a credential frame is available. |
| 114 // This is called after OnControl() is called with the credential frame | 167 // This is called after OnControl() is called with the credential frame |
| 115 // associated with the payload being delivered here. | 168 // associated with the payload being delivered here. |
| 116 // |frame_data| A buffer containing the header data chunk received. | 169 // |header_data| A buffer containing the header data chunk received. |
| 117 // |len| The length of the header data buffer. A length of zero indicates | 170 // |len| The length of the header data buffer. A length of zero indicates |
| 118 // that the header data block has been completely sent. | 171 // that the header data block has been completely sent. |
| 119 // When this function returns true the visitor indicates that it accepted | 172 // When this function returns true the visitor indicates that it accepted |
| 120 // all of the data. Returning false indicates that that an unrecoverable | 173 // all of the data. Returning false indicates that that an unrecoverable |
| 121 // error has occurred, such as bad header data or resource exhaustion. | 174 // error has occurred, such as bad header data or resource exhaustion. |
| 122 virtual bool OnCredentialFrameData(const char* frame_data, | 175 virtual bool OnCredentialFrameData(const char* header_data, |
| 123 size_t len) = 0; | 176 size_t len) = 0; |
| 124 | 177 |
| 125 // Called when a data frame header is received. The frame's data | 178 // Called when a data frame header is received. The frame's data |
| 126 // payload will be provided via subsequent calls to | 179 // payload will be provided via subsequent calls to |
| 127 // OnStreamFrameData(). | 180 // OnStreamFrameData(). |
| 128 virtual void OnDataFrameHeader(const SpdyDataFrame* frame) = 0; | 181 virtual void OnDataFrameHeader(const SpdyDataFrame* frame) = 0; |
| 129 | 182 |
| 130 // Called when data is received. | 183 // Called when data is received. |
| 131 // |stream_id| The stream receiving data. | 184 // |stream_id| The stream receiving data. |
| 132 // |data| A buffer containing the data received. | 185 // |data| A buffer containing the data received. |
| 133 // |len| The length of the data buffer. | 186 // |len| The length of the data buffer. |
| 134 // When the other side has finished sending data on this stream, | 187 // When the other side has finished sending data on this stream, |
| 135 // this method will be called with a zero-length buffer. | 188 // this method will be called with a zero-length buffer. |
| 136 virtual void OnStreamFrameData(SpdyStreamId stream_id, | 189 virtual void OnStreamFrameData(SpdyStreamId stream_id, |
| 137 const char* data, | 190 const char* data, |
| 138 size_t len) = 0; | 191 size_t len) = 0; |
| 192 |
| 193 // Called when a complete setting within a SETTINGS frame has been parsed and |
| 194 // validated. |
| 195 virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0; |
| 139 }; | 196 }; |
| 140 | 197 |
| 141 class NET_EXPORT_PRIVATE SpdyFramer { | 198 class NET_EXPORT_PRIVATE SpdyFramer { |
| 142 public: | 199 public: |
| 143 // SPDY states. | 200 // SPDY states. |
| 144 // TODO(mbelshe): Can we move these into the implementation | 201 // TODO(mbelshe): Can we move these into the implementation |
| 145 // and avoid exposing through the header. (Needed for test) | 202 // and avoid exposing through the header. (Needed for test) |
| 146 enum SpdyState { | 203 enum SpdyState { |
| 147 SPDY_ERROR, | 204 SPDY_ERROR, |
| 148 SPDY_DONE, | 205 SPDY_DONE, |
| 149 SPDY_RESET, | 206 SPDY_RESET, |
| 150 SPDY_AUTO_RESET, | 207 SPDY_AUTO_RESET, |
| 151 SPDY_READING_COMMON_HEADER, | 208 SPDY_READING_COMMON_HEADER, |
| 152 SPDY_CONTROL_FRAME_PAYLOAD, | 209 SPDY_CONTROL_FRAME_PAYLOAD, |
| 153 SPDY_IGNORE_REMAINING_PAYLOAD, | 210 SPDY_IGNORE_REMAINING_PAYLOAD, |
| 154 SPDY_FORWARD_STREAM_FRAME, | 211 SPDY_FORWARD_STREAM_FRAME, |
| 155 SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, | 212 SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, |
| 156 SPDY_CONTROL_FRAME_HEADER_BLOCK, | 213 SPDY_CONTROL_FRAME_HEADER_BLOCK, |
| 157 SPDY_CREDENTIAL_FRAME_PAYLOAD, | 214 SPDY_CREDENTIAL_FRAME_PAYLOAD, |
| 215 SPDY_SETTINGS_FRAME_PAYLOAD, |
| 158 }; | 216 }; |
| 159 | 217 |
| 160 // SPDY error codes. | 218 // SPDY error codes. |
| 161 enum SpdyError { | 219 enum SpdyError { |
| 162 SPDY_NO_ERROR, | 220 SPDY_NO_ERROR, |
| 163 SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. | 221 SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. |
| 164 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. | 222 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. |
| 165 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. | 223 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. |
| 166 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. | 224 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. |
| 167 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. | 225 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. |
| 168 SPDY_COMPRESS_FAILURE, // There was an error compressing. | 226 SPDY_COMPRESS_FAILURE, // There was an error compressing. |
| 169 SPDY_CREDENTIAL_FRAME_CORRUPT, // CREDENTIAL frame could not be parsed. | 227 SPDY_CREDENTIAL_FRAME_CORRUPT, // CREDENTIAL frame could not be parsed. |
| 170 | 228 |
| 171 LAST_ERROR, // Must be the last entry in the enum. | 229 LAST_ERROR, // Must be the last entry in the enum. |
| 172 }; | 230 }; |
| 173 | 231 |
| 174 // Constant for invalid (or unknown) stream IDs. | 232 // Constant for invalid (or unknown) stream IDs. |
| 175 static const SpdyStreamId kInvalidStream; | 233 static const SpdyStreamId kInvalidStream; |
| 176 | 234 |
| 177 // The maximum size of header data chunks delivered to the framer visitor | 235 // The maximum size of header data chunks delivered to the framer visitor |
| 178 // through OnControlFrameHeaderData. (It is exposed here for unit test | 236 // through OnControlFrameHeaderData. (It is exposed here for unit test |
| 179 // purposes.) | 237 // purposes.) |
| 180 static const size_t kHeaderDataChunkMaxSize; | 238 static const size_t kHeaderDataChunkMaxSize; |
| 181 | 239 |
| 182 // Create a new Framer. | 240 // Create a new Framer, provided a SPDY version. |
| 183 SpdyFramer(); | 241 explicit SpdyFramer(int version); |
| 184 virtual ~SpdyFramer(); | 242 virtual ~SpdyFramer(); |
| 185 | 243 |
| 186 // Set callbacks to be called from the framer. A visitor must be set, or | 244 // Set callbacks to be called from the framer. A visitor must be set, or |
| 187 // else the framer will likely crash. It is acceptable for the visitor | 245 // else the framer will likely crash. It is acceptable for the visitor |
| 188 // to do nothing. If this is called multiple times, only the last visitor | 246 // to do nothing. If this is called multiple times, only the last visitor |
| 189 // will be used. | 247 // will be used. |
| 190 void set_visitor(SpdyFramerVisitorInterface* visitor) { | 248 void set_visitor(SpdyFramerVisitorInterface* visitor) { |
| 191 visitor_ = visitor; | 249 visitor_ = visitor; |
| 192 } | 250 } |
| 193 | 251 |
| 194 // Pass data into the framer for parsing. | 252 // Pass data into the framer for parsing. |
| 195 // Returns the number of bytes consumed. It is safe to pass more bytes in | 253 // Returns the number of bytes consumed. It is safe to pass more bytes in |
| 196 // than may be consumed. | 254 // than may be consumed. |
| 197 size_t ProcessInput(const char* data, size_t len); | 255 size_t ProcessInput(const char* data, size_t len); |
| 198 | 256 |
| 199 // Resets the framer state after a frame has been successfully decoded. | 257 // Resets the framer state after a frame has been successfully decoded. |
| 200 // TODO(mbelshe): can we make this private? | 258 // TODO(mbelshe): can we make this private? |
| 201 void Reset(); | 259 void Reset(); |
| 202 | 260 |
| 203 // Check the state of the framer. | 261 // Check the state of the framer. |
| 204 SpdyError error_code() const { return error_code_; } | 262 SpdyError error_code() const { return error_code_; } |
| 205 SpdyState state() const { return state_; } | 263 SpdyState state() const { return state_; } |
| 206 | 264 |
| 207 bool MessageFullyRead() { | 265 bool MessageFullyRead() { |
| 208 return state_ == SPDY_DONE || state_ == SPDY_AUTO_RESET; | 266 return state_ == SPDY_DONE || state_ == SPDY_AUTO_RESET; |
| 209 } | 267 } |
| 210 bool HasError() { return state_ == SPDY_ERROR; } | 268 bool HasError() { return state_ == SPDY_ERROR; } |
| 211 | 269 |
| 212 // Further parsing utilities. | |
| 213 // Given a control frame, parse out a SpdyHeaderBlock. Only | |
| 214 // valid for SYN_STREAM and SYN_REPLY frames. | |
| 215 // Returns true if successfully parsed, false otherwise. | |
| 216 bool ParseHeaderBlock(const SpdyFrame* frame, SpdyHeaderBlock* block); | |
| 217 | |
| 218 // Given a buffer containing a decompressed header block in SPDY | 270 // Given a buffer containing a decompressed header block in SPDY |
| 219 // serialized format, parse out a SpdyHeaderBlock, putting the results | 271 // serialized format, parse out a SpdyHeaderBlock, putting the results |
| 220 // in the given header block. | 272 // in the given header block. |
| 221 // Returns true if successfully parsed, false otherwise. | 273 // Returns true if successfully parsed, false otherwise. |
| 222 static bool ParseHeaderBlockInBuffer(const char* header_data, | 274 bool ParseHeaderBlockInBuffer(const char* header_data, |
| 223 size_t header_length, | 275 size_t header_length, |
| 224 SpdyHeaderBlock* block); | 276 SpdyHeaderBlock* block); |
| 225 | 277 |
| 226 // Create a SpdySynStreamControlFrame. | 278 // Create a SpdySynStreamControlFrame. |
| 227 // |stream_id| is the id for this stream. | 279 // |stream_id| is the id for this stream. |
| 228 // |associated_stream_id| is the associated stream id for this stream. | 280 // |associated_stream_id| is the associated stream id for this stream. |
| 229 // |priority| is the priority (0-3) for this stream. | 281 // |priority| is the priority (GetHighestPriority()-GetLowestPriority) for |
| 282 // this stream. |
| 230 // |flags| is the flags to use with the data. | 283 // |flags| is the flags to use with the data. |
| 231 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. | 284 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. |
| 232 // |compressed| specifies whether the frame should be compressed. | 285 // |compressed| specifies whether the frame should be compressed. |
| 233 // |headers| is the header block to include in the frame. | 286 // |headers| is the header block to include in the frame. |
| 234 SpdySynStreamControlFrame* CreateSynStream(SpdyStreamId stream_id, | 287 SpdySynStreamControlFrame* CreateSynStream(SpdyStreamId stream_id, |
| 235 SpdyStreamId associated_stream_id, | 288 SpdyStreamId associated_stream_id, |
| 236 int priority, | 289 SpdyPriority priority, |
| 237 SpdyControlFlags flags, | 290 SpdyControlFlags flags, |
| 238 bool compressed, | 291 bool compressed, |
| 239 const SpdyHeaderBlock* headers); | 292 const SpdyHeaderBlock* headers); |
| 240 | 293 |
| 241 // Create a SpdySynReplyControlFrame. | 294 // Create a SpdySynReplyControlFrame. |
| 242 // |stream_id| is the stream for this frame. | 295 // |stream_id| is the stream for this frame. |
| 243 // |flags| is the flags to use with the data. | 296 // |flags| is the flags to use with the data. |
| 244 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. | 297 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. |
| 245 // |compressed| specifies whether the frame should be compressed. | 298 // |compressed| specifies whether the frame should be compressed. |
| 246 // |headers| is the header block to include in the frame. | 299 // |headers| is the header block to include in the frame. |
| 247 SpdySynReplyControlFrame* CreateSynReply(SpdyStreamId stream_id, | 300 SpdySynReplyControlFrame* CreateSynReply(SpdyStreamId stream_id, |
| 248 SpdyControlFlags flags, | 301 SpdyControlFlags flags, |
| 249 bool compressed, | 302 bool compressed, |
| 250 const SpdyHeaderBlock* headers); | 303 const SpdyHeaderBlock* headers); |
| 251 | 304 |
| 252 static SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id, | 305 SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id, |
| 253 SpdyStatusCodes status); | 306 SpdyStatusCodes status) const; |
| 254 | 307 |
| 255 // Creates an instance of SpdySettingsControlFrame. The SETTINGS frame is | 308 // Creates an instance of SpdySettingsControlFrame. The SETTINGS frame is |
| 256 // used to communicate name/value pairs relevant to the communication channel. | 309 // used to communicate name/value pairs relevant to the communication channel. |
| 257 // TODO(mbelshe): add the name/value pairs!! | 310 SpdySettingsControlFrame* CreateSettings(const SpdySettings& values) const; |
| 258 static SpdySettingsControlFrame* CreateSettings(const SpdySettings& values); | |
| 259 | |
| 260 static SpdyNoOpControlFrame* CreateNopFrame(); | |
| 261 | 311 |
| 262 // Creates an instance of SpdyPingControlFrame. The unique_id is used to | 312 // Creates an instance of SpdyPingControlFrame. The unique_id is used to |
| 263 // identify the ping request/response. | 313 // identify the ping request/response. |
| 264 static SpdyPingControlFrame* CreatePingFrame(uint32 unique_id); | 314 SpdyPingControlFrame* CreatePingFrame(uint32 unique_id) const; |
| 265 | 315 |
| 266 // Creates an instance of SpdyGoAwayControlFrame. The GOAWAY frame is used | 316 // Creates an instance of SpdyGoAwayControlFrame. The GOAWAY frame is used |
| 267 // prior to the shutting down of the TCP connection, and includes the | 317 // prior to the shutting down of the TCP connection, and includes the |
| 268 // stream_id of the last stream the sender of the frame is willing to process | 318 // stream_id of the last stream the sender of the frame is willing to process |
| 269 // to completion. | 319 // to completion. |
| 270 static SpdyGoAwayControlFrame* CreateGoAway( | 320 SpdyGoAwayControlFrame* CreateGoAway( |
| 271 SpdyStreamId last_accepted_stream_id); | 321 SpdyStreamId last_accepted_stream_id) const; |
| 272 | 322 |
| 273 // Creates an instance of SpdyHeadersControlFrame. The HEADERS frame is used | 323 // Creates an instance of SpdyHeadersControlFrame. The HEADERS frame is used |
| 274 // for sending additional headers outside of a SYN_STREAM/SYN_REPLY. The | 324 // for sending additional headers outside of a SYN_STREAM/SYN_REPLY. The |
| 275 // arguments are the same as for CreateSynReply. | 325 // arguments are the same as for CreateSynReply. |
| 276 SpdyHeadersControlFrame* CreateHeaders(SpdyStreamId stream_id, | 326 SpdyHeadersControlFrame* CreateHeaders(SpdyStreamId stream_id, |
| 277 SpdyControlFlags flags, | 327 SpdyControlFlags flags, |
| 278 bool compressed, | 328 bool compressed, |
| 279 const SpdyHeaderBlock* headers); | 329 const SpdyHeaderBlock* headers); |
| 280 | 330 |
| 281 // Creates an instance of SpdyWindowUpdateControlFrame. The WINDOW_UPDATE | 331 // Creates an instance of SpdyWindowUpdateControlFrame. The WINDOW_UPDATE |
| 282 // frame is used to implement per stream flow control in SPDY. | 332 // frame is used to implement per stream flow control in SPDY. |
| 283 static SpdyWindowUpdateControlFrame* CreateWindowUpdate( | 333 SpdyWindowUpdateControlFrame* CreateWindowUpdate( |
| 284 SpdyStreamId stream_id, | 334 SpdyStreamId stream_id, |
| 285 uint32 delta_window_size); | 335 uint32 delta_window_size) const; |
| 286 | 336 |
| 287 // Creates an instance of SpdyCredentialControlFrame. The CREDENTIAL | 337 // Creates an instance of SpdyCredentialControlFrame. The CREDENTIAL |
| 288 // frame is used to send a client certificate to the server when | 338 // frame is used to send a client certificate to the server when |
| 289 // request more than one origin are sent over the same SPDY session. | 339 // request more than one origin are sent over the same SPDY session. |
| 290 static SpdyCredentialControlFrame* CreateCredentialFrame( | 340 SpdyCredentialControlFrame* CreateCredentialFrame( |
| 291 const SpdyCredential& credential); | 341 const SpdyCredential& credential) const; |
| 292 | 342 |
| 293 // Given a SpdySettingsControlFrame, extract the settings. | 343 // Given a SpdySettingsControlFrame, extract the settings. |
| 294 // Returns true on successful parse, false otherwise. | 344 // Returns true on successful parse, false otherwise. |
| 295 static bool ParseSettings(const SpdySettingsControlFrame* frame, | 345 static bool ParseSettings(const SpdySettingsControlFrame* frame, |
| 296 SpdySettings* settings); | 346 SpdySettings* settings); |
| 297 | 347 |
| 298 // Given a SpdyCredentialControlFrame's payload, extract the credential. | 348 // Given a SpdyCredentialControlFrame's payload, extract the credential. |
| 299 // Returns true on successful parse, false otherwise. | 349 // Returns true on successful parse, false otherwise. |
| 300 // TODO(hkhalil): Implement CREDENTIAL frame parsing in SpdyFramer | 350 // TODO(hkhalil): Implement CREDENTIAL frame parsing in SpdyFramer |
| 301 // and eliminate this method. | 351 // and eliminate this method. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 323 // not build its state in a serial (stream based) manner.... For now, we're | 373 // not build its state in a serial (stream based) manner.... For now, we're |
| 324 // using zlib anyway. | 374 // using zlib anyway. |
| 325 | 375 |
| 326 // Compresses a SpdyFrame. | 376 // Compresses a SpdyFrame. |
| 327 // On success, returns a new SpdyFrame with the payload compressed. | 377 // On success, returns a new SpdyFrame with the payload compressed. |
| 328 // Compression state is maintained as part of the SpdyFramer. | 378 // Compression state is maintained as part of the SpdyFramer. |
| 329 // Returned frame must be freed with "delete". | 379 // Returned frame must be freed with "delete". |
| 330 // On failure, returns NULL. | 380 // On failure, returns NULL. |
| 331 SpdyFrame* CompressFrame(const SpdyFrame& frame); | 381 SpdyFrame* CompressFrame(const SpdyFrame& frame); |
| 332 | 382 |
| 333 // Decompresses a SpdyFrame. | |
| 334 // On success, returns a new SpdyFrame with the payload decompressed. | |
| 335 // Compression state is maintained as part of the SpdyFramer. | |
| 336 // Returned frame must be freed with "delete". | |
| 337 // On failure, returns NULL. | |
| 338 SpdyFrame* DecompressFrame(const SpdyFrame& frame); | |
| 339 | |
| 340 // Create a copy of a frame. | 383 // Create a copy of a frame. |
| 341 // Returned frame must be freed with "delete". | 384 // Returned frame must be freed with "delete". |
| 342 SpdyFrame* DuplicateFrame(const SpdyFrame& frame); | 385 SpdyFrame* DuplicateFrame(const SpdyFrame& frame); |
| 343 | 386 |
| 344 // Returns true if a frame could be compressed. | 387 // Returns true if a frame could be compressed. |
| 345 bool IsCompressible(const SpdyFrame& frame) const; | 388 bool IsCompressible(const SpdyFrame& frame) const; |
| 346 | 389 |
| 347 // Get the minimum size of the control frame for the given control frame | 390 // Get the minimum size of the control frame for the given control frame |
| 348 // type. This is useful for validating frame blocks. | 391 // type. This is useful for validating frame blocks. |
| 349 static size_t GetMinimumControlFrameSize(SpdyControlType type); | 392 static size_t GetMinimumControlFrameSize(SpdyControlType type); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 366 void set_display_protocol(const std::string& protocol) { | 409 void set_display_protocol(const std::string& protocol) { |
| 367 display_protocol_ = protocol; | 410 display_protocol_ = protocol; |
| 368 } | 411 } |
| 369 | 412 |
| 370 // For debugging. | 413 // For debugging. |
| 371 static const char* StateToString(int state); | 414 static const char* StateToString(int state); |
| 372 static const char* ErrorCodeToString(int error_code); | 415 static const char* ErrorCodeToString(int error_code); |
| 373 static const char* StatusCodeToString(int status_code); | 416 static const char* StatusCodeToString(int status_code); |
| 374 static const char* ControlTypeToString(SpdyControlType type); | 417 static const char* ControlTypeToString(SpdyControlType type); |
| 375 | 418 |
| 376 static void set_protocol_version(int version) { spdy_version_= version; } | 419 // TODO(hkhalil): Remove SpdyFramer::set_protocol_version() |
| 377 static int protocol_version() { return spdy_version_; } | 420 void set_protocol_version(int version) { spdy_version_= version; } |
| 421 int protocol_version() const { return spdy_version_; } |
| 378 | 422 |
| 379 // Export the compression dictionary | 423 bool probable_http_response() { return probable_http_response_; } |
| 380 static const char kDictionary[]; | 424 |
| 381 static const int kDictionarySize; | 425 SpdyPriority GetLowestPriority() const { return spdy_version_ < 3 ? 3 : 7; } |
| 426 SpdyPriority GetHighestPriority() const { return 0; } |
| 382 | 427 |
| 383 protected: | 428 protected: |
| 384 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HeaderCompression); | 429 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, BasicCompression); |
| 385 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ExpandBuffer_HeapSmash); | 430 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, ControlFrameSizesAreValidated); |
| 386 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HugeHeaderBlock); | 431 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, HeaderCompression); |
| 387 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, UnclosedStreamDataCompressors); | 432 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, DecompressUncompressedFrame); |
| 433 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, ExpandBuffer_HeapSmash); |
| 434 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, HugeHeaderBlock); |
| 435 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, UnclosedStreamDataCompressors); |
| 436 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, |
| 437 UnclosedStreamDataCompressorsOneByteAtATime); |
| 438 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, |
| 439 UncompressLargerThanFrameBufferInitialSize); |
| 440 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, ReadLargeSettingsFrame); |
| 441 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy2Test, |
| 442 ReadLargeSettingsFrameInSmallChunks); |
| 443 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, BasicCompression); |
| 444 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, ControlFrameSizesAreValidated); |
| 445 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, HeaderCompression); |
| 446 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, DecompressUncompressedFrame); |
| 447 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, ExpandBuffer_HeapSmash); |
| 448 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, HugeHeaderBlock); |
| 449 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, UnclosedStreamDataCompressors); |
| 450 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, |
| 451 UnclosedStreamDataCompressorsOneByteAtATime); |
| 452 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, |
| 453 UncompressLargerThanFrameBufferInitialSize); |
| 454 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, ReadLargeSettingsFrame); |
| 455 FRIEND_TEST_ALL_PREFIXES(SpdyFramerSpdy3Test, |
| 456 ReadLargeSettingsFrameInSmallChunks); |
| 388 friend class net::HttpNetworkLayer; // This is temporary for the server. | 457 friend class net::HttpNetworkLayer; // This is temporary for the server. |
| 389 friend class net::HttpNetworkTransactionTest; | 458 friend class net::HttpNetworkTransactionTest; |
| 390 friend class net::HttpProxyClientSocketPoolTest; | 459 friend class net::HttpProxyClientSocketPoolTest; |
| 391 friend class net::SpdyHttpStreamTest; | 460 friend class net::SpdyHttpStreamTest; |
| 392 friend class net::SpdyNetworkTransactionTest; | 461 friend class net::SpdyNetworkTransactionTest; |
| 393 friend class net::SpdyProxyClientSocketTest; | 462 friend class net::SpdyProxyClientSocketTest; |
| 394 friend class net::SpdySessionTest; | 463 friend class net::SpdySessionTest; |
| 395 friend class net::SpdyStreamTest; | 464 friend class net::SpdyStreamTest; |
| 396 friend class net::SpdyWebSocketStreamTest; | 465 friend class net::SpdyWebSocketStreamTest; |
| 397 friend class net::WebSocketJobTest; | 466 friend class net::WebSocketJobTest; |
| 398 friend class test::TestSpdyVisitor; | 467 friend class test_spdy2::TestSpdyVisitor; |
| 399 friend void test::FramerSetEnableCompressionHelper(SpdyFramer* framer, | 468 friend class test_spdy3::TestSpdyVisitor; |
| 400 bool compress); | |
| 401 | 469 |
| 402 private: | 470 private: |
| 403 typedef std::map<SpdyStreamId, z_stream*> CompressorMap; | 471 typedef std::map<SpdyStreamId, z_stream*> CompressorMap; |
| 404 | 472 |
| 405 // Internal breakout from ProcessInput. Returns the number of bytes | 473 // Internal breakouts from ProcessInput. Each returns the number of bytes |
| 406 // consumed from the data. | 474 // consumed from the data. |
| 407 size_t ProcessCommonHeader(const char* data, size_t len); | 475 size_t ProcessCommonHeader(const char* data, size_t len); |
| 408 void ProcessControlFrameHeader(); | |
| 409 size_t ProcessControlFramePayload(const char* data, size_t len); | 476 size_t ProcessControlFramePayload(const char* data, size_t len); |
| 410 size_t ProcessCredentialFramePayload(const char* data, size_t len); | 477 size_t ProcessCredentialFramePayload(const char* data, size_t len); |
| 411 size_t ProcessControlFrameBeforeHeaderBlock(const char* data, size_t len); | 478 size_t ProcessControlFrameBeforeHeaderBlock(const char* data, size_t len); |
| 412 size_t ProcessControlFrameHeaderBlock(const char* data, size_t len); | 479 size_t ProcessControlFrameHeaderBlock(const char* data, size_t len); |
| 480 size_t ProcessSettingsFramePayload(const char* data, size_t len); |
| 413 size_t ProcessDataFramePayload(const char* data, size_t len); | 481 size_t ProcessDataFramePayload(const char* data, size_t len); |
| 414 | 482 |
| 483 // Helpers for above internal breakouts from ProcessInput. |
| 484 void ProcessControlFrameHeader(); |
| 485 bool ProcessSetting(const char* data); // Always passed exactly 8 bytes. |
| 486 |
| 415 // Get (and lazily initialize) the ZLib state. | 487 // Get (and lazily initialize) the ZLib state. |
| 416 z_stream* GetHeaderCompressor(); | 488 z_stream* GetHeaderCompressor(); |
| 417 z_stream* GetHeaderDecompressor(); | 489 z_stream* GetHeaderDecompressor(); |
| 418 z_stream* GetStreamCompressor(SpdyStreamId id); | |
| 419 z_stream* GetStreamDecompressor(SpdyStreamId id); | 490 z_stream* GetStreamDecompressor(SpdyStreamId id); |
| 420 | 491 |
| 421 // Compression helpers | 492 // Compression helpers |
| 422 SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame); | 493 SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame); |
| 423 SpdyDataFrame* CompressDataFrame(const SpdyDataFrame& frame); | |
| 424 SpdyControlFrame* DecompressControlFrame(const SpdyControlFrame& frame); | |
| 425 SpdyDataFrame* DecompressDataFrame(const SpdyDataFrame& frame); | |
| 426 SpdyFrame* CompressFrameWithZStream(const SpdyFrame& frame, | |
| 427 z_stream* compressor); | |
| 428 SpdyFrame* DecompressFrameWithZStream(const SpdyFrame& frame, | |
| 429 z_stream* decompressor); | |
| 430 void CleanupCompressorForStream(SpdyStreamId id); | 494 void CleanupCompressorForStream(SpdyStreamId id); |
| 431 void CleanupDecompressorForStream(SpdyStreamId id); | 495 void CleanupDecompressorForStream(SpdyStreamId id); |
| 432 void CleanupStreamCompressorsAndDecompressors(); | 496 void CleanupStreamCompressorsAndDecompressors(); |
| 433 | 497 |
| 434 // Not used (yet) | |
| 435 size_t BytesSafeToRead() const; | |
| 436 | |
| 437 // Deliver the given control frame's compressed headers block to the visitor | 498 // Deliver the given control frame's compressed headers block to the visitor |
| 438 // in decompressed form, in chunks. Returns true if the visitor has | 499 // in decompressed form, in chunks. Returns true if the visitor has |
| 439 // accepted all of the chunks. | 500 // accepted all of the chunks. |
| 440 bool IncrementallyDecompressControlFrameHeaderData( | 501 bool IncrementallyDecompressControlFrameHeaderData( |
| 441 const SpdyControlFrame* frame, | 502 const SpdyControlFrame* frame, |
| 442 const char* data, | 503 const char* data, |
| 443 size_t len); | 504 size_t len); |
| 444 | 505 |
| 445 // Deliver the given control frame's uncompressed headers block to the | 506 // Deliver the given control frame's uncompressed headers block to the |
| 446 // visitor in chunks. Returns true if the visitor has accepted all of the | 507 // visitor in chunks. Returns true if the visitor has accepted all of the |
| 447 // chunks. | 508 // chunks. |
| 448 bool IncrementallyDeliverControlFrameHeaderData(const SpdyControlFrame* frame, | 509 bool IncrementallyDeliverControlFrameHeaderData(const SpdyControlFrame* frame, |
| 449 const char* data, | 510 const char* data, |
| 450 size_t len); | 511 size_t len); |
| 451 | 512 |
| 452 // Utility to copy the given data block to the current frame buffer, up | 513 // Utility to copy the given data block to the current frame buffer, up |
| 453 // to the given maximum number of bytes, and update the buffer | 514 // to the given maximum number of bytes, and update the buffer |
| 454 // data (pointer and length). Returns the number of bytes | 515 // data (pointer and length). Returns the number of bytes |
| 455 // read, and: | 516 // read, and: |
| 456 // *data is advanced the number of bytes read. | 517 // *data is advanced the number of bytes read. |
| 457 // *len is reduced by the number of bytes read. | 518 // *len is reduced by the number of bytes read. |
| 458 size_t UpdateCurrentFrameBuffer(const char** data, size_t* len, | 519 size_t UpdateCurrentFrameBuffer(const char** data, size_t* len, |
| 459 size_t max_bytes); | 520 size_t max_bytes); |
| 460 | 521 |
| 522 // Retrieve serialized length of SpdyHeaderBlock. |
| 523 size_t GetSerializedLength(const SpdyHeaderBlock* headers) const; |
| 524 |
| 525 // Serializes a SpdyHeaderBlock. |
| 526 void WriteHeaderBlock(SpdyFrameBuilder* frame, |
| 527 const SpdyHeaderBlock* headers) const; |
| 528 |
| 461 // Set the error code and moves the framer into the error state. | 529 // Set the error code and moves the framer into the error state. |
| 462 void set_error(SpdyError error); | 530 void set_error(SpdyError error); |
| 463 | 531 |
| 464 // Expands the control frame buffer to accomodate a particular payload size. | 532 // Expands the control frame buffer to accomodate a particular payload size. |
| 465 void ExpandControlFrameBuffer(size_t size); | 533 void ExpandControlFrameBuffer(size_t size); |
| 466 | 534 |
| 467 // Given a frame, breakdown the variable payload length, the static header | 535 // Given a frame, breakdown the variable payload length, the static header |
| 468 // header length, and variable payload pointer. | 536 // header length, and variable payload pointer. |
| 469 bool GetFrameBoundaries(const SpdyFrame& frame, int* payload_length, | 537 bool GetFrameBoundaries(const SpdyFrame& frame, int* payload_length, |
| 470 int* header_length, const char** payload) const; | 538 int* header_length, const char** payload) const; |
| 471 | 539 |
| 472 int num_stream_compressors() const { return stream_compressors_.size(); } | 540 int num_stream_compressors() const { return stream_compressors_.size(); } |
| 473 int num_stream_decompressors() const { return stream_decompressors_.size(); } | 541 int num_stream_decompressors() const { return stream_decompressors_.size(); } |
| 474 | 542 |
| 475 // The initial size of the control frame buffer; this is used internally | 543 // The initial size of the control frame buffer; this is used internally |
| 476 // as we parse through control frames. (It is exposed here for unit test | 544 // as we parse through control frames. (It is exposed here for unit test |
| 477 // purposes.) | 545 // purposes.) |
| 478 // This is only used when compression is enabled; otherwise, | 546 // This is only used when compression is enabled; otherwise, |
| 479 // kUncompressedControlFrameBufferInitialSize is used. | 547 // kUncompressedControlFrameBufferInitialSize is used. |
| 480 static size_t kControlFrameBufferInitialSize; | 548 static size_t kControlFrameBufferInitialSize; |
| 481 | 549 |
| 482 // The initial size of the control frame buffer when compression is disabled. | 550 // The initial size of the control frame buffer when compression is disabled. |
| 483 // This exists because we don't do stream (de)compressed control frame data to | 551 // This exists because we don't do stream (de)compressed control frame data to |
| 484 // our visitor; we instead buffer the entirety of the control frame and then | 552 // our visitor; we instead buffer the entirety of the control frame and then |
| 485 // decompress in one fell swoop. | 553 // decompress in one fell swoop. |
| 486 // Since this is only used for control frame headers, the maximum control | 554 // Since this is only used for control frame headers, the maximum control |
| 487 // frame header size (18B) is sufficient; all remaining control frame data is | 555 // frame header size (18B) is sufficient; all remaining control frame data is |
| 488 // streamed to the visitor. | 556 // streamed to the visitor. |
| 489 // In addition to the maximum control frame header size, we account for any | |
| 490 // LOAS checksumming (16B) that may occur in the VTL case. | |
| 491 // TODO(hkhalil): Remove post code-yellow once streamed inflate is properly | 557 // TODO(hkhalil): Remove post code-yellow once streamed inflate is properly |
| 492 // implemented. | 558 // implemented. |
| 493 static const size_t kUncompressedControlFrameBufferInitialSize = 18 + 16; | 559 static size_t kUncompressedControlFrameBufferInitialSize; |
| 494 | 560 |
| 495 // The maximum size of the control frame buffer that we support. | 561 // The maximum size of the control frame buffer that we support. |
| 496 // TODO(mbelshe): We should make this stream-based so there are no limits. | 562 // TODO(mbelshe): We should make this stream-based so there are no limits. |
| 497 static size_t kControlFrameBufferMaxSize; | 563 static size_t kControlFrameBufferMaxSize; |
| 498 | 564 |
| 499 // The size of the buffer into which compressed frames are inflated. | |
| 500 static const size_t kDecompressionBufferSize = 8 * 1024; | |
| 501 | |
| 502 SpdyState state_; | 565 SpdyState state_; |
| 503 SpdyError error_code_; | 566 SpdyError error_code_; |
| 504 size_t remaining_data_; | 567 size_t remaining_data_; |
| 505 | 568 |
| 506 // The number of bytes remaining to read from the current control frame's | 569 // The number of bytes remaining to read from the current control frame's |
| 507 // payload. | 570 // payload. |
| 508 size_t remaining_control_payload_; | 571 size_t remaining_control_payload_; |
| 509 | 572 |
| 510 // The number of bytes remaining to read from the current control frame's | 573 // The number of bytes remaining to read from the current control frame's |
| 511 // headers. Note that header data blocks (for control types that have them) | 574 // headers. Note that header data blocks (for control types that have them) |
| 512 // are part of the frame's payload, and not the frame's headers. | 575 // are part of the frame's payload, and not the frame's headers. |
| 513 size_t remaining_control_header_; | 576 size_t remaining_control_header_; |
| 514 | 577 |
| 515 char* current_frame_buffer_; | 578 char* current_frame_buffer_; |
| 516 size_t current_frame_len_; // Number of bytes read into the current_frame_. | 579 size_t current_frame_len_; // Number of bytes read into the current_frame_. |
| 517 size_t current_frame_capacity_; | 580 size_t current_frame_capacity_; |
| 518 | 581 |
| 582 // Scratch space for handling SETTINGS frames. |
| 583 // TODO(hkhalil): Unify memory for this scratch space with |
| 584 // current_frame_buffer_. |
| 585 SpdySettingsScratch settings_scratch_; |
| 586 |
| 519 bool validate_control_frame_sizes_; | 587 bool validate_control_frame_sizes_; |
| 520 bool enable_compression_; // Controls all compression | 588 bool enable_compression_; // Controls all compression |
| 521 // SPDY header compressors. | 589 // SPDY header compressors. |
| 522 scoped_ptr<z_stream> header_compressor_; | 590 scoped_ptr<z_stream> header_compressor_; |
| 523 scoped_ptr<z_stream> header_decompressor_; | 591 scoped_ptr<z_stream> header_decompressor_; |
| 524 | 592 |
| 525 // Per-stream data compressors. | 593 // Per-stream data compressors. |
| 526 CompressorMap stream_compressors_; | 594 CompressorMap stream_compressors_; |
| 527 CompressorMap stream_decompressors_; | 595 CompressorMap stream_decompressors_; |
| 528 | 596 |
| 529 SpdyFramerVisitorInterface* visitor_; | 597 SpdyFramerVisitorInterface* visitor_; |
| 530 | 598 |
| 531 std::string display_protocol_; | 599 std::string display_protocol_; |
| 532 | 600 |
| 601 int spdy_version_; |
| 602 |
| 603 // Tracks if we've ever gotten far enough in framing to see a control frame of |
| 604 // type SYN_STREAM or SYN_REPLY. |
| 605 // |
| 606 // If we ever get something which looks like a data frame before we've had a |
| 607 // SYN, we explicitly check to see if it looks like we got an HTTP response to |
| 608 // a SPDY request. This boolean lets us do that. |
| 609 bool syn_frame_processed_; |
| 610 |
| 611 // If we ever get a data frame before a SYN frame, we check to see if it |
| 612 // starts with HTTP. If it does, we likely have an HTTP response. This |
| 613 // isn't guaranteed though: we could have gotten a settings frame and then |
| 614 // corrupt data that just looks like HTTP, but deterministic checking requires |
| 615 // a lot more state. |
| 616 bool probable_http_response_; |
| 617 |
| 533 static bool compression_default_; | 618 static bool compression_default_; |
| 534 static int spdy_version_; | |
| 535 }; | 619 }; |
| 536 | 620 |
| 537 } // namespace spdy | 621 } // namespace spdy |
| 538 | 622 |
| 539 #endif // NET_SPDY_SPDY_FRAMER_H_ | 623 #endif // NET_SPDY_SPDY_FRAMER_H_ |
| OLD | NEW |