| 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 |