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

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

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 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't
6 // constantly adding and subtracting header sizes; this is ugly and error- 6 // constantly adding and subtracting header sizes; this is ugly and error-
7 // prone. 7 // prone.
8 8
9 #include "net/spdy/spdy_framer.h" 9 #include "net/spdy/spdy_framer.h"
10 10
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/metrics/stats_counters.h" 12 #include "base/metrics/stats_counters.h"
13 #include "base/third_party/valgrind/memcheck.h" 13 #include "base/third_party/valgrind/memcheck.h"
14 #include "net/spdy/spdy_frame_builder.h" 14 #include "net/spdy/spdy_frame_builder.h"
15 #include "net/spdy/spdy_frame_reader.h"
15 #include "net/spdy/spdy_bitmasks.h" 16 #include "net/spdy/spdy_bitmasks.h"
16 17
17 #if defined(USE_SYSTEM_ZLIB) 18 #if defined(USE_SYSTEM_ZLIB)
18 #include <zlib.h> 19 #include <zlib.h>
19 #else 20 #else
20 #include "third_party/zlib/zlib.h" 21 #include "third_party/zlib/zlib.h"
21 #endif 22 #endif
22 23
23 using std::vector; 24 using std::vector;
24 25
25 namespace spdy { 26 namespace spdy {
26 27
27 SpdyCredential::SpdyCredential() : slot(0) { }
28 SpdyCredential::~SpdyCredential() { }
29
30 // Compute the id of our dictionary so that we know we're using the 28 // Compute the id of our dictionary so that we know we're using the
31 // right one when asked for it. 29 // right one when asked for it.
32 uLong CalculateDictionaryId() { 30 uLong CalculateDictionaryId(const char* dictionary,
31 const size_t dictionary_size) {
33 uLong initial_value = adler32(0L, Z_NULL, 0); 32 uLong initial_value = adler32(0L, Z_NULL, 0);
34 return adler32(initial_value, 33 return adler32(initial_value,
35 reinterpret_cast<const Bytef*>(SpdyFramer::kDictionary), 34 reinterpret_cast<const Bytef*>(dictionary),
36 SpdyFramer::kDictionarySize); 35 dictionary_size);
37 } 36 }
38 37
39 // Adler ID for the SPDY header compressor dictionary. 38 // Adler ID for the SPDY header compressor dictionaries.
40 const uLong kDictionaryId = CalculateDictionaryId(); 39 const uLong kV2DictionaryId = CalculateDictionaryId(kV2Dictionary,
41 40 kV2DictionarySize);
42 int DecompressHeaderBlockInZStream(z_stream* decompressor) { 41 const uLong kV3DictionaryId = CalculateDictionaryId(kV3Dictionary,
43 int rv = inflate(decompressor, Z_SYNC_FLUSH); 42 kV3DictionarySize);
44 if (rv == Z_NEED_DICT) {
45 // Need to try again with the right dictionary.
46 if (decompressor->adler == kDictionaryId) {
47 rv = inflateSetDictionary(decompressor,
48 (const Bytef*)SpdyFramer::kDictionary,
49 SpdyFramer::kDictionarySize);
50 if (rv == Z_OK)
51 rv = inflate(decompressor, Z_SYNC_FLUSH);
52 }
53 }
54 return rv;
55 }
56
57 // Retrieve serialized length of SpdyHeaderBlock.
58 size_t GetSerializedLength(const SpdyHeaderBlock* headers) {
59 size_t total_length = SpdyControlFrame::kNumNameValuePairsSize;
60 SpdyHeaderBlock::const_iterator it;
61 for (it = headers->begin(); it != headers->end(); ++it) {
62 // We add space for the length of the name and the length of the value as
63 // well as the length of the name and the length of the value.
64 total_length += SpdyControlFrame::kLengthOfNameSize +
65 it->first.size() +
66 SpdyControlFrame::kLengthOfValueSize +
67 it->second.size();
68 }
69 return total_length;
70 }
71
72 // Serializes a SpdyHeaderBlock.
73 void WriteHeaderBlock(SpdyFrameBuilder* frame, const SpdyHeaderBlock* headers) {
74 frame->WriteUInt16(headers->size()); // Number of headers.
75 SpdyHeaderBlock::const_iterator it;
76 for (it = headers->begin(); it != headers->end(); ++it) {
77 bool wrote_header;
78 wrote_header = frame->WriteString(it->first);
79 wrote_header &= frame->WriteString(it->second);
80 DCHECK(wrote_header);
81 }
82 }
83 43
84 // Creates a FlagsAndLength. 44 // Creates a FlagsAndLength.
85 FlagsAndLength CreateFlagsAndLength(SpdyControlFlags flags, size_t length) { 45 FlagsAndLength CreateFlagsAndLength(SpdyControlFlags flags, size_t length) {
86 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask)); 46 DCHECK_EQ(0u, length & ~static_cast<size_t>(kLengthMask));
87 FlagsAndLength flags_length; 47 FlagsAndLength flags_length;
88 flags_length.length_ = htonl(static_cast<uint32>(length)); 48 flags_length.length_ = htonl(static_cast<uint32>(length));
89 DCHECK_EQ(0, flags & ~kControlFlagsMask); 49 DCHECK_EQ(0, flags & ~kControlFlagsMask);
90 flags_length.flags_[0] = flags; 50 flags_length.flags_[0] = flags;
91 return flags_length; 51 return flags_length;
92 } 52 }
93 53
94 // By default is compression on or off. 54 // By default is compression on or off.
95 bool SpdyFramer::compression_default_ = true; 55 bool SpdyFramer::compression_default_ = true;
96 56
97 // The initial size of the control frame buffer; this is used internally 57 // The initial size of the control frame buffer; this is used internally
98 // as we parse through control frames. (It is exposed here for unit test 58 // as we parse through control frames. (It is exposed here for unit test
99 // purposes.) 59 // purposes.)
100 size_t SpdyFramer::kControlFrameBufferInitialSize = 32 * 1024; 60 size_t SpdyFramer::kControlFrameBufferInitialSize = 32 * 1024;
101 61
102 // The maximum size of the control frame buffer that we support. 62 // The maximum size of the control frame buffer that we support.
103 // TODO(mbelshe): We should make this stream-based so there are no limits. 63 // TODO(mbelshe): We should make this stream-based so there are no limits.
104 size_t SpdyFramer::kControlFrameBufferMaxSize = 64 * 1024; 64 size_t SpdyFramer::kControlFrameBufferMaxSize = 64 * 1024;
105 65
106 int SpdyFramer::spdy_version_ = kSpdyProtocolVersion; 66 // The initial size of the control frame buffer when compression is disabled.
67 // This exists because we don't do stream (de)compressed control frame data to
68 // our visitor; we instead buffer the entirety of the control frame and then
69 // decompress in one fell swoop.
70 // Since this is only used for control frame headers, the maximum control
71 // frame header size (18B) is sufficient; all remaining control frame data is
72 // streamed to the visitor.
73 // In addition to the maximum control frame header size, we account for any
74 // LOAS checksumming (16B) that may occur in the VTL case.
75 size_t SpdyFramer::kUncompressedControlFrameBufferInitialSize = 18 + 16;
Ryan Hamilton 2012/03/10 03:23:02 Hm. Ok, I guess this explains the value, but we d
ramant (doing other things) 2012/03/10 19:45:29 I think it could get used in unittests (when in so
Ryan Hamilton 2012/03/11 15:52:02 Let's find out from hkhalil. The way I read the c
107 76
108 const SpdyStreamId SpdyFramer::kInvalidStream = -1; 77 const SpdyStreamId SpdyFramer::kInvalidStream = -1;
109 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; 78 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
110 79
80
111 #ifdef DEBUG_SPDY_STATE_CHANGES 81 #ifdef DEBUG_SPDY_STATE_CHANGES
112 #define CHANGE_STATE(newstate) \ 82 #define CHANGE_STATE(newstate) \
113 { \ 83 { \
114 do { \ 84 do { \
115 LOG(INFO) << "Changing state from: " \ 85 LOG(INFO) << "Changing state from: " \
116 << StateToString(state_) \ 86 << StateToString(state_) \
117 << " to " << StateToString(newstate) << "\n"; \ 87 << " to " << StateToString(newstate) << "\n"; \
118 state_ = newstate; \ 88 state_ = newstate; \
119 } while (false); \ 89 } while (false); \
120 } 90 }
121 #else 91 #else
122 #define CHANGE_STATE(newstate) (state_ = newstate) 92 #define CHANGE_STATE(newstate) (state_ = newstate)
123 #endif 93 #endif
124 94
125 SpdyFramer::SpdyFramer() 95 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version,
96 uint32 wire) {
97 if (version < 3) {
98 ConvertFlagsAndIdForSpdy2(&wire);
99 }
100 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
101 }
102
103 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
104 : flags_(flags), id_(id & 0x00ffffff) {
105 DCHECK_GT(static_cast<uint32>(1 << 24), id);
106 }
107
108 uint32 SettingsFlagsAndId::GetWireFormat(int version) const {
109 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
110 if (version < 3) {
111 ConvertFlagsAndIdForSpdy2(&wire);
112 }
113 return wire;
114 }
115
116 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
117 // This method is used to preserve buggy behavior and works on both
118 // little-endian and big-endian hosts.
119 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
120 // as well as vice versa).
121 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
122 uint8* wire_array = reinterpret_cast<uint8*>(val);
123 std::swap(wire_array[0], wire_array[3]);
124 std::swap(wire_array[1], wire_array[2]);
125 }
126
127 SpdyCredential::SpdyCredential() : slot(0) { }
128 SpdyCredential::~SpdyCredential() { }
129
130 SpdyFramer::SpdyFramer(int version)
126 : state_(SPDY_RESET), 131 : state_(SPDY_RESET),
127 error_code_(SPDY_NO_ERROR), 132 error_code_(SPDY_NO_ERROR),
128 remaining_data_(0), 133 remaining_data_(0),
129 remaining_control_payload_(0), 134 remaining_control_payload_(0),
130 remaining_control_header_(0), 135 remaining_control_header_(0),
131 current_frame_buffer_(NULL), 136 current_frame_buffer_(NULL),
132 current_frame_len_(0), 137 current_frame_len_(0),
133 current_frame_capacity_(0), 138 current_frame_capacity_(0),
134 validate_control_frame_sizes_(true), 139 validate_control_frame_sizes_(true),
135 enable_compression_(compression_default_), 140 enable_compression_(compression_default_),
136 visitor_(NULL), 141 visitor_(NULL),
137 display_protocol_("SPDY") { 142 display_protocol_("SPDY"),
143 spdy_version_(version),
144 syn_frame_processed_(false),
145 probable_http_response_(false) {
146 DCHECK_GE(3, version);
147 DCHECK_LE(2, version);
138 } 148 }
139 149
140 SpdyFramer::~SpdyFramer() { 150 SpdyFramer::~SpdyFramer() {
141 if (header_compressor_.get()) { 151 if (header_compressor_.get()) {
142 deflateEnd(header_compressor_.get()); 152 deflateEnd(header_compressor_.get());
143 } 153 }
144 if (header_decompressor_.get()) { 154 if (header_decompressor_.get()) {
145 inflateEnd(header_decompressor_.get()); 155 inflateEnd(header_decompressor_.get());
146 } 156 }
147 CleanupStreamCompressorsAndDecompressors(); 157 CleanupStreamCompressorsAndDecompressors();
148 delete [] current_frame_buffer_; 158 delete [] current_frame_buffer_;
149 } 159 }
150 160
151 void SpdyFramer::Reset() { 161 void SpdyFramer::Reset() {
152 state_ = SPDY_RESET; 162 state_ = SPDY_RESET;
153 error_code_ = SPDY_NO_ERROR; 163 error_code_ = SPDY_NO_ERROR;
154 remaining_data_ = 0; 164 remaining_data_ = 0;
155 remaining_control_payload_ = 0; 165 remaining_control_payload_ = 0;
156 remaining_control_header_ = 0; 166 remaining_control_header_ = 0;
157 current_frame_len_ = 0; 167 current_frame_len_ = 0;
168 settings_scratch_.Reset();
158 // TODO(hkhalil): Remove once initial_size == kControlFrameBufferInitialSize. 169 // TODO(hkhalil): Remove once initial_size == kControlFrameBufferInitialSize.
159 size_t initial_size = kControlFrameBufferInitialSize; 170 size_t initial_size = kControlFrameBufferInitialSize;
160 if (!enable_compression_) { 171 if (!enable_compression_) {
161 initial_size = kUncompressedControlFrameBufferInitialSize; 172 initial_size = kUncompressedControlFrameBufferInitialSize;
162 } 173 }
163 if (current_frame_capacity_ != initial_size) { 174 if (current_frame_capacity_ != initial_size) {
164 delete [] current_frame_buffer_; 175 delete [] current_frame_buffer_;
165 current_frame_buffer_ = 0; 176 current_frame_buffer_ = 0;
166 current_frame_capacity_ = 0; 177 current_frame_capacity_ = 0;
167 ExpandControlFrameBuffer(initial_size); 178 ExpandControlFrameBuffer(initial_size);
(...skipping 17 matching lines...) Expand all
185 case SPDY_IGNORE_REMAINING_PAYLOAD: 196 case SPDY_IGNORE_REMAINING_PAYLOAD:
186 return "IGNORE_REMAINING_PAYLOAD"; 197 return "IGNORE_REMAINING_PAYLOAD";
187 case SPDY_FORWARD_STREAM_FRAME: 198 case SPDY_FORWARD_STREAM_FRAME:
188 return "FORWARD_STREAM_FRAME"; 199 return "FORWARD_STREAM_FRAME";
189 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: 200 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
190 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; 201 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
191 case SPDY_CONTROL_FRAME_HEADER_BLOCK: 202 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
192 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; 203 return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
193 case SPDY_CREDENTIAL_FRAME_PAYLOAD: 204 case SPDY_CREDENTIAL_FRAME_PAYLOAD:
194 return "SPDY_CREDENTIAL_FRAME_PAYLOAD"; 205 return "SPDY_CREDENTIAL_FRAME_PAYLOAD";
206 case SPDY_SETTINGS_FRAME_PAYLOAD:
207 return "SPDY_SETTINGS_FRAME_PAYLOAD";
195 } 208 }
196 return "UNKNOWN_STATE"; 209 return "UNKNOWN_STATE";
197 } 210 }
198 211
199 void SpdyFramer::set_error(SpdyError error) { 212 void SpdyFramer::set_error(SpdyError error) {
200 DCHECK(visitor_); 213 DCHECK(visitor_);
201 error_code_ = error; 214 error_code_ = error;
202 CHANGE_STATE(SPDY_ERROR); 215 CHANGE_STATE(SPDY_ERROR);
203 visitor_->OnError(this); 216 visitor_->OnError(this);
204 } 217 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 continue; 310 continue;
298 } 311 }
299 312
300 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: { 313 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: {
301 // Control frames that contain header blocks (SYN_STREAM, SYN_REPLY, 314 // Control frames that contain header blocks (SYN_STREAM, SYN_REPLY,
302 // HEADERS) take a different path through the state machine - they 315 // HEADERS) take a different path through the state machine - they
303 // will go: 316 // will go:
304 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK 317 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
305 // 2. SPDY_CONTROL_FRAME_HEADER_BLOCK 318 // 2. SPDY_CONTROL_FRAME_HEADER_BLOCK
306 // 319 //
320 // SETTINGS frames take a slightly modified route:
321 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
322 // 2. SPDY_SETTINGS_FRAME_PAYLOAD
323 //
307 // All other control frames will use the alternate route directly to 324 // All other control frames will use the alternate route directly to
308 // SPDY_CONTROL_FRAME_PAYLOAD 325 // SPDY_CONTROL_FRAME_PAYLOAD
309 int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len); 326 int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len);
310 len -= bytes_read; 327 len -= bytes_read;
311 data += bytes_read; 328 data += bytes_read;
312 continue; 329 continue;
313 } 330 }
314 331
332 case SPDY_SETTINGS_FRAME_PAYLOAD: {
333 int bytes_read = ProcessSettingsFramePayload(data, len);
334 len -= bytes_read;
335 data += bytes_read;
336 continue;
337 }
338
315 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { 339 case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
316 int bytes_read = ProcessControlFrameHeaderBlock(data, len); 340 int bytes_read = ProcessControlFrameHeaderBlock(data, len);
317 len -= bytes_read; 341 len -= bytes_read;
318 data += bytes_read; 342 data += bytes_read;
319 continue; 343 continue;
320 } 344 }
321 345
322 case SPDY_CREDENTIAL_FRAME_PAYLOAD: { 346 case SPDY_CREDENTIAL_FRAME_PAYLOAD: {
323 size_t bytes_read = ProcessCredentialFramePayload(data, len); 347 size_t bytes_read = ProcessCredentialFramePayload(data, len);
324 len -= bytes_read; 348 len -= bytes_read;
325 data += bytes_read; 349 data += bytes_read;
326 continue;
327 } 350 }
328 351
329 case SPDY_CONTROL_FRAME_PAYLOAD: { 352 case SPDY_CONTROL_FRAME_PAYLOAD: {
330 size_t bytes_read = ProcessControlFramePayload(data, len); 353 size_t bytes_read = ProcessControlFramePayload(data, len);
331 len -= bytes_read; 354 len -= bytes_read;
332 data += bytes_read; 355 data += bytes_read;
333 } 356 }
334 // intentional fallthrough 357 // intentional fallthrough
335 case SPDY_IGNORE_REMAINING_PAYLOAD: 358 case SPDY_IGNORE_REMAINING_PAYLOAD:
336 // control frame has too-large payload 359 // control frame has too-large payload
337 // intentional fallthrough 360 // intentional fallthrough
338 case SPDY_FORWARD_STREAM_FRAME: { 361 case SPDY_FORWARD_STREAM_FRAME: {
339 size_t bytes_read = ProcessDataFramePayload(data, len); 362 size_t bytes_read = ProcessDataFramePayload(data, len);
340 len -= bytes_read; 363 len -= bytes_read;
341 data += bytes_read; 364 data += bytes_read;
342 continue; 365 continue;
343 } 366 }
344 default: 367 default:
368 LOG(ERROR) << "Invalid value for " << display_protocol_
369 << " framer state: " << state_;
345 // This ensures that we don't infinite-loop if state_ gets an 370 // This ensures that we don't infinite-loop if state_ gets an
346 // invalid value somehow, such as due to a SpdyFramer getting deleted 371 // invalid value somehow, such as due to a SpdyFramer getting deleted
347 // from a callback it calls. 372 // from a callback it calls.
348 goto bottom; 373 goto bottom;
349 } 374 }
350 } 375 }
351 bottom: 376 bottom:
352 return original_len - len; 377 return original_len - len;
353 } 378 }
354 379
(...skipping 21 matching lines...) Expand all
376 visitor_->OnDataFrameHeader(&data_frame); 401 visitor_->OnDataFrameHeader(&data_frame);
377 if (current_frame.flags() & DATA_FLAG_FIN) { 402 if (current_frame.flags() & DATA_FLAG_FIN) {
378 visitor_->OnStreamFrameData(data_frame.stream_id(), NULL, 0); 403 visitor_->OnStreamFrameData(data_frame.stream_id(), NULL, 0);
379 } 404 }
380 CHANGE_STATE(SPDY_AUTO_RESET); 405 CHANGE_STATE(SPDY_AUTO_RESET);
381 } else { 406 } else {
382 remaining_data_ = current_frame.length(); 407 remaining_data_ = current_frame.length();
383 408
384 // This is just a sanity check for help debugging early frame errors. 409 // This is just a sanity check for help debugging early frame errors.
385 if (remaining_data_ > 1000000u) { 410 if (remaining_data_ > 1000000u) {
386 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_ 411 // The strncmp for 5 is safe because we only hit this point if we
387 << " session is likely corrupt."; 412 // have SpdyFrame::kHeaderSize (8) bytes
413 if (!syn_frame_processed_ &&
414 strncmp(current_frame_buffer_, "HTTP/", 5) == 0) {
415 LOG(WARNING) << "Unexpected HTTP response to spdy request";
416 probable_http_response_ = true;
417 } else {
418 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_
419 << " session is likely corrupt.";
420 }
388 } 421 }
389 422
390 // if we're here, then we have the common header all received. 423 // if we're here, then we have the common header all received.
391 if (!current_frame.is_control_frame()) { 424 if (!current_frame.is_control_frame()) {
392 SpdyDataFrame data_frame(current_frame_buffer_, false); 425 SpdyDataFrame data_frame(current_frame_buffer_, false);
393 visitor_->OnDataFrameHeader(&data_frame); 426 visitor_->OnDataFrameHeader(&data_frame);
394 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); 427 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
395 } else { 428 } else {
396 ProcessControlFrameHeader(); 429 ProcessControlFrameHeader();
397 } 430 }
398 } 431 }
399 return original_len - len; 432 return original_len - len;
400 } 433 }
401 434
402 void SpdyFramer::ProcessControlFrameHeader() { 435 void SpdyFramer::ProcessControlFrameHeader() {
403 DCHECK_EQ(SPDY_NO_ERROR, error_code_); 436 DCHECK_EQ(SPDY_NO_ERROR, error_code_);
404 DCHECK_LE(static_cast<size_t>(SpdyFrame::kHeaderSize), current_frame_len_); 437 DCHECK_LE(static_cast<size_t>(SpdyFrame::kHeaderSize), current_frame_len_);
405 SpdyControlFrame current_control_frame(current_frame_buffer_, false); 438 SpdyControlFrame current_control_frame(current_frame_buffer_, false);
406 439
407 // We check version before we check validity: version can never be 'invalid', 440 // We check version before we check validity: version can never be 'invalid',
408 // it can only be unsupported. 441 // it can only be unsupported.
409 if (current_control_frame.version() != spdy_version_) { 442 if (current_control_frame.version() != spdy_version_) {
443 DLOG(INFO) << "Unsupported SPDY version " << current_control_frame.version()
444 << " (expected " << spdy_version_ << ")";
410 set_error(SPDY_UNSUPPORTED_VERSION); 445 set_error(SPDY_UNSUPPORTED_VERSION);
411 return; 446 return;
412 } 447 }
413 448
414 // Next up, check to see if we have valid data. This should be after version 449 // Next up, check to see if we have valid data. This should be after version
415 // checking (otherwise if the the type were out of bounds due to a version 450 // checking (otherwise if the the type were out of bounds due to a version
416 // upgrade we would misclassify the error) and before checking the type 451 // upgrade we would misclassify the error) and before checking the type
417 // (type can definitely be out of bounds) 452 // (type can definitely be out of bounds)
418 if (!current_control_frame.AppearsToBeAValidControlFrame()) { 453 if (!current_control_frame.AppearsToBeAValidControlFrame()) {
419 set_error(SPDY_INVALID_CONTROL_FRAME); 454 set_error(SPDY_INVALID_CONTROL_FRAME);
(...skipping 18 matching lines...) Expand all
438 if (current_control_frame.length() < 473 if (current_control_frame.length() <
439 SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize) 474 SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize)
440 set_error(SPDY_INVALID_CONTROL_FRAME); 475 set_error(SPDY_INVALID_CONTROL_FRAME);
441 break; 476 break;
442 case RST_STREAM: 477 case RST_STREAM:
443 if (current_control_frame.length() != 478 if (current_control_frame.length() !=
444 SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize) 479 SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize)
445 set_error(SPDY_INVALID_CONTROL_FRAME); 480 set_error(SPDY_INVALID_CONTROL_FRAME);
446 break; 481 break;
447 case SETTINGS: 482 case SETTINGS:
483 // Make sure that we have an integral number of 8-byte key/value pairs,
484 // plus a 4-byte length field.
448 if (current_control_frame.length() < 485 if (current_control_frame.length() <
449 SpdySettingsControlFrame::size() - SpdyControlFrame::kHeaderSize) 486 SpdySettingsControlFrame::size() - SpdyControlFrame::kHeaderSize ||
487 (current_control_frame.length() % 8 != 4)) {
488 DLOG(WARNING) << "Invalid length for SETTINGS frame: "
489 << current_control_frame.length();
450 set_error(SPDY_INVALID_CONTROL_FRAME); 490 set_error(SPDY_INVALID_CONTROL_FRAME);
491 }
451 break; 492 break;
452 case GOAWAY: 493 case GOAWAY:
453 if (current_control_frame.length() != 494 if (current_control_frame.length() !=
454 SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize) 495 SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize)
455 set_error(SPDY_INVALID_CONTROL_FRAME); 496 set_error(SPDY_INVALID_CONTROL_FRAME);
456 break; 497 break;
457 case HEADERS: 498 case HEADERS:
458 if (current_control_frame.length() < 499 if (current_control_frame.length() <
459 SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize) 500 SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize)
460 set_error(SPDY_INVALID_CONTROL_FRAME); 501 set_error(SPDY_INVALID_CONTROL_FRAME);
(...skipping 17 matching lines...) Expand all
478 default: 519 default:
479 LOG(WARNING) << "Valid " << display_protocol_ 520 LOG(WARNING) << "Valid " << display_protocol_
480 << " control frame with unhandled type: " 521 << " control frame with unhandled type: "
481 << current_control_frame.type(); 522 << current_control_frame.type();
482 DCHECK(false); 523 DCHECK(false);
483 set_error(SPDY_INVALID_CONTROL_FRAME); 524 set_error(SPDY_INVALID_CONTROL_FRAME);
484 break; 525 break;
485 } 526 }
486 } 527 }
487 528
488 // We only support version 1 of this protocol.
489 if (current_control_frame.version() != spdy_version_) {
490 set_error(SPDY_UNSUPPORTED_VERSION);
491 return;
492 }
493
494 remaining_control_payload_ = current_control_frame.length(); 529 remaining_control_payload_ = current_control_frame.length();
495 if (remaining_control_payload_ > 530 if (remaining_control_payload_ >
496 kControlFrameBufferMaxSize - SpdyFrame::kHeaderSize) { 531 kControlFrameBufferMaxSize - SpdyFrame::kHeaderSize) {
497 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 532 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
498 return; 533 return;
499 } 534 }
500 535
501 if (current_control_frame.type() == CREDENTIAL) { 536 if (current_control_frame.type() == CREDENTIAL) {
502 visitor_->OnControl(&current_control_frame); 537 visitor_->OnControl(&current_control_frame);
503 CHANGE_STATE(SPDY_CREDENTIAL_FRAME_PAYLOAD); 538 CHANGE_STATE(SPDY_CREDENTIAL_FRAME_PAYLOAD);
504 return; 539 return;
505 } 540 }
506 541
507 int32 frame_size_without_header_block; 542 // Determine the frame size without variable-length data.
543 int32 frame_size_without_variable_data;
508 switch (current_control_frame.type()) { 544 switch (current_control_frame.type()) {
509 case SYN_STREAM: 545 case SYN_STREAM:
510 frame_size_without_header_block = SpdySynStreamControlFrame::size(); 546 syn_frame_processed_ = true;
547 frame_size_without_variable_data = SpdySynStreamControlFrame::size();
511 break; 548 break;
512 case SYN_REPLY: 549 case SYN_REPLY:
513 frame_size_without_header_block = SpdySynReplyControlFrame::size(); 550 syn_frame_processed_ = true;
551 frame_size_without_variable_data = SpdySynReplyControlFrame::size();
552 // SPDY 2 had two bytes of unused space preceeding payload.
553 if (spdy_version_ < 3) {
554 frame_size_without_variable_data += 2;
555 }
514 break; 556 break;
515 case HEADERS: 557 case HEADERS:
516 frame_size_without_header_block = SpdyHeadersControlFrame::size(); 558 frame_size_without_variable_data = SpdyHeadersControlFrame::size();
559 // SPDY 2 had two bytes of unused space preceeding payload.
560 if (spdy_version_ < 3) {
561 frame_size_without_variable_data += 2;
562 }
563 break;
564 case SETTINGS:
565 frame_size_without_variable_data = SpdySettingsControlFrame::size();
517 break; 566 break;
518 default: 567 default:
519 frame_size_without_header_block = -1; 568 frame_size_without_variable_data = -1;
520 LOG_IF(DFATAL, remaining_control_payload_ + SpdyFrame::kHeaderSize >
521 current_frame_capacity_)
522 << display_protocol_
523 << " control frame buffer too small for fixed-length frame.";
524 ExpandControlFrameBuffer(remaining_control_payload_);
525 break; 569 break;
526 } 570 }
527 571
528 if (frame_size_without_header_block > 0) { 572 if (frame_size_without_variable_data == -1) {
573 LOG_IF(ERROR, remaining_control_payload_ + SpdyFrame::kHeaderSize >
574 current_frame_capacity_)
575 << display_protocol_
576 << " control frame buffer too small for fixed-length frame.";
577 // TODO(hkhalil): Remove ExpandControlFrameBuffer().
578 ExpandControlFrameBuffer(remaining_control_payload_);
579 }
580 if (frame_size_without_variable_data > 0) {
529 // We have a control frame with a header block. We need to parse the 581 // We have a control frame with a header block. We need to parse the
530 // remainder of the control frame's header before we can parse the header 582 // remainder of the control frame's header before we can parse the header
531 // block. The start of the header block varies with the control type. 583 // block. The start of the header block varies with the control type.
532 DCHECK_GE(static_cast<uint32>(frame_size_without_header_block), 584 DCHECK_GE(frame_size_without_variable_data,
533 current_frame_len_); 585 static_cast<int32>(current_frame_len_));
534 remaining_control_header_ = frame_size_without_header_block - 586 remaining_control_header_ = frame_size_without_variable_data -
535 current_frame_len_; 587 current_frame_len_;
536 remaining_control_payload_ += SpdyFrame::kHeaderSize - 588 remaining_control_payload_ += SpdyFrame::kHeaderSize -
537 frame_size_without_header_block; 589 frame_size_without_variable_data;
538 CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK); 590 CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK);
539 return; 591 return;
540 } 592 }
541 593
542 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD); 594 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD);
543 } 595 }
544 596
545 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len, 597 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
546 size_t max_bytes) { 598 size_t max_bytes) {
547 size_t bytes_to_read = std::min(*len, max_bytes); 599 size_t bytes_to_read = std::min(*len, max_bytes);
548 DCHECK_GE(current_frame_capacity_, current_frame_len_ + bytes_to_read); 600 DCHECK_GE(current_frame_capacity_, current_frame_len_ + bytes_to_read);
549 memcpy(&current_frame_buffer_[current_frame_len_], *data, bytes_to_read); 601 memcpy(&current_frame_buffer_[current_frame_len_], *data, bytes_to_read);
550 current_frame_len_ += bytes_to_read; 602 current_frame_len_ += bytes_to_read;
551 *data += bytes_to_read; 603 *data += bytes_to_read;
552 *len -= bytes_to_read; 604 *len -= bytes_to_read;
553 return bytes_to_read; 605 return bytes_to_read;
554 } 606 }
555 607
608 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock* headers) const {
609 const size_t num_name_value_pairs_size
610 = (spdy_version_ < 3) ? sizeof(uint16) : sizeof(uint32);
611 const size_t length_of_name_size = num_name_value_pairs_size;
612 const size_t length_of_value_size = num_name_value_pairs_size;
613
614 size_t total_length = num_name_value_pairs_size;
615 for (SpdyHeaderBlock::const_iterator it = headers->begin();
616 it != headers->end();
617 ++it) {
618 // We add space for the length of the name and the length of the value as
619 // well as the length of the name and the length of the value.
620 total_length += length_of_name_size + it->first.size() +
621 length_of_value_size + it->second.size();
622 }
623 return total_length;
624 }
625
626 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
627 const SpdyHeaderBlock* headers) const {
628 if (spdy_version_ < 3) {
629 frame->WriteUInt16(headers->size()); // Number of headers.
630 } else {
631 frame->WriteUInt32(headers->size()); // Number of headers.
632 }
633 SpdyHeaderBlock::const_iterator it;
634 for (it = headers->begin(); it != headers->end(); ++it) {
635 bool wrote_header;
636 if (spdy_version_ < 3) {
637 wrote_header = frame->WriteString(it->first);
638 wrote_header &= frame->WriteString(it->second);
639 } else {
640 wrote_header = frame->WriteStringPiece32(it->first);
641 wrote_header &= frame->WriteStringPiece32(it->second);
642 }
643 DCHECK(wrote_header);
644 }
645 }
646
647
556 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data, 648 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
557 size_t len) { 649 size_t len) {
558 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_); 650 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
559 DCHECK_GT(remaining_control_header_, 0u); 651 DCHECK_GT(remaining_control_header_, 0u);
560 size_t original_len = len; 652 size_t original_len = len;
561 653
562 if (remaining_control_header_) { 654 if (remaining_control_header_) {
563 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, 655 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
564 remaining_control_header_); 656 remaining_control_header_);
565 remaining_control_header_ -= bytes_read; 657 remaining_control_header_ -= bytes_read;
566 if (remaining_control_header_ == 0) { 658 if (remaining_control_header_ == 0) {
567 SpdyControlFrame control_frame(current_frame_buffer_, false); 659 SpdyControlFrame control_frame(current_frame_buffer_, false);
568 DCHECK(control_frame.type() == SYN_STREAM || 660 DCHECK(control_frame.type() == SYN_STREAM ||
569 control_frame.type() == SYN_REPLY || 661 control_frame.type() == SYN_REPLY ||
570 control_frame.type() == HEADERS); 662 control_frame.type() == HEADERS ||
663 control_frame.type() == SETTINGS);
571 visitor_->OnControl(&control_frame); 664 visitor_->OnControl(&control_frame);
572 665
573 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 666 if (control_frame.type() == SETTINGS) {
667 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
668 } else {
669 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
670 }
574 } 671 }
575 } 672 }
576 return original_len - len; 673 return original_len - len;
577 } 674 }
578 675
579 // Does not buffer the control payload. Instead, either passes directly to the 676 // Does not buffer the control payload. Instead, either passes directly to the
580 // visitor or decompresses and then passes directly to the visitor, via 677 // visitor or decompresses and then passes directly to the visitor, via
581 // IncrementallyDeliverControlFrameHeaderData() or 678 // IncrementallyDeliverControlFrameHeaderData() or
582 // IncrementallyDecompressControlFrameHeaderData() respectively. 679 // IncrementallyDecompressControlFrameHeaderData() respectively.
583 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, 680 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 715
619 // Handle error. 716 // Handle error.
620 if (!processed_successfully) { 717 if (!processed_successfully) {
621 return data_len; 718 return data_len;
622 } 719 }
623 720
624 // Return amount processed. 721 // Return amount processed.
625 return process_bytes; 722 return process_bytes;
626 } 723 }
627 724
725 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
726 size_t data_len) {
727 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
728 SpdyControlFrame control_frame(current_frame_buffer_, false);
729 DCHECK_EQ(control_frame.type(), SETTINGS);
730 size_t unprocessed_bytes = std::min(data_len, remaining_control_payload_);
731 size_t processed_bytes = 0;
732 DCHECK_GT(unprocessed_bytes, 0u);
733
734 // Loop over our incoming data.
735 while (unprocessed_bytes > 0) {
736 // Process up to one setting at a time.
737 size_t processing = std::min(
738 unprocessed_bytes,
739 static_cast<size_t>(8 - settings_scratch_.setting_buf_len));
740
741 // Check if we have a complete setting in our input.
742 if (processing == 8) {
743 // Parse the setting directly out of the input without buffering.
744 if (!ProcessSetting(data + processed_bytes)) {
745 set_error(SPDY_INVALID_CONTROL_FRAME);
746 return processed_bytes;
747 }
748 } else {
749 // Continue updating settings_scratch_.setting_buf.
750 memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len,
751 data + processed_bytes,
752 processing);
753 settings_scratch_.setting_buf_len += processing;
754
755 // Check if we have a complete setting buffered.
756 if (settings_scratch_.setting_buf_len == 8) {
757 if (!ProcessSetting(settings_scratch_.setting_buf)) {
758 set_error(SPDY_INVALID_CONTROL_FRAME);
759 return processed_bytes;
760 }
761 // Reset settings_scratch_.setting_buf for our next setting.
762 settings_scratch_.setting_buf_len = 0;
763 }
764 }
765
766 // Iterate.
767 unprocessed_bytes -= processing;
768 processed_bytes += processing;
769 }
770
771 // Check if we're done handling this SETTINGS frame.
772 remaining_control_payload_ -= processed_bytes;
773 if (remaining_control_payload_ == 0) {
774 CHANGE_STATE(SPDY_AUTO_RESET);
775 }
776
777 return processed_bytes;
778 }
779
780 bool SpdyFramer::ProcessSetting(const char* data) {
781 // Extract fields.
782 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
783 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
784 SettingsFlagsAndId id_and_flags =
785 SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire);
786 uint8 flags = id_and_flags.flags();
787 uint32 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
788
789 // Validate id.
790 switch (id_and_flags.id()) {
791 case SETTINGS_UPLOAD_BANDWIDTH:
792 case SETTINGS_DOWNLOAD_BANDWIDTH:
793 case SETTINGS_ROUND_TRIP_TIME:
794 case SETTINGS_MAX_CONCURRENT_STREAMS:
795 case SETTINGS_CURRENT_CWND:
796 case SETTINGS_DOWNLOAD_RETRANS_RATE:
797 case SETTINGS_INITIAL_WINDOW_SIZE:
798 // Valid values.
799 break;
800 default:
801 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_and_flags.id();
802 return false;
803 }
804 SpdySettingsIds id = static_cast<SpdySettingsIds>(id_and_flags.id());
805
806 // Detect duplciates.
807 if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) {
808 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
809 << " in " << display_protocol_ << " SETTINGS frame "
810 << "(last settikng id was "
811 << settings_scratch_.last_setting_id << ").";
812 return false;
813 }
814 settings_scratch_.last_setting_id = id;
815
816 // Validate flags.
817 uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
818 if ((flags & ~(kFlagsMask)) != 0) {
819 DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": "
820 << flags;
821 return false;
822 }
823
824 // Validation succeeded. Pass on to visitor.
825 visitor_->OnSetting(id, flags, value);
826 return true;
827 }
828
628 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { 829 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
629 size_t original_len = len; 830 size_t original_len = len;
630 if (remaining_control_payload_) { 831 if (remaining_control_payload_) {
631 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, 832 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
632 remaining_control_payload_); 833 remaining_control_payload_);
633 remaining_control_payload_ -= bytes_read; 834 remaining_control_payload_ -= bytes_read;
634 remaining_data_ -= bytes_read; 835 remaining_data_ -= bytes_read;
635 if (remaining_control_payload_ == 0) { 836 if (remaining_control_payload_ == 0) {
636 SpdyControlFrame control_frame(current_frame_buffer_, false); 837 SpdyControlFrame control_frame(current_frame_buffer_, false);
637 DCHECK(!control_frame.has_header_block()); 838 DCHECK(!control_frame.has_header_block());
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 DCHECK_LE(alloc_size, kControlFrameBufferMaxSize); 923 DCHECK_LE(alloc_size, kControlFrameBufferMaxSize);
723 if (alloc_size <= current_frame_capacity_) 924 if (alloc_size <= current_frame_capacity_)
724 return; 925 return;
725 char* new_buffer = new char[alloc_size]; 926 char* new_buffer = new char[alloc_size];
726 memcpy(new_buffer, current_frame_buffer_, current_frame_len_); 927 memcpy(new_buffer, current_frame_buffer_, current_frame_len_);
727 delete [] current_frame_buffer_; 928 delete [] current_frame_buffer_;
728 current_frame_capacity_ = alloc_size; 929 current_frame_capacity_ = alloc_size;
729 current_frame_buffer_ = new_buffer; 930 current_frame_buffer_ = new_buffer;
730 } 931 }
731 932
732 /* static */
733 bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, 933 bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
734 size_t header_length, 934 size_t header_length,
735 SpdyHeaderBlock* block) { 935 SpdyHeaderBlock* block) {
736 SpdyFrameBuilder builder(header_data, header_length); 936 SpdyFrameReader reader(header_data, header_length);
737 void* iter = NULL; 937
738 uint16 num_headers; 938 // Read number of headers.
739 if (builder.ReadUInt16(&iter, &num_headers)) { 939 uint32 num_headers;
740 for (int index = 0; index < num_headers; ++index) { 940 if (spdy_version_ < 3) {
741 std::string name; 941 uint16 temp;
742 std::string value; 942 if (!reader.ReadUInt16(&temp)) {
743 if (!builder.ReadString(&iter, &name)) 943 DLOG(INFO) << "Unable to read number of headers.";
744 return false; 944 return false;
745 if (!builder.ReadString(&iter, &value))
746 return false;
747 if (block->find(name) == block->end()) {
748 (*block)[name] = value;
749 } else {
750 return false;
751 }
752 } 945 }
753 return true; 946 num_headers = temp;
754 } 947 } else {
755 return false; 948 if (!reader.ReadUInt32(&num_headers)) {
756 } 949 DLOG(INFO) << "Unable to read number of headers.";
757 950 return false;
758 bool SpdyFramer::ParseHeaderBlock(const SpdyFrame* frame, 951 }
759 SpdyHeaderBlock* block) {
760 SpdyControlFrame control_frame(frame->data(), false);
761 uint32 type = control_frame.type();
762 if (type != SYN_STREAM && type != SYN_REPLY && type != HEADERS)
763 return false;
764
765 // Find the header data within the control frame.
766 scoped_ptr<SpdyFrame> decompressed_frame(DecompressFrame(*frame));
767 if (!decompressed_frame.get())
768 return false;
769
770 const char *header_data = NULL;
771 int header_length = 0;
772
773 switch (type) {
774 case SYN_STREAM:
775 {
776 SpdySynStreamControlFrame syn_frame(decompressed_frame->data(), false);
777 header_data = syn_frame.header_block();
778 header_length = syn_frame.header_block_len();
779 }
780 break;
781 case SYN_REPLY:
782 {
783 SpdySynReplyControlFrame syn_frame(decompressed_frame->data(), false);
784 header_data = syn_frame.header_block();
785 header_length = syn_frame.header_block_len();
786 }
787 break;
788 case HEADERS:
789 {
790 SpdyHeadersControlFrame header_frame(decompressed_frame->data(), false);
791 header_data = header_frame.header_block();
792 header_length = header_frame.header_block_len();
793 }
794 break;
795 } 952 }
796 953
797 SpdyFrameBuilder builder(header_data, header_length); 954 // Read each header.
798 void* iter = NULL; 955 for (uint32 index = 0; index < num_headers; ++index) {
799 uint16 num_headers; 956 base::StringPiece temp;
800 if (builder.ReadUInt16(&iter, &num_headers)) { 957
801 int index; 958 // Read header name.
802 for (index = 0; index < num_headers; ++index) { 959 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
803 std::string name; 960 : !reader.ReadStringPiece32(&temp)) {
804 std::string value; 961 DLOG(INFO) << "Unable to read header name (" << index + 1 << " of "
805 if (!builder.ReadString(&iter, &name)) 962 << num_headers << ").";
806 break; 963 return false;
807 if (!builder.ReadString(&iter, &value))
808 break;
809 if (!name.size() || !value.size())
810 return false;
811 if (block->find(name) == block->end()) {
812 (*block)[name] = value;
813 } else {
814 return false;
815 }
816 } 964 }
817 return index == num_headers && 965 std::string name;
818 iter == header_data + header_length; 966 temp.CopyToString(&name);
967
968 // Read header value.
969 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
970 : !reader.ReadStringPiece32(&temp)) {
971 DLOG(INFO) << "Unable to read header value (" << index + 1 << " of "
972 << num_headers << ").";
973 return false;
974 }
975 std::string value;
976 temp.CopyToString(&value);
977
978 // Ensure no duplicates.
979 if (block->find(name) != block->end()) {
980 DLOG(INFO) << "Duplicate header '" << name << "' (" << index + 1 << " of "
981 << num_headers << ").";
982 return false;
983 }
984
985 // Store header.
986 (*block)[name] = value;
819 } 987 }
820 return false; 988 return true;
821 } 989 }
822 990
823 /* static */ 991 /* static */
824 bool SpdyFramer::ParseSettings(const SpdySettingsControlFrame* frame, 992 bool SpdyFramer::ParseSettings(const SpdySettingsControlFrame* frame,
825 SpdySettings* settings) { 993 SpdySettings* settings) {
826 DCHECK_EQ(frame->type(), SETTINGS); 994 DCHECK_EQ(frame->type(), SETTINGS);
827 DCHECK(settings); 995 DCHECK(settings);
828 996
829 SpdyFrameBuilder parser(frame->header_block(), frame->header_block_len()); 997 SpdyFrameReader parser(frame->header_block(), frame->header_block_len());
830 void* iter = NULL;
831 for (size_t index = 0; index < frame->num_entries(); ++index) { 998 for (size_t index = 0; index < frame->num_entries(); ++index) {
832 uint32 id; 999 uint32 id_and_flags_wire;
833 uint32 value; 1000 uint32 value;
834 if (!parser.ReadUInt32(&iter, &id)) 1001 // SettingsFlagsAndId accepts off-the-wire (network byte order) data, so we
1002 // use ReadBytes() instead of ReadUInt32() as the latter calls ntohl().
1003 if (!parser.ReadBytes(&id_and_flags_wire, 4)) {
835 return false; 1004 return false;
836 if (!parser.ReadUInt32(&iter, &value)) 1005 }
1006 if (!parser.ReadUInt32(&value))
837 return false; 1007 return false;
838 settings->insert(settings->end(), std::make_pair(id, value)); 1008 SettingsFlagsAndId id_and_flags =
1009 SettingsFlagsAndId::FromWireFormat(frame->version(), id_and_flags_wire);
1010 settings->insert(settings->end(), std::make_pair(id_and_flags, value));
839 } 1011 }
840 return true; 1012 return true;
841 } 1013 }
842 1014
843 /* static */ 1015 /* static */
844 bool SpdyFramer::ParseCredentialData(const char* data, size_t len, 1016 bool SpdyFramer::ParseCredentialData(const char* data, size_t len,
845 SpdyCredential* credential) { 1017 SpdyCredential* credential) {
846 DCHECK(credential); 1018 DCHECK(credential);
847 1019
848 void* iter = NULL; 1020 SpdyFrameReader parser(data, len);
849 SpdyFrameBuilder parser(data, len); 1021 base::StringPiece temp;
850 if (!parser.ReadUInt16(&iter, &credential->slot)) 1022 if (!parser.ReadUInt16(&credential->slot)) {
851 return false; 1023 return false;
1024 }
852 1025
853 uint32 proof_len; 1026 if (!parser.ReadStringPiece32(&temp)) {
854 const char* proof_data;
855 if (!parser.ReadReadLen32PrefixedData(&iter, &proof_data, &proof_len))
856 return false; 1027 return false;
857 credential->proof.assign(proof_data, proof_len); 1028 }
1029 temp.CopyToString(&credential->proof);
858 1030
859 while (parser.IteratorHasRoomFor(iter, 1)) { 1031 while (!parser.IsDoneReading()) {
860 uint32 cert_len; 1032 if (!parser.ReadStringPiece32(&temp)) {
861 const char* cert_data;
862 if (!parser.ReadReadLen32PrefixedData(&iter, &cert_data, &cert_len))
863 return false; 1033 return false;
864 credential->certs.push_back(""); 1034 }
865 credential->certs.back().assign(cert_data, cert_len); 1035 std::string cert;
1036 temp.CopyToString(&cert);
1037 credential->certs.push_back(cert);
866 } 1038 }
867 return true; 1039 return true;
868 } 1040 }
869 1041
870 SpdySynStreamControlFrame* SpdyFramer::CreateSynStream( 1042 SpdySynStreamControlFrame* SpdyFramer::CreateSynStream(
871 SpdyStreamId stream_id, SpdyStreamId associated_stream_id, int priority, 1043 SpdyStreamId stream_id,
872 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) { 1044 SpdyStreamId associated_stream_id,
873 DCHECK_GT(stream_id, static_cast<SpdyStreamId>(0)); 1045 SpdyPriority priority,
1046 SpdyControlFlags flags,
1047 bool compressed,
1048 const SpdyHeaderBlock* headers) {
874 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 1049 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
875 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask); 1050 DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask);
876 1051
877 // Find our length. 1052 // Find our length.
878 size_t expected_frame_size = SpdySynStreamControlFrame::size() + 1053 size_t expected_frame_size = SpdySynStreamControlFrame::size() +
879 GetSerializedLength(headers); 1054 GetSerializedLength(headers);
880 1055
881 // Create our FlagsAndLength. 1056 // Create our FlagsAndLength.
882 FlagsAndLength flags_length = CreateFlagsAndLength( 1057 FlagsAndLength flags_length = CreateFlagsAndLength(
883 flags, 1058 flags,
884 expected_frame_size - SpdyFrame::kHeaderSize); 1059 expected_frame_size - SpdyFrame::kHeaderSize);
885 1060
886 SpdyFrameBuilder frame(expected_frame_size); 1061 SpdyFrameBuilder frame(expected_frame_size);
887 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1062 frame.WriteUInt16(kControlFlagMask | spdy_version_);
888 frame.WriteUInt16(SYN_STREAM); 1063 frame.WriteUInt16(SYN_STREAM);
889 frame.WriteBytes(&flags_length, sizeof(flags_length)); 1064 frame.WriteBytes(&flags_length, sizeof(flags_length));
890 frame.WriteUInt32(stream_id); 1065 frame.WriteUInt32(stream_id);
891 frame.WriteUInt32(associated_stream_id); 1066 frame.WriteUInt32(associated_stream_id);
892 frame.WriteUInt16(ntohs(priority) << 6); // Priority. 1067 // Cap as appropriate.
1068 if (priority > GetLowestPriority()) {
1069 DLOG(ERROR) << "Priority out-of-bounds.";
1070 priority = GetLowestPriority();
1071 }
1072 // Priority is 2 bits for <spdy3, 3 bits otherwise.
1073 frame.WriteUInt16(ntohs(priority) << (spdy_version_ < 3 ? 6 : 5));
893 WriteHeaderBlock(&frame, headers); 1074 WriteHeaderBlock(&frame, headers);
894 1075
895 scoped_ptr<SpdySynStreamControlFrame> syn_frame( 1076 scoped_ptr<SpdySynStreamControlFrame> syn_frame(
896 reinterpret_cast<SpdySynStreamControlFrame*>(frame.take())); 1077 reinterpret_cast<SpdySynStreamControlFrame*>(frame.take()));
897 if (compressed) { 1078 if (compressed) {
898 return reinterpret_cast<SpdySynStreamControlFrame*>( 1079 return reinterpret_cast<SpdySynStreamControlFrame*>(
899 CompressControlFrame(*syn_frame.get())); 1080 CompressControlFrame(*syn_frame.get()));
900 } 1081 }
901 return syn_frame.release(); 1082 return syn_frame.release();
902 } 1083 }
903 1084
904 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(SpdyStreamId stream_id, 1085 SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(
905 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) { 1086 SpdyStreamId stream_id,
1087 SpdyControlFlags flags,
1088 bool compressed,
1089 const SpdyHeaderBlock* headers) {
906 DCHECK_GT(stream_id, 0u); 1090 DCHECK_GT(stream_id, 0u);
907 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 1091 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
908 1092
909 // Find our length. 1093 // Find our length.
910 size_t expected_frame_size = SpdySynReplyControlFrame::size() + 1094 size_t expected_frame_size = SpdySynReplyControlFrame::size() +
911 GetSerializedLength(headers); 1095 GetSerializedLength(headers);
1096 // In SPDY 2, there were 2 unused bytes before payload.
1097 if (spdy_version_ < 3) {
1098 expected_frame_size += 2;
1099 }
912 1100
913 // Create our FlagsAndLength. 1101 // Create our FlagsAndLength.
914 FlagsAndLength flags_length = CreateFlagsAndLength( 1102 FlagsAndLength flags_length = CreateFlagsAndLength(
915 flags, 1103 flags,
916 expected_frame_size - SpdyFrame::kHeaderSize); 1104 expected_frame_size - SpdyFrame::kHeaderSize);
917 1105
918 SpdyFrameBuilder frame(expected_frame_size); 1106 SpdyFrameBuilder frame(expected_frame_size);
919 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1107 frame.WriteUInt16(kControlFlagMask | spdy_version_);
920 frame.WriteUInt16(SYN_REPLY); 1108 frame.WriteUInt16(SYN_REPLY);
921 frame.WriteBytes(&flags_length, sizeof(flags_length)); 1109 frame.WriteBytes(&flags_length, sizeof(flags_length));
922 frame.WriteUInt32(stream_id); 1110 frame.WriteUInt32(stream_id);
923 frame.WriteUInt16(0); // Unused 1111 if (spdy_version_ < 3) {
1112 frame.WriteUInt16(0); // Unused
1113 }
924 WriteHeaderBlock(&frame, headers); 1114 WriteHeaderBlock(&frame, headers);
925 1115
926 scoped_ptr<SpdySynReplyControlFrame> reply_frame( 1116 scoped_ptr<SpdySynReplyControlFrame> reply_frame(
927 reinterpret_cast<SpdySynReplyControlFrame*>(frame.take())); 1117 reinterpret_cast<SpdySynReplyControlFrame*>(frame.take()));
928 if (compressed) { 1118 if (compressed) {
929 return reinterpret_cast<SpdySynReplyControlFrame*>( 1119 return reinterpret_cast<SpdySynReplyControlFrame*>(
930 CompressControlFrame(*reply_frame.get())); 1120 CompressControlFrame(*reply_frame.get()));
931 } 1121 }
932 return reply_frame.release(); 1122 return reply_frame.release();
933 } 1123 }
934 1124
935 /* static */ 1125 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(
936 SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(SpdyStreamId stream_id, 1126 SpdyStreamId stream_id,
937 SpdyStatusCodes status) { 1127 SpdyStatusCodes status) const {
938 DCHECK_GT(stream_id, 0u); 1128 DCHECK_GT(stream_id, 0u);
939 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 1129 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
940 DCHECK_NE(status, INVALID); 1130 DCHECK_NE(status, INVALID);
941 DCHECK_LT(status, NUM_STATUS_CODES); 1131 DCHECK_LT(status, NUM_STATUS_CODES);
942 1132
943 SpdyFrameBuilder frame(SpdyRstStreamControlFrame::size()); 1133 SpdyFrameBuilder frame(SpdyRstStreamControlFrame::size());
944 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1134 frame.WriteUInt16(kControlFlagMask | spdy_version_);
945 frame.WriteUInt16(RST_STREAM); 1135 frame.WriteUInt16(RST_STREAM);
946 frame.WriteUInt32(8); 1136 frame.WriteUInt32(8);
947 frame.WriteUInt32(stream_id); 1137 frame.WriteUInt32(stream_id);
948 frame.WriteUInt32(status); 1138 frame.WriteUInt32(status);
949 return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take()); 1139 return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take());
950 } 1140 }
951 1141
952 /* static */
953 SpdySettingsControlFrame* SpdyFramer::CreateSettings( 1142 SpdySettingsControlFrame* SpdyFramer::CreateSettings(
954 const SpdySettings& values) { 1143 const SpdySettings& values) const {
955 SpdyFrameBuilder frame(SpdySettingsControlFrame::size() + 8 * values.size()); 1144 SpdyFrameBuilder frame(SpdySettingsControlFrame::size() + 8 * values.size());
956 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1145 frame.WriteUInt16(kControlFlagMask | spdy_version_);
957 frame.WriteUInt16(SETTINGS); 1146 frame.WriteUInt16(SETTINGS);
958 size_t settings_size = 1147 size_t settings_size =
959 SpdySettingsControlFrame::size() - SpdyFrame::kHeaderSize + 1148 SpdySettingsControlFrame::size() - SpdyFrame::kHeaderSize +
960 8 * values.size(); 1149 8 * values.size();
961 frame.WriteUInt32(settings_size); 1150 frame.WriteUInt32(settings_size);
962 frame.WriteUInt32(values.size()); 1151 frame.WriteUInt32(values.size());
963 SpdySettings::const_iterator it = values.begin(); 1152 SpdySettings::const_iterator it = values.begin();
964 while (it != values.end()) { 1153 while (it != values.end()) {
965 frame.WriteUInt32(it->first.id_); 1154 uint32 id_and_flags_wire = it->first.GetWireFormat(spdy_version_);
1155 frame.WriteBytes(&id_and_flags_wire, 4);
966 frame.WriteUInt32(it->second); 1156 frame.WriteUInt32(it->second);
967 ++it; 1157 ++it;
968 } 1158 }
969 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take()); 1159 return reinterpret_cast<SpdySettingsControlFrame*>(frame.take());
970 } 1160 }
971 1161
972 /* static */ 1162 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const {
973 SpdyNoOpControlFrame* SpdyFramer::CreateNopFrame() {
974 SpdyFrameBuilder frame(SpdyNoOpControlFrame::size());
975 frame.WriteUInt16(kControlFlagMask | spdy_version_);
976 frame.WriteUInt16(NOOP);
977 frame.WriteUInt32(0);
978 return reinterpret_cast<SpdyNoOpControlFrame*>(frame.take());
979 }
980
981 /* static */
982 SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) {
983 SpdyFrameBuilder frame(SpdyPingControlFrame::size()); 1163 SpdyFrameBuilder frame(SpdyPingControlFrame::size());
984 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1164 frame.WriteUInt16(kControlFlagMask | spdy_version_);
985 frame.WriteUInt16(PING); 1165 frame.WriteUInt16(PING);
986 size_t ping_size = SpdyPingControlFrame::size() - SpdyFrame::kHeaderSize; 1166 size_t ping_size = SpdyPingControlFrame::size() - SpdyFrame::kHeaderSize;
987 frame.WriteUInt32(ping_size); 1167 frame.WriteUInt32(ping_size);
988 frame.WriteUInt32(unique_id); 1168 frame.WriteUInt32(unique_id);
989 return reinterpret_cast<SpdyPingControlFrame*>(frame.take()); 1169 return reinterpret_cast<SpdyPingControlFrame*>(frame.take());
990 } 1170 }
991 1171
992 /* static */
993 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway( 1172 SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway(
994 SpdyStreamId last_accepted_stream_id) { 1173 SpdyStreamId last_accepted_stream_id) const {
995 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask); 1174 DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask);
996 1175
997 SpdyFrameBuilder frame(SpdyGoAwayControlFrame::size()); 1176 SpdyFrameBuilder frame(SpdyGoAwayControlFrame::size());
998 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1177 frame.WriteUInt16(kControlFlagMask | spdy_version_);
999 frame.WriteUInt16(GOAWAY); 1178 frame.WriteUInt16(GOAWAY);
1000 size_t go_away_size = SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize; 1179 size_t go_away_size = SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize;
1001 frame.WriteUInt32(go_away_size); 1180 frame.WriteUInt32(go_away_size);
1002 frame.WriteUInt32(last_accepted_stream_id); 1181 frame.WriteUInt32(last_accepted_stream_id);
1003 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take()); 1182 return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take());
1004 } 1183 }
1005 1184
1006 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(SpdyStreamId stream_id, 1185 SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(
1007 SpdyControlFlags flags, bool compressed, const SpdyHeaderBlock* headers) { 1186 SpdyStreamId stream_id,
1187 SpdyControlFlags flags,
1188 bool compressed,
1189 const SpdyHeaderBlock* headers) {
1008 // Basically the same as CreateSynReply(). 1190 // Basically the same as CreateSynReply().
1009 DCHECK_GT(stream_id, 0u); 1191 DCHECK_GT(stream_id, 0u);
1010 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 1192 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1011 1193
1012 // Find our length. 1194 // Find our length.
1013 size_t expected_frame_size = SpdyHeadersControlFrame::size() + 1195 size_t expected_frame_size = SpdyHeadersControlFrame::size() +
1014 GetSerializedLength(headers); 1196 GetSerializedLength(headers);
1197 // In SPDY 2, there were 2 unused bytes before payload.
1198 if (spdy_version_ < 3) {
1199 expected_frame_size += 2;
1200 }
1015 1201
1016 // Create our FlagsAndLength. 1202 // Create our FlagsAndLength.
1017 FlagsAndLength flags_length = CreateFlagsAndLength( 1203 FlagsAndLength flags_length = CreateFlagsAndLength(
1018 flags, 1204 flags,
1019 expected_frame_size - SpdyFrame::kHeaderSize); 1205 expected_frame_size - SpdyFrame::kHeaderSize);
1020 1206
1021 SpdyFrameBuilder frame(expected_frame_size); 1207 SpdyFrameBuilder frame(expected_frame_size);
1022 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1208 frame.WriteUInt16(kControlFlagMask | spdy_version_);
1023 frame.WriteUInt16(HEADERS); 1209 frame.WriteUInt16(HEADERS);
1024 frame.WriteBytes(&flags_length, sizeof(flags_length)); 1210 frame.WriteBytes(&flags_length, sizeof(flags_length));
1025 frame.WriteUInt32(stream_id); 1211 frame.WriteUInt32(stream_id);
1026 frame.WriteUInt16(0); // Unused 1212 if (spdy_version_ < 3) {
1213 frame.WriteUInt16(0); // Unused
1214 }
1027 WriteHeaderBlock(&frame, headers); 1215 WriteHeaderBlock(&frame, headers);
1028 DCHECK_EQ(static_cast<size_t>(frame.length()), expected_frame_size); 1216 DCHECK_EQ(static_cast<size_t>(frame.length()), expected_frame_size);
1029 1217
1030 scoped_ptr<SpdyHeadersControlFrame> headers_frame( 1218 scoped_ptr<SpdyHeadersControlFrame> headers_frame(
1031 reinterpret_cast<SpdyHeadersControlFrame*>(frame.take())); 1219 reinterpret_cast<SpdyHeadersControlFrame*>(frame.take()));
1032 if (compressed) { 1220 if (compressed) {
1033 return reinterpret_cast<SpdyHeadersControlFrame*>( 1221 return reinterpret_cast<SpdyHeadersControlFrame*>(
1034 CompressControlFrame(*headers_frame.get())); 1222 CompressControlFrame(*headers_frame.get()));
1035 } 1223 }
1036 return headers_frame.release(); 1224 return headers_frame.release();
1037 } 1225 }
1038 1226
1039 /* static */
1040 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( 1227 SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate(
1041 SpdyStreamId stream_id, 1228 SpdyStreamId stream_id,
1042 uint32 delta_window_size) { 1229 uint32 delta_window_size) const {
1043 DCHECK_GT(stream_id, 0u); 1230 DCHECK_GT(stream_id, 0u);
1044 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 1231 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1045 DCHECK_GT(delta_window_size, 0u); 1232 DCHECK_GT(delta_window_size, 0u);
1046 DCHECK_LE(delta_window_size, spdy::kSpdyStreamMaximumWindowSize); 1233 DCHECK_LE(delta_window_size,
1234 static_cast<uint32>(spdy::kSpdyStreamMaximumWindowSize));
1047 1235
1048 SpdyFrameBuilder frame(SpdyWindowUpdateControlFrame::size()); 1236 SpdyFrameBuilder frame(SpdyWindowUpdateControlFrame::size());
1049 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1237 frame.WriteUInt16(kControlFlagMask | spdy_version_);
1050 frame.WriteUInt16(WINDOW_UPDATE); 1238 frame.WriteUInt16(WINDOW_UPDATE);
1051 size_t window_update_size = SpdyWindowUpdateControlFrame::size() - 1239 size_t window_update_size = SpdyWindowUpdateControlFrame::size() -
1052 SpdyFrame::kHeaderSize; 1240 SpdyFrame::kHeaderSize;
1053 frame.WriteUInt32(window_update_size); 1241 frame.WriteUInt32(window_update_size);
1054 frame.WriteUInt32(stream_id); 1242 frame.WriteUInt32(stream_id);
1055 frame.WriteUInt32(delta_window_size); 1243 frame.WriteUInt32(delta_window_size);
1056 return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take()); 1244 return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take());
1057 } 1245 }
1058 1246
1059 /* static */
1060 SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame( 1247 SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame(
1061 const SpdyCredential& credential) { 1248 const SpdyCredential& credential) const {
1062 // Calculate the size of the frame by adding the size of the 1249 // Calculate the size of the frame by adding the size of the
1063 // variable length data to the size of the fixed length data. 1250 // variable length data to the size of the fixed length data.
1064 size_t frame_size = SpdyCredentialControlFrame::size() + 1251 size_t frame_size = SpdyCredentialControlFrame::size() +
1065 credential.proof.length(); 1252 credential.proof.length();
1066 DCHECK_EQ(SpdyCredentialControlFrame::size(), 14u); 1253 DCHECK_EQ(SpdyCredentialControlFrame::size(), 14u);
1067 for (vector<std::string>::const_iterator cert = credential.certs.begin(); 1254 for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
1068 cert != credential.certs.end(); 1255 cert != credential.certs.end();
1069 cert++) { 1256 ++cert) {
1070 frame_size += sizeof(uint32); // size of the cert_length field 1257 frame_size += sizeof(uint32); // size of the cert_length field
1071 frame_size += cert->length(); // size of the cert_data field 1258 frame_size += cert->length(); // size of the cert_data field
1072 } 1259 }
1073 size_t payload_size = frame_size - SpdyFrame::kHeaderSize; 1260 size_t payload_size = frame_size - SpdyFrame::kHeaderSize;
1074 1261
1075 SpdyFrameBuilder frame(frame_size); 1262 SpdyFrameBuilder frame(frame_size);
1076 // Create our FlagsAndLength. 1263 // Create our FlagsAndLength.
1077 SpdyControlFlags flags = spdy::CONTROL_FLAG_NONE; 1264 SpdyControlFlags flags = CONTROL_FLAG_NONE;
1078 FlagsAndLength flags_length = CreateFlagsAndLength(flags, payload_size); 1265 FlagsAndLength flags_length = CreateFlagsAndLength(flags, payload_size);
1079 1266
1080 frame.WriteUInt16(kControlFlagMask | spdy_version_); 1267 frame.WriteUInt16(kControlFlagMask | spdy_version_);
1081 frame.WriteUInt16(CREDENTIAL); 1268 frame.WriteUInt16(CREDENTIAL);
1082 frame.WriteBytes(&flags_length, sizeof(flags_length)); 1269 frame.WriteBytes(&flags_length, sizeof(flags_length));
1083 frame.WriteUInt16(credential.slot); 1270 frame.WriteUInt16(credential.slot);
1084 frame.WriteUInt32(credential.proof.size()); 1271 frame.WriteUInt32(credential.proof.size());
1085 frame.WriteBytes(credential.proof.c_str(), credential.proof.size()); 1272 frame.WriteBytes(credential.proof.c_str(), credential.proof.size());
1086 for (vector<std::string>::const_iterator cert = credential.certs.begin(); 1273 for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
1087 cert != credential.certs.end(); 1274 cert != credential.certs.end();
1088 cert++) { 1275 ++cert) {
1089 frame.WriteUInt32(cert->length()); 1276 frame.WriteUInt32(cert->length());
1090 frame.WriteBytes(cert->c_str(), cert->length()); 1277 frame.WriteBytes(cert->c_str(), cert->length());
1091 } 1278 }
1092 return reinterpret_cast<SpdyCredentialControlFrame*>(frame.take()); 1279 return reinterpret_cast<SpdyCredentialControlFrame*>(frame.take());
1093 } 1280 }
1094 1281
1095 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id, 1282 SpdyDataFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id,
1096 const char* data, 1283 const char* data,
1097 uint32 len, SpdyDataFlags flags) { 1284 uint32 len, SpdyDataFlags flags) {
1098 DCHECK_GT(stream_id, 0u);
1099 DCHECK_EQ(0u, stream_id & ~kStreamIdMask); 1285 DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
1100 1286
1101 SpdyFrameBuilder frame(SpdyDataFrame::size() + len); 1287 SpdyFrameBuilder frame(SpdyDataFrame::size() + len);
1102 frame.WriteUInt32(stream_id); 1288 frame.WriteUInt32(stream_id);
1103 1289
1104 DCHECK_EQ(0u, len & ~static_cast<size_t>(kLengthMask)); 1290 DCHECK_EQ(0u, len & ~static_cast<size_t>(kLengthMask));
1105 FlagsAndLength flags_length; 1291 FlagsAndLength flags_length;
1106 flags_length.length_ = htonl(len); 1292 flags_length.length_ = htonl(len);
1107 DCHECK_EQ(0, flags & ~kDataFlagsMask); 1293 DCHECK_EQ(0, flags & ~kDataFlagsMask);
1108 flags_length.flags_[0] = flags; 1294 flags_length.flags_[0] = flags;
1109 frame.WriteBytes(&flags_length, sizeof(flags_length)); 1295 frame.WriteBytes(&flags_length, sizeof(flags_length));
1110 1296
1111 frame.WriteBytes(data, len); 1297 frame.WriteBytes(data, len);
1112 scoped_ptr<SpdyFrame> data_frame(frame.take()); 1298 scoped_ptr<SpdyFrame> data_frame(frame.take());
1113 SpdyDataFrame* rv; 1299 SpdyDataFrame* rv;
1114 if (flags & DATA_FLAG_COMPRESSED) { 1300 if (flags & DATA_FLAG_COMPRESSED) {
1115 rv = reinterpret_cast<SpdyDataFrame*>(CompressFrame(*data_frame.get())); 1301 LOG(DFATAL) << "DATA_FLAG_COMPRESSED invalid for " << display_protocol_
1116 } else { 1302 << ".";
1117 rv = reinterpret_cast<SpdyDataFrame*>(data_frame.release());
1118 } 1303 }
1304 rv = reinterpret_cast<SpdyDataFrame*>(data_frame.release());
1119 1305
1120 if (flags & DATA_FLAG_FIN) { 1306 if (flags & DATA_FLAG_FIN) {
1121 CleanupCompressorForStream(stream_id); 1307 CleanupCompressorForStream(stream_id);
1122 } 1308 }
1123 1309
1124 return rv; 1310 return rv;
1125 } 1311 }
1126 1312
1127 // The following compression setting are based on Brian Olson's analysis. See 1313 // The following compression setting are based on Brian Olson's analysis. See
1128 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79 2 1314 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79 2
1129 // for more details. 1315 // for more details.
1130 static const int kCompressorLevel = 9; 1316 static const int kCompressorLevel = 9;
1131 static const int kCompressorWindowSizeInBits = 11; 1317 static const int kCompressorWindowSizeInBits = 11;
1132 static const int kCompressorMemLevel = 1; 1318 static const int kCompressorMemLevel = 1;
1133 1319
1134 // This is just a hacked dictionary to use for shrinking HTTP-like headers.
1135 // TODO(mbelshe): Use a scientific methodology for computing the dictionary.
1136 const char SpdyFramer::kDictionary[] =
1137 "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
1138 "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
1139 "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
1140 "-agent10010120020120220320420520630030130230330430530630740040140240340440"
1141 "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
1142 "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
1143 "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
1144 "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
1145 "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
1146 "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
1147 "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
1148 "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
1149 ".1statusversionurl";
1150 const int SpdyFramer::kDictionarySize = arraysize(kDictionary);
1151
1152 SpdyFrame* SpdyFramer::CompressFrame(const SpdyFrame& frame) { 1320 SpdyFrame* SpdyFramer::CompressFrame(const SpdyFrame& frame) {
1153 if (frame.is_control_frame()) { 1321 if (frame.is_control_frame()) {
1154 return CompressControlFrame( 1322 return CompressControlFrame(
1155 reinterpret_cast<const SpdyControlFrame&>(frame)); 1323 reinterpret_cast<const SpdyControlFrame&>(frame));
1156 } 1324 }
1157 return CompressDataFrame(reinterpret_cast<const SpdyDataFrame&>(frame)); 1325 return NULL;
1158 }
1159
1160 SpdyFrame* SpdyFramer::DecompressFrame(const SpdyFrame& frame) {
1161 if (frame.is_control_frame()) {
1162 return DecompressControlFrame(
1163 reinterpret_cast<const SpdyControlFrame&>(frame));
1164 }
1165 return DecompressDataFrame(reinterpret_cast<const SpdyDataFrame&>(frame));
1166 } 1326 }
1167 1327
1168 bool SpdyFramer::IsCompressible(const SpdyFrame& frame) const { 1328 bool SpdyFramer::IsCompressible(const SpdyFrame& frame) const {
1169 // The important frames to compress are those which contain large 1329 // The important frames to compress are those which contain large
1170 // amounts of compressible data - namely the headers in the SYN_STREAM 1330 // amounts of compressible data - namely the headers in the SYN_STREAM
1171 // and SYN_REPLY. 1331 // and SYN_REPLY.
1172 // TODO(mbelshe): Reconcile this with the spec when the spec is
1173 // explicit about which frames compress and which do not.
1174 if (frame.is_control_frame()) { 1332 if (frame.is_control_frame()) {
1175 const SpdyControlFrame& control_frame = 1333 const SpdyControlFrame& control_frame =
1176 reinterpret_cast<const SpdyControlFrame&>(frame); 1334 reinterpret_cast<const SpdyControlFrame&>(frame);
1177 return control_frame.type() == SYN_STREAM || 1335 return control_frame.type() == SYN_STREAM ||
1178 control_frame.type() == SYN_REPLY; 1336 control_frame.type() == SYN_REPLY;
1179 } 1337 }
1180 1338
1181 const SpdyDataFrame& data_frame = 1339 // We don't compress Data frames.
1182 reinterpret_cast<const SpdyDataFrame&>(frame); 1340 return false;
1183 return (data_frame.flags() & DATA_FLAG_COMPRESSED) != 0;
1184 } 1341 }
1185 1342
1186 z_stream* SpdyFramer::GetHeaderCompressor() { 1343 z_stream* SpdyFramer::GetHeaderCompressor() {
1187 if (header_compressor_.get()) 1344 if (header_compressor_.get())
1188 return header_compressor_.get(); // Already initialized. 1345 return header_compressor_.get(); // Already initialized.
1189 1346
1190 header_compressor_.reset(new z_stream); 1347 header_compressor_.reset(new z_stream);
1191 memset(header_compressor_.get(), 0, sizeof(z_stream)); 1348 memset(header_compressor_.get(), 0, sizeof(z_stream));
1192 1349
1193 int success = deflateInit2(header_compressor_.get(), 1350 int success = deflateInit2(header_compressor_.get(),
1194 kCompressorLevel, 1351 kCompressorLevel,
1195 Z_DEFLATED, 1352 Z_DEFLATED,
1196 kCompressorWindowSizeInBits, 1353 kCompressorWindowSizeInBits,
1197 kCompressorMemLevel, 1354 kCompressorMemLevel,
1198 Z_DEFAULT_STRATEGY); 1355 Z_DEFAULT_STRATEGY);
1199 if (success == Z_OK) 1356 if (success == Z_OK) {
1357 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
1358 : kV3Dictionary;
1359 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
1360 : kV3DictionarySize;
1200 success = deflateSetDictionary(header_compressor_.get(), 1361 success = deflateSetDictionary(header_compressor_.get(),
1201 reinterpret_cast<const Bytef*>(kDictionary), 1362 reinterpret_cast<const Bytef*>(dictionary),
1202 kDictionarySize); 1363 dictionary_size);
1364 }
1203 if (success != Z_OK) { 1365 if (success != Z_OK) {
1204 LOG(WARNING) << "deflateSetDictionary failure: " << success; 1366 LOG(WARNING) << "deflateSetDictionary failure: " << success;
1205 header_compressor_.reset(NULL); 1367 header_compressor_.reset(NULL);
1206 return NULL; 1368 return NULL;
1207 } 1369 }
1208 return header_compressor_.get(); 1370 return header_compressor_.get();
1209 } 1371 }
1210 1372
1211 z_stream* SpdyFramer::GetHeaderDecompressor() { 1373 z_stream* SpdyFramer::GetHeaderDecompressor() {
1212 if (header_decompressor_.get()) 1374 if (header_decompressor_.get())
1213 return header_decompressor_.get(); // Already initialized. 1375 return header_decompressor_.get(); // Already initialized.
1214 1376
1215 header_decompressor_.reset(new z_stream); 1377 header_decompressor_.reset(new z_stream);
1216 memset(header_decompressor_.get(), 0, sizeof(z_stream)); 1378 memset(header_decompressor_.get(), 0, sizeof(z_stream));
1217 1379
1218 int success = inflateInit(header_decompressor_.get()); 1380 int success = inflateInit(header_decompressor_.get());
1219 if (success != Z_OK) { 1381 if (success != Z_OK) {
1220 LOG(WARNING) << "inflateInit failure: " << success; 1382 LOG(WARNING) << "inflateInit failure: " << success;
1221 header_decompressor_.reset(NULL); 1383 header_decompressor_.reset(NULL);
1222 return NULL; 1384 return NULL;
1223 } 1385 }
1224 return header_decompressor_.get(); 1386 return header_decompressor_.get();
1225 } 1387 }
1226 1388
1227 z_stream* SpdyFramer::GetStreamCompressor(SpdyStreamId stream_id) {
1228 CompressorMap::iterator it = stream_compressors_.find(stream_id);
1229 if (it != stream_compressors_.end())
1230 return it->second; // Already initialized.
1231
1232 scoped_ptr<z_stream> compressor(new z_stream);
1233 memset(compressor.get(), 0, sizeof(z_stream));
1234
1235 int success = deflateInit2(compressor.get(),
1236 kCompressorLevel,
1237 Z_DEFLATED,
1238 kCompressorWindowSizeInBits,
1239 kCompressorMemLevel,
1240 Z_DEFAULT_STRATEGY);
1241 if (success != Z_OK) {
1242 LOG(WARNING) << "deflateInit failure: " << success;
1243 return NULL;
1244 }
1245 return stream_compressors_[stream_id] = compressor.release();
1246 }
1247
1248 z_stream* SpdyFramer::GetStreamDecompressor(SpdyStreamId stream_id) { 1389 z_stream* SpdyFramer::GetStreamDecompressor(SpdyStreamId stream_id) {
1249 CompressorMap::iterator it = stream_decompressors_.find(stream_id); 1390 CompressorMap::iterator it = stream_decompressors_.find(stream_id);
1250 if (it != stream_decompressors_.end()) 1391 if (it != stream_decompressors_.end())
1251 return it->second; // Already initialized. 1392 return it->second; // Already initialized.
1252 1393
1253 scoped_ptr<z_stream> decompressor(new z_stream); 1394 scoped_ptr<z_stream> decompressor(new z_stream);
1254 memset(decompressor.get(), 0, sizeof(z_stream)); 1395 memset(decompressor.get(), 0, sizeof(z_stream));
1255 1396
1256 int success = inflateInit(decompressor.get()); 1397 int success = inflateInit(decompressor.get());
1257 if (success != Z_OK) { 1398 if (success != Z_OK) {
(...skipping 23 matching lines...) Expand all
1281 } 1422 }
1282 break; 1423 break;
1283 case SYN_REPLY: 1424 case SYN_REPLY:
1284 { 1425 {
1285 const SpdySynReplyControlFrame& syn_frame = 1426 const SpdySynReplyControlFrame& syn_frame =
1286 reinterpret_cast<const SpdySynReplyControlFrame&>(frame); 1427 reinterpret_cast<const SpdySynReplyControlFrame&>(frame);
1287 frame_size = SpdySynReplyControlFrame::size(); 1428 frame_size = SpdySynReplyControlFrame::size();
1288 *payload_length = syn_frame.header_block_len(); 1429 *payload_length = syn_frame.header_block_len();
1289 *header_length = frame_size; 1430 *header_length = frame_size;
1290 *payload = frame.data() + *header_length; 1431 *payload = frame.data() + *header_length;
1432 // SPDY 2 had two bytes of unused space preceeding payload.
1433 if (spdy_version_ < 3) {
1434 *header_length += 2;
1435 *payload += 2;
1436 }
1291 } 1437 }
1292 break; 1438 break;
1293 case HEADERS: 1439 case HEADERS:
1294 { 1440 {
1295 const SpdyHeadersControlFrame& headers_frame = 1441 const SpdyHeadersControlFrame& headers_frame =
1296 reinterpret_cast<const SpdyHeadersControlFrame&>(frame); 1442 reinterpret_cast<const SpdyHeadersControlFrame&>(frame);
1297 frame_size = SpdyHeadersControlFrame::size(); 1443 frame_size = SpdyHeadersControlFrame::size();
1298 *payload_length = headers_frame.header_block_len(); 1444 *payload_length = headers_frame.header_block_len();
1299 *header_length = frame_size; 1445 *header_length = frame_size;
1300 *payload = frame.data() + *header_length; 1446 *payload = frame.data() + *header_length;
1447 // SPDY 2 had two bytes of unused space preceeding payload.
1448 if (spdy_version_ < 3) {
1449 *header_length += 2;
1450 *payload += 2;
1451 }
1301 } 1452 }
1302 break; 1453 break;
1303 default: 1454 default:
1304 // TODO(mbelshe): set an error? 1455 // TODO(mbelshe): set an error?
1305 return false; // We can't compress this frame! 1456 return false; // We can't compress this frame!
1306 } 1457 }
1307 } else { 1458 } else {
1308 frame_size = SpdyFrame::kHeaderSize; 1459 frame_size = SpdyFrame::kHeaderSize;
1309 *header_length = frame_size; 1460 *header_length = frame_size;
1310 *payload_length = frame.length(); 1461 *payload_length = frame.length();
1311 *payload = frame.data() + SpdyFrame::kHeaderSize; 1462 *payload = frame.data() + SpdyFrame::kHeaderSize;
1312 } 1463 }
1313 return true; 1464 return true;
1314 } 1465 }
1315 1466
1316 SpdyControlFrame* SpdyFramer::CompressControlFrame( 1467 SpdyControlFrame* SpdyFramer::CompressControlFrame(
1317 const SpdyControlFrame& frame) { 1468 const SpdyControlFrame& frame) {
1318 z_stream* compressor = GetHeaderCompressor(); 1469 z_stream* compressor = GetHeaderCompressor();
1319 if (!compressor) 1470 if (!compressor)
1320 return NULL; 1471 return NULL;
1321 return reinterpret_cast<SpdyControlFrame*>(
1322 CompressFrameWithZStream(frame, compressor));
1323 }
1324 1472
1325 SpdyDataFrame* SpdyFramer::CompressDataFrame(const SpdyDataFrame& frame) {
1326 z_stream* compressor = GetStreamCompressor(frame.stream_id());
1327 if (!compressor)
1328 return NULL;
1329 return reinterpret_cast<SpdyDataFrame*>(
1330 CompressFrameWithZStream(frame, compressor));
1331 }
1332
1333 SpdyControlFrame* SpdyFramer::DecompressControlFrame(
1334 const SpdyControlFrame& frame) {
1335 z_stream* decompressor = GetHeaderDecompressor();
1336 if (!decompressor) {
1337 LOG(DFATAL) << "Couldn't get decompressor for handling control frame.";
1338 set_error(SPDY_DECOMPRESS_FAILURE);
1339 return NULL;
1340 }
1341 return reinterpret_cast<SpdyControlFrame*>(
1342 DecompressFrameWithZStream(frame, decompressor));
1343 }
1344
1345 SpdyDataFrame* SpdyFramer::DecompressDataFrame(const SpdyDataFrame& frame) {
1346 z_stream* decompressor = GetStreamDecompressor(frame.stream_id());
1347 if (!decompressor)
1348 return NULL;
1349 return reinterpret_cast<SpdyDataFrame*>(
1350 DecompressFrameWithZStream(frame, decompressor));
1351 }
1352
1353 SpdyFrame* SpdyFramer::CompressFrameWithZStream(const SpdyFrame& frame,
1354 z_stream* compressor) {
1355 int payload_length; 1473 int payload_length;
1356 int header_length; 1474 int header_length;
1357 const char* payload; 1475 const char* payload;
1358 1476
1359 base::StatsCounter compressed_frames("spdy.CompressedFrames"); 1477 base::StatsCounter compressed_frames("spdy.CompressedFrames");
1360 base::StatsCounter pre_compress_bytes("spdy.PreCompressSize"); 1478 base::StatsCounter pre_compress_bytes("spdy.PreCompressSize");
1361 base::StatsCounter post_compress_bytes("spdy.PostCompressSize"); 1479 base::StatsCounter post_compress_bytes("spdy.PostCompressSize");
1362 1480
1363 if (!enable_compression_) 1481 if (!enable_compression_)
1364 return DuplicateFrame(frame); 1482 return reinterpret_cast<SpdyControlFrame*>(DuplicateFrame(frame));
1365 1483
1366 if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload)) 1484 if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload))
1367 return NULL; 1485 return NULL;
1368 1486
1369 // Create an output frame. 1487 // Create an output frame.
1370 int compressed_max_size = deflateBound(compressor, payload_length); 1488 int compressed_max_size = deflateBound(compressor, payload_length);
1371 int new_frame_size = header_length + compressed_max_size; 1489 int new_frame_size = header_length + compressed_max_size;
1372 scoped_ptr<SpdyFrame> new_frame(new SpdyFrame(new_frame_size)); 1490 if ((frame.type() == SYN_REPLY || frame.type() == HEADERS) &&
1491 spdy_version_ < 3) {
1492 new_frame_size += 2;
1493 }
1494 DCHECK_GE(new_frame_size,
1495 static_cast<int>(frame.length() + SpdyFrame::kHeaderSize));
1496 scoped_ptr<SpdyControlFrame> new_frame(new SpdyControlFrame(new_frame_size));
1373 memcpy(new_frame->data(), frame.data(), 1497 memcpy(new_frame->data(), frame.data(),
1374 frame.length() + SpdyFrame::kHeaderSize); 1498 frame.length() + SpdyFrame::kHeaderSize);
1375 1499
1376 compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload)); 1500 compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload));
1377 compressor->avail_in = payload_length; 1501 compressor->avail_in = payload_length;
1378 compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) + 1502 compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) +
1379 header_length; 1503 header_length;
1380 compressor->avail_out = compressed_max_size; 1504 compressor->avail_out = compressed_max_size;
1381 1505
1382 // Data packets have a 'compressed' flag. 1506 // Data packets have a 'compressed' flag.
1507 // TODO(hkhalil): Remove post code-yellow. It's impossible to execute this
1508 // branch given that SpdyControlFrame::is_control_frame always returns true.
1509 DCHECK(new_frame->is_control_frame());
1383 if (!new_frame->is_control_frame()) { 1510 if (!new_frame->is_control_frame()) {
1384 SpdyDataFrame* data_frame = 1511 SpdyDataFrame* data_frame =
1385 reinterpret_cast<SpdyDataFrame*>(new_frame.get()); 1512 reinterpret_cast<SpdyDataFrame*>(new_frame.get());
1386 data_frame->set_flags(data_frame->flags() | DATA_FLAG_COMPRESSED); 1513 data_frame->set_flags(data_frame->flags() | DATA_FLAG_COMPRESSED);
1387 } 1514 }
1388 1515
1389 // Make sure that all the data we pass to zlib is defined. 1516 // Make sure that all the data we pass to zlib is defined.
1390 // This way, all Valgrind reports on the compressed data are zlib's fault. 1517 // This way, all Valgrind reports on the compressed data are zlib's fault.
1391 (void)VALGRIND_CHECK_MEM_IS_DEFINED(compressor->next_in, 1518 (void)VALGRIND_CHECK_MEM_IS_DEFINED(compressor->next_in,
1392 compressor->avail_in); 1519 compressor->avail_in);
(...skipping 16 matching lines...) Expand all
1409 header_length + compressed_size - SpdyFrame::kHeaderSize); 1536 header_length + compressed_size - SpdyFrame::kHeaderSize);
1410 1537
1411 pre_compress_bytes.Add(payload_length); 1538 pre_compress_bytes.Add(payload_length);
1412 post_compress_bytes.Add(new_frame->length()); 1539 post_compress_bytes.Add(new_frame->length());
1413 1540
1414 compressed_frames.Increment(); 1541 compressed_frames.Increment();
1415 1542
1416 return new_frame.release(); 1543 return new_frame.release();
1417 } 1544 }
1418 1545
1419 SpdyFrame* SpdyFramer::DecompressFrameWithZStream(const SpdyFrame& frame,
1420 z_stream* decompressor) {
1421 int payload_length;
1422 int header_length;
1423 const char* payload;
1424
1425 base::StatsCounter decompressed_frames("spdy.DecompressedFrames");
1426 base::StatsCounter pre_decompress_bytes("spdy.PreDeCompressSize");
1427 base::StatsCounter post_decompress_bytes("spdy.PostDeCompressSize");
1428
1429 if (!enable_compression_)
1430 return DuplicateFrame(frame);
1431
1432 if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload))
1433 return NULL;
1434
1435 if (!frame.is_control_frame()) {
1436 const SpdyDataFrame& data_frame =
1437 reinterpret_cast<const SpdyDataFrame&>(frame);
1438 if ((data_frame.flags() & DATA_FLAG_COMPRESSED) == 0)
1439 return DuplicateFrame(frame);
1440 }
1441
1442 // Create an output frame. Assume it does not need to be longer than
1443 // the input data.
1444 size_t decompressed_max_size = kControlFrameBufferInitialSize;
1445 int new_frame_size = header_length + decompressed_max_size;
1446 if (frame.length() > decompressed_max_size)
1447 return NULL;
1448 scoped_ptr<SpdyFrame> new_frame(new SpdyFrame(new_frame_size));
1449 memcpy(new_frame->data(), frame.data(),
1450 frame.length() + SpdyFrame::kHeaderSize);
1451
1452 decompressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload));
1453 decompressor->avail_in = payload_length;
1454 decompressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) +
1455 header_length;
1456 decompressor->avail_out = decompressed_max_size;
1457
1458 int rv = inflate(decompressor, Z_SYNC_FLUSH);
1459 if (rv == Z_NEED_DICT) {
1460 // Need to try again with the right dictionary.
1461 if (decompressor->adler == kDictionaryId) {
1462 rv = inflateSetDictionary(decompressor,
1463 (const Bytef*)SpdyFramer::kDictionary,
1464 SpdyFramer::kDictionarySize);
1465 if (rv == Z_OK)
1466 rv = inflate(decompressor, Z_SYNC_FLUSH);
1467 }
1468 }
1469 if (rv != Z_OK) { // How can we know that it decompressed everything?
1470 LOG(WARNING) << "inflate failure: " << rv;
1471 return NULL;
1472 }
1473
1474 // Unset the compressed flag for data frames.
1475 if (!new_frame->is_control_frame()) {
1476 SpdyDataFrame* data_frame =
1477 reinterpret_cast<SpdyDataFrame*>(new_frame.get());
1478 data_frame->set_flags(data_frame->flags() & ~DATA_FLAG_COMPRESSED);
1479 }
1480
1481 int decompressed_size = decompressed_max_size - decompressor->avail_out;
1482 new_frame->set_length(
1483 header_length + decompressed_size - SpdyFrame::kHeaderSize);
1484
1485 // If there is data left, then the frame didn't fully decompress. This
1486 // means that there is stranded data at the end of this frame buffer which
1487 // will be ignored.
1488 DCHECK_EQ(decompressor->avail_in, 0u);
1489
1490 pre_decompress_bytes.Add(frame.length());
1491 post_decompress_bytes.Add(new_frame->length());
1492
1493 decompressed_frames.Increment();
1494
1495 return new_frame.release();
1496 }
1497
1498 // Incrementally decompress the control frame's header block, feeding the 1546 // Incrementally decompress the control frame's header block, feeding the
1499 // result to the visitor in chunks. Continue this until the visitor 1547 // result to the visitor in chunks. Continue this until the visitor
1500 // indicates that it cannot process any more data, or (more commonly) we 1548 // indicates that it cannot process any more data, or (more commonly) we
1501 // run out of data to deliver. 1549 // run out of data to deliver.
1502 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( 1550 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
1503 const SpdyControlFrame* control_frame, 1551 const SpdyControlFrame* control_frame,
1504 const char* data, 1552 const char* data,
1505 size_t len) { 1553 size_t len) {
1506 // Get a decompressor or set error. 1554 // Get a decompressor or set error.
1507 z_stream* decomp = GetHeaderDecompressor(); 1555 z_stream* decomp = GetHeaderDecompressor();
1508 if (decomp == NULL) { 1556 if (decomp == NULL) {
1509 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers."; 1557 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers.";
1510 set_error(SPDY_DECOMPRESS_FAILURE); 1558 set_error(SPDY_DECOMPRESS_FAILURE);
1511 return false; 1559 return false;
1512 } 1560 }
1513 1561
1514 bool processed_successfully = true; 1562 bool processed_successfully = true;
1515 char buffer[kHeaderDataChunkMaxSize]; 1563 char buffer[kHeaderDataChunkMaxSize];
1516 1564
1517 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data)); 1565 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data));
1518 decomp->avail_in = len; 1566 decomp->avail_in = len;
1519 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame); 1567 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
1520 DCHECK_LT(0u, stream_id); 1568 DCHECK_LT(0u, stream_id);
1521 while (decomp->avail_in > 0 && processed_successfully) { 1569 while (decomp->avail_in > 0 && processed_successfully) {
1522 decomp->next_out = reinterpret_cast<Bytef*>(buffer); 1570 decomp->next_out = reinterpret_cast<Bytef*>(buffer);
1523 decomp->avail_out = arraysize(buffer); 1571 decomp->avail_out = arraysize(buffer);
1524 int rv = DecompressHeaderBlockInZStream(decomp); 1572
1525 if (rv != Z_OK && rv != Z_BUF_ERROR) { 1573 int rv = inflate(decomp, Z_SYNC_FLUSH);
1526 set_error(SPDY_DECOMPRESS_FAILURE); 1574 if (rv == Z_NEED_DICT) {
1527 DLOG(WARNING) << "inflate failure: " << rv; 1575 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
1528 processed_successfully = false; 1576 : kV3Dictionary;
1529 } else { 1577 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
1578 : kV3DictionarySize;
1579 const uLong dictionary_id = (spdy_version_ < 3) ? kV2DictionaryId
1580 : kV3DictionaryId;
1581 // Need to try again with the right dictionary.
1582 if (decomp->adler == dictionary_id) {
1583 rv = inflateSetDictionary(decomp,
1584 reinterpret_cast<const Bytef*>(dictionary),
1585 dictionary_size);
1586 if (rv == Z_OK)
1587 rv = inflate(decomp, Z_SYNC_FLUSH);
1588 }
1589 }
1590
1591 // Inflate will generate a Z_BUF_ERROR if it runs out of input
1592 // without producing any output. The input is consumed and
1593 // buffered internally by zlib so we can detect this condition by
1594 // checking if avail_in is 0 after the call to inflate.
1595 bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0));
1596 if ((rv == Z_OK) || input_exhausted) {
1530 size_t decompressed_len = arraysize(buffer) - decomp->avail_out; 1597 size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
1531 if (decompressed_len > 0) { 1598 if (decompressed_len > 0) {
1532 processed_successfully = visitor_->OnControlFrameHeaderData( 1599 processed_successfully = visitor_->OnControlFrameHeaderData(
1533 stream_id, buffer, decompressed_len); 1600 stream_id, buffer, decompressed_len);
1534 } 1601 }
1535 if (!processed_successfully) { 1602 if (!processed_successfully) {
1536 // Assume that the problem was the header block was too large for the 1603 // Assume that the problem was the header block was too large for the
1537 // visitor. 1604 // visitor.
1538 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 1605 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
1539 } 1606 }
1607 } else {
1608 DLOG(WARNING) << "inflate failure: " << rv << " " << len;
1609 set_error(SPDY_DECOMPRESS_FAILURE);
1610 processed_successfully = false;
1540 } 1611 }
1541 } 1612 }
1542 return processed_successfully; 1613 return processed_successfully;
1543 } 1614 }
1544 1615
1545 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( 1616 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
1546 const SpdyControlFrame* control_frame, const char* data, size_t len) { 1617 const SpdyControlFrame* control_frame, const char* data, size_t len) {
1547 bool read_successfully = true; 1618 bool read_successfully = true;
1548 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame); 1619 const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
1549 DCHECK_LT(0u, stream_id);
1550 while (read_successfully && len > 0) { 1620 while (read_successfully && len > 0) {
1551 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); 1621 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
1552 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, 1622 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data,
1553 bytes_to_deliver); 1623 bytes_to_deliver);
1554 data += bytes_to_deliver; 1624 data += bytes_to_deliver;
1555 len -= bytes_to_deliver; 1625 len -= bytes_to_deliver;
1556 if (!read_successfully) { 1626 if (!read_successfully) {
1557 // Assume that the problem was the header block was too large for the 1627 // Assume that the problem was the header block was too large for the
1558 // visitor. 1628 // visitor.
1559 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 1629 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 switch (type) { 1685 switch (type) {
1616 case SYN_STREAM: 1686 case SYN_STREAM:
1617 return SpdySynStreamControlFrame::size(); 1687 return SpdySynStreamControlFrame::size();
1618 case SYN_REPLY: 1688 case SYN_REPLY:
1619 return SpdySynReplyControlFrame::size(); 1689 return SpdySynReplyControlFrame::size();
1620 case RST_STREAM: 1690 case RST_STREAM:
1621 return SpdyRstStreamControlFrame::size(); 1691 return SpdyRstStreamControlFrame::size();
1622 case SETTINGS: 1692 case SETTINGS:
1623 return SpdySettingsControlFrame::size(); 1693 return SpdySettingsControlFrame::size();
1624 case NOOP: 1694 case NOOP:
1625 return SpdyNoOpControlFrame::size(); 1695 // Even though NOOP is no longer supported, we still correctly report its
1696 // size so that it can be handled correctly as incoming data if
1697 // implementations so desire.
1698 return SpdyFrame::kHeaderSize;
1626 case PING: 1699 case PING:
1627 return SpdyPingControlFrame::size(); 1700 return SpdyPingControlFrame::size();
1628 case GOAWAY: 1701 case GOAWAY:
1629 return SpdyGoAwayControlFrame::size(); 1702 return SpdyGoAwayControlFrame::size();
1630 case HEADERS: 1703 case HEADERS:
1631 return SpdyHeadersControlFrame::size(); 1704 return SpdyHeadersControlFrame::size();
1632 case WINDOW_UPDATE: 1705 case WINDOW_UPDATE:
1633 return SpdyWindowUpdateControlFrame::size(); 1706 return SpdyWindowUpdateControlFrame::size();
1634 case CREDENTIAL: 1707 case CREDENTIAL:
1635 return SpdyCredentialControlFrame::size(); 1708 return SpdyCredentialControlFrame::size();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 case PING: 1748 case PING:
1676 case GOAWAY: 1749 case GOAWAY:
1677 case CREDENTIAL: 1750 case CREDENTIAL:
1678 case NUM_CONTROL_FRAME_TYPES: // makes compiler happy 1751 case NUM_CONTROL_FRAME_TYPES: // makes compiler happy
1679 break; 1752 break;
1680 } 1753 }
1681 } 1754 }
1682 return stream_id; 1755 return stream_id;
1683 } 1756 }
1684 1757
1685 size_t SpdyFramer::BytesSafeToRead() const {
1686 switch (state_) {
1687 case SPDY_ERROR:
1688 case SPDY_DONE:
1689 case SPDY_AUTO_RESET:
1690 case SPDY_RESET:
1691 return 0;
1692 case SPDY_READING_COMMON_HEADER:
1693 DCHECK_LT(current_frame_len_,
1694 static_cast<size_t>(SpdyFrame::kHeaderSize));
1695 return SpdyFrame::kHeaderSize - current_frame_len_;
1696 // TODO(rtenneti): Add support for SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
1697 // and SPDY_CONTROL_FRAME_HEADER_BLOCK.
1698 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
1699 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
1700 return 0;
1701 case SPDY_CONTROL_FRAME_PAYLOAD:
1702 case SPDY_CREDENTIAL_FRAME_PAYLOAD:
1703 case SPDY_IGNORE_REMAINING_PAYLOAD:
1704 case SPDY_FORWARD_STREAM_FRAME:
1705 return remaining_data_;
1706 }
1707 // We should never get to here.
1708 return 0;
1709 }
1710
1711 void SpdyFramer::set_enable_compression(bool value) { 1758 void SpdyFramer::set_enable_compression(bool value) {
1712 enable_compression_ = value; 1759 enable_compression_ = value;
1713 } 1760 }
1714 1761
1762 void SpdyFramer::set_validate_control_frame_sizes(bool value) {
1763 validate_control_frame_sizes_ = value;
1764 }
1765
1715 void SpdyFramer::set_enable_compression_default(bool value) { 1766 void SpdyFramer::set_enable_compression_default(bool value) {
1716 compression_default_ = value; 1767 compression_default_ = value;
1717 } 1768 }
1718 1769
1719 void SpdyFramer::set_validate_control_frame_sizes(bool value) {
1720 validate_control_frame_sizes_ = value;
1721 }
1722
1723 } // namespace spdy 1770 } // namespace spdy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698