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

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

Issue 246073007: SPDY & HPACK: Land recent internal changes (through 65328503) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on upstream change: Expanded FRAME_TOO_LARGE/FRAME_SIZE_ERROR comment. Created 6 years, 7 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_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
6 // constantly adding and subtracting header sizes; this is ugly and error-
7 // prone.
8
9 #include "net/spdy/spdy_framer.h" 5 #include "net/spdy/spdy_framer.h"
10 6
11 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
12 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
13 #include "base/metrics/stats_counters.h" 9 #include "base/metrics/stats_counters.h"
14 #include "base/third_party/valgrind/memcheck.h" 10 #include "base/third_party/valgrind/memcheck.h"
15 #include "net/spdy/spdy_frame_builder.h" 11 #include "net/spdy/spdy_frame_builder.h"
16 #include "net/spdy/spdy_frame_reader.h" 12 #include "net/spdy/spdy_frame_reader.h"
17 #include "net/spdy/spdy_bitmasks.h" 13 #include "net/spdy/spdy_bitmasks.h"
18 #include "third_party/zlib/zlib.h" 14 #include "third_party/zlib/zlib.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #else 69 #else
74 #define CHANGE_STATE(newstate) \ 70 #define CHANGE_STATE(newstate) \
75 do { \ 71 do { \
76 DCHECK(state_ != SPDY_ERROR); \ 72 DCHECK(state_ != SPDY_ERROR); \
77 DCHECK_EQ(previous_state_, state_); \ 73 DCHECK_EQ(previous_state_, state_); \
78 previous_state_ = state_; \ 74 previous_state_ = state_; \
79 state_ = newstate; \ 75 state_ = newstate; \
80 } while (false) 76 } while (false)
81 #endif 77 #endif
82 78
83 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version, 79 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(
84 uint32 wire) { 80 SpdyMajorVersion version, uint32 wire) {
85 if (version < 3) { 81 if (version < SPDY3) {
86 ConvertFlagsAndIdForSpdy2(&wire); 82 ConvertFlagsAndIdForSpdy2(&wire);
87 } 83 }
88 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); 84 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
89 } 85 }
90 86
91 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) 87 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
92 : flags_(flags), id_(id & 0x00ffffff) { 88 : flags_(flags), id_(id & 0x00ffffff) {
93 LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id; 89 LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id;
94 } 90 }
95 91
96 uint32 SettingsFlagsAndId::GetWireFormat(int version) const { 92 uint32 SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version)
93 const {
97 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); 94 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
98 if (version < 3) { 95 if (version < SPDY3) {
99 ConvertFlagsAndIdForSpdy2(&wire); 96 ConvertFlagsAndIdForSpdy2(&wire);
100 } 97 }
101 return wire; 98 return wire;
102 } 99 }
103 100
104 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field. 101 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
105 // This method is used to preserve buggy behavior and works on both 102 // This method is used to preserve buggy behavior and works on both
106 // little-endian and big-endian hosts. 103 // little-endian and big-endian hosts.
107 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 104 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
108 // as well as vice versa). 105 // as well as vice versa).
(...skipping 10 matching lines...) Expand all
119 116
120 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( 117 bool SpdyFramerVisitorInterface::OnRstStreamFrameData(
121 const char* rst_stream_data, 118 const char* rst_stream_data,
122 size_t len) { 119 size_t len) {
123 return true; 120 return true;
124 } 121 }
125 122
126 SpdyFramer::SpdyFramer(SpdyMajorVersion version) 123 SpdyFramer::SpdyFramer(SpdyMajorVersion version)
127 : current_frame_buffer_(new char[kControlFrameBufferSize]), 124 : current_frame_buffer_(new char[kControlFrameBufferSize]),
128 enable_compression_(true), 125 enable_compression_(true),
126 hpack_encoder_(ObtainHpackHuffmanTable()),
129 hpack_decoder_(ObtainHpackHuffmanTable()), 127 hpack_decoder_(ObtainHpackHuffmanTable()),
130 visitor_(NULL), 128 visitor_(NULL),
131 debug_visitor_(NULL), 129 debug_visitor_(NULL),
132 display_protocol_("SPDY"), 130 display_protocol_("SPDY"),
133 spdy_version_(version), 131 spdy_version_(version),
134 syn_frame_processed_(false), 132 syn_frame_processed_(false),
135 probable_http_response_(false), 133 probable_http_response_(false),
136 expect_continuation_(0), 134 expect_continuation_(0),
137 end_stream_when_done_(false) { 135 end_stream_when_done_(false) {
138 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION); 136 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION);
(...skipping 20 matching lines...) Expand all
159 current_frame_type_ = DATA; 157 current_frame_type_ = DATA;
160 current_frame_flags_ = 0; 158 current_frame_flags_ = 0;
161 current_frame_length_ = 0; 159 current_frame_length_ = 0;
162 current_frame_stream_id_ = kInvalidStream; 160 current_frame_stream_id_ = kInvalidStream;
163 settings_scratch_.Reset(); 161 settings_scratch_.Reset();
164 remaining_padding_payload_length_ = 0; 162 remaining_padding_payload_length_ = 0;
165 remaining_padding_length_fields_ = 0; 163 remaining_padding_length_fields_ = 0;
166 } 164 }
167 165
168 size_t SpdyFramer::GetDataFrameMinimumSize() const { 166 size_t SpdyFramer::GetDataFrameMinimumSize() const {
169 // Size, in bytes, of the data frame header. Future versions of SPDY 167 return SpdyConstants::GetDataFrameMinimumSize();
170 // will likely vary this, so we allow for the flexibility of a function call
171 // for this value as opposed to a constant.
172 return 8;
173 } 168 }
174 169
175 // Size, in bytes, of the control frame header. 170 // Size, in bytes, of the control frame header.
176 size_t SpdyFramer::GetControlFrameHeaderSize() const { 171 size_t SpdyFramer::GetControlFrameHeaderSize() const {
177 switch (protocol_version()) { 172 return SpdyConstants::GetControlFrameHeaderSize(protocol_version());
178 case SPDY2:
179 case SPDY3:
180 case SPDY4:
181 return 8;
182 }
183 LOG(DFATAL) << "Unhandled SPDY version.";
184 return 0;
185 } 173 }
186 174
187 size_t SpdyFramer::GetSynStreamMinimumSize() const { 175 size_t SpdyFramer::GetSynStreamMinimumSize() const {
188 // Size, in bytes, of a SYN_STREAM frame not including the variable-length 176 // Size, in bytes, of a SYN_STREAM frame not including the variable-length
189 // name-value block. 177 // name-value block.
190 if (protocol_version() <= SPDY3) { 178 if (protocol_version() <= SPDY3) {
191 // Calculated as: 179 // Calculated as:
192 // control frame header + 2 * 4 (stream IDs) + 1 (priority) 180 // control frame header + 2 * 4 (stream IDs) + 1 (priority)
193 // + 1 (unused, was credential slot) 181 // + 1 (unused, was credential slot)
194 return GetControlFrameHeaderSize() + 10; 182 return GetControlFrameHeaderSize() + 10;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 244
257 size_t SpdyFramer::GetGoAwayMinimumSize() const { 245 size_t SpdyFramer::GetGoAwayMinimumSize() const {
258 // Size, in bytes, of this GOAWAY frame. Calculated as: 246 // Size, in bytes, of this GOAWAY frame. Calculated as:
259 // 1. Control frame header size 247 // 1. Control frame header size
260 size_t size = GetControlFrameHeaderSize(); 248 size_t size = GetControlFrameHeaderSize();
261 249
262 // 2. Last good stream id (4 bytes) 250 // 2. Last good stream id (4 bytes)
263 size += 4; 251 size += 4;
264 252
265 // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes) 253 // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes)
266 if (protocol_version() >= 3) { 254 if (protocol_version() >= SPDY3) {
267 size += 4; 255 size += 4;
268 } 256 }
269 257
270 return size; 258 return size;
271 } 259 }
272 260
273 size_t SpdyFramer::GetHeadersMinimumSize() const { 261 size_t SpdyFramer::GetHeadersMinimumSize() const {
274 // Size, in bytes, of a HEADERS frame not including the variable-length 262 // Size, in bytes, of a HEADERS frame not including the variable-length
275 // name-value block. 263 // name-value block.
276 size_t size = GetControlFrameHeaderSize(); 264 size_t size = GetControlFrameHeaderSize();
(...skipping 18 matching lines...) Expand all
295 // control frame header + 4 (stream id) + 4 (delta) 283 // control frame header + 4 (stream id) + 4 (delta)
296 return GetControlFrameHeaderSize() + 8; 284 return GetControlFrameHeaderSize() + 8;
297 } else { 285 } else {
298 // Calculated as: 286 // Calculated as:
299 // frame prefix + 4 (delta) 287 // frame prefix + 4 (delta)
300 return GetControlFrameHeaderSize() + 4; 288 return GetControlFrameHeaderSize() + 4;
301 } 289 }
302 } 290 }
303 291
304 size_t SpdyFramer::GetBlockedSize() const { 292 size_t SpdyFramer::GetBlockedSize() const {
305 DCHECK_LE(4, protocol_version()); 293 DCHECK_LT(SPDY3, protocol_version());
306 // Size, in bytes, of a BLOCKED frame. 294 // Size, in bytes, of a BLOCKED frame.
307 // The BLOCKED frame has no payload beyond the control frame header. 295 // The BLOCKED frame has no payload beyond the control frame header.
308 return GetControlFrameHeaderSize(); 296 return GetControlFrameHeaderSize();
309 } 297 }
310 298
311 size_t SpdyFramer::GetPushPromiseMinimumSize() const { 299 size_t SpdyFramer::GetPushPromiseMinimumSize() const {
312 DCHECK_LE(4, protocol_version()); 300 DCHECK_LT(SPDY3, protocol_version());
313 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. 301 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block.
314 // Calculated as frame prefix + 4 (promised stream id). 302 // Calculated as frame prefix + 4 (promised stream id).
315 return GetControlFrameHeaderSize() + 4; 303 return GetControlFrameHeaderSize() + 4;
316 } 304 }
317 305
318 size_t SpdyFramer::GetContinuationMinimumSize() const { 306 size_t SpdyFramer::GetContinuationMinimumSize() const {
319 // Size, in bytes, of a CONTINUATION frame not including the variable-length 307 // Size, in bytes, of a CONTINUATION frame not including the variable-length
320 // headers fragments. 308 // headers fragments.
321 return GetControlFrameHeaderSize(); 309 return GetControlFrameHeaderSize();
322 } 310 }
323 311
324 size_t SpdyFramer::GetFrameMinimumSize() const { 312 size_t SpdyFramer::GetFrameMinimumSize() const {
325 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); 313 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
326 } 314 }
327 315
328 size_t SpdyFramer::GetFrameMaximumSize() const { 316 size_t SpdyFramer::GetFrameMaximumSize() const {
329 if (protocol_version() <= SPDY3) { 317 return SpdyConstants::GetFrameMaximumSize(protocol_version());
330 // 24-bit length field plus eight-byte frame header.
331 return ((1<<24) - 1) + 8;
332 } else {
333 // 14-bit length field.
334 return (1<<14) - 1;
335 }
336 } 318 }
337 319
338 size_t SpdyFramer::GetDataFrameMaximumPayload() const { 320 size_t SpdyFramer::GetDataFrameMaximumPayload() const {
339 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); 321 return GetFrameMaximumSize() - GetDataFrameMinimumSize();
340 } 322 }
341 323
324 size_t SpdyFramer::GetPrefixLength(SpdyFrameType type) const {
325 return SpdyConstants::GetPrefixLength(type, protocol_version());
326 }
327
342 const char* SpdyFramer::StateToString(int state) { 328 const char* SpdyFramer::StateToString(int state) {
343 switch (state) { 329 switch (state) {
344 case SPDY_ERROR: 330 case SPDY_ERROR:
345 return "ERROR"; 331 return "ERROR";
346 case SPDY_AUTO_RESET: 332 case SPDY_AUTO_RESET:
347 return "AUTO_RESET"; 333 return "AUTO_RESET";
348 case SPDY_RESET: 334 case SPDY_RESET:
349 return "RESET"; 335 return "RESET";
350 case SPDY_READING_COMMON_HEADER: 336 case SPDY_READING_COMMON_HEADER:
351 return "READING_COMMON_HEADER"; 337 return "READING_COMMON_HEADER";
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 case RST_STREAM_FLOW_CONTROL_ERROR: 417 case RST_STREAM_FLOW_CONTROL_ERROR:
432 return "FLOW_CONTROL_ERROR"; 418 return "FLOW_CONTROL_ERROR";
433 case RST_STREAM_STREAM_IN_USE: 419 case RST_STREAM_STREAM_IN_USE:
434 return "STREAM_IN_USE"; 420 return "STREAM_IN_USE";
435 case RST_STREAM_STREAM_ALREADY_CLOSED: 421 case RST_STREAM_STREAM_ALREADY_CLOSED:
436 return "STREAM_ALREADY_CLOSED"; 422 return "STREAM_ALREADY_CLOSED";
437 case RST_STREAM_INVALID_CREDENTIALS: 423 case RST_STREAM_INVALID_CREDENTIALS:
438 return "INVALID_CREDENTIALS"; 424 return "INVALID_CREDENTIALS";
439 case RST_STREAM_FRAME_TOO_LARGE: 425 case RST_STREAM_FRAME_TOO_LARGE:
440 return "FRAME_TOO_LARGE"; 426 return "FRAME_TOO_LARGE";
427 case RST_STREAM_CONNECT_ERROR:
428 return "CONNECT_ERROR";
429 case RST_STREAM_ENHANCE_YOUR_CALM:
430 return "ENHANCE_YOUR_CALM";
441 } 431 }
442 return "UNKNOWN_STATUS"; 432 return "UNKNOWN_STATUS";
443 } 433 }
444 434
445 const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) { 435 const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) {
446 switch (type) { 436 switch (type) {
447 case DATA: 437 case DATA:
448 return "DATA"; 438 return "DATA";
449 case SYN_STREAM: 439 case SYN_STREAM:
450 return "SYN_STREAM"; 440 return "SYN_STREAM";
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 break; 555 break;
566 } 556 }
567 557
568 case SPDY_CONSUME_PADDING: { 558 case SPDY_CONSUME_PADDING: {
569 size_t bytes_read = ProcessFramePadding(data, len); 559 size_t bytes_read = ProcessFramePadding(data, len);
570 len -= bytes_read; 560 len -= bytes_read;
571 data += bytes_read; 561 data += bytes_read;
572 break; 562 break;
573 } 563 }
574 564
575 case SPDY_IGNORE_REMAINING_PAYLOAD: 565 case SPDY_IGNORE_REMAINING_PAYLOAD: {
576 // control frame has too-large payload 566 size_t bytes_read = ProcessIgnoredControlFramePayload(/*data,*/ len);
577 // intentional fallthrough 567 len -= bytes_read;
568 data += bytes_read;
569 break;
570 }
571
578 case SPDY_FORWARD_STREAM_FRAME: { 572 case SPDY_FORWARD_STREAM_FRAME: {
579 size_t bytes_read = ProcessDataFramePayload(data, len); 573 size_t bytes_read = ProcessDataFramePayload(data, len);
580 len -= bytes_read; 574 len -= bytes_read;
581 data += bytes_read; 575 data += bytes_read;
582 break; 576 break;
583 } 577 }
578
584 default: 579 default:
585 LOG(DFATAL) << "Invalid value for " << display_protocol_ 580 LOG(DFATAL) << "Invalid value for " << display_protocol_
586 << " framer state: " << state_; 581 << " framer state: " << state_;
587 // This ensures that we don't infinite-loop if state_ gets an 582 // This ensures that we don't infinite-loop if state_ gets an
588 // invalid value somehow, such as due to a SpdyFramer getting deleted 583 // invalid value somehow, such as due to a SpdyFramer getting deleted
589 // from a callback it calls. 584 // from a callback it calls.
590 goto bottom; 585 goto bottom;
591 } 586 }
592 } while (state_ != previous_state_); 587 } while (state_ != previous_state_);
593 bottom: 588 bottom:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 627
633 uint16 control_frame_type_field = DATA; 628 uint16 control_frame_type_field = DATA;
634 // ProcessControlFrameHeader() will set current_frame_type_ to the 629 // ProcessControlFrameHeader() will set current_frame_type_ to the
635 // correct value if this is a valid control frame. 630 // correct value if this is a valid control frame.
636 current_frame_type_ = DATA; 631 current_frame_type_ = DATA;
637 if (protocol_version() <= SPDY3) { 632 if (protocol_version() <= SPDY3) {
638 bool successful_read = reader->ReadUInt16(&version); 633 bool successful_read = reader->ReadUInt16(&version);
639 DCHECK(successful_read); 634 DCHECK(successful_read);
640 is_control_frame = (version & kControlFlagMask) != 0; 635 is_control_frame = (version & kControlFlagMask) != 0;
641 version &= ~kControlFlagMask; // Only valid for control frames. 636 version &= ~kControlFlagMask; // Only valid for control frames.
642
643 if (is_control_frame) { 637 if (is_control_frame) {
638 // We check version before we check validity: version can never be
639 // 'invalid', it can only be unsupported.
640 if (version < SpdyConstants::SerializeMajorVersion(SPDY_MIN_VERSION) ||
641 version > SpdyConstants::SerializeMajorVersion(SPDY_MAX_VERSION) ||
642 SpdyConstants::ParseMajorVersion(version) != protocol_version()) {
643 // Version does not match the version the framer was initialized with.
644 DVLOG(1) << "Unsupported SPDY version "
645 << version
646 << " (expected " << protocol_version() << ")";
647 set_error(SPDY_UNSUPPORTED_VERSION);
648 return 0;
649 } else {
650 // Convert version from wire format to SpdyMajorVersion.
651 version = SpdyConstants::ParseMajorVersion(version);
652 }
644 // We check control_frame_type_field's validity in 653 // We check control_frame_type_field's validity in
645 // ProcessControlFrameHeader(). 654 // ProcessControlFrameHeader().
646 successful_read = reader->ReadUInt16(&control_frame_type_field); 655 successful_read = reader->ReadUInt16(&control_frame_type_field);
647 } else { 656 } else {
648 reader->Rewind(); 657 reader->Rewind();
649 successful_read = reader->ReadUInt31(&current_frame_stream_id_); 658 successful_read = reader->ReadUInt31(&current_frame_stream_id_);
650 } 659 }
651 DCHECK(successful_read); 660 DCHECK(successful_read);
652 661
653 successful_read = reader->ReadUInt8(&current_frame_flags_); 662 successful_read = reader->ReadUInt8(&current_frame_flags_);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); 758 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
750 } else { 759 } else {
751 // Empty data frame. 760 // Empty data frame.
752 if (current_frame_flags_ & DATA_FLAG_FIN) { 761 if (current_frame_flags_ & DATA_FLAG_FIN) {
753 visitor_->OnStreamFrameData( 762 visitor_->OnStreamFrameData(
754 current_frame_stream_id_, NULL, 0, true); 763 current_frame_stream_id_, NULL, 0, true);
755 } 764 }
756 CHANGE_STATE(SPDY_AUTO_RESET); 765 CHANGE_STATE(SPDY_AUTO_RESET);
757 } 766 }
758 } 767 }
759 } else if (version != protocol_version()) {
760 // We check version before we check validity: version can never be
761 // 'invalid', it can only be unsupported.
762 DVLOG(1) << "Unsupported SPDY version " << version
763 << " (expected " << protocol_version() << ")";
764 set_error(SPDY_UNSUPPORTED_VERSION);
765 } else { 768 } else {
766 ProcessControlFrameHeader(control_frame_type_field); 769 ProcessControlFrameHeader(control_frame_type_field);
767 } 770 }
768 771
769 return original_len - len; 772 return original_len - len;
770 } 773 }
771 774
772 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { 775 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
773 DCHECK_EQ(SPDY_NO_ERROR, error_code_); 776 DCHECK_EQ(SPDY_NO_ERROR, error_code_);
774 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); 777 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 if (current_frame_length_ < GetPushPromiseMinimumSize()) { 923 if (current_frame_length_ < GetPushPromiseMinimumSize()) {
921 set_error(SPDY_INVALID_CONTROL_FRAME); 924 set_error(SPDY_INVALID_CONTROL_FRAME);
922 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { 925 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) {
923 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
924 } else if (protocol_version() > SPDY3 && current_frame_flags_ & 927 } else if (protocol_version() > SPDY3 && current_frame_flags_ &
925 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { 928 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) {
926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 929 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
927 } 930 }
928 break; 931 break;
929 case CONTINUATION: 932 case CONTINUATION:
930 if (current_frame_length_ < GetContinuationMinimumSize()) { 933 if (current_frame_length_ < GetContinuationMinimumSize() ||
934 protocol_version() <= SPDY3) {
931 set_error(SPDY_INVALID_CONTROL_FRAME); 935 set_error(SPDY_INVALID_CONTROL_FRAME);
932 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { 936 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) {
933 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 937 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
934 } 938 }
935 break; 939 break;
936 default: 940 default:
937 LOG(WARNING) << "Valid " << display_protocol_ 941 LOG(WARNING) << "Valid " << display_protocol_
938 << " control frame with unhandled type: " 942 << " control frame with unhandled type: "
939 << current_frame_type_; 943 << current_frame_type_;
940 // This branch should be unreachable because of the frame type bounds 944 // This branch should be unreachable because of the frame type bounds
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_, 1040 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_,
1037 *data, 1041 *data,
1038 bytes_to_read); 1042 bytes_to_read);
1039 current_frame_buffer_length_ += bytes_to_read; 1043 current_frame_buffer_length_ += bytes_to_read;
1040 *data += bytes_to_read; 1044 *data += bytes_to_read;
1041 *len -= bytes_to_read; 1045 *len -= bytes_to_read;
1042 } 1046 }
1043 return bytes_to_read; 1047 return bytes_to_read;
1044 } 1048 }
1045 1049
1046 size_t SpdyFramer::GetSerializedLength(const int spdy_version, 1050 size_t SpdyFramer::GetSerializedLength(
1047 const SpdyHeaderBlock* headers) { 1051 const SpdyMajorVersion spdy_version,
1052 const SpdyHeaderBlock* headers) {
1048 const size_t num_name_value_pairs_size 1053 const size_t num_name_value_pairs_size
1049 = (spdy_version < 3) ? sizeof(uint16) : sizeof(uint32); 1054 = (spdy_version < SPDY3) ? sizeof(uint16) : sizeof(uint32);
1050 const size_t length_of_name_size = num_name_value_pairs_size; 1055 const size_t length_of_name_size = num_name_value_pairs_size;
1051 const size_t length_of_value_size = num_name_value_pairs_size; 1056 const size_t length_of_value_size = num_name_value_pairs_size;
1052 1057
1053 size_t total_length = num_name_value_pairs_size; 1058 size_t total_length = num_name_value_pairs_size;
1054 for (SpdyHeaderBlock::const_iterator it = headers->begin(); 1059 for (SpdyHeaderBlock::const_iterator it = headers->begin();
1055 it != headers->end(); 1060 it != headers->end();
1056 ++it) { 1061 ++it) {
1057 // We add space for the length of the name and the length of the value as 1062 // We add space for the length of the name and the length of the value as
1058 // well as the length of the name and the length of the value. 1063 // well as the length of the name and the length of the value.
1059 total_length += length_of_name_size + it->first.size() + 1064 total_length += length_of_name_size + it->first.size() +
1060 length_of_value_size + it->second.size(); 1065 length_of_value_size + it->second.size();
1061 } 1066 }
1062 return total_length; 1067 return total_length;
1063 } 1068 }
1064 1069
1065 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame, 1070 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
1066 const int spdy_version, 1071 const SpdyMajorVersion spdy_version,
1067 const SpdyHeaderBlock* headers) { 1072 const SpdyHeaderBlock* headers) {
1068 if (spdy_version < 3) { 1073 if (spdy_version < SPDY3) {
1069 frame->WriteUInt16(headers->size()); // Number of headers. 1074 frame->WriteUInt16(headers->size()); // Number of headers.
1070 } else { 1075 } else {
1071 frame->WriteUInt32(headers->size()); // Number of headers. 1076 frame->WriteUInt32(headers->size()); // Number of headers.
1072 } 1077 }
1073 SpdyHeaderBlock::const_iterator it; 1078 SpdyHeaderBlock::const_iterator it;
1074 for (it = headers->begin(); it != headers->end(); ++it) { 1079 for (it = headers->begin(); it != headers->end(); ++it) {
1075 if (spdy_version < 3) { 1080 if (spdy_version < SPDY3) {
1076 frame->WriteString(it->first); 1081 frame->WriteString(it->first);
1077 frame->WriteString(it->second); 1082 frame->WriteString(it->second);
1078 } else { 1083 } else {
1079 frame->WriteStringPiece32(it->first); 1084 frame->WriteStringPiece32(it->first);
1080 frame->WriteStringPiece32(it->second); 1085 frame->WriteStringPiece32(it->second);
1081 } 1086 }
1082 } 1087 }
1083 } 1088 }
1084 1089
1085 // TODO(phajdan.jr): Clean up after we no longer need 1090 // TODO(phajdan.jr): Clean up after we no longer need
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 DCHECK_LT(SPDY3, protocol_version()); 1595 DCHECK_LT(SPDY3, protocol_version());
1591 DCHECK_EQ(0u, remaining_data_length_); 1596 DCHECK_EQ(0u, remaining_data_length_);
1592 1597
1593 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block(); 1598 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block();
1594 if (block.empty()) { 1599 if (block.empty()) {
1595 // Special-case this to make tests happy. 1600 // Special-case this to make tests happy.
1596 ProcessControlFrameHeaderBlock(NULL, 0, false); 1601 ProcessControlFrameHeaderBlock(NULL, 0, false);
1597 return; 1602 return;
1598 } 1603 }
1599 SpdyFrameBuilder builder( 1604 SpdyFrameBuilder builder(
1600 GetSerializedLength(protocol_version(), &block)); 1605 GetSerializedLength(protocol_version(), &block),
1606 SPDY3);
1601 1607
1602 SerializeNameValueBlockWithoutCompression(&builder, block); 1608 SerializeNameValueBlockWithoutCompression(&builder, block);
1603 scoped_ptr<SpdyFrame> frame(builder.take()); 1609 scoped_ptr<SpdyFrame> frame(builder.take());
1604 1610
1605 remaining_data_length_ = frame->size(); 1611 remaining_data_length_ = frame->size();
1606 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); 1612 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false);
1607 } 1613 }
1608 1614
1609 bool SpdyFramer::ProcessSetting(const char* data) { 1615 bool SpdyFramer::ProcessSetting(const char* data) {
1610 int id_field; 1616 int id_field;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. 1749 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1744 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_); 1750 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1745 DCHECK(successful_read); 1751 DCHECK(successful_read);
1746 1752
1747 // In SPDYv3 and up, frames also specify a status code - parse it out. 1753 // In SPDYv3 and up, frames also specify a status code - parse it out.
1748 SpdyGoAwayStatus status = GOAWAY_OK; 1754 SpdyGoAwayStatus status = GOAWAY_OK;
1749 if (protocol_version() >= SPDY3) { 1755 if (protocol_version() >= SPDY3) {
1750 uint32 status_raw = GOAWAY_OK; 1756 uint32 status_raw = GOAWAY_OK;
1751 successful_read = reader.ReadUInt32(&status_raw); 1757 successful_read = reader.ReadUInt32(&status_raw);
1752 DCHECK(successful_read); 1758 DCHECK(successful_read);
1753 // We've read an unsigned integer, so it's enough to only check 1759 if (SpdyConstants::IsValidGoAwayStatus(protocol_version(),
1754 // upper bound to ensure the value is in valid range. 1760 status_raw)) {
1755 if (status_raw < GOAWAY_NUM_STATUS_CODES) { 1761 status = SpdyConstants::ParseGoAwayStatus(protocol_version(),
1756 status = static_cast<SpdyGoAwayStatus>(status_raw); 1762 status_raw);
1757 } else { 1763 } else {
1758 // TODO(hkhalil): Probably best to OnError here, depending on
1759 // our interpretation of the spec. Keeping with existing liberal
1760 // behavior for now.
1761 DCHECK(false); 1764 DCHECK(false);
1765 // Throw an error for SPDY4+, keep liberal behavior
1766 // for earlier versions.
1767 if (protocol_version() > SPDY3) {
1768 DLOG(WARNING) << "Invalid GO_AWAY status " << status_raw;
1769 set_error(SPDY_INVALID_CONTROL_FRAME);
1770 return 0;
1771 }
1762 } 1772 }
1763 } 1773 }
1764 // Finished parsing the GOAWAY header, call frame handler. 1774 // Finished parsing the GOAWAY header, call frame handler.
1765 visitor_->OnGoAway(current_frame_stream_id_, status); 1775 visitor_->OnGoAway(current_frame_stream_id_, status);
1766 } 1776 }
1767 } 1777 }
1768 1778
1769 // Handle remaining data as opaque. 1779 // Handle remaining data as opaque.
1770 bool processed_successfully = true; 1780 bool processed_successfully = true;
1771 if (len > 0) { 1781 if (len > 0) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1809 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. 1819 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1810 if (protocol_version() <= SPDY3) { 1820 if (protocol_version() <= SPDY3) {
1811 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_); 1821 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1812 DCHECK(successful_read); 1822 DCHECK(successful_read);
1813 } 1823 }
1814 1824
1815 SpdyRstStreamStatus status = RST_STREAM_INVALID; 1825 SpdyRstStreamStatus status = RST_STREAM_INVALID;
1816 uint32 status_raw = status; 1826 uint32 status_raw = status;
1817 bool successful_read = reader.ReadUInt32(&status_raw); 1827 bool successful_read = reader.ReadUInt32(&status_raw);
1818 DCHECK(successful_read); 1828 DCHECK(successful_read);
1819 // We've read an unsigned integer, so it's enough to only check 1829 if (SpdyConstants::IsValidRstStreamStatus(protocol_version(),
1820 // upper bound to ensure the value is in valid range. 1830 status_raw)) {
1821 if (status_raw > RST_STREAM_INVALID &&
1822 status_raw < RST_STREAM_NUM_STATUS_CODES) {
1823 status = static_cast<SpdyRstStreamStatus>(status_raw); 1831 status = static_cast<SpdyRstStreamStatus>(status_raw);
1824 } else { 1832 } else {
1825 // TODO(hkhalil): Probably best to OnError here, depending on 1833 // Throw an error for SPDY4+, keep liberal behavior
1826 // our interpretation of the spec. Keeping with existing liberal 1834 // for earlier versions.
1827 // behavior for now. 1835 if (protocol_version() > SPDY3) {
1836 DLOG(WARNING) << "Invalid RST_STREAM status " << status_raw;
1837 set_error(SPDY_INVALID_CONTROL_FRAME);
1838 return 0;
1839 }
1828 } 1840 }
1829 // Finished parsing the RST_STREAM header, call frame handler. 1841 // Finished parsing the RST_STREAM header, call frame handler.
1830 visitor_->OnRstStream(current_frame_stream_id_, status); 1842 visitor_->OnRstStream(current_frame_stream_id_, status);
1831 } 1843 }
1832 } 1844 }
1833 1845
1834 // Handle remaining data as opaque. 1846 // Handle remaining data as opaque.
1835 bool processed_successfully = true; 1847 bool processed_successfully = true;
1836 if (len > 0) { 1848 if (len > 0) {
1837 processed_successfully = visitor_->OnRstStreamFrameData(data, len); 1849 processed_successfully = visitor_->OnRstStreamFrameData(data, len);
(...skipping 10 matching lines...) Expand all
1848 } 1860 }
1849 1861
1850 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { 1862 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
1851 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); 1863 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);
1852 1864
1853 size_t original_len = len; 1865 size_t original_len = len;
1854 if (remaining_padding_length_fields_ == 0) { 1866 if (remaining_padding_length_fields_ == 0) {
1855 DCHECK_EQ(remaining_padding_payload_length_, 0u); 1867 DCHECK_EQ(remaining_padding_payload_length_, 0u);
1856 bool pad_low = false; 1868 bool pad_low = false;
1857 bool pad_high = false; 1869 bool pad_high = false;
1858 if (current_frame_flags_ & net::DATA_FLAG_PAD_LOW) { 1870 if (current_frame_flags_ & DATA_FLAG_PAD_LOW) {
1859 pad_low = true; 1871 pad_low = true;
1860 ++remaining_padding_length_fields_; 1872 ++remaining_padding_length_fields_;
1861 } 1873 }
1862 if (current_frame_flags_ & net::DATA_FLAG_PAD_HIGH) { 1874 if (current_frame_flags_ & DATA_FLAG_PAD_HIGH) {
1863 pad_high = true; 1875 pad_high = true;
1864 ++remaining_padding_length_fields_; 1876 ++remaining_padding_length_fields_;
1865 } 1877 }
1866 if ((pad_high && !pad_low) || 1878 if ((pad_high && !pad_low) ||
1867 remaining_data_length_ < remaining_padding_length_fields_) { 1879 remaining_data_length_ < remaining_padding_length_fields_) {
1868 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 1880 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
1869 return 0; 1881 return 0;
1870 } 1882 }
1871 } 1883 }
1872 1884
(...skipping 29 matching lines...) Expand all
1902 // Communicate the padding to the visitor through a NULL data pointer, with 1914 // Communicate the padding to the visitor through a NULL data pointer, with
1903 // a nonzero size. 1915 // a nonzero size.
1904 if (amount_to_discard) { 1916 if (amount_to_discard) {
1905 visitor_->OnStreamFrameData( 1917 visitor_->OnStreamFrameData(
1906 current_frame_stream_id_, NULL, amount_to_discard, false); 1918 current_frame_stream_id_, NULL, amount_to_discard, false);
1907 } 1919 }
1908 data += amount_to_discard; 1920 data += amount_to_discard;
1909 len -= amount_to_discard; 1921 len -= amount_to_discard;
1910 remaining_padding_payload_length_ -= amount_to_discard; 1922 remaining_padding_payload_length_ -= amount_to_discard;
1911 remaining_data_length_ -= amount_to_discard; 1923 remaining_data_length_ -= amount_to_discard;
1912
1913 // If the FIN flag is set, and there is no more data in this data
1914 // frame, inform the visitor of EOF via a 0-length data frame.
1915 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) {
1916 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1917 }
1918 } 1924 }
1919 1925
1920 if (remaining_data_length_ == 0) { 1926 if (remaining_data_length_ == 0) {
1927 // If the FIN flag is set, and there is no more data in this data frame,
1928 // inform the visitor of EOF via a 0-length data frame.
1929 if (current_frame_flags_ & DATA_FLAG_FIN) {
1930 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1931 }
1932
1921 CHANGE_STATE(SPDY_AUTO_RESET); 1933 CHANGE_STATE(SPDY_AUTO_RESET);
1922 } 1934 }
1923 return original_len - len; 1935 return original_len - len;
1924 } 1936 }
1925 1937
1926 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { 1938 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
1927 size_t original_len = len; 1939 size_t original_len = len;
1928 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) { 1940 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) {
1929 size_t amount_to_forward = std::min( 1941 size_t amount_to_forward = std::min(
1930 remaining_data_length_ - remaining_padding_payload_length_, len); 1942 remaining_data_length_ - remaining_padding_payload_length_, len);
1931 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { 1943 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
1932 // Only inform the visitor if there is data. 1944 // Only inform the visitor if there is data.
1933 if (amount_to_forward) { 1945 if (amount_to_forward) {
1934 visitor_->OnStreamFrameData( 1946 visitor_->OnStreamFrameData(
1935 current_frame_stream_id_, data, amount_to_forward, false); 1947 current_frame_stream_id_, data, amount_to_forward, false);
1936 } 1948 }
1937 } 1949 }
1938 data += amount_to_forward; 1950 data += amount_to_forward;
1939 len -= amount_to_forward; 1951 len -= amount_to_forward;
1940 remaining_data_length_ -= amount_to_forward; 1952 remaining_data_length_ -= amount_to_forward;
1941
1942 // If the FIN flag is set, and there is no more data in this data
1943 // frame, inform the visitor of EOF via a 0-length data frame.
1944 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) {
1945 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1946 }
1947 } 1953 }
1948 1954
1949 if (remaining_data_length_ == remaining_padding_payload_length_) { 1955 if (remaining_data_length_ == remaining_padding_payload_length_) {
1950 CHANGE_STATE(SPDY_CONSUME_PADDING); 1956 CHANGE_STATE(SPDY_CONSUME_PADDING);
1951 } 1957 }
1952 return original_len - len; 1958 return original_len - len;
1953 } 1959 }
1954 1960
1961 size_t SpdyFramer::ProcessIgnoredControlFramePayload(/*const char* data,*/
1962 size_t len) {
1963 size_t original_len = len;
1964 if (remaining_data_length_ > 0) {
1965 size_t amount_to_ignore = std::min(remaining_data_length_, len);
1966 len -= amount_to_ignore;
1967 remaining_data_length_ -= amount_to_ignore;
1968 }
1969
1970 if (remaining_data_length_ == 0) {
1971 CHANGE_STATE(SPDY_AUTO_RESET);
1972 }
1973 return original_len - len;
1974 }
1975
1955 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, 1976 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
1956 size_t header_length, 1977 size_t header_length,
1957 SpdyHeaderBlock* block) const { 1978 SpdyHeaderBlock* block) const {
1958 SpdyFrameReader reader(header_data, header_length); 1979 SpdyFrameReader reader(header_data, header_length);
1959 1980
1960 // Read number of headers. 1981 // Read number of headers.
1961 uint32 num_headers; 1982 uint32 num_headers;
1962 if (protocol_version() <= SPDY2) { 1983 if (protocol_version() <= SPDY2) {
1963 uint16 temp; 1984 uint16 temp;
1964 if (!reader.ReadUInt16(&temp)) { 1985 if (!reader.ReadUInt16(&temp)) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 << num_headers << ")."; 2022 << num_headers << ").";
2002 return 0; 2023 return 0;
2003 } 2024 }
2004 2025
2005 // Store header. 2026 // Store header.
2006 (*block)[name] = value; 2027 (*block)[name] = value;
2007 } 2028 }
2008 return reader.GetBytesConsumed(); 2029 return reader.GetBytesConsumed();
2009 } 2030 }
2010 2031
2011 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& datair) const { 2032 SpdySerializedFrame* SpdyFramer::SerializeData(
2033 const SpdyDataIR& data_ir) const {
2012 uint8 flags = DATA_FLAG_NONE; 2034 uint8 flags = DATA_FLAG_NONE;
2013 if (datair.fin()) { 2035 if (data_ir.fin()) {
2014 flags = DATA_FLAG_FIN; 2036 flags = DATA_FLAG_FIN;
2015 } 2037 }
2016 2038
2017 if (protocol_version() > SPDY3) { 2039 if (protocol_version() > SPDY3) {
2018 int num_padding_fields = 0; 2040 int num_padding_fields = 0;
2019 if (datair.pad_low()) { 2041 if (data_ir.pad_low()) {
2020 flags |= DATA_FLAG_PAD_LOW; 2042 flags |= DATA_FLAG_PAD_LOW;
2021 ++num_padding_fields; 2043 ++num_padding_fields;
2022 } 2044 }
2023 if (datair.pad_high()) { 2045 if (data_ir.pad_high()) {
2024 flags |= DATA_FLAG_PAD_HIGH; 2046 flags |= DATA_FLAG_PAD_HIGH;
2025 ++num_padding_fields; 2047 ++num_padding_fields;
2026 } 2048 }
2027 2049
2028 const size_t size_with_padding = num_padding_fields + 2050 const size_t size_with_padding = num_padding_fields +
2029 datair.data().length() + datair.padding_payload_len() + 2051 data_ir.data().length() + data_ir.padding_payload_len() +
2030 GetDataFrameMinimumSize(); 2052 GetDataFrameMinimumSize();
2031 SpdyFrameBuilder builder(size_with_padding); 2053 SpdyFrameBuilder builder(size_with_padding, protocol_version());
2032 builder.WriteDataFrameHeader(*this, datair.stream_id(), flags); 2054 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
2033 if (datair.pad_high()) { 2055 if (data_ir.pad_high()) {
2034 builder.WriteUInt8(datair.padding_payload_len() >> 8); 2056 builder.WriteUInt8(data_ir.padding_payload_len() >> 8);
2035 } 2057 }
2036 if (datair.pad_low()) { 2058 if (data_ir.pad_low()) {
2037 builder.WriteUInt8(datair.padding_payload_len() & 0xff); 2059 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
2038 } 2060 }
2039 builder.WriteBytes(datair.data().data(), datair.data().length()); 2061 builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
2040 if (datair.padding_payload_len() > 0) { 2062 if (data_ir.padding_payload_len() > 0) {
2041 string padding = string(datair.padding_payload_len(), '0'); 2063 string padding = string(data_ir.padding_payload_len(), '0');
2042 builder.WriteBytes(padding.data(), padding.length()); 2064 builder.WriteBytes(padding.data(), padding.length());
2043 } 2065 }
2044 DCHECK_EQ(size_with_padding, builder.length()); 2066 DCHECK_EQ(size_with_padding, builder.length());
2045 return builder.take(); 2067 return builder.take();
2046 } else { 2068 } else {
2047 const size_t size = GetDataFrameMinimumSize() + datair.data().length(); 2069 const size_t size = GetDataFrameMinimumSize() + data_ir.data().length();
2048 SpdyFrameBuilder builder(size); 2070 SpdyFrameBuilder builder(size, protocol_version());
2049 builder.WriteDataFrameHeader(*this, datair.stream_id(), flags); 2071 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
2050 builder.WriteBytes(datair.data().data(), datair.data().length()); 2072 builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
2051 DCHECK_EQ(size, builder.length()); 2073 DCHECK_EQ(size, builder.length());
2052 return builder.take(); 2074 return builder.take();
2053 } 2075 }
2054 } 2076 }
2055 2077
2056 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader( 2078 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
2057 const SpdyDataIR& data) const { 2079 const SpdyDataIR& data_ir) const {
2058 const size_t kSize = GetDataFrameMinimumSize();
2059
2060 uint8 flags = DATA_FLAG_NONE; 2080 uint8 flags = DATA_FLAG_NONE;
2061 if (data.fin()) { 2081 if (data_ir.fin()) {
2062 flags = DATA_FLAG_FIN; 2082 flags = DATA_FLAG_FIN;
2063 } 2083 }
2084
2085 size_t frame_size = GetDataFrameMinimumSize();
2086 size_t num_padding_fields = 0;
2064 if (protocol_version() > SPDY3) { 2087 if (protocol_version() > SPDY3) {
2065 if (data.pad_low()) { 2088 if (data_ir.pad_low()) {
2066 flags |= DATA_FLAG_PAD_LOW; 2089 flags |= DATA_FLAG_PAD_LOW;
2090 ++num_padding_fields;
2067 } 2091 }
2068 if (data.pad_high()) { 2092 if (data_ir.pad_high()) {
2069 flags |= DATA_FLAG_PAD_HIGH; 2093 flags |= DATA_FLAG_PAD_HIGH;
2094 ++num_padding_fields;
2070 } 2095 }
2096 frame_size += num_padding_fields;
2071 } 2097 }
2072 2098
2073 SpdyFrameBuilder builder(kSize); 2099 SpdyFrameBuilder builder(frame_size, protocol_version());
2074 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); 2100 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
2075 builder.OverwriteLength(*this, data.data().length()); 2101 if (protocol_version() > SPDY3) {
2076 DCHECK_EQ(kSize, builder.length()); 2102 if (data_ir.pad_high()) {
2103 builder.WriteUInt8(data_ir.padding_payload_len() >> 8);
2104 }
2105 if (data_ir.pad_low()) {
2106 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
2107 }
2108 builder.OverwriteLength(*this, num_padding_fields +
2109 data_ir.data().length() + data_ir.padding_payload_len());
2110 } else {
2111 builder.OverwriteLength(*this, data_ir.data().length());
2112 }
2113 DCHECK_EQ(frame_size, builder.length());
2077 return builder.take(); 2114 return builder.take();
2078 } 2115 }
2079 2116
2080 SpdySerializedFrame* SpdyFramer::SerializeSynStream( 2117 SpdySerializedFrame* SpdyFramer::SerializeSynStream(
2081 const SpdySynStreamIR& syn_stream) { 2118 const SpdySynStreamIR& syn_stream) {
2082 uint8 flags = 0; 2119 uint8 flags = 0;
2083 if (syn_stream.fin()) { 2120 if (syn_stream.fin()) {
2084 flags |= CONTROL_FLAG_FIN; 2121 flags |= CONTROL_FLAG_FIN;
2085 } 2122 }
2086 if (syn_stream.unidirectional()) { 2123 if (syn_stream.unidirectional()) {
(...skipping 12 matching lines...) Expand all
2099 if (priority > GetLowestPriority()) { 2136 if (priority > GetLowestPriority()) {
2100 DLOG(DFATAL) << "Priority out-of-bounds."; 2137 DLOG(DFATAL) << "Priority out-of-bounds.";
2101 priority = GetLowestPriority(); 2138 priority = GetLowestPriority();
2102 } 2139 }
2103 2140
2104 // The size of this frame, including variable-length name-value block. 2141 // The size of this frame, including variable-length name-value block.
2105 size_t size = GetSynStreamMinimumSize(); 2142 size_t size = GetSynStreamMinimumSize();
2106 2143
2107 string hpack_encoding; 2144 string hpack_encoding;
2108 if (protocol_version() > SPDY3) { 2145 if (protocol_version() > SPDY3) {
2109 hpack_encoder_.EncodeHeaderSet(syn_stream.name_value_block(), 2146 if (enable_compression_) {
2110 &hpack_encoding); 2147 hpack_encoder_.EncodeHeaderSet(
2148 syn_stream.name_value_block(), &hpack_encoding);
2149 } else {
2150 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2151 syn_stream.name_value_block(), &hpack_encoding);
2152 }
2111 size += hpack_encoding.size(); 2153 size += hpack_encoding.size();
2112 } else { 2154 } else {
2113 size += GetSerializedLength(syn_stream.name_value_block()); 2155 size += GetSerializedLength(syn_stream.name_value_block());
2114 } 2156 }
2115 2157
2116 SpdyFrameBuilder builder(size); 2158 SpdyFrameBuilder builder(size, protocol_version());
2117 if (protocol_version() <= SPDY3) { 2159 if (protocol_version() <= SPDY3) {
2118 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); 2160 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
2119 builder.WriteUInt32(syn_stream.stream_id()); 2161 builder.WriteUInt32(syn_stream.stream_id());
2120 builder.WriteUInt32(syn_stream.associated_to_stream_id()); 2162 builder.WriteUInt32(syn_stream.associated_to_stream_id());
2121 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); 2163 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5));
2122 builder.WriteUInt8(0); // Unused byte where credential slot used to be. 2164 builder.WriteUInt8(0); // Unused byte where credential slot used to be.
2123 } else { 2165 } else {
2124 builder.WriteFramePrefix(*this, 2166 builder.BeginNewFrame(*this,
2125 HEADERS, 2167 HEADERS,
2126 flags, 2168 flags,
2127 syn_stream.stream_id()); 2169 syn_stream.stream_id());
2128 builder.WriteUInt32(priority); 2170 builder.WriteUInt32(priority);
2129 } 2171 }
2130 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); 2172 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
2131 if (protocol_version() > SPDY3) { 2173 if (protocol_version() > SPDY3) {
2132 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2174 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2133 } else { 2175 } else {
2134 SerializeNameValueBlock(&builder, syn_stream); 2176 SerializeNameValueBlock(&builder, syn_stream);
2135 } 2177 }
2136 2178
2137 if (debug_visitor_) { 2179 if (debug_visitor_) {
(...skipping 21 matching lines...) Expand all
2159 // we never expect to have to overflow into a CONTINUATION frame. 2201 // we never expect to have to overflow into a CONTINUATION frame.
2160 if (protocol_version() > SPDY3) { 2202 if (protocol_version() > SPDY3) {
2161 flags |= HEADERS_FLAG_END_HEADERS; 2203 flags |= HEADERS_FLAG_END_HEADERS;
2162 } 2204 }
2163 2205
2164 // The size of this frame, including variable-length name-value block. 2206 // The size of this frame, including variable-length name-value block.
2165 size_t size = GetSynReplyMinimumSize(); 2207 size_t size = GetSynReplyMinimumSize();
2166 2208
2167 string hpack_encoding; 2209 string hpack_encoding;
2168 if (protocol_version() > SPDY3) { 2210 if (protocol_version() > SPDY3) {
2169 hpack_encoder_.EncodeHeaderSet(syn_reply.name_value_block(), 2211 if (enable_compression_) {
2170 &hpack_encoding); 2212 hpack_encoder_.EncodeHeaderSet(
2213 syn_reply.name_value_block(), &hpack_encoding);
2214 } else {
2215 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2216 syn_reply.name_value_block(), &hpack_encoding);
2217 }
2171 size += hpack_encoding.size(); 2218 size += hpack_encoding.size();
2172 } else { 2219 } else {
2173 size += GetSerializedLength(syn_reply.name_value_block()); 2220 size += GetSerializedLength(syn_reply.name_value_block());
2174 } 2221 }
2175 2222
2176 SpdyFrameBuilder builder(size); 2223 SpdyFrameBuilder builder(size, protocol_version());
2177 if (protocol_version() <= SPDY3) { 2224 if (protocol_version() <= SPDY3) {
2178 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); 2225 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
2179 builder.WriteUInt32(syn_reply.stream_id()); 2226 builder.WriteUInt32(syn_reply.stream_id());
2180 } else { 2227 } else {
2181 builder.WriteFramePrefix(*this, 2228 builder.BeginNewFrame(*this,
2182 HEADERS, 2229 HEADERS,
2183 flags, 2230 flags,
2184 syn_reply.stream_id()); 2231 syn_reply.stream_id());
2185 } 2232 }
2186 if (protocol_version() < SPDY3) { 2233 if (protocol_version() < SPDY3) {
2187 builder.WriteUInt16(0); // Unused. 2234 builder.WriteUInt16(0); // Unused.
2188 } 2235 }
2189 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); 2236 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length());
2190 if (protocol_version() > SPDY3) { 2237 if (protocol_version() > SPDY3) {
2191 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2238 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2192 } else { 2239 } else {
2193 SerializeNameValueBlock(&builder, syn_reply); 2240 SerializeNameValueBlock(&builder, syn_reply);
2194 } 2241 }
(...skipping 16 matching lines...) Expand all
2211 const SpdyRstStreamIR& rst_stream) const { 2258 const SpdyRstStreamIR& rst_stream) const {
2212 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM 2259 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM
2213 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2, 2260 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2,
2214 // which doesn't currently include RST_STREAM payloads. GFE flags have been 2261 // which doesn't currently include RST_STREAM payloads. GFE flags have been
2215 // commented but left in place to simplify future patching. 2262 // commented but left in place to simplify future patching.
2216 // Compute the output buffer size, taking opaque data into account. 2263 // Compute the output buffer size, taking opaque data into account.
2217 uint16 expected_length = GetRstStreamMinimumSize(); 2264 uint16 expected_length = GetRstStreamMinimumSize();
2218 if (protocol_version() > SPDY3) { 2265 if (protocol_version() > SPDY3) {
2219 expected_length += rst_stream.description().size(); 2266 expected_length += rst_stream.description().size();
2220 } 2267 }
2221 SpdyFrameBuilder builder(expected_length); 2268 SpdyFrameBuilder builder(expected_length, protocol_version());
2222 2269
2223 // Serialize the RST_STREAM frame. 2270 // Serialize the RST_STREAM frame.
2224 if (protocol_version() <= SPDY3) { 2271 if (protocol_version() <= SPDY3) {
2225 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); 2272 builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
2226 builder.WriteUInt32(rst_stream.stream_id()); 2273 builder.WriteUInt32(rst_stream.stream_id());
2227 } else { 2274 } else {
2228 builder.WriteFramePrefix(*this, RST_STREAM, 0, rst_stream.stream_id()); 2275 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id());
2229 } 2276 }
2230 2277
2231 builder.WriteUInt32(rst_stream.status()); 2278 builder.WriteUInt32(rst_stream.status());
2232 2279
2233 // In SPDY4 and up, RST_STREAM frames may also specify opaque data. 2280 // In SPDY4 and up, RST_STREAM frames may also specify opaque data.
2234 if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) { 2281 if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) {
2235 builder.WriteBytes(rst_stream.description().data(), 2282 builder.WriteBytes(rst_stream.description().data(),
2236 rst_stream.description().size()); 2283 rst_stream.description().size());
2237 } 2284 }
2238 2285
(...skipping 13 matching lines...) Expand all
2252 if (settings.is_ack()) { 2299 if (settings.is_ack()) {
2253 flags |= SETTINGS_FLAG_ACK; 2300 flags |= SETTINGS_FLAG_ACK;
2254 } 2301 }
2255 } 2302 }
2256 const SpdySettingsIR::ValueMap* values = &(settings.values()); 2303 const SpdySettingsIR::ValueMap* values = &(settings.values());
2257 2304
2258 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); 2305 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5);
2259 // Size, in bytes, of this SETTINGS frame. 2306 // Size, in bytes, of this SETTINGS frame.
2260 const size_t size = GetSettingsMinimumSize() + 2307 const size_t size = GetSettingsMinimumSize() +
2261 (values->size() * setting_size); 2308 (values->size() * setting_size);
2262 SpdyFrameBuilder builder(size); 2309 SpdyFrameBuilder builder(size, protocol_version());
2263 if (protocol_version() <= SPDY3) { 2310 if (protocol_version() <= SPDY3) {
2264 builder.WriteControlFrameHeader(*this, SETTINGS, flags); 2311 builder.WriteControlFrameHeader(*this, SETTINGS, flags);
2265 } else { 2312 } else {
2266 builder.WriteFramePrefix(*this, SETTINGS, flags, 0); 2313 builder.BeginNewFrame(*this, SETTINGS, flags, 0);
2267 } 2314 }
2268 2315
2269 // If this is an ACK, payload should be empty. 2316 // If this is an ACK, payload should be empty.
2270 if (protocol_version() > SPDY3 && settings.is_ack()) { 2317 if (protocol_version() > SPDY3 && settings.is_ack()) {
2271 return builder.take(); 2318 return builder.take();
2272 } 2319 }
2273 2320
2274 if (protocol_version() <= SPDY3) { 2321 if (protocol_version() <= SPDY3) {
2275 builder.WriteUInt32(values->size()); 2322 builder.WriteUInt32(values->size());
2276 } 2323 }
(...skipping 17 matching lines...) Expand all
2294 } else { 2341 } else {
2295 builder.WriteUInt8(SpdyConstants::SerializeSettingId(protocol_version(), 2342 builder.WriteUInt8(SpdyConstants::SerializeSettingId(protocol_version(),
2296 it->first)); 2343 it->first));
2297 } 2344 }
2298 builder.WriteUInt32(it->second.value); 2345 builder.WriteUInt32(it->second.value);
2299 } 2346 }
2300 DCHECK_EQ(size, builder.length()); 2347 DCHECK_EQ(size, builder.length());
2301 return builder.take(); 2348 return builder.take();
2302 } 2349 }
2303 2350
2304 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
2305 DCHECK_LT(SPDY3, protocol_version());
2306 SpdyFrameBuilder builder(GetBlockedSize());
2307 builder.WriteFramePrefix(*this, BLOCKED, kNoFlags, blocked.stream_id());
2308 return builder.take();
2309 }
2310
2311 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { 2351 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
2312 SpdyFrameBuilder builder(GetPingSize()); 2352 SpdyFrameBuilder builder(GetPingSize(), protocol_version());
2313 if (protocol_version() <= SPDY3) { 2353 if (protocol_version() <= SPDY3) {
2314 builder.WriteControlFrameHeader(*this, PING, kNoFlags); 2354 builder.WriteControlFrameHeader(*this, PING, kNoFlags);
2315 builder.WriteUInt32(static_cast<uint32>(ping.id())); 2355 builder.WriteUInt32(static_cast<uint32>(ping.id()));
2316 } else { 2356 } else {
2317 uint8 flags = 0; 2357 uint8 flags = 0;
2318 if (ping.is_ack()) { 2358 if (ping.is_ack()) {
2319 flags |= PING_FLAG_ACK; 2359 flags |= PING_FLAG_ACK;
2320 } 2360 }
2321 builder.WriteFramePrefix(*this, PING, flags, 0); 2361 builder.BeginNewFrame(*this, PING, flags, 0);
2322 builder.WriteUInt64(ping.id()); 2362 builder.WriteUInt64(ping.id());
2323 } 2363 }
2324 DCHECK_EQ(GetPingSize(), builder.length()); 2364 DCHECK_EQ(GetPingSize(), builder.length());
2325 return builder.take(); 2365 return builder.take();
2326 } 2366 }
2327 2367
2328 SpdySerializedFrame* SpdyFramer::SerializeGoAway( 2368 SpdySerializedFrame* SpdyFramer::SerializeGoAway(
2329 const SpdyGoAwayIR& goaway) const { 2369 const SpdyGoAwayIR& goaway) const {
2330 2370
2331 // Compute the output buffer size, take opaque data into account. 2371 // Compute the output buffer size, take opaque data into account.
2332 uint16 expected_length = GetGoAwayMinimumSize(); 2372 uint16 expected_length = GetGoAwayMinimumSize();
2333 if (protocol_version() > SPDY3) { 2373 if (protocol_version() > SPDY3) {
2334 expected_length += goaway.description().size(); 2374 expected_length += goaway.description().size();
2335 } 2375 }
2336 SpdyFrameBuilder builder(expected_length); 2376 SpdyFrameBuilder builder(expected_length, protocol_version());
2337 2377
2338 // Serialize the GOAWAY frame. 2378 // Serialize the GOAWAY frame.
2339 if (protocol_version() <= SPDY3) { 2379 if (protocol_version() <= SPDY3) {
2340 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); 2380 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags);
2341 } else { 2381 } else {
2342 builder.WriteFramePrefix(*this, GOAWAY, 0, 0); 2382 builder.BeginNewFrame(*this, GOAWAY, 0, 0);
2343 } 2383 }
2344 2384
2345 // GOAWAY frames specify the last good stream id for all SPDY versions. 2385 // GOAWAY frames specify the last good stream id for all SPDY versions.
2346 builder.WriteUInt32(goaway.last_good_stream_id()); 2386 builder.WriteUInt32(goaway.last_good_stream_id());
2347 2387
2348 // In SPDY3 and up, GOAWAY frames also specify the error status code. 2388 // In SPDY3 and up, GOAWAY frames also specify the error status code.
2349 if (protocol_version() >= SPDY3) { 2389 if (protocol_version() >= SPDY3) {
2350 builder.WriteUInt32(goaway.status()); 2390 builder.WriteUInt32(goaway.status());
2351 } 2391 }
2352 2392
2353 // In SPDY4 and up, GOAWAY frames may also specify opaque data. 2393 // In SPDY4 and up, GOAWAY frames may also specify opaque data.
2354 if ((protocol_version() > SPDY3) && (goaway.description().size() > 0)) { 2394 if ((protocol_version() > SPDY3) && (goaway.description().size() > 0)) {
2355 builder.WriteBytes(goaway.description().data(), 2395 builder.WriteBytes(goaway.description().data(),
2356 goaway.description().size()); 2396 goaway.description().size());
2357 } 2397 }
2358 2398
2359 DCHECK_EQ(expected_length, builder.length()); 2399 DCHECK_EQ(expected_length, builder.length());
2360 return builder.take(); 2400 return builder.take();
2361 } 2401 }
2362 2402
2363 SpdySerializedFrame* SpdyFramer::SerializeHeaders( 2403 SpdySerializedFrame* SpdyFramer::SerializeHeaders(
2364 const SpdyHeadersIR& headers) { 2404 const SpdyHeadersIR& headers) {
2365 uint8 flags = 0; 2405 uint8 flags = 0;
2366 if (headers.fin()) { 2406 if (headers.fin()) {
2367 flags |= CONTROL_FLAG_FIN; 2407 flags |= CONTROL_FLAG_FIN;
2368 } 2408 }
2369 if (protocol_version() > SPDY3) { 2409 if (protocol_version() > SPDY3) {
2410 // TODO(mlavan): If we overflow into a CONTINUATION frame, this will
2411 // get overwritten below, so we should probably just get rid of the
2412 // end_headers field.
2370 if (headers.end_headers()) { 2413 if (headers.end_headers()) {
2371 flags |= HEADERS_FLAG_END_HEADERS; 2414 flags |= HEADERS_FLAG_END_HEADERS;
2372 } 2415 }
2373 if (headers.has_priority()) { 2416 if (headers.has_priority()) {
2374 flags |= HEADERS_FLAG_PRIORITY; 2417 flags |= HEADERS_FLAG_PRIORITY;
2375 } 2418 }
2376 } 2419 }
2377 2420
2378 // The size of this frame, including variable-length name-value block. 2421 // The size of this frame, including variable-length name-value block.
2379 size_t size = GetHeadersMinimumSize(); 2422 size_t size = GetHeadersMinimumSize();
2380 2423
2381 uint32 priority = headers.priority(); 2424 uint32 priority = headers.priority();
2382 if (headers.has_priority()) { 2425 if (headers.has_priority()) {
2383 if (priority > GetLowestPriority()) { 2426 if (priority > GetLowestPriority()) {
2384 DLOG(DFATAL) << "Priority out-of-bounds."; 2427 DLOG(DFATAL) << "Priority out-of-bounds.";
2385 priority = GetLowestPriority(); 2428 priority = GetLowestPriority();
2386 } 2429 }
2387 size += 4; 2430 size += 4;
2388 } 2431 }
2389 2432
2390 string hpack_encoding; 2433 string hpack_encoding;
2391 if (protocol_version() > SPDY3) { 2434 if (protocol_version() > SPDY3) {
2392 hpack_encoder_.EncodeHeaderSet(headers.name_value_block(), &hpack_encoding); 2435 if (enable_compression_) {
2436 hpack_encoder_.EncodeHeaderSet(
2437 headers.name_value_block(), &hpack_encoding);
2438 } else {
2439 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2440 headers.name_value_block(), &hpack_encoding);
2441 }
2393 size += hpack_encoding.size(); 2442 size += hpack_encoding.size();
2443 if (size > GetControlFrameBufferMaxSize()) {
2444 size += GetNumberRequiredContinuationFrames(size) *
2445 GetContinuationMinimumSize();
2446 flags &= ~HEADERS_FLAG_END_HEADERS;
2447 }
2394 } else { 2448 } else {
2395 size += GetSerializedLength(headers.name_value_block()); 2449 size += GetSerializedLength(headers.name_value_block());
2396 } 2450 }
2397 2451
2398 SpdyFrameBuilder builder(size); 2452 SpdyFrameBuilder builder(size, protocol_version());
2399 if (protocol_version() <= SPDY3) { 2453 if (protocol_version() <= SPDY3) {
2400 builder.WriteControlFrameHeader(*this, HEADERS, flags); 2454 builder.WriteControlFrameHeader(*this, HEADERS, flags);
2401 builder.WriteUInt32(headers.stream_id()); 2455 builder.WriteUInt32(headers.stream_id());
2402 } else { 2456 } else {
2403 builder.WriteFramePrefix(*this, 2457 builder.BeginNewFrame(*this,
2404 HEADERS, 2458 HEADERS,
2405 flags, 2459 flags,
2406 headers.stream_id()); 2460 headers.stream_id());
2407 if (headers.has_priority()) { 2461 if (headers.has_priority()) {
2408 builder.WriteUInt32(priority); 2462 builder.WriteUInt32(priority);
2409 } 2463 }
2410 } 2464 }
2411 if (protocol_version() <= SPDY2) { 2465 if (protocol_version() <= SPDY2) {
2412 builder.WriteUInt16(0); // Unused. 2466 builder.WriteUInt16(0); // Unused.
2413 } 2467 }
2414 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); 2468 DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
2415 2469
2416 if (protocol_version() > SPDY3) { 2470 if (protocol_version() > SPDY3) {
2417 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2471 WritePayloadWithContinuation(&builder,
2472 hpack_encoding,
2473 headers.stream_id(),
2474 HEADERS);
2418 } else { 2475 } else {
2419 SerializeNameValueBlock(&builder, headers); 2476 SerializeNameValueBlock(&builder, headers);
2420 } 2477 }
2421 2478
2422 if (debug_visitor_) { 2479 if (debug_visitor_) {
2423 const size_t payload_len = protocol_version() > SPDY3 ? 2480 const size_t payload_len = protocol_version() > SPDY3 ?
2424 hpack_encoding.size() : 2481 hpack_encoding.size() :
2425 GetSerializedLength(protocol_version(), 2482 GetSerializedLength(protocol_version(),
2426 &(headers.name_value_block())); 2483 &(headers.name_value_block()));
2427 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), 2484 debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
2428 HEADERS, 2485 HEADERS,
2429 payload_len, 2486 payload_len,
2430 builder.length()); 2487 builder.length());
2431 } 2488 }
2432 2489
2433 return builder.take(); 2490 return builder.take();
2434 } 2491 }
2435 2492
2436 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( 2493 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
2437 const SpdyWindowUpdateIR& window_update) const { 2494 const SpdyWindowUpdateIR& window_update) const {
2438 SpdyFrameBuilder builder(GetWindowUpdateSize()); 2495 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version());
2439 if (protocol_version() <= SPDY3) { 2496 if (protocol_version() <= SPDY3) {
2440 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); 2497 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
2441 builder.WriteUInt32(window_update.stream_id()); 2498 builder.WriteUInt32(window_update.stream_id());
2442 } else { 2499 } else {
2443 builder.WriteFramePrefix(*this, 2500 builder.BeginNewFrame(*this,
2444 WINDOW_UPDATE, 2501 WINDOW_UPDATE,
2445 kNoFlags, 2502 kNoFlags,
2446 window_update.stream_id()); 2503 window_update.stream_id());
2447 } 2504 }
2448 builder.WriteUInt32(window_update.delta()); 2505 builder.WriteUInt32(window_update.delta());
2449 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); 2506 DCHECK_EQ(GetWindowUpdateSize(), builder.length());
2450 return builder.take(); 2507 return builder.take();
2451 } 2508 }
2452 2509
2510 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
2511 DCHECK_LT(SPDY3, protocol_version());
2512 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version());
2513 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
2514 return builder.take();
2515 }
2516
2453 SpdyFrame* SpdyFramer::SerializePushPromise( 2517 SpdyFrame* SpdyFramer::SerializePushPromise(
2454 const SpdyPushPromiseIR& push_promise) { 2518 const SpdyPushPromiseIR& push_promise) {
2455 DCHECK_LT(SPDY3, protocol_version()); 2519 DCHECK_LT(SPDY3, protocol_version());
2456 uint8 flags = 0; 2520 uint8 flags = 0;
2521 // TODO(mlavan): If we overflow into a CONTINUATION frame, this will
2522 // get overwritten below, so we should probably just get rid of the
2523 // end_push_promise field.
2457 if (push_promise.end_push_promise()) { 2524 if (push_promise.end_push_promise()) {
2458 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2525 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2459 } 2526 }
2460 // The size of this frame, including variable-length name-value block. 2527 // The size of this frame, including variable-length name-value block.
2461 size_t size = GetPushPromiseMinimumSize(); 2528 size_t size = GetPushPromiseMinimumSize();
2462 2529
2463 string hpack_encoding; 2530 string hpack_encoding;
2464 if (protocol_version() > SPDY3) { 2531 if (protocol_version() > SPDY3) {
2465 hpack_encoder_.EncodeHeaderSet(push_promise.name_value_block(), 2532 if (enable_compression_) {
2466 &hpack_encoding); 2533 hpack_encoder_.EncodeHeaderSet(
2534 push_promise.name_value_block(), &hpack_encoding);
2535 } else {
2536 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2537 push_promise.name_value_block(), &hpack_encoding);
2538 }
2467 size += hpack_encoding.size(); 2539 size += hpack_encoding.size();
2540 if (size > GetControlFrameBufferMaxSize()) {
2541 size += GetNumberRequiredContinuationFrames(size) *
2542 GetContinuationMinimumSize();
2543 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2544 }
2468 } else { 2545 } else {
2469 size += GetSerializedLength(push_promise.name_value_block()); 2546 size += GetSerializedLength(push_promise.name_value_block());
2470 } 2547 }
2471 2548
2472 SpdyFrameBuilder builder(size); 2549 SpdyFrameBuilder builder(size, protocol_version());
2473 builder.WriteFramePrefix(*this, PUSH_PROMISE, flags, 2550 builder.BeginNewFrame(*this,
2474 push_promise.stream_id()); 2551 PUSH_PROMISE,
2552 flags,
2553 push_promise.stream_id());
2475 builder.WriteUInt32(push_promise.promised_stream_id()); 2554 builder.WriteUInt32(push_promise.promised_stream_id());
2476 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); 2555 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
2477 2556
2478 if (protocol_version() > SPDY3) { 2557 if (protocol_version() > SPDY3) {
2479 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2558 WritePayloadWithContinuation(&builder,
2559 hpack_encoding,
2560 push_promise.stream_id(),
2561 PUSH_PROMISE);
2480 } else { 2562 } else {
2481 SerializeNameValueBlock(&builder, push_promise); 2563 SerializeNameValueBlock(&builder, push_promise);
2482 } 2564 }
2483 2565
2484 if (debug_visitor_) { 2566 if (debug_visitor_) {
2485 const size_t payload_len = protocol_version() > SPDY3 ? 2567 const size_t payload_len = protocol_version() > SPDY3 ?
2486 hpack_encoding.size() : 2568 hpack_encoding.size() :
2487 GetSerializedLength(protocol_version(), 2569 GetSerializedLength(protocol_version(),
2488 &(push_promise.name_value_block())); 2570 &(push_promise.name_value_block()));
2489 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), 2571 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
(...skipping 10 matching lines...) Expand all
2500 const SpdyContinuationIR& continuation) { 2582 const SpdyContinuationIR& continuation) {
2501 CHECK_LT(SPDY3, protocol_version()); 2583 CHECK_LT(SPDY3, protocol_version());
2502 uint8 flags = 0; 2584 uint8 flags = 0;
2503 if (continuation.end_headers()) { 2585 if (continuation.end_headers()) {
2504 flags |= HEADERS_FLAG_END_HEADERS; 2586 flags |= HEADERS_FLAG_END_HEADERS;
2505 } 2587 }
2506 2588
2507 // The size of this frame, including variable-length name-value block. 2589 // The size of this frame, including variable-length name-value block.
2508 size_t size = GetContinuationMinimumSize(); 2590 size_t size = GetContinuationMinimumSize();
2509 string hpack_encoding; 2591 string hpack_encoding;
2510 hpack_encoder_.EncodeHeaderSet(continuation.name_value_block(), 2592 if (enable_compression_) {
2511 &hpack_encoding); 2593 hpack_encoder_.EncodeHeaderSet(
2594 continuation.name_value_block(), &hpack_encoding);
2595 } else {
2596 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2597 continuation.name_value_block(), &hpack_encoding);
2598 }
2512 size += hpack_encoding.size(); 2599 size += hpack_encoding.size();
2513 2600
2514 SpdyFrameBuilder builder(size); 2601 SpdyFrameBuilder builder(size, protocol_version());
2515 builder.WriteFramePrefix(*this, CONTINUATION, flags, 2602 builder.BeginNewFrame(*this, CONTINUATION, flags,
2516 continuation.stream_id()); 2603 continuation.stream_id());
2517 DCHECK_EQ(GetContinuationMinimumSize(), builder.length()); 2604 DCHECK_EQ(GetContinuationMinimumSize(), builder.length());
2518 2605
2519 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2606 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2520 2607
2521 if (debug_visitor_) { 2608 if (debug_visitor_) {
2522 const size_t payload_len = hpack_encoding.size(); 2609 const size_t payload_len = hpack_encoding.size();
2523 debug_visitor_->OnSendCompressedFrame(continuation.stream_id(), 2610 debug_visitor_->OnSendCompressedFrame(continuation.stream_id(),
2524 CONTINUATION, payload_len, builder.length()); 2611 CONTINUATION, payload_len, builder.length());
2525 } 2612 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 GetSerializedLength(protocol_version(), &headers); 2682 GetSerializedLength(protocol_version(), &headers);
2596 if (!enable_compression_) { 2683 if (!enable_compression_) {
2597 return uncompressed_length; 2684 return uncompressed_length;
2598 } 2685 }
2599 z_stream* compressor = GetHeaderCompressor(); 2686 z_stream* compressor = GetHeaderCompressor();
2600 // Since we'll be performing lots of flushes when compressing the data, 2687 // Since we'll be performing lots of flushes when compressing the data,
2601 // zlib's lower bounds may be insufficient. 2688 // zlib's lower bounds may be insufficient.
2602 return 2 * deflateBound(compressor, uncompressed_length); 2689 return 2 * deflateBound(compressor, uncompressed_length);
2603 } 2690 }
2604 2691
2692 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) {
2693 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize();
2694 DCHECK_GT(protocol_version(), SPDY3);
2695 DCHECK_GT(size, kMaxControlFrameSize);
2696 size_t overflow = size - kMaxControlFrameSize;
2697 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1;
2698 }
2699
2700 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
2701 const string& hpack_encoding,
2702 SpdyStreamId stream_id,
2703 SpdyFrameType type) {
2704 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize();
2705
2706 // In addition to the prefix, fixed_field_size includes the size of
2707 // any fields that come before the variable-length name/value block.
2708 size_t fixed_field_size = 0;
2709 uint8 end_flag = 0;
2710 uint8 flags = 0;
2711 if (type == HEADERS) {
2712 fixed_field_size = GetHeadersMinimumSize();
2713 end_flag = HEADERS_FLAG_END_HEADERS;
2714 } else if (type == PUSH_PROMISE) {
2715 fixed_field_size = GetPushPromiseMinimumSize();
2716 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2717 } else {
2718 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
2719 << FrameTypeToString(type);
2720 }
2721
2722 // Write as much of the payload as possible into the initial frame.
2723 size_t bytes_remaining = hpack_encoding.size() -
2724 std::min(hpack_encoding.size(),
2725 kMaxControlFrameSize - fixed_field_size);
2726 builder->WriteBytes(&hpack_encoding[0],
2727 hpack_encoding.size() - bytes_remaining);
2728
2729 if (bytes_remaining > 0) {
2730 builder->OverwriteLength(*this,
2731 kMaxControlFrameSize - GetControlFrameHeaderSize());
2732 }
2733
2734 // Tack on CONTINUATION frames for the overflow.
2735 while (bytes_remaining > 0) {
2736 size_t bytes_to_write = std::min(bytes_remaining,
2737 kMaxControlFrameSize -
2738 GetContinuationMinimumSize());
2739 // Write CONTINUATION frame prefix.
2740 if (bytes_remaining == bytes_to_write) {
2741 flags |= end_flag;
2742 }
2743 builder->BeginNewFrame(*this,
2744 CONTINUATION,
2745 flags,
2746 stream_id);
2747 // Write payload fragment.
2748 builder->WriteBytes(&hpack_encoding[hpack_encoding.size() -
2749 bytes_remaining],
2750 bytes_to_write);
2751 bytes_remaining -= bytes_to_write;
2752 }
2753 }
2754
2605 // The following compression setting are based on Brian Olson's analysis. See 2755 // The following compression setting are based on Brian Olson's analysis. See
2606 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79 2 2756 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79 2
2607 // for more details. 2757 // for more details.
2608 #if defined(USE_SYSTEM_ZLIB) 2758 #if defined(USE_SYSTEM_ZLIB)
2609 // System zlib is not expected to have workaround for http://crbug.com/139744, 2759 // System zlib is not expected to have workaround for http://crbug.com/139744,
2610 // so disable compression in that case. 2760 // so disable compression in that case.
2611 // TODO(phajdan.jr): Remove the special case when it's no longer necessary. 2761 // TODO(phajdan.jr): Remove the special case when it's no longer necessary.
2612 static const int kCompressorLevel = 0; 2762 static const int kCompressorLevel = 0;
2613 #else // !defined(USE_SYSTEM_ZLIB) 2763 #else // !defined(USE_SYSTEM_ZLIB)
2614 static const int kCompressorLevel = 9; 2764 static const int kCompressorLevel = 9;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
2782 const SpdyFrameWithNameValueBlockIR& frame) { 2932 const SpdyFrameWithNameValueBlockIR& frame) {
2783 CHECK_GE(SPDY3, protocol_version()); 2933 CHECK_GE(SPDY3, protocol_version());
2784 if (!enable_compression_) { 2934 if (!enable_compression_) {
2785 return SerializeNameValueBlockWithoutCompression(builder, 2935 return SerializeNameValueBlockWithoutCompression(builder,
2786 frame.name_value_block()); 2936 frame.name_value_block());
2787 } 2937 }
2788 2938
2789 // First build an uncompressed version to be fed into the compressor. 2939 // First build an uncompressed version to be fed into the compressor.
2790 const size_t uncompressed_len = GetSerializedLength( 2940 const size_t uncompressed_len = GetSerializedLength(
2791 protocol_version(), &(frame.name_value_block())); 2941 protocol_version(), &(frame.name_value_block()));
2792 SpdyFrameBuilder uncompressed_builder(uncompressed_len); 2942 SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version());
2793 SerializeNameValueBlockWithoutCompression(&uncompressed_builder, 2943 SerializeNameValueBlockWithoutCompression(&uncompressed_builder,
2794 frame.name_value_block()); 2944 frame.name_value_block());
2795 scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take()); 2945 scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take());
2796 2946
2797 z_stream* compressor = GetHeaderCompressor(); 2947 z_stream* compressor = GetHeaderCompressor();
2798 if (!compressor) { 2948 if (!compressor) {
2799 LOG(DFATAL) << "Could not obtain compressor."; 2949 LOG(DFATAL) << "Could not obtain compressor.";
2800 return; 2950 return;
2801 } 2951 }
2802 2952
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2841 builder->Seek(compressed_size); 2991 builder->Seek(compressed_size);
2842 builder->RewriteLength(*this); 2992 builder->RewriteLength(*this);
2843 2993
2844 pre_compress_bytes.Add(uncompressed_len); 2994 pre_compress_bytes.Add(uncompressed_len);
2845 post_compress_bytes.Add(compressed_size); 2995 post_compress_bytes.Add(compressed_size);
2846 2996
2847 compressed_frames.Increment(); 2997 compressed_frames.Increment();
2848 } 2998 }
2849 2999
2850 } // namespace net 3000 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698