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

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

Powered by Google App Engine
This is Rietveld 408576698