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 #include "net/spdy/spdy_framer.h" | 5 #include "net/spdy/spdy_framer.h" |
6 | 6 |
7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/metrics/stats_counters.h" | 9 #include "base/metrics/stats_counters.h" |
10 #include "base/third_party/valgrind/memcheck.h" | 10 #include "base/third_party/valgrind/memcheck.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 uLong CalculateDictionaryId(const char* dictionary, | 25 uLong CalculateDictionaryId(const char* dictionary, |
26 const size_t dictionary_size) { | 26 const size_t dictionary_size) { |
27 uLong initial_value = adler32(0L, Z_NULL, 0); | 27 uLong initial_value = adler32(0L, Z_NULL, 0); |
28 return adler32(initial_value, | 28 return adler32(initial_value, |
29 reinterpret_cast<const Bytef*>(dictionary), | 29 reinterpret_cast<const Bytef*>(dictionary), |
30 dictionary_size); | 30 dictionary_size); |
31 } | 31 } |
32 | 32 |
33 struct DictionaryIds { | 33 struct DictionaryIds { |
34 DictionaryIds() | 34 DictionaryIds() |
35 : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)), | 35 : v2_dictionary_id( |
36 v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize)) | 36 CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)), |
37 {} | 37 v3_dictionary_id( |
| 38 CalculateDictionaryId(kV3Dictionary, kV3DictionarySize)) {} |
38 const uLong v2_dictionary_id; | 39 const uLong v2_dictionary_id; |
39 const uLong v3_dictionary_id; | 40 const uLong v3_dictionary_id; |
40 }; | 41 }; |
41 | 42 |
42 // Adler ID for the SPDY header compressor dictionaries. Note that they are | 43 // Adler ID for the SPDY header compressor dictionaries. Note that they are |
43 // initialized lazily to avoid static initializers. | 44 // initialized lazily to avoid static initializers. |
44 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; | 45 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; |
45 | 46 |
46 // Used to indicate no flags in a SPDY flags field. | 47 // Used to indicate no flags in a SPDY flags field. |
47 const uint8 kNoFlags = 0; | 48 const uint8 kNoFlags = 0; |
48 | 49 |
49 } // namespace | 50 } // namespace |
50 | 51 |
51 const SpdyStreamId SpdyFramer::kInvalidStream = -1; | 52 const SpdyStreamId SpdyFramer::kInvalidStream = -1; |
52 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; | 53 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; |
53 // The size of the control frame buffer. Must be >= the minimum size of the | 54 // The size of the control frame buffer. Must be >= the minimum size of the |
54 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for | 55 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for |
55 // calculation details. | 56 // calculation details. |
56 const size_t SpdyFramer::kControlFrameBufferSize = 18; | 57 const size_t SpdyFramer::kControlFrameBufferSize = 18; |
57 | 58 |
58 #ifdef DEBUG_SPDY_STATE_CHANGES | 59 #ifdef DEBUG_SPDY_STATE_CHANGES |
59 #define CHANGE_STATE(newstate) \ | 60 #define CHANGE_STATE(newstate) \ |
60 do { \ | 61 do { \ |
61 DVLOG(1) << "Changing state from: " \ | 62 DVLOG(1) << "Changing state from: " << StateToString(state_) << " to " \ |
62 << StateToString(state_) \ | 63 << StateToString(newstate) << "\n"; \ |
63 << " to " << StateToString(newstate) << "\n"; \ | 64 DCHECK(state_ != SPDY_ERROR); \ |
64 DCHECK(state_ != SPDY_ERROR); \ | 65 DCHECK_EQ(previous_state_, state_); \ |
65 DCHECK_EQ(previous_state_, state_); \ | 66 previous_state_ = state_; \ |
66 previous_state_ = state_; \ | 67 state_ = newstate; \ |
67 state_ = newstate; \ | |
68 } while (false) | 68 } while (false) |
69 #else | 69 #else |
70 #define CHANGE_STATE(newstate) \ | 70 #define CHANGE_STATE(newstate) \ |
71 do { \ | 71 do { \ |
72 DCHECK(state_ != SPDY_ERROR); \ | 72 DCHECK(state_ != SPDY_ERROR); \ |
73 DCHECK_EQ(previous_state_, state_); \ | 73 DCHECK_EQ(previous_state_, state_); \ |
74 previous_state_ = state_; \ | 74 previous_state_ = state_; \ |
75 state_ = newstate; \ | 75 state_ = newstate; \ |
76 } while (false) | 76 } while (false) |
77 #endif | 77 #endif |
78 | 78 |
79 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat( | 79 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(SpdyMajorVersion version, |
80 SpdyMajorVersion version, uint32 wire) { | 80 uint32 wire) { |
81 if (version < SPDY3) { | 81 if (version < SPDY3) { |
82 ConvertFlagsAndIdForSpdy2(&wire); | 82 ConvertFlagsAndIdForSpdy2(&wire); |
83 } | 83 } |
84 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); | 84 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); |
85 } | 85 } |
86 | 86 |
87 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) | 87 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) |
88 : flags_(flags), id_(id & 0x00ffffff) { | 88 : flags_(flags), id_(id & 0x00ffffff) { |
89 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; |
90 } | 90 } |
91 | 91 |
92 uint32 SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version) | 92 uint32 SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version) const { |
93 const { | |
94 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); | 93 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); |
95 if (version < SPDY3) { | 94 if (version < SPDY3) { |
96 ConvertFlagsAndIdForSpdy2(&wire); | 95 ConvertFlagsAndIdForSpdy2(&wire); |
97 } | 96 } |
98 return wire; | 97 return wire; |
99 } | 98 } |
100 | 99 |
101 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field. | 100 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field. |
102 // This method is used to preserve buggy behavior and works on both | 101 // This method is used to preserve buggy behavior and works on both |
103 // little-endian and big-endian hosts. | 102 // little-endian and big-endian hosts. |
104 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 | 103 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 |
105 // as well as vice versa). | 104 // as well as vice versa). |
106 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) { | 105 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) { |
107 uint8* wire_array = reinterpret_cast<uint8*>(val); | 106 uint8* wire_array = reinterpret_cast<uint8*>(val); |
108 std::swap(wire_array[0], wire_array[3]); | 107 std::swap(wire_array[0], wire_array[3]); |
109 std::swap(wire_array[1], wire_array[2]); | 108 std::swap(wire_array[1], wire_array[2]); |
110 } | 109 } |
111 | 110 |
112 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data, | 111 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data, |
113 size_t len) { | 112 size_t len) { |
114 return true; | 113 return true; |
115 } | 114 } |
116 | 115 |
117 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( | 116 bool SpdyFramerVisitorInterface::OnRstStreamFrameData( |
118 const char* rst_stream_data, | 117 const char* rst_stream_data, |
119 size_t len) { | 118 size_t len) { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 size += 4; | 250 size += 4; |
252 | 251 |
253 // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes) | 252 // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes) |
254 if (protocol_version() >= SPDY3) { | 253 if (protocol_version() >= SPDY3) { |
255 size += 4; | 254 size += 4; |
256 } | 255 } |
257 | 256 |
258 return size; | 257 return size; |
259 } | 258 } |
260 | 259 |
261 size_t SpdyFramer::GetHeadersMinimumSize() const { | 260 size_t SpdyFramer::GetHeadersMinimumSize() const { |
262 // Size, in bytes, of a HEADERS frame not including the variable-length | 261 // Size, in bytes, of a HEADERS frame not including the variable-length |
263 // name-value block. | 262 // name-value block. |
264 size_t size = GetControlFrameHeaderSize(); | 263 size_t size = GetControlFrameHeaderSize(); |
265 if (protocol_version() <= SPDY3) { | 264 if (protocol_version() <= SPDY3) { |
266 // Calculated as: | 265 // Calculated as: |
267 // control frame header + 4 (stream IDs) | 266 // control frame header + 4 (stream IDs) |
268 size += 4; | 267 size += 4; |
269 } | 268 } |
270 | 269 |
271 // In SPDY 2, there were 2 unused bytes before payload. | 270 // In SPDY 2, there were 2 unused bytes before payload. |
(...skipping 24 matching lines...) Expand all Loading... |
296 return GetControlFrameHeaderSize(); | 295 return GetControlFrameHeaderSize(); |
297 } | 296 } |
298 | 297 |
299 size_t SpdyFramer::GetPushPromiseMinimumSize() const { | 298 size_t SpdyFramer::GetPushPromiseMinimumSize() const { |
300 DCHECK_LT(SPDY3, protocol_version()); | 299 DCHECK_LT(SPDY3, protocol_version()); |
301 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. | 300 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. |
302 // Calculated as frame prefix + 4 (promised stream id). | 301 // Calculated as frame prefix + 4 (promised stream id). |
303 return GetControlFrameHeaderSize() + 4; | 302 return GetControlFrameHeaderSize() + 4; |
304 } | 303 } |
305 | 304 |
306 size_t SpdyFramer::GetContinuationMinimumSize() const { | 305 size_t SpdyFramer::GetContinuationMinimumSize() const { |
307 // Size, in bytes, of a CONTINUATION frame not including the variable-length | 306 // Size, in bytes, of a CONTINUATION frame not including the variable-length |
308 // headers fragments. | 307 // headers fragments. |
309 return GetControlFrameHeaderSize(); | 308 return GetControlFrameHeaderSize(); |
310 } | 309 } |
311 | 310 |
312 size_t SpdyFramer::GetFrameMinimumSize() const { | 311 size_t SpdyFramer::GetFrameMinimumSize() const { |
313 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); | 312 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); |
314 } | 313 } |
315 | 314 |
316 size_t SpdyFramer::GetFrameMaximumSize() const { | 315 size_t SpdyFramer::GetFrameMaximumSize() const { |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 | 577 |
579 default: | 578 default: |
580 LOG(DFATAL) << "Invalid value for " << display_protocol_ | 579 LOG(DFATAL) << "Invalid value for " << display_protocol_ |
581 << " framer state: " << state_; | 580 << " framer state: " << state_; |
582 // This ensures that we don't infinite-loop if state_ gets an | 581 // This ensures that we don't infinite-loop if state_ gets an |
583 // invalid value somehow, such as due to a SpdyFramer getting deleted | 582 // invalid value somehow, such as due to a SpdyFramer getting deleted |
584 // from a callback it calls. | 583 // from a callback it calls. |
585 goto bottom; | 584 goto bottom; |
586 } | 585 } |
587 } while (state_ != previous_state_); | 586 } while (state_ != previous_state_); |
588 bottom: | 587 bottom: |
589 DCHECK(len == 0 || state_ == SPDY_ERROR); | 588 DCHECK(len == 0 || state_ == SPDY_ERROR); |
590 if (current_frame_buffer_length_ == 0 && | 589 if (current_frame_buffer_length_ == 0 && remaining_data_length_ == 0 && |
591 remaining_data_length_ == 0 && | |
592 remaining_control_header_ == 0) { | 590 remaining_control_header_ == 0) { |
593 DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR) | 591 DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR) |
594 << "State: " << StateToString(state_); | 592 << "State: " << StateToString(state_); |
595 } | 593 } |
596 | 594 |
597 return original_len - len; | 595 return original_len - len; |
598 } | 596 } |
599 | 597 |
600 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { | 598 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { |
601 // This should only be called when we're in the SPDY_READING_COMMON_HEADER | 599 // This should only be called when we're in the SPDY_READING_COMMON_HEADER |
602 // state. | 600 // state. |
603 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); | 601 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER); |
604 | 602 |
605 size_t original_len = len; | 603 size_t original_len = len; |
606 | 604 |
607 // Update current frame buffer as needed. | 605 // Update current frame buffer as needed. |
608 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) { | 606 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) { |
609 size_t bytes_desired = | 607 size_t bytes_desired = |
610 GetControlFrameHeaderSize() - current_frame_buffer_length_; | 608 GetControlFrameHeaderSize() - current_frame_buffer_length_; |
611 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); | 609 UpdateCurrentFrameBuffer(&data, &len, bytes_desired); |
612 } | 610 } |
613 | 611 |
614 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) { | 612 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) { |
615 // Not enough information to do anything meaningful. | 613 // Not enough information to do anything meaningful. |
616 return original_len - len; | 614 return original_len - len; |
617 } | 615 } |
618 | 616 |
619 // Using a scoped_ptr here since we may need to create a new SpdyFrameReader | 617 // Using a scoped_ptr here since we may need to create a new SpdyFrameReader |
620 // when processing DATA frames below. | 618 // when processing DATA frames below. |
621 scoped_ptr<SpdyFrameReader> reader( | 619 scoped_ptr<SpdyFrameReader> reader(new SpdyFrameReader( |
622 new SpdyFrameReader(current_frame_buffer_.get(), | 620 current_frame_buffer_.get(), current_frame_buffer_length_)); |
623 current_frame_buffer_length_)); | |
624 | 621 |
625 uint16 version = 0; | 622 uint16 version = 0; |
626 bool is_control_frame = false; | 623 bool is_control_frame = false; |
627 | 624 |
628 uint16 control_frame_type_field = DATA; | 625 uint16 control_frame_type_field = DATA; |
629 // ProcessControlFrameHeader() will set current_frame_type_ to the | 626 // ProcessControlFrameHeader() will set current_frame_type_ to the |
630 // correct value if this is a valid control frame. | 627 // correct value if this is a valid control frame. |
631 current_frame_type_ = DATA; | 628 current_frame_type_ = DATA; |
632 if (protocol_version() <= SPDY3) { | 629 if (protocol_version() <= SPDY3) { |
633 bool successful_read = reader->ReadUInt16(&version); | 630 bool successful_read = reader->ReadUInt16(&version); |
634 DCHECK(successful_read); | 631 DCHECK(successful_read); |
635 is_control_frame = (version & kControlFlagMask) != 0; | 632 is_control_frame = (version & kControlFlagMask) != 0; |
636 version &= ~kControlFlagMask; // Only valid for control frames. | 633 version &= ~kControlFlagMask; // Only valid for control frames. |
637 if (is_control_frame) { | 634 if (is_control_frame) { |
638 // We check version before we check validity: version can never be | 635 // We check version before we check validity: version can never be |
639 // 'invalid', it can only be unsupported. | 636 // 'invalid', it can only be unsupported. |
640 if (version < SpdyConstants::SerializeMajorVersion(SPDY_MIN_VERSION) || | 637 if (version < SpdyConstants::SerializeMajorVersion(SPDY_MIN_VERSION) || |
641 version > SpdyConstants::SerializeMajorVersion(SPDY_MAX_VERSION) || | 638 version > SpdyConstants::SerializeMajorVersion(SPDY_MAX_VERSION) || |
642 SpdyConstants::ParseMajorVersion(version) != protocol_version()) { | 639 SpdyConstants::ParseMajorVersion(version) != protocol_version()) { |
643 // Version does not match the version the framer was initialized with. | 640 // Version does not match the version the framer was initialized with. |
644 DVLOG(1) << "Unsupported SPDY version " | 641 DVLOG(1) << "Unsupported SPDY version " << version << " (expected " |
645 << version | 642 << protocol_version() << ")"; |
646 << " (expected " << protocol_version() << ")"; | |
647 set_error(SPDY_UNSUPPORTED_VERSION); | 643 set_error(SPDY_UNSUPPORTED_VERSION); |
648 return 0; | 644 return 0; |
649 } else { | 645 } else { |
650 // Convert version from wire format to SpdyMajorVersion. | 646 // Convert version from wire format to SpdyMajorVersion. |
651 version = SpdyConstants::ParseMajorVersion(version); | 647 version = SpdyConstants::ParseMajorVersion(version); |
652 } | 648 } |
653 // We check control_frame_type_field's validity in | 649 // We check control_frame_type_field's validity in |
654 // ProcessControlFrameHeader(). | 650 // ProcessControlFrameHeader(). |
655 successful_read = reader->ReadUInt16(&control_frame_type_field); | 651 successful_read = reader->ReadUInt16(&control_frame_type_field); |
656 } else { | 652 } else { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 686 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
691 DCHECK(successful_read); | 687 DCHECK(successful_read); |
692 | 688 |
693 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); | 689 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); |
694 DCHECK(successful_read); | 690 DCHECK(successful_read); |
695 | 691 |
696 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); | 692 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); |
697 | 693 |
698 // Before we accept a DATA frame, we need to make sure we're not in the | 694 // Before we accept a DATA frame, we need to make sure we're not in the |
699 // middle of processing a header block. | 695 // middle of processing a header block. |
700 const bool is_continuation_frame = (control_frame_type_field == | 696 const bool is_continuation_frame = |
701 SpdyConstants::SerializeFrameType(protocol_version(), CONTINUATION)); | 697 (control_frame_type_field == |
| 698 SpdyConstants::SerializeFrameType(protocol_version(), CONTINUATION)); |
702 if ((expect_continuation_ != 0) != is_continuation_frame) { | 699 if ((expect_continuation_ != 0) != is_continuation_frame) { |
703 if (expect_continuation_ != 0) { | 700 if (expect_continuation_ != 0) { |
704 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " | 701 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " |
705 << "frame, but instead received frame type " | 702 << "frame, but instead received frame type " |
706 << control_frame_type_field; | 703 << control_frame_type_field; |
707 } else { | 704 } else { |
708 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; | 705 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; |
709 } | 706 } |
710 set_error(SPDY_UNEXPECTED_FRAME); | 707 set_error(SPDY_UNEXPECTED_FRAME); |
711 return original_len - len; | 708 return original_len - len; |
(...skipping 24 matching lines...) Expand all Loading... |
736 if (!is_control_frame) { | 733 if (!is_control_frame) { |
737 if (protocol_version() > SPDY3) { | 734 if (protocol_version() > SPDY3) { |
738 // Catch bogus tests sending oversized DATA frames. | 735 // Catch bogus tests sending oversized DATA frames. |
739 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_) | 736 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_) |
740 << "DATA frame too large for SPDY >= 4."; | 737 << "DATA frame too large for SPDY >= 4."; |
741 } | 738 } |
742 | 739 |
743 uint8 valid_data_flags = 0; | 740 uint8 valid_data_flags = 0; |
744 if (protocol_version() > SPDY3) { | 741 if (protocol_version() > SPDY3) { |
745 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | | 742 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | |
746 DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH; | 743 DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH; |
747 } else { | 744 } else { |
748 valid_data_flags = DATA_FLAG_FIN; | 745 valid_data_flags = DATA_FLAG_FIN; |
749 } | 746 } |
750 | 747 |
751 if (current_frame_flags_ & ~valid_data_flags) { | 748 if (current_frame_flags_ & ~valid_data_flags) { |
752 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 749 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
753 } else { | 750 } else { |
754 visitor_->OnDataFrameHeader(current_frame_stream_id_, | 751 visitor_->OnDataFrameHeader(current_frame_stream_id_, |
755 remaining_data_length_, | 752 remaining_data_length_, |
756 current_frame_flags_ & DATA_FLAG_FIN); | 753 current_frame_flags_ & DATA_FLAG_FIN); |
757 if (remaining_data_length_ > 0) { | 754 if (remaining_data_length_ > 0) { |
758 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); | 755 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); |
759 } else { | 756 } else { |
760 // Empty data frame. | 757 // Empty data frame. |
761 if (current_frame_flags_ & DATA_FLAG_FIN) { | 758 if (current_frame_flags_ & DATA_FLAG_FIN) { |
762 visitor_->OnStreamFrameData( | 759 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); |
763 current_frame_stream_id_, NULL, 0, true); | |
764 } | 760 } |
765 CHANGE_STATE(SPDY_AUTO_RESET); | 761 CHANGE_STATE(SPDY_AUTO_RESET); |
766 } | 762 } |
767 } | 763 } |
768 } else { | 764 } else { |
769 ProcessControlFrameHeader(control_frame_type_field); | 765 ProcessControlFrameHeader(control_frame_type_field); |
770 } | 766 } |
771 | 767 |
772 return original_len - len; | 768 return original_len - len; |
773 } | 769 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 // opaque data, so we only have a lower limit on the frame size. | 824 // opaque data, so we only have a lower limit on the frame size. |
829 if ((current_frame_length_ != GetRstStreamMinimumSize() && | 825 if ((current_frame_length_ != GetRstStreamMinimumSize() && |
830 protocol_version() <= SPDY3) || | 826 protocol_version() <= SPDY3) || |
831 (current_frame_length_ < GetRstStreamMinimumSize() && | 827 (current_frame_length_ < GetRstStreamMinimumSize() && |
832 protocol_version() > SPDY3)) { | 828 protocol_version() > SPDY3)) { |
833 set_error(SPDY_INVALID_CONTROL_FRAME); | 829 set_error(SPDY_INVALID_CONTROL_FRAME); |
834 } else if (current_frame_flags_ != 0) { | 830 } else if (current_frame_flags_ != 0) { |
835 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 831 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
836 } | 832 } |
837 break; | 833 break; |
838 case SETTINGS: | 834 case SETTINGS: { |
839 { | |
840 // Make sure that we have an integral number of 8-byte key/value pairs, | 835 // Make sure that we have an integral number of 8-byte key/value pairs, |
841 // plus a 4-byte length field in SPDY3 and below. | 836 // plus a 4-byte length field in SPDY3 and below. |
842 size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0); | 837 size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0); |
843 // Size of each key/value pair in bytes. | 838 // Size of each key/value pair in bytes. |
844 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); | 839 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); |
845 if (current_frame_length_ < GetSettingsMinimumSize() || | 840 if (current_frame_length_ < GetSettingsMinimumSize() || |
846 (current_frame_length_ - GetControlFrameHeaderSize()) | 841 (current_frame_length_ - GetControlFrameHeaderSize()) % |
847 % setting_size != values_prefix_size) { | 842 setting_size != |
| 843 values_prefix_size) { |
848 DLOG(WARNING) << "Invalid length for SETTINGS frame: " | 844 DLOG(WARNING) << "Invalid length for SETTINGS frame: " |
849 << current_frame_length_; | 845 << current_frame_length_; |
850 set_error(SPDY_INVALID_CONTROL_FRAME); | 846 set_error(SPDY_INVALID_CONTROL_FRAME); |
851 } else if (protocol_version() <= SPDY3 && | 847 } else if (protocol_version() <= SPDY3 && |
852 current_frame_flags_ & | 848 current_frame_flags_ & |
853 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { | 849 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { |
854 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 850 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
855 } else if (protocol_version() > SPDY3 && | 851 } else if (protocol_version() > SPDY3 && |
856 current_frame_flags_ & ~SETTINGS_FLAG_ACK) { | 852 current_frame_flags_ & ~SETTINGS_FLAG_ACK) { |
857 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 853 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
858 } else if (protocol_version() > SPDY3 && | 854 } else if (protocol_version() > SPDY3 && |
859 current_frame_flags_ & SETTINGS_FLAG_ACK && | 855 current_frame_flags_ & SETTINGS_FLAG_ACK && |
860 current_frame_length_ > GetSettingsMinimumSize()) { | 856 current_frame_length_ > GetSettingsMinimumSize()) { |
861 set_error(SPDY_INVALID_CONTROL_FRAME); | 857 set_error(SPDY_INVALID_CONTROL_FRAME); |
862 } | 858 } |
863 break; | 859 break; |
864 } | 860 } |
865 case PING: | 861 case PING: |
866 if (current_frame_length_ != GetPingSize()) { | 862 if (current_frame_length_ != GetPingSize()) { |
867 set_error(SPDY_INVALID_CONTROL_FRAME); | 863 set_error(SPDY_INVALID_CONTROL_FRAME); |
868 } else if ((protocol_version() <= SPDY3 && current_frame_flags_ != 0) || | 864 } else if ((protocol_version() <= SPDY3 && current_frame_flags_ != 0) || |
869 (current_frame_flags_ & ~PING_FLAG_ACK)) { | 865 (current_frame_flags_ & ~PING_FLAG_ACK)) { |
870 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 866 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
871 } | 867 } |
872 break; | 868 break; |
873 case GOAWAY: | 869 case GOAWAY: { |
874 { | 870 // For SPDY version < 4, there are only mandatory fields and the header |
875 // For SPDY version < 4, there are only mandatory fields and the header | 871 // has a fixed length. For SPDY version >= 4, optional opaque data may |
876 // has a fixed length. For SPDY version >= 4, optional opaque data may | 872 // be appended to the GOAWAY frame, thus there is only a minimal length |
877 // be appended to the GOAWAY frame, thus there is only a minimal length | 873 // restriction. |
878 // restriction. | 874 if ((current_frame_length_ != GetGoAwayMinimumSize() && |
879 if ((current_frame_length_ != GetGoAwayMinimumSize() && | 875 protocol_version() <= SPDY3) || |
880 protocol_version() <= SPDY3) || | 876 (current_frame_length_ < GetGoAwayMinimumSize() && |
881 (current_frame_length_ < GetGoAwayMinimumSize() && | 877 protocol_version() > SPDY3)) { |
882 protocol_version() > SPDY3)) { | 878 set_error(SPDY_INVALID_CONTROL_FRAME); |
883 set_error(SPDY_INVALID_CONTROL_FRAME); | 879 } else if (current_frame_flags_ != 0) { |
884 } else if (current_frame_flags_ != 0) { | 880 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
885 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | |
886 } | |
887 break; | |
888 } | |
889 case HEADERS: | |
890 { | |
891 size_t min_size = GetHeadersMinimumSize(); | |
892 if (protocol_version() > SPDY3 && | |
893 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { | |
894 min_size += 4; | |
895 } | |
896 if (current_frame_length_ < min_size) { | |
897 set_error(SPDY_INVALID_CONTROL_FRAME); | |
898 } else if (protocol_version() <= SPDY3 && | |
899 current_frame_flags_ & ~CONTROL_FLAG_FIN) { | |
900 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | |
901 } else if (protocol_version() > SPDY3 && current_frame_flags_ & | |
902 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | |
903 HEADERS_FLAG_END_HEADERS)) { | |
904 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | |
905 } | |
906 } | 881 } |
907 break; | 882 break; |
| 883 } |
| 884 case HEADERS: { |
| 885 size_t min_size = GetHeadersMinimumSize(); |
| 886 if (protocol_version() > SPDY3 && |
| 887 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { |
| 888 min_size += 4; |
| 889 } |
| 890 if (current_frame_length_ < min_size) { |
| 891 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 892 } else if (protocol_version() <= SPDY3 && |
| 893 current_frame_flags_ & ~CONTROL_FLAG_FIN) { |
| 894 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 895 } else if (protocol_version() > SPDY3 && |
| 896 current_frame_flags_ & |
| 897 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
| 898 HEADERS_FLAG_END_HEADERS)) { |
| 899 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 900 } |
| 901 } break; |
908 case WINDOW_UPDATE: | 902 case WINDOW_UPDATE: |
909 if (current_frame_length_ != GetWindowUpdateSize()) { | 903 if (current_frame_length_ != GetWindowUpdateSize()) { |
910 set_error(SPDY_INVALID_CONTROL_FRAME); | 904 set_error(SPDY_INVALID_CONTROL_FRAME); |
911 } else if (current_frame_flags_ != 0) { | 905 } else if (current_frame_flags_ != 0) { |
912 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 906 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
913 } | 907 } |
914 break; | 908 break; |
915 case BLOCKED: | 909 case BLOCKED: |
916 if (current_frame_length_ != GetBlockedSize()) { | 910 if (current_frame_length_ != GetBlockedSize()) { |
917 set_error(SPDY_INVALID_CONTROL_FRAME); | 911 set_error(SPDY_INVALID_CONTROL_FRAME); |
918 } else if (current_frame_flags_ != 0) { | 912 } else if (current_frame_flags_ != 0) { |
919 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 913 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
920 } | 914 } |
921 break; | 915 break; |
922 case PUSH_PROMISE: | 916 case PUSH_PROMISE: |
923 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 917 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
924 set_error(SPDY_INVALID_CONTROL_FRAME); | 918 set_error(SPDY_INVALID_CONTROL_FRAME); |
925 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { | 919 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { |
926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 920 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
927 } else if (protocol_version() > SPDY3 && current_frame_flags_ & | 921 } else if (protocol_version() > SPDY3 && |
928 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { | 922 current_frame_flags_ & ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { |
929 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 923 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
930 } | 924 } |
931 break; | 925 break; |
932 case CONTINUATION: | 926 case CONTINUATION: |
933 if (current_frame_length_ < GetContinuationMinimumSize() || | 927 if (current_frame_length_ < GetContinuationMinimumSize() || |
934 protocol_version() <= SPDY3) { | 928 protocol_version() <= SPDY3) { |
935 set_error(SPDY_INVALID_CONTROL_FRAME); | 929 set_error(SPDY_INVALID_CONTROL_FRAME); |
936 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { | 930 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { |
937 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 931 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
938 } | 932 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 } | 1008 } |
1015 return; | 1009 return; |
1016 } | 1010 } |
1017 | 1011 |
1018 if (frame_size_without_variable_data > 0) { | 1012 if (frame_size_without_variable_data > 0) { |
1019 // We have a control frame with a header block. We need to parse the | 1013 // We have a control frame with a header block. We need to parse the |
1020 // remainder of the control frame's header before we can parse the header | 1014 // remainder of the control frame's header before we can parse the header |
1021 // block. The start of the header block varies with the control type. | 1015 // block. The start of the header block varies with the control type. |
1022 DCHECK_GE(frame_size_without_variable_data, | 1016 DCHECK_GE(frame_size_without_variable_data, |
1023 static_cast<int32>(current_frame_buffer_length_)); | 1017 static_cast<int32>(current_frame_buffer_length_)); |
1024 remaining_control_header_ = frame_size_without_variable_data - | 1018 remaining_control_header_ = |
1025 current_frame_buffer_length_; | 1019 frame_size_without_variable_data - current_frame_buffer_length_; |
1026 | 1020 |
1027 CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK); | 1021 CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK); |
1028 return; | 1022 return; |
1029 } | 1023 } |
1030 | 1024 |
1031 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD); | 1025 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD); |
1032 } | 1026 } |
1033 | 1027 |
1034 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len, | 1028 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, |
| 1029 size_t* len, |
1035 size_t max_bytes) { | 1030 size_t max_bytes) { |
1036 size_t bytes_to_read = std::min(*len, max_bytes); | 1031 size_t bytes_to_read = std::min(*len, max_bytes); |
1037 if (bytes_to_read > 0) { | 1032 if (bytes_to_read > 0) { |
1038 DCHECK_GE(kControlFrameBufferSize, | 1033 DCHECK_GE(kControlFrameBufferSize, |
1039 current_frame_buffer_length_ + bytes_to_read); | 1034 current_frame_buffer_length_ + bytes_to_read); |
1040 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_, | 1035 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_, |
1041 *data, | 1036 *data, |
1042 bytes_to_read); | 1037 bytes_to_read); |
1043 current_frame_buffer_length_ += bytes_to_read; | 1038 current_frame_buffer_length_ += bytes_to_read; |
1044 *data += bytes_to_read; | 1039 *data += bytes_to_read; |
1045 *len -= bytes_to_read; | 1040 *len -= bytes_to_read; |
1046 } | 1041 } |
1047 return bytes_to_read; | 1042 return bytes_to_read; |
1048 } | 1043 } |
1049 | 1044 |
1050 size_t SpdyFramer::GetSerializedLength( | 1045 size_t SpdyFramer::GetSerializedLength(const SpdyMajorVersion spdy_version, |
1051 const SpdyMajorVersion spdy_version, | 1046 const SpdyHeaderBlock* headers) { |
1052 const SpdyHeaderBlock* headers) { | 1047 const size_t num_name_value_pairs_size = |
1053 const size_t num_name_value_pairs_size | 1048 (spdy_version < SPDY3) ? sizeof(uint16) : sizeof(uint32); |
1054 = (spdy_version < SPDY3) ? sizeof(uint16) : sizeof(uint32); | |
1055 const size_t length_of_name_size = num_name_value_pairs_size; | 1049 const size_t length_of_name_size = num_name_value_pairs_size; |
1056 const size_t length_of_value_size = num_name_value_pairs_size; | 1050 const size_t length_of_value_size = num_name_value_pairs_size; |
1057 | 1051 |
1058 size_t total_length = num_name_value_pairs_size; | 1052 size_t total_length = num_name_value_pairs_size; |
1059 for (SpdyHeaderBlock::const_iterator it = headers->begin(); | 1053 for (SpdyHeaderBlock::const_iterator it = headers->begin(); |
1060 it != headers->end(); | 1054 it != headers->end(); |
1061 ++it) { | 1055 ++it) { |
1062 // We add space for the length of the name and the length of the value as | 1056 // We add space for the length of the name and the length of the value as |
1063 // well as the length of the name and the length of the value. | 1057 // well as the length of the name and the length of the value. |
1064 total_length += length_of_name_size + it->first.size() + | 1058 total_length += length_of_name_size + it->first.size() + |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 | 1104 |
1111 // WriteZ writes |data| to the deflate context |out|. WriteZ will flush as | 1105 // WriteZ writes |data| to the deflate context |out|. WriteZ will flush as |
1112 // needed when switching between classes of data. | 1106 // needed when switching between classes of data. |
1113 static void WriteZ(const base::StringPiece& data, | 1107 static void WriteZ(const base::StringPiece& data, |
1114 ZDataClass clas, | 1108 ZDataClass clas, |
1115 z_stream* out) { | 1109 z_stream* out) { |
1116 int rv; | 1110 int rv; |
1117 | 1111 |
1118 // If we are switching from standard to non-standard data then we need to end | 1112 // If we are switching from standard to non-standard data then we need to end |
1119 // the current Huffman context to avoid it leaking between them. | 1113 // the current Huffman context to avoid it leaking between them. |
1120 if (out->clas == kZStandardData && | 1114 if (out->clas == kZStandardData && clas != kZStandardData) { |
1121 clas != kZStandardData) { | |
1122 out->avail_in = 0; | 1115 out->avail_in = 0; |
1123 rv = deflate(out, Z_PARTIAL_FLUSH); | 1116 rv = deflate(out, Z_PARTIAL_FLUSH); |
1124 DCHECK_EQ(Z_OK, rv); | 1117 DCHECK_EQ(Z_OK, rv); |
1125 DCHECK_EQ(0u, out->avail_in); | 1118 DCHECK_EQ(0u, out->avail_in); |
1126 DCHECK_LT(0u, out->avail_out); | 1119 DCHECK_LT(0u, out->avail_out); |
1127 } | 1120 } |
1128 | 1121 |
1129 out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data())); | 1122 out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data())); |
1130 out->avail_in = data.size(); | 1123 out->avail_in = data.size(); |
1131 out->clas = clas; | 1124 out->clas = clas; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 cookie = cookie_values[i].as_string(); | 1210 cookie = cookie_values[i].as_string(); |
1218 } else if (i == 0) { | 1211 } else if (i == 0) { |
1219 cookie = cookie_values[i].as_string() + ";"; | 1212 cookie = cookie_values[i].as_string() + ";"; |
1220 } else if (i < cookie_values.size() - 1) { | 1213 } else if (i < cookie_values.size() - 1) { |
1221 cookie = " " + cookie_values[i].as_string() + ";"; | 1214 cookie = " " + cookie_values[i].as_string() + ";"; |
1222 } else { | 1215 } else { |
1223 cookie = " " + cookie_values[i].as_string(); | 1216 cookie = " " + cookie_values[i].as_string(); |
1224 } | 1217 } |
1225 WriteZ(cookie, kZCookieData, z); | 1218 WriteZ(cookie, kZCookieData, z); |
1226 } | 1219 } |
1227 } else if (it->first == "accept" || | 1220 } else if (it->first == "accept" || it->first == "accept-charset" || |
1228 it->first == "accept-charset" || | |
1229 it->first == "accept-encoding" || | 1221 it->first == "accept-encoding" || |
1230 it->first == "accept-language" || | 1222 it->first == "accept-language" || it->first == "host" || |
1231 it->first == "host" || | 1223 it->first == "version" || it->first == "method" || |
1232 it->first == "version" || | 1224 it->first == "scheme" || it->first == ":host" || |
1233 it->first == "method" || | 1225 it->first == ":version" || it->first == ":method" || |
1234 it->first == "scheme" || | 1226 it->first == ":scheme" || it->first == "user-agent") { |
1235 it->first == ":host" || | |
1236 it->first == ":version" || | |
1237 it->first == ":method" || | |
1238 it->first == ":scheme" || | |
1239 it->first == "user-agent") { | |
1240 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); | 1227 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); |
1241 WriteZ(it->second, kZStandardData, z); | 1228 WriteZ(it->second, kZStandardData, z); |
1242 } else { | 1229 } else { |
1243 // Non-whitelisted headers are Huffman compressed in their own block, but | 1230 // Non-whitelisted headers are Huffman compressed in their own block, but |
1244 // don't match against the window. | 1231 // don't match against the window. |
1245 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); | 1232 WriteLengthZ(it->second.size(), length_length, kZStandardData, z); |
1246 WriteZ(it->second, kZHuffmanOnlyData, z); | 1233 WriteZ(it->second, kZHuffmanOnlyData, z); |
1247 } | 1234 } |
1248 } | 1235 } |
1249 | 1236 |
1250 z->avail_in = 0; | 1237 z->avail_in = 0; |
1251 int rv = deflate(z, Z_SYNC_FLUSH); | 1238 int rv = deflate(z, Z_SYNC_FLUSH); |
1252 DCHECK_EQ(Z_OK, rv); | 1239 DCHECK_EQ(Z_OK, rv); |
1253 z->clas = kZStandardData; | 1240 z->clas = kZStandardData; |
1254 } | 1241 } |
1255 #endif // !defined(USE_SYSTEM_ZLIB) | 1242 #endif // !defined(USE_SYSTEM_ZLIB) |
1256 | 1243 |
1257 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data, | 1244 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data, |
1258 size_t len) { | 1245 size_t len) { |
1259 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_); | 1246 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_); |
1260 const size_t original_len = len; | 1247 const size_t original_len = len; |
1261 | 1248 |
1262 if (remaining_control_header_ > 0) { | 1249 if (remaining_control_header_ > 0) { |
1263 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, | 1250 size_t bytes_read = |
1264 remaining_control_header_); | 1251 UpdateCurrentFrameBuffer(&data, &len, remaining_control_header_); |
1265 remaining_control_header_ -= bytes_read; | 1252 remaining_control_header_ -= bytes_read; |
1266 remaining_data_length_ -= bytes_read; | 1253 remaining_data_length_ -= bytes_read; |
1267 } | 1254 } |
1268 | 1255 |
1269 if (remaining_control_header_ == 0) { | 1256 if (remaining_control_header_ == 0) { |
1270 SpdyFrameReader reader(current_frame_buffer_.get(), | 1257 SpdyFrameReader reader(current_frame_buffer_.get(), |
1271 current_frame_buffer_length_); | 1258 current_frame_buffer_length_); |
1272 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. | 1259 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. |
1273 | 1260 |
1274 switch (current_frame_type_) { | 1261 switch (current_frame_type_) { |
1275 case SYN_STREAM: | 1262 case SYN_STREAM: { |
1276 { | 1263 DCHECK_GE(SPDY3, protocol_version()); |
1277 DCHECK_GE(SPDY3, protocol_version()); | 1264 bool successful_read = true; |
1278 bool successful_read = true; | 1265 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
1279 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1266 DCHECK(successful_read); |
1280 DCHECK(successful_read); | 1267 if (current_frame_stream_id_ == 0) { |
1281 if (current_frame_stream_id_ == 0) { | 1268 set_error(SPDY_INVALID_CONTROL_FRAME); |
1282 set_error(SPDY_INVALID_CONTROL_FRAME); | 1269 break; |
1283 break; | 1270 } |
1284 } | |
1285 | 1271 |
1286 SpdyStreamId associated_to_stream_id = kInvalidStream; | 1272 SpdyStreamId associated_to_stream_id = kInvalidStream; |
1287 successful_read = reader.ReadUInt31(&associated_to_stream_id); | 1273 successful_read = reader.ReadUInt31(&associated_to_stream_id); |
1288 DCHECK(successful_read); | 1274 DCHECK(successful_read); |
1289 | 1275 |
1290 SpdyPriority priority = 0; | 1276 SpdyPriority priority = 0; |
1291 successful_read = reader.ReadUInt8(&priority); | 1277 successful_read = reader.ReadUInt8(&priority); |
1292 DCHECK(successful_read); | 1278 DCHECK(successful_read); |
1293 if (protocol_version() <= SPDY2) { | 1279 if (protocol_version() <= SPDY2) { |
1294 priority = priority >> 6; | 1280 priority = priority >> 6; |
1295 } else { | 1281 } else { |
1296 priority = priority >> 5; | 1282 priority = priority >> 5; |
1297 } | 1283 } |
1298 | 1284 |
1299 // Seek past unused byte; used to be credential slot in SPDY 3. | 1285 // Seek past unused byte; used to be credential slot in SPDY 3. |
1300 reader.Seek(1); | 1286 reader.Seek(1); |
1301 | 1287 |
1302 DCHECK(reader.IsDoneReading()); | 1288 DCHECK(reader.IsDoneReading()); |
1303 if (debug_visitor_) { | 1289 if (debug_visitor_) { |
1304 debug_visitor_->OnReceiveCompressedFrame( | 1290 debug_visitor_->OnReceiveCompressedFrame(current_frame_stream_id_, |
1305 current_frame_stream_id_, | 1291 current_frame_type_, |
1306 current_frame_type_, | 1292 current_frame_length_); |
1307 current_frame_length_); | |
1308 } | |
1309 visitor_->OnSynStream( | |
1310 current_frame_stream_id_, | |
1311 associated_to_stream_id, | |
1312 priority, | |
1313 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, | |
1314 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); | |
1315 } | 1293 } |
| 1294 visitor_->OnSynStream( |
| 1295 current_frame_stream_id_, |
| 1296 associated_to_stream_id, |
| 1297 priority, |
| 1298 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, |
| 1299 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); |
| 1300 } |
1316 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1301 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
1317 break; | 1302 break; |
1318 case SETTINGS: | 1303 case SETTINGS: |
1319 if (protocol_version() > SPDY3 && | 1304 if (protocol_version() > SPDY3 && |
1320 current_frame_flags_ & SETTINGS_FLAG_ACK) { | 1305 current_frame_flags_ & SETTINGS_FLAG_ACK) { |
1321 visitor_->OnSettingsAck(); | 1306 visitor_->OnSettingsAck(); |
1322 CHANGE_STATE(SPDY_AUTO_RESET); | 1307 CHANGE_STATE(SPDY_AUTO_RESET); |
1323 } else { | 1308 } else { |
1324 visitor_->OnSettings(current_frame_flags_ & | 1309 visitor_->OnSettings( |
| 1310 current_frame_flags_ & |
1325 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); | 1311 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); |
1326 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); | 1312 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); |
1327 } | 1313 } |
1328 break; | 1314 break; |
1329 case SYN_REPLY: | 1315 case SYN_REPLY: |
1330 case HEADERS: | 1316 case HEADERS: |
1331 // SYN_REPLY and HEADERS are the same, save for the visitor call. | 1317 // SYN_REPLY and HEADERS are the same, save for the visitor call. |
1332 { | 1318 { |
1333 if (protocol_version() > SPDY3) { | 1319 if (protocol_version() > SPDY3) { |
1334 DCHECK_EQ(HEADERS, current_frame_type_); | 1320 DCHECK_EQ(HEADERS, current_frame_type_); |
1335 } | 1321 } |
1336 bool successful_read = true; | 1322 bool successful_read = true; |
1337 if (protocol_version() <= SPDY3) { | 1323 if (protocol_version() <= SPDY3) { |
1338 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | 1324 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
1339 DCHECK(successful_read); | 1325 DCHECK(successful_read); |
1340 } | 1326 } |
1341 if (current_frame_stream_id_ == 0) { | 1327 if (current_frame_stream_id_ == 0) { |
1342 set_error(SPDY_INVALID_CONTROL_FRAME); | 1328 set_error(SPDY_INVALID_CONTROL_FRAME); |
1343 break; | 1329 break; |
1344 } | 1330 } |
1345 if (protocol_version() <= SPDY2) { | 1331 if (protocol_version() <= SPDY2) { |
1346 // SPDY 2 had two unused bytes here. Seek past them. | 1332 // SPDY 2 had two unused bytes here. Seek past them. |
1347 reader.Seek(2); | 1333 reader.Seek(2); |
1348 } | 1334 } |
1349 if (protocol_version() > SPDY3 && | 1335 if (protocol_version() > SPDY3 && |
1350 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && | 1336 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && |
1351 current_frame_type_ == HEADERS) { | 1337 current_frame_type_ == HEADERS) { |
1352 expect_continuation_ = current_frame_stream_id_; | 1338 expect_continuation_ = current_frame_stream_id_; |
1353 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; | 1339 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; |
1354 } | 1340 } |
1355 const bool has_priority = | 1341 const bool has_priority = |
1356 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; | 1342 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; |
1357 uint32 priority = 0; | 1343 uint32 priority = 0; |
1358 if (protocol_version() > SPDY3 && has_priority) { | 1344 if (protocol_version() > SPDY3 && has_priority) { |
1359 successful_read = reader.ReadUInt31(&priority); | 1345 successful_read = reader.ReadUInt31(&priority); |
1360 DCHECK(successful_read); | 1346 DCHECK(successful_read); |
1361 } | 1347 } |
1362 DCHECK(reader.IsDoneReading()); | 1348 DCHECK(reader.IsDoneReading()); |
1363 if (debug_visitor_) { | 1349 if (debug_visitor_) { |
1364 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM. | 1350 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM. |
1365 SpdyFrameType reported_type = current_frame_type_; | 1351 SpdyFrameType reported_type = current_frame_type_; |
1366 if (protocol_version() > SPDY3 && has_priority) { | 1352 if (protocol_version() > SPDY3 && has_priority) { |
1367 reported_type = SYN_STREAM; | 1353 reported_type = SYN_STREAM; |
1368 } | 1354 } |
1369 debug_visitor_->OnReceiveCompressedFrame( | 1355 debug_visitor_->OnReceiveCompressedFrame( |
1370 current_frame_stream_id_, | 1356 current_frame_stream_id_, reported_type, current_frame_length_); |
1371 reported_type, | |
1372 current_frame_length_); | |
1373 } | 1357 } |
1374 if (current_frame_type_ == SYN_REPLY) { | 1358 if (current_frame_type_ == SYN_REPLY) { |
1375 visitor_->OnSynReply( | 1359 visitor_->OnSynReply( |
1376 current_frame_stream_id_, | 1360 current_frame_stream_id_, |
1377 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); | 1361 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); |
1378 } else if (protocol_version() > SPDY3 && | 1362 } else if (protocol_version() > SPDY3 && |
1379 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { | 1363 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { |
1380 // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes | 1364 // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes |
1381 // can be made independent of wire changes. | 1365 // can be made independent of wire changes. |
1382 visitor_->OnSynStream( | 1366 visitor_->OnSynStream(current_frame_stream_id_, |
1383 current_frame_stream_id_, | 1367 0, // associated_to_stream_id |
1384 0, // associated_to_stream_id | 1368 priority, |
1385 priority, | 1369 current_frame_flags_ & CONTROL_FLAG_FIN, |
1386 current_frame_flags_ & CONTROL_FLAG_FIN, | 1370 false); // unidirectional |
1387 false); // unidirectional | |
1388 } else { | 1371 } else { |
1389 visitor_->OnHeaders( | 1372 visitor_->OnHeaders(current_frame_stream_id_, |
1390 current_frame_stream_id_, | 1373 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, |
1391 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, | 1374 expect_continuation_ == 0); |
1392 expect_continuation_ == 0); | |
1393 } | 1375 } |
1394 } | 1376 } |
1395 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1377 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
1396 break; | 1378 break; |
1397 case PUSH_PROMISE: | 1379 case PUSH_PROMISE: { |
1398 { | 1380 DCHECK_LT(SPDY3, protocol_version()); |
1399 DCHECK_LT(SPDY3, protocol_version()); | 1381 if (current_frame_stream_id_ == 0) { |
1400 if (current_frame_stream_id_ == 0) { | 1382 set_error(SPDY_INVALID_CONTROL_FRAME); |
1401 set_error(SPDY_INVALID_CONTROL_FRAME); | 1383 break; |
1402 break; | |
1403 } | |
1404 SpdyStreamId promised_stream_id = kInvalidStream; | |
1405 bool successful_read = reader.ReadUInt31(&promised_stream_id); | |
1406 DCHECK(successful_read); | |
1407 DCHECK(reader.IsDoneReading()); | |
1408 if (promised_stream_id == 0) { | |
1409 set_error(SPDY_INVALID_CONTROL_FRAME); | |
1410 break; | |
1411 } | |
1412 if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) { | |
1413 expect_continuation_ = current_frame_stream_id_; | |
1414 } | |
1415 if (debug_visitor_) { | |
1416 debug_visitor_->OnReceiveCompressedFrame( | |
1417 current_frame_stream_id_, | |
1418 current_frame_type_, | |
1419 current_frame_length_); | |
1420 } | |
1421 visitor_->OnPushPromise(current_frame_stream_id_, | |
1422 promised_stream_id, | |
1423 (current_frame_flags_ & | |
1424 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0); | |
1425 } | 1384 } |
| 1385 SpdyStreamId promised_stream_id = kInvalidStream; |
| 1386 bool successful_read = reader.ReadUInt31(&promised_stream_id); |
| 1387 DCHECK(successful_read); |
| 1388 DCHECK(reader.IsDoneReading()); |
| 1389 if (promised_stream_id == 0) { |
| 1390 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1391 break; |
| 1392 } |
| 1393 if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) { |
| 1394 expect_continuation_ = current_frame_stream_id_; |
| 1395 } |
| 1396 if (debug_visitor_) { |
| 1397 debug_visitor_->OnReceiveCompressedFrame(current_frame_stream_id_, |
| 1398 current_frame_type_, |
| 1399 current_frame_length_); |
| 1400 } |
| 1401 visitor_->OnPushPromise( |
| 1402 current_frame_stream_id_, |
| 1403 promised_stream_id, |
| 1404 (current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0); |
| 1405 } |
1426 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1406 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
1427 break; | 1407 break; |
1428 case CONTINUATION: | 1408 case CONTINUATION: { |
1429 { | 1409 // Check to make sure the stream id of the current frame is |
1430 // Check to make sure the stream id of the current frame is | 1410 // the same as that of the preceding frame. |
1431 // the same as that of the preceding frame. | 1411 // If we're at this point we should already know that |
1432 // If we're at this point we should already know that | 1412 // expect_continuation_ != 0, so this doubles as a check |
1433 // expect_continuation_ != 0, so this doubles as a check | 1413 // that current_frame_stream_id != 0. |
1434 // that current_frame_stream_id != 0. | 1414 if (current_frame_stream_id_ != expect_continuation_) { |
1435 if (current_frame_stream_id_ != expect_continuation_) { | 1415 set_error(SPDY_INVALID_CONTROL_FRAME); |
1436 set_error(SPDY_INVALID_CONTROL_FRAME); | 1416 break; |
1437 break; | |
1438 } | |
1439 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) { | |
1440 expect_continuation_ = 0; | |
1441 } | |
1442 if (debug_visitor_) { | |
1443 debug_visitor_->OnReceiveCompressedFrame( | |
1444 current_frame_stream_id_, | |
1445 current_frame_type_, | |
1446 current_frame_length_); | |
1447 } | |
1448 visitor_->OnContinuation(current_frame_stream_id_, | |
1449 (current_frame_flags_ & | |
1450 HEADERS_FLAG_END_HEADERS) != 0); | |
1451 } | 1417 } |
| 1418 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) { |
| 1419 expect_continuation_ = 0; |
| 1420 } |
| 1421 if (debug_visitor_) { |
| 1422 debug_visitor_->OnReceiveCompressedFrame(current_frame_stream_id_, |
| 1423 current_frame_type_, |
| 1424 current_frame_length_); |
| 1425 } |
| 1426 visitor_->OnContinuation( |
| 1427 current_frame_stream_id_, |
| 1428 (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) != 0); |
| 1429 } |
1452 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1430 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
1453 break; | 1431 break; |
1454 default: | 1432 default: |
1455 DCHECK(false); | 1433 DCHECK(false); |
1456 } | 1434 } |
1457 } | 1435 } |
1458 return original_len - len; | 1436 return original_len - len; |
1459 } | 1437 } |
1460 | 1438 |
1461 // Does not buffer the control payload. Instead, either passes directly to the | 1439 // Does not buffer the control payload. Instead, either passes directly to the |
1462 // visitor or decompresses and then passes directly to the visitor, via | 1440 // visitor or decompresses and then passes directly to the visitor, via |
1463 // IncrementallyDeliverControlFrameHeaderData() or | 1441 // IncrementallyDeliverControlFrameHeaderData() or |
1464 // IncrementallyDecompressControlFrameHeaderData() respectively. | 1442 // IncrementallyDecompressControlFrameHeaderData() respectively. |
1465 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, | 1443 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, |
1466 size_t data_len, | 1444 size_t data_len, |
1467 bool is_hpack_header_block) { | 1445 bool is_hpack_header_block) { |
1468 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); | 1446 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); |
1469 | 1447 |
1470 bool processed_successfully = true; | 1448 bool processed_successfully = true; |
1471 if (current_frame_type_ != SYN_STREAM && | 1449 if (current_frame_type_ != SYN_STREAM && current_frame_type_ != SYN_REPLY && |
1472 current_frame_type_ != SYN_REPLY && | 1450 current_frame_type_ != HEADERS && current_frame_type_ != PUSH_PROMISE && |
1473 current_frame_type_ != HEADERS && | |
1474 current_frame_type_ != PUSH_PROMISE && | |
1475 current_frame_type_ != CONTINUATION) { | 1451 current_frame_type_ != CONTINUATION) { |
1476 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; | 1452 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; |
1477 } | 1453 } |
1478 size_t process_bytes = std::min(data_len, remaining_data_length_); | 1454 size_t process_bytes = std::min(data_len, remaining_data_length_); |
1479 if (is_hpack_header_block) { | 1455 if (is_hpack_header_block) { |
1480 if (!hpack_decoder_.HandleControlFrameHeadersData(current_frame_stream_id_, | 1456 if (!hpack_decoder_.HandleControlFrameHeadersData( |
1481 data, | 1457 current_frame_stream_id_, data, process_bytes)) { |
1482 process_bytes)) { | |
1483 // TODO(jgraettinger): Finer-grained HPACK error codes. | 1458 // TODO(jgraettinger): Finer-grained HPACK error codes. |
1484 set_error(SPDY_DECOMPRESS_FAILURE); | 1459 set_error(SPDY_DECOMPRESS_FAILURE); |
1485 processed_successfully = false; | 1460 processed_successfully = false; |
1486 } | 1461 } |
1487 } else if (process_bytes > 0) { | 1462 } else if (process_bytes > 0) { |
1488 if (enable_compression_ && protocol_version() <= SPDY3) { | 1463 if (enable_compression_ && protocol_version() <= SPDY3) { |
1489 processed_successfully = IncrementallyDecompressControlFrameHeaderData( | 1464 processed_successfully = IncrementallyDecompressControlFrameHeaderData( |
1490 current_frame_stream_id_, data, process_bytes); | 1465 current_frame_stream_id_, data, process_bytes); |
1491 } else { | 1466 } else { |
1492 processed_successfully = IncrementallyDeliverControlFrameHeaderData( | 1467 processed_successfully = IncrementallyDeliverControlFrameHeaderData( |
1493 current_frame_stream_id_, data, process_bytes); | 1468 current_frame_stream_id_, data, process_bytes); |
1494 } | 1469 } |
1495 } | 1470 } |
1496 remaining_data_length_ -= process_bytes; | 1471 remaining_data_length_ -= process_bytes; |
1497 | 1472 |
1498 // Handle the case that there is no futher data in this frame. | 1473 // Handle the case that there is no futher data in this frame. |
1499 if (remaining_data_length_ == 0 && processed_successfully) { | 1474 if (remaining_data_length_ == 0 && processed_successfully) { |
1500 if (expect_continuation_ == 0) { | 1475 if (expect_continuation_ == 0) { |
1501 if (is_hpack_header_block) { | 1476 if (is_hpack_header_block) { |
1502 if (!hpack_decoder_.HandleControlFrameHeadersComplete( | 1477 if (!hpack_decoder_.HandleControlFrameHeadersComplete( |
1503 current_frame_stream_id_)) { | 1478 current_frame_stream_id_)) { |
1504 set_error(SPDY_DECOMPRESS_FAILURE); | 1479 set_error(SPDY_DECOMPRESS_FAILURE); |
1505 processed_successfully = false; | 1480 processed_successfully = false; |
1506 } else { | 1481 } else { |
1507 // TODO(jgraettinger): To be removed with migration to | 1482 // TODO(jgraettinger): To be removed with migration to |
1508 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3 | 1483 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3 |
1509 // block, delivered via reentrant call to | 1484 // block, delivered via reentrant call to |
1510 // ProcessControlFrameHeaderBlock(). | 1485 // ProcessControlFrameHeaderBlock(). |
1511 DeliverHpackBlockAsSpdy3Block(); | 1486 DeliverHpackBlockAsSpdy3Block(); |
1512 return process_bytes; | 1487 return process_bytes; |
1513 } | 1488 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { | 1569 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { |
1595 DCHECK_LT(SPDY3, protocol_version()); | 1570 DCHECK_LT(SPDY3, protocol_version()); |
1596 DCHECK_EQ(0u, remaining_data_length_); | 1571 DCHECK_EQ(0u, remaining_data_length_); |
1597 | 1572 |
1598 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block(); | 1573 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block(); |
1599 if (block.empty()) { | 1574 if (block.empty()) { |
1600 // Special-case this to make tests happy. | 1575 // Special-case this to make tests happy. |
1601 ProcessControlFrameHeaderBlock(NULL, 0, false); | 1576 ProcessControlFrameHeaderBlock(NULL, 0, false); |
1602 return; | 1577 return; |
1603 } | 1578 } |
1604 SpdyFrameBuilder builder( | 1579 SpdyFrameBuilder builder(GetSerializedLength(protocol_version(), &block), |
1605 GetSerializedLength(protocol_version(), &block), | 1580 SPDY3); |
1606 SPDY3); | |
1607 | 1581 |
1608 SerializeNameValueBlockWithoutCompression(&builder, block); | 1582 SerializeNameValueBlockWithoutCompression(&builder, block); |
1609 scoped_ptr<SpdyFrame> frame(builder.take()); | 1583 scoped_ptr<SpdyFrame> frame(builder.take()); |
1610 | 1584 |
1611 remaining_data_length_ = frame->size(); | 1585 remaining_data_length_ = frame->size(); |
1612 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); | 1586 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); |
1613 } | 1587 } |
1614 | 1588 |
1615 bool SpdyFramer::ProcessSetting(const char* data) { | 1589 bool SpdyFramer::ProcessSetting(const char* data) { |
1616 int id_field; | 1590 int id_field; |
1617 SpdySettingsIds id; | 1591 SpdySettingsIds id; |
1618 uint8 flags = 0; | 1592 uint8 flags = 0; |
1619 uint32 value; | 1593 uint32 value; |
1620 | 1594 |
1621 // Extract fields. | 1595 // Extract fields. |
1622 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. | 1596 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. |
1623 if (protocol_version() <= SPDY3) { | 1597 if (protocol_version() <= SPDY3) { |
1624 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); | 1598 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); |
1625 SettingsFlagsAndId id_and_flags = | 1599 SettingsFlagsAndId id_and_flags = SettingsFlagsAndId::FromWireFormat( |
1626 SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire); | 1600 protocol_version(), id_and_flags_wire); |
1627 id_field = id_and_flags.id(); | 1601 id_field = id_and_flags.id(); |
1628 flags = id_and_flags.flags(); | 1602 flags = id_and_flags.flags(); |
1629 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); | 1603 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); |
1630 } else { | 1604 } else { |
1631 id_field = *(reinterpret_cast<const uint8*>(data)); | 1605 id_field = *(reinterpret_cast<const uint8*>(data)); |
1632 value = ntohl(*(reinterpret_cast<const uint32*>(data + 1))); | 1606 value = ntohl(*(reinterpret_cast<const uint32*>(data + 1))); |
1633 } | 1607 } |
1634 | 1608 |
1635 // Validate id. | 1609 // Validate id. |
1636 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { | 1610 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { |
(...skipping 22 matching lines...) Expand all Loading... |
1659 } | 1633 } |
1660 } | 1634 } |
1661 | 1635 |
1662 // Validation succeeded. Pass on to visitor. | 1636 // Validation succeeded. Pass on to visitor. |
1663 visitor_->OnSetting(id, flags, value); | 1637 visitor_->OnSetting(id, flags, value); |
1664 return true; | 1638 return true; |
1665 } | 1639 } |
1666 | 1640 |
1667 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { | 1641 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { |
1668 size_t original_len = len; | 1642 size_t original_len = len; |
1669 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, | 1643 size_t bytes_read = |
1670 remaining_data_length_); | 1644 UpdateCurrentFrameBuffer(&data, &len, remaining_data_length_); |
1671 remaining_data_length_ -= bytes_read; | 1645 remaining_data_length_ -= bytes_read; |
1672 if (remaining_data_length_ == 0) { | 1646 if (remaining_data_length_ == 0) { |
1673 SpdyFrameReader reader(current_frame_buffer_.get(), | 1647 SpdyFrameReader reader(current_frame_buffer_.get(), |
1674 current_frame_buffer_length_); | 1648 current_frame_buffer_length_); |
1675 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header. | 1649 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header. |
1676 | 1650 |
1677 // Use frame-specific handlers. | 1651 // Use frame-specific handlers. |
1678 switch (current_frame_type_) { | 1652 switch (current_frame_type_) { |
1679 case PING: { | 1653 case PING: { |
1680 SpdyPingId id = 0; | 1654 SpdyPingId id = 0; |
1681 bool is_ack = protocol_version() > SPDY3 && | 1655 bool is_ack = protocol_version() > SPDY3 && |
1682 (current_frame_flags_ & PING_FLAG_ACK); | 1656 (current_frame_flags_ & PING_FLAG_ACK); |
1683 bool successful_read = true; | 1657 bool successful_read = true; |
1684 if (protocol_version() <= SPDY3) { | 1658 if (protocol_version() <= SPDY3) { |
1685 uint32 id32 = 0; | 1659 uint32 id32 = 0; |
1686 successful_read = reader.ReadUInt32(&id32); | 1660 successful_read = reader.ReadUInt32(&id32); |
1687 id = id32; | 1661 id = id32; |
1688 } else { | 1662 } else { |
1689 successful_read = reader.ReadUInt64(&id); | 1663 successful_read = reader.ReadUInt64(&id); |
1690 } | 1664 } |
| 1665 DCHECK(successful_read); |
| 1666 DCHECK(reader.IsDoneReading()); |
| 1667 visitor_->OnPing(id, is_ack); |
| 1668 } break; |
| 1669 case WINDOW_UPDATE: { |
| 1670 uint32 delta_window_size = 0; |
| 1671 bool successful_read = true; |
| 1672 if (protocol_version() <= SPDY3) { |
| 1673 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
1691 DCHECK(successful_read); | 1674 DCHECK(successful_read); |
1692 DCHECK(reader.IsDoneReading()); | |
1693 visitor_->OnPing(id, is_ack); | |
1694 } | 1675 } |
1695 break; | 1676 successful_read = reader.ReadUInt32(&delta_window_size); |
1696 case WINDOW_UPDATE: { | 1677 DCHECK(successful_read); |
1697 uint32 delta_window_size = 0; | 1678 DCHECK(reader.IsDoneReading()); |
1698 bool successful_read = true; | 1679 visitor_->OnWindowUpdate(current_frame_stream_id_, delta_window_size); |
1699 if (protocol_version() <= SPDY3) { | 1680 } break; |
1700 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | |
1701 DCHECK(successful_read); | |
1702 } | |
1703 successful_read = reader.ReadUInt32(&delta_window_size); | |
1704 DCHECK(successful_read); | |
1705 DCHECK(reader.IsDoneReading()); | |
1706 visitor_->OnWindowUpdate(current_frame_stream_id_, | |
1707 delta_window_size); | |
1708 } | |
1709 break; | |
1710 case BLOCKED: { | 1681 case BLOCKED: { |
1711 DCHECK_LT(SPDY3, protocol_version()); | 1682 DCHECK_LT(SPDY3, protocol_version()); |
1712 DCHECK(reader.IsDoneReading()); | 1683 DCHECK(reader.IsDoneReading()); |
1713 visitor_->OnBlocked(current_frame_stream_id_); | 1684 visitor_->OnBlocked(current_frame_stream_id_); |
1714 } | 1685 } break; |
1715 break; | |
1716 default: | 1686 default: |
1717 // Unreachable. | 1687 // Unreachable. |
1718 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; | 1688 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; |
1719 } | 1689 } |
1720 | 1690 |
1721 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 1691 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
1722 } | 1692 } |
1723 return original_len - len; | 1693 return original_len - len; |
1724 } | 1694 } |
1725 | 1695 |
(...skipping 25 matching lines...) Expand all Loading... |
1751 DCHECK(successful_read); | 1721 DCHECK(successful_read); |
1752 | 1722 |
1753 // In SPDYv3 and up, frames also specify a status code - parse it out. | 1723 // In SPDYv3 and up, frames also specify a status code - parse it out. |
1754 SpdyGoAwayStatus status = GOAWAY_OK; | 1724 SpdyGoAwayStatus status = GOAWAY_OK; |
1755 if (protocol_version() >= SPDY3) { | 1725 if (protocol_version() >= SPDY3) { |
1756 uint32 status_raw = GOAWAY_OK; | 1726 uint32 status_raw = GOAWAY_OK; |
1757 successful_read = reader.ReadUInt32(&status_raw); | 1727 successful_read = reader.ReadUInt32(&status_raw); |
1758 DCHECK(successful_read); | 1728 DCHECK(successful_read); |
1759 if (SpdyConstants::IsValidGoAwayStatus(protocol_version(), | 1729 if (SpdyConstants::IsValidGoAwayStatus(protocol_version(), |
1760 status_raw)) { | 1730 status_raw)) { |
1761 status = SpdyConstants::ParseGoAwayStatus(protocol_version(), | 1731 status = |
1762 status_raw); | 1732 SpdyConstants::ParseGoAwayStatus(protocol_version(), status_raw); |
1763 } else { | 1733 } else { |
1764 DCHECK(false); | 1734 DCHECK(false); |
1765 // Throw an error for SPDY4+, keep liberal behavior | 1735 // Throw an error for SPDY4+, keep liberal behavior |
1766 // for earlier versions. | 1736 // for earlier versions. |
1767 if (protocol_version() > SPDY3) { | 1737 if (protocol_version() > SPDY3) { |
1768 DLOG(WARNING) << "Invalid GO_AWAY status " << status_raw; | 1738 DLOG(WARNING) << "Invalid GO_AWAY status " << status_raw; |
1769 set_error(SPDY_INVALID_CONTROL_FRAME); | 1739 set_error(SPDY_INVALID_CONTROL_FRAME); |
1770 return 0; | 1740 return 0; |
1771 } | 1741 } |
1772 } | 1742 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 remaining_data_length_ -= amount_to_ignore; | 1937 remaining_data_length_ -= amount_to_ignore; |
1968 } | 1938 } |
1969 | 1939 |
1970 if (remaining_data_length_ == 0) { | 1940 if (remaining_data_length_ == 0) { |
1971 CHANGE_STATE(SPDY_AUTO_RESET); | 1941 CHANGE_STATE(SPDY_AUTO_RESET); |
1972 } | 1942 } |
1973 return original_len - len; | 1943 return original_len - len; |
1974 } | 1944 } |
1975 | 1945 |
1976 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, | 1946 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, |
1977 size_t header_length, | 1947 size_t header_length, |
1978 SpdyHeaderBlock* block) const { | 1948 SpdyHeaderBlock* block) const { |
1979 SpdyFrameReader reader(header_data, header_length); | 1949 SpdyFrameReader reader(header_data, header_length); |
1980 | 1950 |
1981 // Read number of headers. | 1951 // Read number of headers. |
1982 uint32 num_headers; | 1952 uint32 num_headers; |
1983 if (protocol_version() <= SPDY2) { | 1953 if (protocol_version() <= SPDY2) { |
1984 uint16 temp; | 1954 uint16 temp; |
1985 if (!reader.ReadUInt16(&temp)) { | 1955 if (!reader.ReadUInt16(&temp)) { |
1986 DVLOG(1) << "Unable to read number of headers."; | 1956 DVLOG(1) << "Unable to read number of headers."; |
1987 return 0; | 1957 return 0; |
1988 } | 1958 } |
1989 num_headers = temp; | 1959 num_headers = temp; |
1990 } else { | 1960 } else { |
1991 if (!reader.ReadUInt32(&num_headers)) { | 1961 if (!reader.ReadUInt32(&num_headers)) { |
1992 DVLOG(1) << "Unable to read number of headers."; | 1962 DVLOG(1) << "Unable to read number of headers."; |
1993 return 0; | 1963 return 0; |
1994 } | 1964 } |
1995 } | 1965 } |
1996 | 1966 |
1997 // Read each header. | 1967 // Read each header. |
1998 for (uint32 index = 0; index < num_headers; ++index) { | 1968 for (uint32 index = 0; index < num_headers; ++index) { |
1999 base::StringPiece temp; | 1969 base::StringPiece temp; |
2000 | 1970 |
2001 // Read header name. | 1971 // Read header name. |
2002 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp) | 1972 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp) |
2003 : !reader.ReadStringPiece32(&temp)) { | 1973 : !reader.ReadStringPiece32(&temp)) { |
2004 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " | 1974 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " |
2005 << num_headers << ")."; | 1975 << num_headers << ")."; |
2006 return 0; | 1976 return 0; |
2007 } | 1977 } |
2008 std::string name = temp.as_string(); | 1978 std::string name = temp.as_string(); |
2009 | 1979 |
2010 // Read header value. | 1980 // Read header value. |
2011 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp) | 1981 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp) |
2012 : !reader.ReadStringPiece32(&temp)) { | 1982 : !reader.ReadStringPiece32(&temp)) { |
2013 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " | 1983 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " |
2014 << num_headers << ")."; | 1984 << num_headers << ")."; |
2015 return 0; | 1985 return 0; |
2016 } | 1986 } |
2017 std::string value = temp.as_string(); | 1987 std::string value = temp.as_string(); |
2018 | 1988 |
2019 // Ensure no duplicates. | 1989 // Ensure no duplicates. |
2020 if (block->find(name) != block->end()) { | 1990 if (block->find(name) != block->end()) { |
2021 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of " | 1991 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of " |
2022 << num_headers << ")."; | 1992 << num_headers << ")."; |
(...skipping 17 matching lines...) Expand all Loading... |
2040 int num_padding_fields = 0; | 2010 int num_padding_fields = 0; |
2041 if (data_ir.pad_low()) { | 2011 if (data_ir.pad_low()) { |
2042 flags |= DATA_FLAG_PAD_LOW; | 2012 flags |= DATA_FLAG_PAD_LOW; |
2043 ++num_padding_fields; | 2013 ++num_padding_fields; |
2044 } | 2014 } |
2045 if (data_ir.pad_high()) { | 2015 if (data_ir.pad_high()) { |
2046 flags |= DATA_FLAG_PAD_HIGH; | 2016 flags |= DATA_FLAG_PAD_HIGH; |
2047 ++num_padding_fields; | 2017 ++num_padding_fields; |
2048 } | 2018 } |
2049 | 2019 |
2050 const size_t size_with_padding = num_padding_fields + | 2020 const size_t size_with_padding = |
2051 data_ir.data().length() + data_ir.padding_payload_len() + | 2021 num_padding_fields + data_ir.data().length() + |
2052 GetDataFrameMinimumSize(); | 2022 data_ir.padding_payload_len() + GetDataFrameMinimumSize(); |
2053 SpdyFrameBuilder builder(size_with_padding, protocol_version()); | 2023 SpdyFrameBuilder builder(size_with_padding, protocol_version()); |
2054 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 2024 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); |
2055 if (data_ir.pad_high()) { | 2025 if (data_ir.pad_high()) { |
2056 builder.WriteUInt8(data_ir.padding_payload_len() >> 8); | 2026 builder.WriteUInt8(data_ir.padding_payload_len() >> 8); |
2057 } | 2027 } |
2058 if (data_ir.pad_low()) { | 2028 if (data_ir.pad_low()) { |
2059 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 2029 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
2060 } | 2030 } |
2061 builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); | 2031 builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); |
2062 if (data_ir.padding_payload_len() > 0) { | 2032 if (data_ir.padding_payload_len() > 0) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2098 | 2068 |
2099 SpdyFrameBuilder builder(frame_size, protocol_version()); | 2069 SpdyFrameBuilder builder(frame_size, protocol_version()); |
2100 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 2070 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); |
2101 if (protocol_version() > SPDY3) { | 2071 if (protocol_version() > SPDY3) { |
2102 if (data_ir.pad_high()) { | 2072 if (data_ir.pad_high()) { |
2103 builder.WriteUInt8(data_ir.padding_payload_len() >> 8); | 2073 builder.WriteUInt8(data_ir.padding_payload_len() >> 8); |
2104 } | 2074 } |
2105 if (data_ir.pad_low()) { | 2075 if (data_ir.pad_low()) { |
2106 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 2076 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
2107 } | 2077 } |
2108 builder.OverwriteLength(*this, num_padding_fields + | 2078 builder.OverwriteLength(*this, |
2109 data_ir.data().length() + data_ir.padding_payload_len()); | 2079 num_padding_fields + data_ir.data().length() + |
| 2080 data_ir.padding_payload_len()); |
2110 } else { | 2081 } else { |
2111 builder.OverwriteLength(*this, data_ir.data().length()); | 2082 builder.OverwriteLength(*this, data_ir.data().length()); |
2112 } | 2083 } |
2113 DCHECK_EQ(frame_size, builder.length()); | 2084 DCHECK_EQ(frame_size, builder.length()); |
2114 return builder.take(); | 2085 return builder.take(); |
2115 } | 2086 } |
2116 | 2087 |
2117 SpdySerializedFrame* SpdyFramer::SerializeSynStream( | 2088 SpdySerializedFrame* SpdyFramer::SerializeSynStream( |
2118 const SpdySynStreamIR& syn_stream) { | 2089 const SpdySynStreamIR& syn_stream) { |
2119 uint8 flags = 0; | 2090 uint8 flags = 0; |
(...skipping 17 matching lines...) Expand all Loading... |
2137 DLOG(DFATAL) << "Priority out-of-bounds."; | 2108 DLOG(DFATAL) << "Priority out-of-bounds."; |
2138 priority = GetLowestPriority(); | 2109 priority = GetLowestPriority(); |
2139 } | 2110 } |
2140 | 2111 |
2141 // The size of this frame, including variable-length name-value block. | 2112 // The size of this frame, including variable-length name-value block. |
2142 size_t size = GetSynStreamMinimumSize(); | 2113 size_t size = GetSynStreamMinimumSize(); |
2143 | 2114 |
2144 string hpack_encoding; | 2115 string hpack_encoding; |
2145 if (protocol_version() > SPDY3) { | 2116 if (protocol_version() > SPDY3) { |
2146 if (enable_compression_) { | 2117 if (enable_compression_) { |
2147 hpack_encoder_.EncodeHeaderSet( | 2118 hpack_encoder_.EncodeHeaderSet(syn_stream.name_value_block(), |
2148 syn_stream.name_value_block(), &hpack_encoding); | 2119 &hpack_encoding); |
2149 } else { | 2120 } else { |
2150 hpack_encoder_.EncodeHeaderSetWithoutCompression( | 2121 hpack_encoder_.EncodeHeaderSetWithoutCompression( |
2151 syn_stream.name_value_block(), &hpack_encoding); | 2122 syn_stream.name_value_block(), &hpack_encoding); |
2152 } | 2123 } |
2153 size += hpack_encoding.size(); | 2124 size += hpack_encoding.size(); |
2154 } else { | 2125 } else { |
2155 size += GetSerializedLength(syn_stream.name_value_block()); | 2126 size += GetSerializedLength(syn_stream.name_value_block()); |
2156 } | 2127 } |
2157 | 2128 |
2158 SpdyFrameBuilder builder(size, protocol_version()); | 2129 SpdyFrameBuilder builder(size, protocol_version()); |
2159 if (protocol_version() <= SPDY3) { | 2130 if (protocol_version() <= SPDY3) { |
2160 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); | 2131 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); |
2161 builder.WriteUInt32(syn_stream.stream_id()); | 2132 builder.WriteUInt32(syn_stream.stream_id()); |
2162 builder.WriteUInt32(syn_stream.associated_to_stream_id()); | 2133 builder.WriteUInt32(syn_stream.associated_to_stream_id()); |
2163 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); | 2134 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); |
2164 builder.WriteUInt8(0); // Unused byte where credential slot used to be. | 2135 builder.WriteUInt8(0); // Unused byte where credential slot used to be. |
2165 } else { | 2136 } else { |
2166 builder.BeginNewFrame(*this, | 2137 builder.BeginNewFrame(*this, HEADERS, flags, syn_stream.stream_id()); |
2167 HEADERS, | |
2168 flags, | |
2169 syn_stream.stream_id()); | |
2170 builder.WriteUInt32(priority); | 2138 builder.WriteUInt32(priority); |
2171 } | 2139 } |
2172 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); | 2140 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); |
2173 if (protocol_version() > SPDY3) { | 2141 if (protocol_version() > SPDY3) { |
2174 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | 2142 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); |
2175 } else { | 2143 } else { |
2176 SerializeNameValueBlock(&builder, syn_stream); | 2144 SerializeNameValueBlock(&builder, syn_stream); |
2177 } | 2145 } |
2178 | 2146 |
2179 if (debug_visitor_) { | 2147 if (debug_visitor_) { |
2180 const size_t payload_len = protocol_version() > SPDY3 ? | 2148 const size_t payload_len = |
2181 hpack_encoding.size() : | 2149 protocol_version() > SPDY3 |
2182 GetSerializedLength(protocol_version(), | 2150 ? hpack_encoding.size() |
2183 &(syn_stream.name_value_block())); | 2151 : GetSerializedLength(protocol_version(), |
| 2152 &(syn_stream.name_value_block())); |
2184 // SPDY 4 reports this compression as a SYN_STREAM compression. | 2153 // SPDY 4 reports this compression as a SYN_STREAM compression. |
2185 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), | 2154 debug_visitor_->OnSendCompressedFrame( |
2186 SYN_STREAM, | 2155 syn_stream.stream_id(), SYN_STREAM, payload_len, builder.length()); |
2187 payload_len, | |
2188 builder.length()); | |
2189 } | 2156 } |
2190 | 2157 |
2191 return builder.take(); | 2158 return builder.take(); |
2192 } | 2159 } |
2193 | 2160 |
2194 SpdySerializedFrame* SpdyFramer::SerializeSynReply( | 2161 SpdySerializedFrame* SpdyFramer::SerializeSynReply( |
2195 const SpdySynReplyIR& syn_reply) { | 2162 const SpdySynReplyIR& syn_reply) { |
2196 uint8 flags = 0; | 2163 uint8 flags = 0; |
2197 if (syn_reply.fin()) { | 2164 if (syn_reply.fin()) { |
2198 flags |= CONTROL_FLAG_FIN; | 2165 flags |= CONTROL_FLAG_FIN; |
2199 } | 2166 } |
2200 // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now | 2167 // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now |
2201 // we never expect to have to overflow into a CONTINUATION frame. | 2168 // we never expect to have to overflow into a CONTINUATION frame. |
2202 if (protocol_version() > SPDY3) { | 2169 if (protocol_version() > SPDY3) { |
2203 flags |= HEADERS_FLAG_END_HEADERS; | 2170 flags |= HEADERS_FLAG_END_HEADERS; |
2204 } | 2171 } |
2205 | 2172 |
2206 // The size of this frame, including variable-length name-value block. | 2173 // The size of this frame, including variable-length name-value block. |
2207 size_t size = GetSynReplyMinimumSize(); | 2174 size_t size = GetSynReplyMinimumSize(); |
2208 | 2175 |
2209 string hpack_encoding; | 2176 string hpack_encoding; |
2210 if (protocol_version() > SPDY3) { | 2177 if (protocol_version() > SPDY3) { |
2211 if (enable_compression_) { | 2178 if (enable_compression_) { |
2212 hpack_encoder_.EncodeHeaderSet( | 2179 hpack_encoder_.EncodeHeaderSet(syn_reply.name_value_block(), |
2213 syn_reply.name_value_block(), &hpack_encoding); | 2180 &hpack_encoding); |
2214 } else { | 2181 } else { |
2215 hpack_encoder_.EncodeHeaderSetWithoutCompression( | 2182 hpack_encoder_.EncodeHeaderSetWithoutCompression( |
2216 syn_reply.name_value_block(), &hpack_encoding); | 2183 syn_reply.name_value_block(), &hpack_encoding); |
2217 } | 2184 } |
2218 size += hpack_encoding.size(); | 2185 size += hpack_encoding.size(); |
2219 } else { | 2186 } else { |
2220 size += GetSerializedLength(syn_reply.name_value_block()); | 2187 size += GetSerializedLength(syn_reply.name_value_block()); |
2221 } | 2188 } |
2222 | 2189 |
2223 SpdyFrameBuilder builder(size, protocol_version()); | 2190 SpdyFrameBuilder builder(size, protocol_version()); |
2224 if (protocol_version() <= SPDY3) { | 2191 if (protocol_version() <= SPDY3) { |
2225 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); | 2192 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); |
2226 builder.WriteUInt32(syn_reply.stream_id()); | 2193 builder.WriteUInt32(syn_reply.stream_id()); |
2227 } else { | 2194 } else { |
2228 builder.BeginNewFrame(*this, | 2195 builder.BeginNewFrame(*this, HEADERS, flags, syn_reply.stream_id()); |
2229 HEADERS, | |
2230 flags, | |
2231 syn_reply.stream_id()); | |
2232 } | 2196 } |
2233 if (protocol_version() < SPDY3) { | 2197 if (protocol_version() < SPDY3) { |
2234 builder.WriteUInt16(0); // Unused. | 2198 builder.WriteUInt16(0); // Unused. |
2235 } | 2199 } |
2236 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); | 2200 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); |
2237 if (protocol_version() > SPDY3) { | 2201 if (protocol_version() > SPDY3) { |
2238 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | 2202 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); |
2239 } else { | 2203 } else { |
2240 SerializeNameValueBlock(&builder, syn_reply); | 2204 SerializeNameValueBlock(&builder, syn_reply); |
2241 } | 2205 } |
2242 | 2206 |
2243 if (debug_visitor_) { | 2207 if (debug_visitor_) { |
2244 const size_t payload_len = protocol_version() > SPDY3 ? | 2208 const size_t payload_len = |
2245 hpack_encoding.size() : | 2209 protocol_version() > SPDY3 |
2246 GetSerializedLength(protocol_version(), | 2210 ? hpack_encoding.size() |
2247 &(syn_reply.name_value_block())); | 2211 : GetSerializedLength(protocol_version(), |
2248 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), | 2212 &(syn_reply.name_value_block())); |
2249 SYN_REPLY, | 2213 debug_visitor_->OnSendCompressedFrame( |
2250 payload_len, | 2214 syn_reply.stream_id(), SYN_REPLY, payload_len, builder.length()); |
2251 builder.length()); | |
2252 } | 2215 } |
2253 | 2216 |
2254 return builder.take(); | 2217 return builder.take(); |
2255 } | 2218 } |
2256 | 2219 |
2257 SpdySerializedFrame* SpdyFramer::SerializeRstStream( | 2220 SpdySerializedFrame* SpdyFramer::SerializeRstStream( |
2258 const SpdyRstStreamIR& rst_stream) const { | 2221 const SpdyRstStreamIR& rst_stream) const { |
2259 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM | 2222 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM |
2260 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2, | 2223 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2, |
2261 // which doesn't currently include RST_STREAM payloads. GFE flags have been | 2224 // which doesn't currently include RST_STREAM payloads. GFE flags have been |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 } | 2260 } |
2298 } else { | 2261 } else { |
2299 if (settings.is_ack()) { | 2262 if (settings.is_ack()) { |
2300 flags |= SETTINGS_FLAG_ACK; | 2263 flags |= SETTINGS_FLAG_ACK; |
2301 } | 2264 } |
2302 } | 2265 } |
2303 const SpdySettingsIR::ValueMap* values = &(settings.values()); | 2266 const SpdySettingsIR::ValueMap* values = &(settings.values()); |
2304 | 2267 |
2305 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); | 2268 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); |
2306 // Size, in bytes, of this SETTINGS frame. | 2269 // Size, in bytes, of this SETTINGS frame. |
2307 const size_t size = GetSettingsMinimumSize() + | 2270 const size_t size = |
2308 (values->size() * setting_size); | 2271 GetSettingsMinimumSize() + (values->size() * setting_size); |
2309 SpdyFrameBuilder builder(size, protocol_version()); | 2272 SpdyFrameBuilder builder(size, protocol_version()); |
2310 if (protocol_version() <= SPDY3) { | 2273 if (protocol_version() <= SPDY3) { |
2311 builder.WriteControlFrameHeader(*this, SETTINGS, flags); | 2274 builder.WriteControlFrameHeader(*this, SETTINGS, flags); |
2312 } else { | 2275 } else { |
2313 builder.BeginNewFrame(*this, SETTINGS, flags, 0); | 2276 builder.BeginNewFrame(*this, SETTINGS, flags, 0); |
2314 } | 2277 } |
2315 | 2278 |
2316 // If this is an ACK, payload should be empty. | 2279 // If this is an ACK, payload should be empty. |
2317 if (protocol_version() > SPDY3 && settings.is_ack()) { | 2280 if (protocol_version() > SPDY3 && settings.is_ack()) { |
2318 return builder.take(); | 2281 return builder.take(); |
(...skipping 13 matching lines...) Expand all Loading... |
2332 } | 2295 } |
2333 if (it->second.persisted) { | 2296 if (it->second.persisted) { |
2334 setting_flags |= SETTINGS_FLAG_PERSISTED; | 2297 setting_flags |= SETTINGS_FLAG_PERSISTED; |
2335 } | 2298 } |
2336 SettingsFlagsAndId flags_and_id( | 2299 SettingsFlagsAndId flags_and_id( |
2337 setting_flags, | 2300 setting_flags, |
2338 SpdyConstants::SerializeSettingId(protocol_version(), it->first)); | 2301 SpdyConstants::SerializeSettingId(protocol_version(), it->first)); |
2339 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); | 2302 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); |
2340 builder.WriteBytes(&id_and_flags_wire, 4); | 2303 builder.WriteBytes(&id_and_flags_wire, 4); |
2341 } else { | 2304 } else { |
2342 builder.WriteUInt8(SpdyConstants::SerializeSettingId(protocol_version(), | 2305 builder.WriteUInt8( |
2343 it->first)); | 2306 SpdyConstants::SerializeSettingId(protocol_version(), it->first)); |
2344 } | 2307 } |
2345 builder.WriteUInt32(it->second.value); | 2308 builder.WriteUInt32(it->second.value); |
2346 } | 2309 } |
2347 DCHECK_EQ(size, builder.length()); | 2310 DCHECK_EQ(size, builder.length()); |
2348 return builder.take(); | 2311 return builder.take(); |
2349 } | 2312 } |
2350 | 2313 |
2351 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { | 2314 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
2352 SpdyFrameBuilder builder(GetPingSize(), protocol_version()); | 2315 SpdyFrameBuilder builder(GetPingSize(), protocol_version()); |
2353 if (protocol_version() <= SPDY3) { | 2316 if (protocol_version() <= SPDY3) { |
2354 builder.WriteControlFrameHeader(*this, PING, kNoFlags); | 2317 builder.WriteControlFrameHeader(*this, PING, kNoFlags); |
2355 builder.WriteUInt32(static_cast<uint32>(ping.id())); | 2318 builder.WriteUInt32(static_cast<uint32>(ping.id())); |
2356 } else { | 2319 } else { |
2357 uint8 flags = 0; | 2320 uint8 flags = 0; |
2358 if (ping.is_ack()) { | 2321 if (ping.is_ack()) { |
2359 flags |= PING_FLAG_ACK; | 2322 flags |= PING_FLAG_ACK; |
2360 } | 2323 } |
2361 builder.BeginNewFrame(*this, PING, flags, 0); | 2324 builder.BeginNewFrame(*this, PING, flags, 0); |
2362 builder.WriteUInt64(ping.id()); | 2325 builder.WriteUInt64(ping.id()); |
2363 } | 2326 } |
2364 DCHECK_EQ(GetPingSize(), builder.length()); | 2327 DCHECK_EQ(GetPingSize(), builder.length()); |
2365 return builder.take(); | 2328 return builder.take(); |
2366 } | 2329 } |
2367 | 2330 |
2368 SpdySerializedFrame* SpdyFramer::SerializeGoAway( | 2331 SpdySerializedFrame* SpdyFramer::SerializeGoAway( |
2369 const SpdyGoAwayIR& goaway) const { | 2332 const SpdyGoAwayIR& goaway) const { |
2370 | |
2371 // Compute the output buffer size, take opaque data into account. | 2333 // Compute the output buffer size, take opaque data into account. |
2372 uint16 expected_length = GetGoAwayMinimumSize(); | 2334 uint16 expected_length = GetGoAwayMinimumSize(); |
2373 if (protocol_version() > SPDY3) { | 2335 if (protocol_version() > SPDY3) { |
2374 expected_length += goaway.description().size(); | 2336 expected_length += goaway.description().size(); |
2375 } | 2337 } |
2376 SpdyFrameBuilder builder(expected_length, protocol_version()); | 2338 SpdyFrameBuilder builder(expected_length, protocol_version()); |
2377 | 2339 |
2378 // Serialize the GOAWAY frame. | 2340 // Serialize the GOAWAY frame. |
2379 if (protocol_version() <= SPDY3) { | 2341 if (protocol_version() <= SPDY3) { |
2380 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); | 2342 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2426 if (priority > GetLowestPriority()) { | 2388 if (priority > GetLowestPriority()) { |
2427 DLOG(DFATAL) << "Priority out-of-bounds."; | 2389 DLOG(DFATAL) << "Priority out-of-bounds."; |
2428 priority = GetLowestPriority(); | 2390 priority = GetLowestPriority(); |
2429 } | 2391 } |
2430 size += 4; | 2392 size += 4; |
2431 } | 2393 } |
2432 | 2394 |
2433 string hpack_encoding; | 2395 string hpack_encoding; |
2434 if (protocol_version() > SPDY3) { | 2396 if (protocol_version() > SPDY3) { |
2435 if (enable_compression_) { | 2397 if (enable_compression_) { |
2436 hpack_encoder_.EncodeHeaderSet( | 2398 hpack_encoder_.EncodeHeaderSet(headers.name_value_block(), |
2437 headers.name_value_block(), &hpack_encoding); | 2399 &hpack_encoding); |
2438 } else { | 2400 } else { |
2439 hpack_encoder_.EncodeHeaderSetWithoutCompression( | 2401 hpack_encoder_.EncodeHeaderSetWithoutCompression( |
2440 headers.name_value_block(), &hpack_encoding); | 2402 headers.name_value_block(), &hpack_encoding); |
2441 } | 2403 } |
2442 size += hpack_encoding.size(); | 2404 size += hpack_encoding.size(); |
2443 if (size > GetControlFrameBufferMaxSize()) { | 2405 if (size > GetControlFrameBufferMaxSize()) { |
2444 size += GetNumberRequiredContinuationFrames(size) * | 2406 size += GetNumberRequiredContinuationFrames(size) * |
2445 GetContinuationMinimumSize(); | 2407 GetContinuationMinimumSize(); |
2446 flags &= ~HEADERS_FLAG_END_HEADERS; | 2408 flags &= ~HEADERS_FLAG_END_HEADERS; |
2447 } | 2409 } |
2448 } else { | 2410 } else { |
2449 size += GetSerializedLength(headers.name_value_block()); | 2411 size += GetSerializedLength(headers.name_value_block()); |
2450 } | 2412 } |
2451 | 2413 |
2452 SpdyFrameBuilder builder(size, protocol_version()); | 2414 SpdyFrameBuilder builder(size, protocol_version()); |
2453 if (protocol_version() <= SPDY3) { | 2415 if (protocol_version() <= SPDY3) { |
2454 builder.WriteControlFrameHeader(*this, HEADERS, flags); | 2416 builder.WriteControlFrameHeader(*this, HEADERS, flags); |
2455 builder.WriteUInt32(headers.stream_id()); | 2417 builder.WriteUInt32(headers.stream_id()); |
2456 } else { | 2418 } else { |
2457 builder.BeginNewFrame(*this, | 2419 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id()); |
2458 HEADERS, | |
2459 flags, | |
2460 headers.stream_id()); | |
2461 if (headers.has_priority()) { | 2420 if (headers.has_priority()) { |
2462 builder.WriteUInt32(priority); | 2421 builder.WriteUInt32(priority); |
2463 } | 2422 } |
2464 } | 2423 } |
2465 if (protocol_version() <= SPDY2) { | 2424 if (protocol_version() <= SPDY2) { |
2466 builder.WriteUInt16(0); // Unused. | 2425 builder.WriteUInt16(0); // Unused. |
2467 } | 2426 } |
2468 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2427 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
2469 | 2428 |
2470 if (protocol_version() > SPDY3) { | 2429 if (protocol_version() > SPDY3) { |
2471 WritePayloadWithContinuation(&builder, | 2430 WritePayloadWithContinuation( |
2472 hpack_encoding, | 2431 &builder, hpack_encoding, headers.stream_id(), HEADERS); |
2473 headers.stream_id(), | |
2474 HEADERS); | |
2475 } else { | 2432 } else { |
2476 SerializeNameValueBlock(&builder, headers); | 2433 SerializeNameValueBlock(&builder, headers); |
2477 } | 2434 } |
2478 | 2435 |
2479 if (debug_visitor_) { | 2436 if (debug_visitor_) { |
2480 const size_t payload_len = protocol_version() > SPDY3 ? | 2437 const size_t payload_len = |
2481 hpack_encoding.size() : | 2438 protocol_version() > SPDY3 |
2482 GetSerializedLength(protocol_version(), | 2439 ? hpack_encoding.size() |
2483 &(headers.name_value_block())); | 2440 : GetSerializedLength(protocol_version(), |
2484 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), | 2441 &(headers.name_value_block())); |
2485 HEADERS, | 2442 debug_visitor_->OnSendCompressedFrame( |
2486 payload_len, | 2443 headers.stream_id(), HEADERS, payload_len, builder.length()); |
2487 builder.length()); | |
2488 } | 2444 } |
2489 | 2445 |
2490 return builder.take(); | 2446 return builder.take(); |
2491 } | 2447 } |
2492 | 2448 |
2493 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( | 2449 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( |
2494 const SpdyWindowUpdateIR& window_update) const { | 2450 const SpdyWindowUpdateIR& window_update) const { |
2495 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version()); | 2451 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version()); |
2496 if (protocol_version() <= SPDY3) { | 2452 if (protocol_version() <= SPDY3) { |
2497 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); | 2453 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); |
2498 builder.WriteUInt32(window_update.stream_id()); | 2454 builder.WriteUInt32(window_update.stream_id()); |
2499 } else { | 2455 } else { |
2500 builder.BeginNewFrame(*this, | 2456 builder.BeginNewFrame( |
2501 WINDOW_UPDATE, | 2457 *this, WINDOW_UPDATE, kNoFlags, window_update.stream_id()); |
2502 kNoFlags, | |
2503 window_update.stream_id()); | |
2504 } | 2458 } |
2505 builder.WriteUInt32(window_update.delta()); | 2459 builder.WriteUInt32(window_update.delta()); |
2506 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); | 2460 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
2507 return builder.take(); | 2461 return builder.take(); |
2508 } | 2462 } |
2509 | 2463 |
2510 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const { | 2464 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const { |
2511 DCHECK_LT(SPDY3, protocol_version()); | 2465 DCHECK_LT(SPDY3, protocol_version()); |
2512 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version()); | 2466 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version()); |
2513 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); | 2467 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); |
2514 return builder.take(); | 2468 return builder.take(); |
2515 } | 2469 } |
2516 | 2470 |
2517 SpdyFrame* SpdyFramer::SerializePushPromise( | 2471 SpdyFrame* SpdyFramer::SerializePushPromise( |
2518 const SpdyPushPromiseIR& push_promise) { | 2472 const SpdyPushPromiseIR& push_promise) { |
2519 DCHECK_LT(SPDY3, protocol_version()); | 2473 DCHECK_LT(SPDY3, protocol_version()); |
2520 uint8 flags = 0; | 2474 uint8 flags = 0; |
2521 // TODO(mlavan): If we overflow into a CONTINUATION frame, this will | 2475 // TODO(mlavan): If we overflow into a CONTINUATION frame, this will |
2522 // get overwritten below, so we should probably just get rid of the | 2476 // get overwritten below, so we should probably just get rid of the |
2523 // end_push_promise field. | 2477 // end_push_promise field. |
2524 if (push_promise.end_push_promise()) { | 2478 if (push_promise.end_push_promise()) { |
2525 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2479 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
2526 } | 2480 } |
2527 // The size of this frame, including variable-length name-value block. | 2481 // The size of this frame, including variable-length name-value block. |
2528 size_t size = GetPushPromiseMinimumSize(); | 2482 size_t size = GetPushPromiseMinimumSize(); |
2529 | 2483 |
2530 string hpack_encoding; | 2484 string hpack_encoding; |
2531 if (protocol_version() > SPDY3) { | 2485 if (protocol_version() > SPDY3) { |
2532 if (enable_compression_) { | 2486 if (enable_compression_) { |
2533 hpack_encoder_.EncodeHeaderSet( | 2487 hpack_encoder_.EncodeHeaderSet(push_promise.name_value_block(), |
2534 push_promise.name_value_block(), &hpack_encoding); | 2488 &hpack_encoding); |
2535 } else { | 2489 } else { |
2536 hpack_encoder_.EncodeHeaderSetWithoutCompression( | 2490 hpack_encoder_.EncodeHeaderSetWithoutCompression( |
2537 push_promise.name_value_block(), &hpack_encoding); | 2491 push_promise.name_value_block(), &hpack_encoding); |
2538 } | 2492 } |
2539 size += hpack_encoding.size(); | 2493 size += hpack_encoding.size(); |
2540 if (size > GetControlFrameBufferMaxSize()) { | 2494 if (size > GetControlFrameBufferMaxSize()) { |
2541 size += GetNumberRequiredContinuationFrames(size) * | 2495 size += GetNumberRequiredContinuationFrames(size) * |
2542 GetContinuationMinimumSize(); | 2496 GetContinuationMinimumSize(); |
2543 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2497 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
2544 } | 2498 } |
2545 } else { | 2499 } else { |
2546 size += GetSerializedLength(push_promise.name_value_block()); | 2500 size += GetSerializedLength(push_promise.name_value_block()); |
2547 } | 2501 } |
2548 | 2502 |
2549 SpdyFrameBuilder builder(size, protocol_version()); | 2503 SpdyFrameBuilder builder(size, protocol_version()); |
2550 builder.BeginNewFrame(*this, | 2504 builder.BeginNewFrame(*this, PUSH_PROMISE, flags, push_promise.stream_id()); |
2551 PUSH_PROMISE, | |
2552 flags, | |
2553 push_promise.stream_id()); | |
2554 builder.WriteUInt32(push_promise.promised_stream_id()); | 2505 builder.WriteUInt32(push_promise.promised_stream_id()); |
2555 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); | 2506 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); |
2556 | 2507 |
2557 if (protocol_version() > SPDY3) { | 2508 if (protocol_version() > SPDY3) { |
2558 WritePayloadWithContinuation(&builder, | 2509 WritePayloadWithContinuation( |
2559 hpack_encoding, | 2510 &builder, hpack_encoding, push_promise.stream_id(), PUSH_PROMISE); |
2560 push_promise.stream_id(), | |
2561 PUSH_PROMISE); | |
2562 } else { | 2511 } else { |
2563 SerializeNameValueBlock(&builder, push_promise); | 2512 SerializeNameValueBlock(&builder, push_promise); |
2564 } | 2513 } |
2565 | 2514 |
2566 if (debug_visitor_) { | 2515 if (debug_visitor_) { |
2567 const size_t payload_len = protocol_version() > SPDY3 ? | 2516 const size_t payload_len = |
2568 hpack_encoding.size() : | 2517 protocol_version() > SPDY3 |
2569 GetSerializedLength(protocol_version(), | 2518 ? hpack_encoding.size() |
2570 &(push_promise.name_value_block())); | 2519 : GetSerializedLength(protocol_version(), |
2571 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), | 2520 &(push_promise.name_value_block())); |
2572 PUSH_PROMISE, payload_len, builder.length()); | 2521 debug_visitor_->OnSendCompressedFrame( |
| 2522 push_promise.stream_id(), PUSH_PROMISE, payload_len, builder.length()); |
2573 } | 2523 } |
2574 | 2524 |
2575 return builder.take(); | 2525 return builder.take(); |
2576 } | 2526 } |
2577 | 2527 |
2578 // TODO(jgraettinger): This implementation is incorrect. The continuation | 2528 // TODO(jgraettinger): This implementation is incorrect. The continuation |
2579 // frame continues a previously-begun HPACK encoding; it doesn't begin a | 2529 // frame continues a previously-begun HPACK encoding; it doesn't begin a |
2580 // new one. Figure out whether it makes sense to keep SerializeContinuation(). | 2530 // new one. Figure out whether it makes sense to keep SerializeContinuation(). |
2581 SpdyFrame* SpdyFramer::SerializeContinuation( | 2531 SpdyFrame* SpdyFramer::SerializeContinuation( |
2582 const SpdyContinuationIR& continuation) { | 2532 const SpdyContinuationIR& continuation) { |
2583 CHECK_LT(SPDY3, protocol_version()); | 2533 CHECK_LT(SPDY3, protocol_version()); |
2584 uint8 flags = 0; | 2534 uint8 flags = 0; |
2585 if (continuation.end_headers()) { | 2535 if (continuation.end_headers()) { |
2586 flags |= HEADERS_FLAG_END_HEADERS; | 2536 flags |= HEADERS_FLAG_END_HEADERS; |
2587 } | 2537 } |
2588 | 2538 |
2589 // The size of this frame, including variable-length name-value block. | 2539 // The size of this frame, including variable-length name-value block. |
2590 size_t size = GetContinuationMinimumSize(); | 2540 size_t size = GetContinuationMinimumSize(); |
2591 string hpack_encoding; | 2541 string hpack_encoding; |
2592 if (enable_compression_) { | 2542 if (enable_compression_) { |
2593 hpack_encoder_.EncodeHeaderSet( | 2543 hpack_encoder_.EncodeHeaderSet(continuation.name_value_block(), |
2594 continuation.name_value_block(), &hpack_encoding); | 2544 &hpack_encoding); |
2595 } else { | 2545 } else { |
2596 hpack_encoder_.EncodeHeaderSetWithoutCompression( | 2546 hpack_encoder_.EncodeHeaderSetWithoutCompression( |
2597 continuation.name_value_block(), &hpack_encoding); | 2547 continuation.name_value_block(), &hpack_encoding); |
2598 } | 2548 } |
2599 size += hpack_encoding.size(); | 2549 size += hpack_encoding.size(); |
2600 | 2550 |
2601 SpdyFrameBuilder builder(size, protocol_version()); | 2551 SpdyFrameBuilder builder(size, protocol_version()); |
2602 builder.BeginNewFrame(*this, CONTINUATION, flags, | 2552 builder.BeginNewFrame(*this, CONTINUATION, flags, continuation.stream_id()); |
2603 continuation.stream_id()); | |
2604 DCHECK_EQ(GetContinuationMinimumSize(), builder.length()); | 2553 DCHECK_EQ(GetContinuationMinimumSize(), builder.length()); |
2605 | 2554 |
2606 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | 2555 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); |
2607 | 2556 |
2608 if (debug_visitor_) { | 2557 if (debug_visitor_) { |
2609 const size_t payload_len = hpack_encoding.size(); | 2558 const size_t payload_len = hpack_encoding.size(); |
2610 debug_visitor_->OnSendCompressedFrame(continuation.stream_id(), | 2559 debug_visitor_->OnSendCompressedFrame( |
2611 CONTINUATION, payload_len, builder.length()); | 2560 continuation.stream_id(), CONTINUATION, payload_len, builder.length()); |
2612 } | 2561 } |
2613 | 2562 |
2614 return builder.take(); | 2563 return builder.take(); |
2615 } | 2564 } |
2616 | 2565 |
2617 namespace { | 2566 namespace { |
2618 | 2567 |
2619 class FrameSerializationVisitor : public SpdyFrameVisitor { | 2568 class FrameSerializationVisitor : public SpdyFrameVisitor { |
2620 public: | 2569 public: |
2621 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} | 2570 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2672 | 2621 |
2673 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { | 2622 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { |
2674 FrameSerializationVisitor visitor(this); | 2623 FrameSerializationVisitor visitor(this); |
2675 frame.Visit(&visitor); | 2624 frame.Visit(&visitor); |
2676 return visitor.ReleaseSerializedFrame(); | 2625 return visitor.ReleaseSerializedFrame(); |
2677 } | 2626 } |
2678 | 2627 |
2679 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) { | 2628 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) { |
2680 CHECK_GE(SPDY3, protocol_version()); | 2629 CHECK_GE(SPDY3, protocol_version()); |
2681 const size_t uncompressed_length = | 2630 const size_t uncompressed_length = |
2682 GetSerializedLength(protocol_version(), &headers); | 2631 GetSerializedLength(protocol_version(), &headers); |
2683 if (!enable_compression_) { | 2632 if (!enable_compression_) { |
2684 return uncompressed_length; | 2633 return uncompressed_length; |
2685 } | 2634 } |
2686 z_stream* compressor = GetHeaderCompressor(); | 2635 z_stream* compressor = GetHeaderCompressor(); |
2687 // Since we'll be performing lots of flushes when compressing the data, | 2636 // Since we'll be performing lots of flushes when compressing the data, |
2688 // zlib's lower bounds may be insufficient. | 2637 // zlib's lower bounds may be insufficient. |
2689 return 2 * deflateBound(compressor, uncompressed_length); | 2638 return 2 * deflateBound(compressor, uncompressed_length); |
2690 } | 2639 } |
2691 | 2640 |
2692 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) { | 2641 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) { |
2693 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize(); | 2642 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize(); |
2694 DCHECK_GT(protocol_version(), SPDY3); | 2643 DCHECK_GT(protocol_version(), SPDY3); |
2695 DCHECK_GT(size, kMaxControlFrameSize); | 2644 DCHECK_GT(size, kMaxControlFrameSize); |
2696 size_t overflow = size - kMaxControlFrameSize; | 2645 size_t overflow = size - kMaxControlFrameSize; |
2697 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1; | 2646 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1; |
2698 } | 2647 } |
2699 | 2648 |
2700 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder, | 2649 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder, |
2701 const string& hpack_encoding, | 2650 const string& hpack_encoding, |
2702 SpdyStreamId stream_id, | 2651 SpdyStreamId stream_id, |
2703 SpdyFrameType type) { | 2652 SpdyFrameType type) { |
2704 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize(); | 2653 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize(); |
2705 | 2654 |
2706 // In addition to the prefix, fixed_field_size includes the size of | 2655 // In addition to the prefix, fixed_field_size includes the size of |
2707 // any fields that come before the variable-length name/value block. | 2656 // any fields that come before the variable-length name/value block. |
2708 size_t fixed_field_size = 0; | 2657 size_t fixed_field_size = 0; |
2709 uint8 end_flag = 0; | 2658 uint8 end_flag = 0; |
2710 uint8 flags = 0; | 2659 uint8 flags = 0; |
2711 if (type == HEADERS) { | 2660 if (type == HEADERS) { |
2712 fixed_field_size = GetHeadersMinimumSize(); | 2661 fixed_field_size = GetHeadersMinimumSize(); |
2713 end_flag = HEADERS_FLAG_END_HEADERS; | 2662 end_flag = HEADERS_FLAG_END_HEADERS; |
2714 } else if (type == PUSH_PROMISE) { | 2663 } else if (type == PUSH_PROMISE) { |
2715 fixed_field_size = GetPushPromiseMinimumSize(); | 2664 fixed_field_size = GetPushPromiseMinimumSize(); |
2716 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2665 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
2717 } else { | 2666 } else { |
2718 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type " | 2667 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type " |
2719 << FrameTypeToString(type); | 2668 << FrameTypeToString(type); |
| 2669 } |
| 2670 |
| 2671 // Write as much of the payload as possible into the initial frame. |
| 2672 size_t bytes_remaining = |
| 2673 hpack_encoding.size() - |
| 2674 std::min(hpack_encoding.size(), kMaxControlFrameSize - fixed_field_size); |
| 2675 builder->WriteBytes(&hpack_encoding[0], |
| 2676 hpack_encoding.size() - bytes_remaining); |
| 2677 |
| 2678 if (bytes_remaining > 0) { |
| 2679 builder->OverwriteLength( |
| 2680 *this, kMaxControlFrameSize - GetControlFrameHeaderSize()); |
| 2681 } |
| 2682 |
| 2683 // Tack on CONTINUATION frames for the overflow. |
| 2684 while (bytes_remaining > 0) { |
| 2685 size_t bytes_to_write = std::min( |
| 2686 bytes_remaining, kMaxControlFrameSize - GetContinuationMinimumSize()); |
| 2687 // Write CONTINUATION frame prefix. |
| 2688 if (bytes_remaining == bytes_to_write) { |
| 2689 flags |= end_flag; |
2720 } | 2690 } |
2721 | 2691 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id); |
2722 // Write as much of the payload as possible into the initial frame. | 2692 // Write payload fragment. |
2723 size_t bytes_remaining = hpack_encoding.size() - | 2693 builder->WriteBytes( |
2724 std::min(hpack_encoding.size(), | 2694 &hpack_encoding[hpack_encoding.size() - bytes_remaining], |
2725 kMaxControlFrameSize - fixed_field_size); | 2695 bytes_to_write); |
2726 builder->WriteBytes(&hpack_encoding[0], | 2696 bytes_remaining -= bytes_to_write; |
2727 hpack_encoding.size() - bytes_remaining); | 2697 } |
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 } | 2698 } |
2754 | 2699 |
2755 // The following compression setting are based on Brian Olson's analysis. See | 2700 // The following compression setting are based on Brian Olson's analysis. See |
2756 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79
2 | 2701 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79
2 |
2757 // for more details. | 2702 // for more details. |
2758 #if defined(USE_SYSTEM_ZLIB) | 2703 #if defined(USE_SYSTEM_ZLIB) |
2759 // System zlib is not expected to have workaround for http://crbug.com/139744, | 2704 // System zlib is not expected to have workaround for http://crbug.com/139744, |
2760 // so disable compression in that case. | 2705 // so disable compression in that case. |
2761 // TODO(phajdan.jr): Remove the special case when it's no longer necessary. | 2706 // TODO(phajdan.jr): Remove the special case when it's no longer necessary. |
2762 static const int kCompressorLevel = 0; | 2707 static const int kCompressorLevel = 0; |
2763 #else // !defined(USE_SYSTEM_ZLIB) | 2708 #else // !defined(USE_SYSTEM_ZLIB) |
2764 static const int kCompressorLevel = 9; | 2709 static const int kCompressorLevel = 9; |
2765 #endif // !defined(USE_SYSTEM_ZLIB) | 2710 #endif // !defined(USE_SYSTEM_ZLIB) |
2766 static const int kCompressorWindowSizeInBits = 11; | 2711 static const int kCompressorWindowSizeInBits = 11; |
2767 static const int kCompressorMemLevel = 1; | 2712 static const int kCompressorMemLevel = 1; |
2768 | 2713 |
2769 z_stream* SpdyFramer::GetHeaderCompressor() { | 2714 z_stream* SpdyFramer::GetHeaderCompressor() { |
2770 if (header_compressor_.get()) | 2715 if (header_compressor_.get()) |
2771 return header_compressor_.get(); // Already initialized. | 2716 return header_compressor_.get(); // Already initialized. |
2772 | 2717 |
2773 header_compressor_.reset(new z_stream); | 2718 header_compressor_.reset(new z_stream); |
2774 memset(header_compressor_.get(), 0, sizeof(z_stream)); | 2719 memset(header_compressor_.get(), 0, sizeof(z_stream)); |
2775 | 2720 |
2776 int success = deflateInit2(header_compressor_.get(), | 2721 int success = deflateInit2(header_compressor_.get(), |
2777 kCompressorLevel, | 2722 kCompressorLevel, |
2778 Z_DEFLATED, | 2723 Z_DEFLATED, |
2779 kCompressorWindowSizeInBits, | 2724 kCompressorWindowSizeInBits, |
2780 kCompressorMemLevel, | 2725 kCompressorMemLevel, |
2781 Z_DEFAULT_STRATEGY); | 2726 Z_DEFAULT_STRATEGY); |
2782 if (success == Z_OK) { | 2727 if (success == Z_OK) { |
2783 const char* dictionary = (protocol_version() <= SPDY2) ? | 2728 const char* dictionary = |
2784 kV2Dictionary : kV3Dictionary; | 2729 (protocol_version() <= SPDY2) ? kV2Dictionary : kV3Dictionary; |
2785 const int dictionary_size = (protocol_version() <= SPDY2) ? | 2730 const int dictionary_size = |
2786 kV2DictionarySize : kV3DictionarySize; | 2731 (protocol_version() <= SPDY2) ? kV2DictionarySize : kV3DictionarySize; |
2787 success = deflateSetDictionary(header_compressor_.get(), | 2732 success = deflateSetDictionary(header_compressor_.get(), |
2788 reinterpret_cast<const Bytef*>(dictionary), | 2733 reinterpret_cast<const Bytef*>(dictionary), |
2789 dictionary_size); | 2734 dictionary_size); |
2790 } | 2735 } |
2791 if (success != Z_OK) { | 2736 if (success != Z_OK) { |
2792 LOG(WARNING) << "deflateSetDictionary failure: " << success; | 2737 LOG(WARNING) << "deflateSetDictionary failure: " << success; |
2793 header_compressor_.reset(NULL); | 2738 header_compressor_.reset(NULL); |
2794 return NULL; | 2739 return NULL; |
2795 } | 2740 } |
2796 return header_compressor_.get(); | 2741 return header_compressor_.get(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2836 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we | 2781 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we |
2837 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've | 2782 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've |
2838 // reached this method successfully, stream_id should be nonzero. | 2783 // reached this method successfully, stream_id should be nonzero. |
2839 DCHECK_LT(0u, stream_id); | 2784 DCHECK_LT(0u, stream_id); |
2840 while (decomp->avail_in > 0 && processed_successfully) { | 2785 while (decomp->avail_in > 0 && processed_successfully) { |
2841 decomp->next_out = reinterpret_cast<Bytef*>(buffer); | 2786 decomp->next_out = reinterpret_cast<Bytef*>(buffer); |
2842 decomp->avail_out = arraysize(buffer); | 2787 decomp->avail_out = arraysize(buffer); |
2843 | 2788 |
2844 int rv = inflate(decomp, Z_SYNC_FLUSH); | 2789 int rv = inflate(decomp, Z_SYNC_FLUSH); |
2845 if (rv == Z_NEED_DICT) { | 2790 if (rv == Z_NEED_DICT) { |
2846 const char* dictionary = (protocol_version() <= SPDY2) ? kV2Dictionary | 2791 const char* dictionary = |
2847 : kV3Dictionary; | 2792 (protocol_version() <= SPDY2) ? kV2Dictionary : kV3Dictionary; |
2848 const int dictionary_size = (protocol_version() <= SPDY2) ? | 2793 const int dictionary_size = |
2849 kV2DictionarySize : kV3DictionarySize; | 2794 (protocol_version() <= SPDY2) ? kV2DictionarySize : kV3DictionarySize; |
2850 const DictionaryIds& ids = g_dictionary_ids.Get(); | 2795 const DictionaryIds& ids = g_dictionary_ids.Get(); |
2851 const uLong dictionary_id = (protocol_version() <= SPDY2) ? | 2796 const uLong dictionary_id = (protocol_version() <= SPDY2) |
2852 ids.v2_dictionary_id : ids.v3_dictionary_id; | 2797 ? ids.v2_dictionary_id |
| 2798 : ids.v3_dictionary_id; |
2853 // Need to try again with the right dictionary. | 2799 // Need to try again with the right dictionary. |
2854 if (decomp->adler == dictionary_id) { | 2800 if (decomp->adler == dictionary_id) { |
2855 rv = inflateSetDictionary(decomp, | 2801 rv = inflateSetDictionary(decomp, |
2856 reinterpret_cast<const Bytef*>(dictionary), | 2802 reinterpret_cast<const Bytef*>(dictionary), |
2857 dictionary_size); | 2803 dictionary_size); |
2858 if (rv == Z_OK) | 2804 if (rv == Z_OK) |
2859 rv = inflate(decomp, Z_SYNC_FLUSH); | 2805 rv = inflate(decomp, Z_SYNC_FLUSH); |
2860 } | 2806 } |
2861 } | 2807 } |
2862 | 2808 |
(...skipping 16 matching lines...) Expand all Loading... |
2879 } else { | 2825 } else { |
2880 DLOG(WARNING) << "inflate failure: " << rv << " " << len; | 2826 DLOG(WARNING) << "inflate failure: " << rv << " " << len; |
2881 set_error(SPDY_DECOMPRESS_FAILURE); | 2827 set_error(SPDY_DECOMPRESS_FAILURE); |
2882 processed_successfully = false; | 2828 processed_successfully = false; |
2883 } | 2829 } |
2884 } | 2830 } |
2885 return processed_successfully; | 2831 return processed_successfully; |
2886 } | 2832 } |
2887 | 2833 |
2888 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( | 2834 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData( |
2889 SpdyStreamId stream_id, const char* data, size_t len) { | 2835 SpdyStreamId stream_id, |
| 2836 const char* data, |
| 2837 size_t len) { |
2890 bool read_successfully = true; | 2838 bool read_successfully = true; |
2891 while (read_successfully && len > 0) { | 2839 while (read_successfully && len > 0) { |
2892 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); | 2840 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize); |
2893 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data, | 2841 read_successfully = |
2894 bytes_to_deliver); | 2842 visitor_->OnControlFrameHeaderData(stream_id, data, bytes_to_deliver); |
2895 data += bytes_to_deliver; | 2843 data += bytes_to_deliver; |
2896 len -= bytes_to_deliver; | 2844 len -= bytes_to_deliver; |
2897 if (!read_successfully) { | 2845 if (!read_successfully) { |
2898 // Assume that the problem was the header block was too large for the | 2846 // Assume that the problem was the header block was too large for the |
2899 // visitor. | 2847 // visitor. |
2900 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); | 2848 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); |
2901 } | 2849 } |
2902 } | 2850 } |
2903 return read_successfully; | 2851 return read_successfully; |
2904 } | 2852 } |
(...skipping 25 matching lines...) Expand all Loading... |
2930 void SpdyFramer::SerializeNameValueBlock( | 2878 void SpdyFramer::SerializeNameValueBlock( |
2931 SpdyFrameBuilder* builder, | 2879 SpdyFrameBuilder* builder, |
2932 const SpdyFrameWithNameValueBlockIR& frame) { | 2880 const SpdyFrameWithNameValueBlockIR& frame) { |
2933 CHECK_GE(SPDY3, protocol_version()); | 2881 CHECK_GE(SPDY3, protocol_version()); |
2934 if (!enable_compression_) { | 2882 if (!enable_compression_) { |
2935 return SerializeNameValueBlockWithoutCompression(builder, | 2883 return SerializeNameValueBlockWithoutCompression(builder, |
2936 frame.name_value_block()); | 2884 frame.name_value_block()); |
2937 } | 2885 } |
2938 | 2886 |
2939 // First build an uncompressed version to be fed into the compressor. | 2887 // First build an uncompressed version to be fed into the compressor. |
2940 const size_t uncompressed_len = GetSerializedLength( | 2888 const size_t uncompressed_len = |
2941 protocol_version(), &(frame.name_value_block())); | 2889 GetSerializedLength(protocol_version(), &(frame.name_value_block())); |
2942 SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version()); | 2890 SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version()); |
2943 SerializeNameValueBlockWithoutCompression(&uncompressed_builder, | 2891 SerializeNameValueBlockWithoutCompression(&uncompressed_builder, |
2944 frame.name_value_block()); | 2892 frame.name_value_block()); |
2945 scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take()); | 2893 scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take()); |
2946 | 2894 |
2947 z_stream* compressor = GetHeaderCompressor(); | 2895 z_stream* compressor = GetHeaderCompressor(); |
2948 if (!compressor) { | 2896 if (!compressor) { |
2949 LOG(DFATAL) << "Could not obtain compressor."; | 2897 LOG(DFATAL) << "Could not obtain compressor."; |
2950 return; | 2898 return; |
2951 } | 2899 } |
2952 | 2900 |
2953 base::StatsCounter compressed_frames("spdy.CompressedFrames"); | 2901 base::StatsCounter compressed_frames("spdy.CompressedFrames"); |
2954 base::StatsCounter pre_compress_bytes("spdy.PreCompressSize"); | 2902 base::StatsCounter pre_compress_bytes("spdy.PreCompressSize"); |
2955 base::StatsCounter post_compress_bytes("spdy.PostCompressSize"); | 2903 base::StatsCounter post_compress_bytes("spdy.PostCompressSize"); |
2956 | 2904 |
2957 // Create an output frame. | 2905 // Create an output frame. |
2958 // Since we'll be performing lots of flushes when compressing the data, | 2906 // Since we'll be performing lots of flushes when compressing the data, |
2959 // zlib's lower bounds may be insufficient. | 2907 // zlib's lower bounds may be insufficient. |
2960 // | 2908 // |
2961 // TODO(akalin): Avoid the duplicate calculation with | 2909 // TODO(akalin): Avoid the duplicate calculation with |
2962 // GetSerializedLength(const SpdyHeaderBlock&). | 2910 // GetSerializedLength(const SpdyHeaderBlock&). |
2963 const int compressed_max_size = | 2911 const int compressed_max_size = |
2964 2 * deflateBound(compressor, uncompressed_len); | 2912 2 * deflateBound(compressor, uncompressed_len); |
2965 | 2913 |
2966 // TODO(phajdan.jr): Clean up after we no longer need | 2914 // TODO(phajdan.jr): Clean up after we no longer need |
2967 // to workaround http://crbug.com/139744. | 2915 // to workaround http://crbug.com/139744. |
2968 #if defined(USE_SYSTEM_ZLIB) | 2916 #if defined(USE_SYSTEM_ZLIB) |
2969 compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data()); | 2917 compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data()); |
2970 compressor->avail_in = uncompressed_len; | 2918 compressor->avail_in = uncompressed_len; |
2971 #endif // defined(USE_SYSTEM_ZLIB) | 2919 #endif // defined(USE_SYSTEM_ZLIB) |
2972 compressor->next_out = reinterpret_cast<Bytef*>( | 2920 compressor->next_out = |
2973 builder->GetWritableBuffer(compressed_max_size)); | 2921 reinterpret_cast<Bytef*>(builder->GetWritableBuffer(compressed_max_size)); |
2974 compressor->avail_out = compressed_max_size; | 2922 compressor->avail_out = compressed_max_size; |
2975 | 2923 |
2976 // TODO(phajdan.jr): Clean up after we no longer need | 2924 // TODO(phajdan.jr): Clean up after we no longer need |
2977 // to workaround http://crbug.com/139744. | 2925 // to workaround http://crbug.com/139744. |
2978 #if defined(USE_SYSTEM_ZLIB) | 2926 #if defined(USE_SYSTEM_ZLIB) |
2979 int rv = deflate(compressor, Z_SYNC_FLUSH); | 2927 int rv = deflate(compressor, Z_SYNC_FLUSH); |
2980 if (rv != Z_OK) { // How can we know that it compressed everything? | 2928 if (rv != Z_OK) { // How can we know that it compressed everything? |
2981 // This shouldn't happen, right? | 2929 // This shouldn't happen, right? |
2982 LOG(WARNING) << "deflate failure: " << rv; | 2930 LOG(WARNING) << "deflate failure: " << rv; |
2983 // TODO(akalin): Upstream this return. | 2931 // TODO(akalin): Upstream this return. |
2984 return; | 2932 return; |
2985 } | 2933 } |
2986 #else | 2934 #else |
2987 WriteHeaderBlockToZ(&frame.name_value_block(), compressor); | 2935 WriteHeaderBlockToZ(&frame.name_value_block(), compressor); |
2988 #endif // defined(USE_SYSTEM_ZLIB) | 2936 #endif // defined(USE_SYSTEM_ZLIB) |
2989 | 2937 |
2990 int compressed_size = compressed_max_size - compressor->avail_out; | 2938 int compressed_size = compressed_max_size - compressor->avail_out; |
2991 builder->Seek(compressed_size); | 2939 builder->Seek(compressed_size); |
2992 builder->RewriteLength(*this); | 2940 builder->RewriteLength(*this); |
2993 | 2941 |
2994 pre_compress_bytes.Add(uncompressed_len); | 2942 pre_compress_bytes.Add(uncompressed_len); |
2995 post_compress_bytes.Add(compressed_size); | 2943 post_compress_bytes.Add(compressed_size); |
2996 | 2944 |
2997 compressed_frames.Increment(); | 2945 compressed_frames.Increment(); |
2998 } | 2946 } |
2999 | 2947 |
3000 } // namespace net | 2948 } // namespace net |
OLD | NEW |