OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. | 54 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. |
55 // Implement this interface to receive event callbacks as frames are | 55 // Implement this interface to receive event callbacks as frames are |
56 // decoded from the framer. | 56 // decoded from the framer. |
57 class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface { | 57 class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface { |
58 public: | 58 public: |
59 virtual ~SpdyFramerVisitorInterface() {} | 59 virtual ~SpdyFramerVisitorInterface() {} |
60 | 60 |
61 // Called if an error is detected in the SpdyFrame protocol. | 61 // Called if an error is detected in the SpdyFrame protocol. |
62 virtual void OnError(SpdyFramer* framer) = 0; | 62 virtual void OnError(SpdyFramer* framer) = 0; |
63 | 63 |
64 // Called when a Control Frame is received. | 64 // Called when a control frame is received. |
65 virtual void OnControl(const SpdyControlFrame* frame) = 0; | 65 virtual void OnControl(const SpdyControlFrame* frame) = 0; |
66 | 66 |
| 67 // Called when a chunk of header data is available. This is called |
| 68 // after OnControl() is called with the control frame associated with the |
| 69 // header data being delivered here. |
| 70 // |stream_id| The stream receiving the header data. |
| 71 // |header_data| A buffer containing the header data chunk received. |
| 72 // |len| The length of the header data buffer. A length of zero indicates |
| 73 // that the header data block has been completely sent. |
| 74 // When this function returns true the visitor indicates that it accepted |
| 75 // all of the data. Returning false indicates that that an unrecoverable |
| 76 // error has occurred, such as bad header data or resource exhaustion. |
| 77 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id, |
| 78 const char* header_data, |
| 79 size_t len) = 0; |
| 80 |
| 81 // Called when a data frame header is received. The frame's data |
| 82 // payload will be provided via subsequent calls to |
| 83 // OnStreamFrameData(). |
| 84 virtual void OnDataFrameHeader(const SpdyDataFrame* frame) = 0; |
| 85 |
67 // Called when data is received. | 86 // Called when data is received. |
68 // |stream_id| The stream receiving data. | 87 // |stream_id| The stream receiving data. |
69 // |data| A buffer containing the data received. | 88 // |data| A buffer containing the data received. |
70 // |len| The length of the data buffer. | 89 // |len| The length of the data buffer. |
71 // When the other side has finished sending data on this stream, | 90 // When the other side has finished sending data on this stream, |
72 // this method will be called with a zero-length buffer. | 91 // this method will be called with a zero-length buffer. |
73 virtual void OnStreamFrameData(SpdyStreamId stream_id, | 92 virtual void OnStreamFrameData(SpdyStreamId stream_id, |
74 const char* data, | 93 const char* data, |
75 size_t len) = 0; | 94 size_t len) = 0; |
76 }; | 95 }; |
77 | 96 |
78 class NET_EXPORT_PRIVATE SpdyFramer { | 97 class NET_EXPORT_PRIVATE SpdyFramer { |
79 public: | 98 public: |
80 // SPDY states. | 99 // SPDY states. |
81 // TODO(mbelshe): Can we move these into the implementation | 100 // TODO(mbelshe): Can we move these into the implementation |
82 // and avoid exposing through the header. (Needed for test) | 101 // and avoid exposing through the header. (Needed for test) |
83 enum SpdyState { | 102 enum SpdyState { |
84 SPDY_ERROR, | 103 SPDY_ERROR, |
85 SPDY_DONE, | 104 SPDY_DONE, |
86 SPDY_RESET, | 105 SPDY_RESET, |
87 SPDY_AUTO_RESET, | 106 SPDY_AUTO_RESET, |
88 SPDY_READING_COMMON_HEADER, | 107 SPDY_READING_COMMON_HEADER, |
89 SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER, | 108 SPDY_INTERPRET_CONTROL_FRAME_COMMON_HEADER, |
90 SPDY_CONTROL_FRAME_PAYLOAD, | 109 SPDY_CONTROL_FRAME_PAYLOAD, |
91 SPDY_IGNORE_REMAINING_PAYLOAD, | 110 SPDY_IGNORE_REMAINING_PAYLOAD, |
92 SPDY_FORWARD_STREAM_FRAME | 111 SPDY_FORWARD_STREAM_FRAME, |
| 112 SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, |
| 113 SPDY_CONTROL_FRAME_HEADER_BLOCK, |
93 }; | 114 }; |
94 | 115 |
95 // SPDY error codes. | 116 // SPDY error codes. |
96 enum SpdyError { | 117 enum SpdyError { |
97 SPDY_NO_ERROR, | 118 SPDY_NO_ERROR, |
98 SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. | 119 SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. |
99 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. | 120 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. |
100 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. | 121 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. |
101 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. | 122 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. |
102 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. | 123 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. |
103 SPDY_COMPRESS_FAILURE, // There was an error compressing. | 124 SPDY_COMPRESS_FAILURE, // There was an error compressing. |
104 | 125 |
105 LAST_ERROR, // Must be the last entry in the enum. | 126 LAST_ERROR, // Must be the last entry in the enum. |
106 }; | 127 }; |
107 | 128 |
| 129 // Constant for invalid (or unknown) stream IDs. |
| 130 static const SpdyStreamId kInvalidStream; |
| 131 |
| 132 // The maximum size of header data chunks delivered to the framer visitor |
| 133 // through OnControlFrameHeaderData. (It is exposed here for unit test |
| 134 // purposes.) |
| 135 static const size_t kHeaderDataChunkMaxSize; |
| 136 |
108 // Create a new Framer. | 137 // Create a new Framer. |
109 SpdyFramer(); | 138 SpdyFramer(); |
110 virtual ~SpdyFramer(); | 139 virtual ~SpdyFramer(); |
111 | 140 |
112 // Set callbacks to be called from the framer. A visitor must be set, or | 141 // Set callbacks to be called from the framer. A visitor must be set, or |
113 // else the framer will likely crash. It is acceptable for the visitor | 142 // else the framer will likely crash. It is acceptable for the visitor |
114 // to do nothing. If this is called multiple times, only the last visitor | 143 // to do nothing. If this is called multiple times, only the last visitor |
115 // will be used. | 144 // will be used. |
116 void set_visitor(SpdyFramerVisitorInterface* visitor) { | 145 void set_visitor(SpdyFramerVisitorInterface* visitor) { |
117 visitor_ = visitor; | 146 visitor_ = visitor; |
(...skipping 16 matching lines...) Expand all Loading... |
134 return state_ == SPDY_DONE || state_ == SPDY_AUTO_RESET; | 163 return state_ == SPDY_DONE || state_ == SPDY_AUTO_RESET; |
135 } | 164 } |
136 bool HasError() { return state_ == SPDY_ERROR; } | 165 bool HasError() { return state_ == SPDY_ERROR; } |
137 | 166 |
138 // Further parsing utilities. | 167 // Further parsing utilities. |
139 // Given a control frame, parse out a SpdyHeaderBlock. Only | 168 // Given a control frame, parse out a SpdyHeaderBlock. Only |
140 // valid for SYN_STREAM and SYN_REPLY frames. | 169 // valid for SYN_STREAM and SYN_REPLY frames. |
141 // Returns true if successfully parsed, false otherwise. | 170 // Returns true if successfully parsed, false otherwise. |
142 bool ParseHeaderBlock(const SpdyFrame* frame, SpdyHeaderBlock* block); | 171 bool ParseHeaderBlock(const SpdyFrame* frame, SpdyHeaderBlock* block); |
143 | 172 |
| 173 // Given a buffer containing a decompressed header block in SPDY |
| 174 // serialized format, parse out a SpdyHeaderBlock, putting the results |
| 175 // in the given header block. |
| 176 // Returns true if successfully parsed, false otherwise. |
| 177 static bool ParseHeaderBlockInBuffer(const char* header_data, |
| 178 size_t header_length, |
| 179 SpdyHeaderBlock* block); |
| 180 |
144 // Create a SpdySynStreamControlFrame. | 181 // Create a SpdySynStreamControlFrame. |
145 // |stream_id| is the id for this stream. | 182 // |stream_id| is the id for this stream. |
146 // |associated_stream_id| is the associated stream id for this stream. | 183 // |associated_stream_id| is the associated stream id for this stream. |
147 // |priority| is the priority (0-3) for this stream. | 184 // |priority| is the priority (0-3) for this stream. |
148 // |flags| is the flags to use with the data. | 185 // |flags| is the flags to use with the data. |
149 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. | 186 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. |
150 // |compressed| specifies whether the frame should be compressed. | 187 // |compressed| specifies whether the frame should be compressed. |
151 // |headers| is the header block to include in the frame. | 188 // |headers| is the header block to include in the frame. |
152 SpdySynStreamControlFrame* CreateSynStream(SpdyStreamId stream_id, | 189 SpdySynStreamControlFrame* CreateSynStream(SpdyStreamId stream_id, |
153 SpdyStreamId associated_stream_id, | 190 SpdyStreamId associated_stream_id, |
154 int priority, | 191 int priority, |
155 SpdyControlFlags flags, | 192 SpdyControlFlags flags, |
156 bool compressed, | 193 bool compressed, |
157 SpdyHeaderBlock* headers); | 194 const SpdyHeaderBlock* headers); |
158 | 195 |
159 // Create a SpdySynReplyControlFrame. | 196 // Create a SpdySynReplyControlFrame. |
160 // |stream_id| is the stream for this frame. | 197 // |stream_id| is the stream for this frame. |
161 // |flags| is the flags to use with the data. | 198 // |flags| is the flags to use with the data. |
162 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. | 199 // To mark this frame as the last frame, enable CONTROL_FLAG_FIN. |
163 // |compressed| specifies whether the frame should be compressed. | 200 // |compressed| specifies whether the frame should be compressed. |
164 // |headers| is the header block to include in the frame. | 201 // |headers| is the header block to include in the frame. |
165 SpdySynReplyControlFrame* CreateSynReply(SpdyStreamId stream_id, | 202 SpdySynReplyControlFrame* CreateSynReply(SpdyStreamId stream_id, |
166 SpdyControlFlags flags, | 203 SpdyControlFlags flags, |
167 bool compressed, | 204 bool compressed, |
168 SpdyHeaderBlock* headers); | 205 const SpdyHeaderBlock* headers); |
169 | 206 |
170 static SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id, | 207 static SpdyRstStreamControlFrame* CreateRstStream(SpdyStreamId stream_id, |
171 SpdyStatusCodes status); | 208 SpdyStatusCodes status); |
172 | 209 |
173 // Creates an instance of SpdySettingsControlFrame. The SETTINGS frame is | 210 // Creates an instance of SpdySettingsControlFrame. The SETTINGS frame is |
174 // used to communicate name/value pairs relevant to the communication channel. | 211 // used to communicate name/value pairs relevant to the communication channel. |
175 // TODO(mbelshe): add the name/value pairs!! | 212 // TODO(mbelshe): add the name/value pairs!! |
176 static SpdySettingsControlFrame* CreateSettings(const SpdySettings& values); | 213 static SpdySettingsControlFrame* CreateSettings(const SpdySettings& values); |
177 | 214 |
178 static SpdyControlFrame* CreateNopFrame(); | 215 static SpdyNoOpControlFrame* CreateNopFrame(); |
| 216 |
| 217 // Creates an instance of SpdyPingControlFrame. The unique_id is used to |
| 218 // identify the ping request/response. |
| 219 static SpdyPingControlFrame* CreatePingFrame(uint32 unique_id); |
179 | 220 |
180 // Creates an instance of SpdyGoAwayControlFrame. The GOAWAY frame is used | 221 // Creates an instance of SpdyGoAwayControlFrame. The GOAWAY frame is used |
181 // prior to the shutting down of the TCP connection, and includes the | 222 // prior to the shutting down of the TCP connection, and includes the |
182 // stream_id of the last stream the sender of the frame is willing to process | 223 // stream_id of the last stream the sender of the frame is willing to process |
183 // to completion. | 224 // to completion. |
184 static SpdyGoAwayControlFrame* CreateGoAway( | 225 static SpdyGoAwayControlFrame* CreateGoAway( |
185 SpdyStreamId last_accepted_stream_id); | 226 SpdyStreamId last_accepted_stream_id); |
186 | 227 |
187 // Creates an instance of SpdyHeadersControlFrame. The HEADERS frame is used | 228 // Creates an instance of SpdyHeadersControlFrame. The HEADERS frame is used |
188 // for sending additional headers outside of a SYN_STREAM/SYN_REPLY. The | 229 // for sending additional headers outside of a SYN_STREAM/SYN_REPLY. The |
189 // arguments are the same as for CreateSynReply. | 230 // arguments are the same as for CreateSynReply. |
190 SpdyHeadersControlFrame* CreateHeaders(SpdyStreamId stream_id, | 231 SpdyHeadersControlFrame* CreateHeaders(SpdyStreamId stream_id, |
191 SpdyControlFlags flags, | 232 SpdyControlFlags flags, |
192 bool compressed, | 233 bool compressed, |
193 SpdyHeaderBlock* headers); | 234 const SpdyHeaderBlock* headers); |
194 | 235 |
195 // Creates an instance of SpdyWindowUpdateControlFrame. The WINDOW_UPDATE | 236 // Creates an instance of SpdyWindowUpdateControlFrame. The WINDOW_UPDATE |
196 // frame is used to implement per stream flow control in SPDY. | 237 // frame is used to implement per stream flow control in SPDY. |
197 static SpdyWindowUpdateControlFrame* CreateWindowUpdate( | 238 static SpdyWindowUpdateControlFrame* CreateWindowUpdate( |
198 SpdyStreamId stream_id, | 239 SpdyStreamId stream_id, |
199 uint32 delta_window_size); | 240 uint32 delta_window_size); |
200 | 241 |
201 // Given a SpdySettingsControlFrame, extract the settings. | 242 // Given a SpdySettingsControlFrame, extract the settings. |
202 // Returns true on successful parse, false otherwise. | 243 // Returns true on successful parse, false otherwise. |
203 static bool ParseSettings(const SpdySettingsControlFrame* frame, | 244 static bool ParseSettings(const SpdySettingsControlFrame* frame, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 // On failure, returns NULL. | 279 // On failure, returns NULL. |
239 SpdyFrame* DecompressFrame(const SpdyFrame& frame); | 280 SpdyFrame* DecompressFrame(const SpdyFrame& frame); |
240 | 281 |
241 // Create a copy of a frame. | 282 // Create a copy of a frame. |
242 // Returned frame must be freed with "delete". | 283 // Returned frame must be freed with "delete". |
243 SpdyFrame* DuplicateFrame(const SpdyFrame& frame); | 284 SpdyFrame* DuplicateFrame(const SpdyFrame& frame); |
244 | 285 |
245 // Returns true if a frame could be compressed. | 286 // Returns true if a frame could be compressed. |
246 bool IsCompressible(const SpdyFrame& frame) const; | 287 bool IsCompressible(const SpdyFrame& frame) const; |
247 | 288 |
| 289 // Get the minimum size of the control frame for the given control frame |
| 290 // type. This is useful for validating frame blocks. |
| 291 static size_t GetMinimumControlFrameSize(SpdyControlType type); |
| 292 |
| 293 // Get the stream ID for the given control frame (SYN_STREAM, SYN_REPLY, and |
| 294 // HEADERS). If the control frame is NULL or of another type, this |
| 295 // function returns kInvalidStream. |
| 296 static SpdyStreamId GetControlFrameStreamId( |
| 297 const SpdyControlFrame* control_frame); |
| 298 |
| 299 // For ease of testing and experimentation we can tweak compression on/off. |
| 300 void set_enable_compression(bool value); |
| 301 |
| 302 // SPDY will by default validate the length of incoming control |
| 303 // frames. Set validation to false if you do not want this behavior. |
| 304 void set_validate_control_frame_sizes(bool value); |
| 305 static void set_enable_compression_default(bool value); |
| 306 |
248 // For debugging. | 307 // For debugging. |
249 static const char* StateToString(int state); | 308 static const char* StateToString(int state); |
250 static const char* ErrorCodeToString(int error_code); | 309 static const char* ErrorCodeToString(int error_code); |
| 310 static const char* StatusCodeToString(int status_code); |
| 311 static const char* ControlTypeToString(SpdyControlType type); |
251 static void set_protocol_version(int version) { spdy_version_= version; } | 312 static void set_protocol_version(int version) { spdy_version_= version; } |
252 static int protocol_version() { return spdy_version_; } | 313 static int protocol_version() { return spdy_version_; } |
253 | 314 |
254 // Export the compression dictionary | 315 // Export the compression dictionary |
255 static const char kDictionary[]; | 316 static const char kDictionary[]; |
256 static const int kDictionarySize; | 317 static const int kDictionarySize; |
257 | 318 |
258 protected: | 319 protected: |
259 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, DataCompression); | 320 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, DataCompression); |
260 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ExpandBuffer_HeapSmash); | 321 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ExpandBuffer_HeapSmash); |
261 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HugeHeaderBlock); | 322 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HugeHeaderBlock); |
262 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, UnclosedStreamDataCompressors); | 323 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, UnclosedStreamDataCompressors); |
263 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, | 324 FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, |
264 UncompressLargerThanFrameBufferInitialSize); | 325 UncompressLargerThanFrameBufferInitialSize); |
265 friend class net::HttpNetworkLayer; // This is temporary for the server. | 326 friend class net::HttpNetworkLayer; // This is temporary for the server. |
266 friend class net::HttpNetworkTransactionTest; | 327 friend class net::HttpNetworkTransactionTest; |
267 friend class net::HttpProxyClientSocketPoolTest; | 328 friend class net::HttpProxyClientSocketPoolTest; |
268 friend class net::SpdyHttpStreamTest; | 329 friend class net::SpdyHttpStreamTest; |
269 friend class net::SpdyNetworkTransactionTest; | 330 friend class net::SpdyNetworkTransactionTest; |
270 friend class net::SpdyProxyClientSocketTest; | 331 friend class net::SpdyProxyClientSocketTest; |
271 friend class net::SpdySessionTest; | 332 friend class net::SpdySessionTest; |
272 friend class net::SpdyStreamTest; | 333 friend class net::SpdyStreamTest; |
273 friend class net::SpdyWebSocketStreamTest; | 334 friend class net::SpdyWebSocketStreamTest; |
274 friend class net::WebSocketJobTest; | 335 friend class net::WebSocketJobTest; |
275 friend class test::TestSpdyVisitor; | 336 friend class test::TestSpdyVisitor; |
276 friend void test::FramerSetEnableCompressionHelper(SpdyFramer* framer, | 337 friend void test::FramerSetEnableCompressionHelper(SpdyFramer* framer, |
277 bool compress); | 338 bool compress); |
278 | 339 |
279 // For ease of testing we can tweak compression on/off. | |
280 void set_enable_compression(bool value); | |
281 static void set_enable_compression_default(bool value); | |
282 | |
283 | |
284 // The initial size of the control frame buffer; this is used internally | 340 // The initial size of the control frame buffer; this is used internally |
285 // as we parse through control frames. (It is exposed here for unit test | 341 // as we parse through control frames. (It is exposed here for unit test |
286 // purposes.) | 342 // purposes.) |
| 343 // This is only used when compression is enabled; otherwise, |
| 344 // kUncompressedControlFrameBufferInitialSize is used. |
287 static size_t kControlFrameBufferInitialSize; | 345 static size_t kControlFrameBufferInitialSize; |
288 | 346 |
289 // The maximum size of the control frame buffer that we support. | 347 // The maximum size of the control frame buffer that we support. |
290 // TODO(mbelshe): We should make this stream-based so there are no limits. | 348 // TODO(mbelshe): We should make this stream-based so there are no limits. |
291 static size_t kControlFrameBufferMaxSize; | 349 static size_t kControlFrameBufferMaxSize; |
292 | 350 |
293 private: | 351 private: |
294 typedef std::map<SpdyStreamId, z_stream*> CompressorMap; | 352 typedef std::map<SpdyStreamId, z_stream*> CompressorMap; |
295 | 353 |
296 // Internal breakout from ProcessInput. Returns the number of bytes | 354 // Internal breakout from ProcessInput. Returns the number of bytes |
297 // consumed from the data. | 355 // consumed from the data. |
298 size_t ProcessCommonHeader(const char* data, size_t len); | 356 size_t ProcessCommonHeader(const char* data, size_t len); |
299 void ProcessControlFrameHeader(); | 357 void ProcessControlFrameHeader(); |
300 size_t ProcessControlFramePayload(const char* data, size_t len); | 358 size_t ProcessControlFramePayload(const char* data, size_t len); |
| 359 size_t ProcessControlFrameBeforeHeaderBlock(const char* data, size_t len); |
| 360 // TODO(hkhalil): Rename to ProcessControlFrameHeaderBlock once said flag is |
| 361 // removed, replacing the old method. |
| 362 size_t NewProcessControlFrameHeaderBlock(const char* data, size_t len); |
| 363 size_t ProcessControlFrameHeaderBlock(const char* data, size_t len); |
301 size_t ProcessDataFramePayload(const char* data, size_t len); | 364 size_t ProcessDataFramePayload(const char* data, size_t len); |
302 | 365 |
303 // Get (and lazily initialize) the ZLib state. | 366 // Get (and lazily initialize) the ZLib state. |
304 z_stream* GetHeaderCompressor(); | 367 z_stream* GetHeaderCompressor(); |
305 z_stream* GetHeaderDecompressor(); | 368 z_stream* GetHeaderDecompressor(); |
306 z_stream* GetStreamCompressor(SpdyStreamId id); | 369 z_stream* GetStreamCompressor(SpdyStreamId id); |
307 z_stream* GetStreamDecompressor(SpdyStreamId id); | 370 z_stream* GetStreamDecompressor(SpdyStreamId id); |
308 | 371 |
309 // Compression helpers | 372 // Compression helpers |
310 SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame); | 373 SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame); |
311 SpdyDataFrame* CompressDataFrame(const SpdyDataFrame& frame); | 374 SpdyDataFrame* CompressDataFrame(const SpdyDataFrame& frame); |
312 SpdyControlFrame* DecompressControlFrame(const SpdyControlFrame& frame); | 375 SpdyControlFrame* DecompressControlFrame(const SpdyControlFrame& frame); |
313 SpdyDataFrame* DecompressDataFrame(const SpdyDataFrame& frame); | 376 SpdyDataFrame* DecompressDataFrame(const SpdyDataFrame& frame); |
314 SpdyFrame* CompressFrameWithZStream(const SpdyFrame& frame, | 377 SpdyFrame* CompressFrameWithZStream(const SpdyFrame& frame, |
315 z_stream* compressor); | 378 z_stream* compressor); |
316 SpdyFrame* DecompressFrameWithZStream(const SpdyFrame& frame, | 379 SpdyFrame* DecompressFrameWithZStream(const SpdyFrame& frame, |
317 z_stream* decompressor); | 380 z_stream* decompressor); |
318 void CleanupCompressorForStream(SpdyStreamId id); | 381 void CleanupCompressorForStream(SpdyStreamId id); |
319 void CleanupDecompressorForStream(SpdyStreamId id); | 382 void CleanupDecompressorForStream(SpdyStreamId id); |
320 void CleanupStreamCompressorsAndDecompressors(); | 383 void CleanupStreamCompressorsAndDecompressors(); |
321 | 384 |
322 // Not used (yet) | 385 // Not used (yet) |
323 size_t BytesSafeToRead() const; | 386 size_t BytesSafeToRead() const; |
324 | 387 |
| 388 // Deliver the given control frame's compressed headers block to the visitor |
| 389 // in decompressed form, in chunks. Returns true if the visitor has |
| 390 // accepted all of the chunks. |
| 391 bool IncrementallyDecompressControlFrameHeaderData( |
| 392 const SpdyControlFrame* frame); |
| 393 |
| 394 // Deliver the given control frame's compressed headers block to the visitor |
| 395 // in decompressed form, in chunks. Returns true if the visitor has |
| 396 // accepted all of the chunks. |
| 397 bool IncrementallyDecompressControlFrameHeaderData( |
| 398 const SpdyControlFrame* frame, |
| 399 const char* data, |
| 400 size_t len); |
| 401 |
| 402 // Deliver the given control frame's uncompressed headers block to the |
| 403 // visitor in chunks. Returns true if the visitor has accepted all of the |
| 404 // chunks. |
| 405 bool IncrementallyDeliverControlFrameHeaderData(const SpdyControlFrame* frame, |
| 406 const char* data, |
| 407 size_t len); |
| 408 |
| 409 // Utility to copy the given data block to the current frame buffer, up |
| 410 // to the given maximum number of bytes, and update the buffer |
| 411 // data (pointer and length). Returns the number of bytes |
| 412 // read, and: |
| 413 // *data is advanced the number of bytes read. |
| 414 // *len is reduced by the number of bytes read. |
| 415 size_t UpdateCurrentFrameBuffer(const char** data, size_t* len, |
| 416 size_t max_bytes); |
| 417 |
325 // Set the error code and moves the framer into the error state. | 418 // Set the error code and moves the framer into the error state. |
326 void set_error(SpdyError error); | 419 void set_error(SpdyError error); |
327 | 420 |
328 // Expands the control frame buffer to accomodate a particular payload size. | 421 // Expands the control frame buffer to accomodate a particular payload size. |
329 void ExpandControlFrameBuffer(size_t size); | 422 void ExpandControlFrameBuffer(size_t size); |
330 | 423 |
331 // Given a frame, breakdown the variable payload length, the static header | 424 // Given a frame, breakdown the variable payload length, the static header |
332 // header length, and variable payload pointer. | 425 // header length, and variable payload pointer. |
333 bool GetFrameBoundaries(const SpdyFrame& frame, int* payload_length, | 426 bool GetFrameBoundaries(const SpdyFrame& frame, int* payload_length, |
334 int* header_length, const char** payload) const; | 427 int* header_length, const char** payload) const; |
335 | 428 |
336 int num_stream_compressors() const { return stream_compressors_.size(); } | 429 int num_stream_compressors() const { return stream_compressors_.size(); } |
337 int num_stream_decompressors() const { return stream_decompressors_.size(); } | 430 int num_stream_decompressors() const { return stream_decompressors_.size(); } |
338 | 431 |
| 432 // The initial size of the control frame buffer when compression is disabled. |
| 433 // This exists because we don't do stream (de)compressed control frame data to |
| 434 // our visitor; we instead buffer the entirety of the control frame and then |
| 435 // decompress in one fell swoop. |
| 436 // Since this is only used for control frame headers, the maximum control |
| 437 // frame header size (18B) is sufficient; all remaining control frame data is |
| 438 // streamed to the visitor. |
| 439 // In addition to the maximum control frame header size, we account for any |
| 440 // LOAS checksumming (16B) that may occur in the VTL case. |
| 441 static const size_t kUncompressedControlFrameBufferInitialSize = 18 + 16; |
| 442 |
| 443 // The size of the buffer into which compressed frames are inflated. |
| 444 static const size_t kDecompressionBufferSize = 8 * 1024; |
| 445 |
339 SpdyState state_; | 446 SpdyState state_; |
340 SpdyError error_code_; | 447 SpdyError error_code_; |
341 size_t remaining_payload_; | 448 size_t remaining_data_; |
| 449 |
| 450 // The number of bytes remaining to read from the current control frame's |
| 451 // payload. |
342 size_t remaining_control_payload_; | 452 size_t remaining_control_payload_; |
343 | 453 |
| 454 // The number of bytes remaining to read from the current control frame's |
| 455 // headers. Note that header data blocks (for control types that have them) |
| 456 // are part of the frame's payload, and not the frame's headers. |
| 457 size_t remaining_control_header_; |
| 458 |
344 char* current_frame_buffer_; | 459 char* current_frame_buffer_; |
345 size_t current_frame_len_; // Number of bytes read into the current_frame_. | 460 size_t current_frame_len_; // Number of bytes read into the current_frame_. |
346 size_t current_frame_capacity_; | 461 size_t current_frame_capacity_; |
347 | 462 |
| 463 bool validate_control_frame_sizes_; |
348 bool enable_compression_; // Controls all compression | 464 bool enable_compression_; // Controls all compression |
349 // SPDY header compressors. | 465 // SPDY header compressors. |
350 scoped_ptr<z_stream> header_compressor_; | 466 scoped_ptr<z_stream> header_compressor_; |
351 scoped_ptr<z_stream> header_decompressor_; | 467 scoped_ptr<z_stream> header_decompressor_; |
352 | 468 |
353 // Per-stream data compressors. | 469 // Per-stream data compressors. |
354 CompressorMap stream_compressors_; | 470 CompressorMap stream_compressors_; |
355 CompressorMap stream_decompressors_; | 471 CompressorMap stream_decompressors_; |
356 | 472 |
357 SpdyFramerVisitorInterface* visitor_; | 473 SpdyFramerVisitorInterface* visitor_; |
358 | 474 |
359 static bool compression_default_; | 475 static bool compression_default_; |
360 static int spdy_version_; | 476 static int spdy_version_; |
361 }; | 477 }; |
362 | 478 |
363 } // namespace spdy | 479 } // namespace spdy |
364 | 480 |
365 #endif // NET_SPDY_SPDY_FRAMER_H_ | 481 #endif // NET_SPDY_SPDY_FRAMER_H_ |
OLD | NEW |