Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: net/spdy/spdy_framer.h

Issue 9618002: SPDY - integration of spdy/3 code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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;
(...skipping 12 matching lines...) Expand all
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 557 // In addition to the maximum control frame header size, we account for any
490 // LOAS checksumming (16B) that may occur in the VTL case. 558 // LOAS checksumming (16B) that may occur in the VTL case.
491 // TODO(hkhalil): Remove post code-yellow once streamed inflate is properly 559 // TODO(hkhalil): Remove post code-yellow once streamed inflate is properly
492 // implemented. 560 // implemented.
493 static const size_t kUncompressedControlFrameBufferInitialSize = 18 + 16; 561 static size_t kUncompressedControlFrameBufferInitialSize;
494 562
495 // The maximum size of the control frame buffer that we support. 563 // 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. 564 // TODO(mbelshe): We should make this stream-based so there are no limits.
497 static size_t kControlFrameBufferMaxSize; 565 static size_t kControlFrameBufferMaxSize;
498 566
499 // The size of the buffer into which compressed frames are inflated.
500 static const size_t kDecompressionBufferSize = 8 * 1024;
501
502 SpdyState state_; 567 SpdyState state_;
503 SpdyError error_code_; 568 SpdyError error_code_;
504 size_t remaining_data_; 569 size_t remaining_data_;
505 570
506 // The number of bytes remaining to read from the current control frame's 571 // The number of bytes remaining to read from the current control frame's
507 // payload. 572 // payload.
508 size_t remaining_control_payload_; 573 size_t remaining_control_payload_;
509 574
510 // The number of bytes remaining to read from the current control frame's 575 // 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) 576 // 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. 577 // are part of the frame's payload, and not the frame's headers.
513 size_t remaining_control_header_; 578 size_t remaining_control_header_;
514 579
515 char* current_frame_buffer_; 580 char* current_frame_buffer_;
516 size_t current_frame_len_; // Number of bytes read into the current_frame_. 581 size_t current_frame_len_; // Number of bytes read into the current_frame_.
517 size_t current_frame_capacity_; 582 size_t current_frame_capacity_;
518 583
584 // Scratch space for handling SETTINGS frames.
585 // TODO(hkhalil): Unify memory for this scratch space with
586 // current_frame_buffer_.
587 SpdySettingsScratch settings_scratch_;
588
519 bool validate_control_frame_sizes_; 589 bool validate_control_frame_sizes_;
520 bool enable_compression_; // Controls all compression 590 bool enable_compression_; // Controls all compression
521 // SPDY header compressors. 591 // SPDY header compressors.
522 scoped_ptr<z_stream> header_compressor_; 592 scoped_ptr<z_stream> header_compressor_;
523 scoped_ptr<z_stream> header_decompressor_; 593 scoped_ptr<z_stream> header_decompressor_;
524 594
525 // Per-stream data compressors. 595 // Per-stream data compressors.
526 CompressorMap stream_compressors_; 596 CompressorMap stream_compressors_;
527 CompressorMap stream_decompressors_; 597 CompressorMap stream_decompressors_;
528 598
529 SpdyFramerVisitorInterface* visitor_; 599 SpdyFramerVisitorInterface* visitor_;
530 600
531 std::string display_protocol_; 601 std::string display_protocol_;
532 602
603 int spdy_version_;
604
605 // Tracks if we've ever gotten far enough in framing to see a control frame of
606 // type SYN_STREAM or SYN_REPLY.
607 //
608 // If we ever get something which looks like a data frame before we've had a
609 // SYN, we explicitly check to see if it looks like we got an HTTP response to
610 // a SPDY request. This boolean lets us do that.
611 bool syn_frame_processed_;
612
613 // If we ever get a data frame before a SYN frame, we check to see if it
614 // starts with HTTP. If it does, we likely have an HTTP response. This
615 // isn't guaranteed though: we could have gotten a settings frame and then
616 // corrupt data that just looks like HTTP, but deterministic checking requires
617 // a lot more state.
618 bool probable_http_response_;
619
533 static bool compression_default_; 620 static bool compression_default_;
534 static int spdy_version_;
535 }; 621 };
536 622
537 } // namespace spdy 623 } // namespace spdy
538 624
539 #endif // NET_SPDY_SPDY_FRAMER_H_ 625 #endif // NET_SPDY_SPDY_FRAMER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698