OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¤t_frame_stream_id_); | 658 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); |
650 } | 659 } |
651 DCHECK(successful_read); | 660 DCHECK(successful_read); |
652 | 661 |
653 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 662 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
1743 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. | 1749 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. |
1744 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1750 bool successful_read = reader.ReadUInt31(¤t_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 Loading... |
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(¤t_frame_stream_id_); | 1821 bool successful_read = reader.ReadUInt31(¤t_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |