Chromium Code Reviews| 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/core/spdy_framer.h" | 5 #include "net/spdy/core/spdy_framer.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cctype> | 10 #include <cctype> |
| 11 #include <ios> | 11 #include <ios> |
| 12 #include <iterator> | 12 #include <iterator> |
| 13 #include <list> | 13 #include <list> |
| 14 #include <new> | 14 #include <new> |
| 15 #include <vector> | |
| 16 | 15 |
| 17 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
| 18 #include "base/logging.h" | 17 #include "base/logging.h" |
| 19 #include "base/metrics/histogram_macros.h" | 18 #include "base/metrics/histogram_macros.h" |
| 20 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 21 #include "net/quic/platform/api/quic_flags.h" | 20 #include "net/quic/platform/api/quic_flags.h" |
| 22 #include "net/spdy/chromium/spdy_flags.h" | 21 #include "net/spdy/chromium/spdy_flags.h" |
| 23 #include "net/spdy/core/hpack/hpack_constants.h" | 22 #include "net/spdy/core/hpack/hpack_constants.h" |
| 24 #include "net/spdy/core/hpack/hpack_decoder.h" | 23 #include "net/spdy/core/hpack/hpack_decoder.h" |
| 25 #include "net/spdy/core/hpack/hpack_decoder3.h" | 24 #include "net/spdy/core/hpack/hpack_decoder3.h" |
| 26 #include "net/spdy/core/http2_frame_decoder_adapter.h" | 25 #include "net/spdy/core/http2_frame_decoder_adapter.h" |
| 27 #include "net/spdy/core/spdy_bitmasks.h" | 26 #include "net/spdy/core/spdy_bitmasks.h" |
| 28 #include "net/spdy/core/spdy_bug_tracker.h" | 27 #include "net/spdy/core/spdy_bug_tracker.h" |
| 29 #include "net/spdy/core/spdy_frame_builder.h" | 28 #include "net/spdy/core/spdy_frame_builder.h" |
| 30 #include "net/spdy/core/spdy_frame_reader.h" | 29 #include "net/spdy/core/spdy_frame_reader.h" |
| 31 #include "net/spdy/core/spdy_framer_decoder_adapter.h" | 30 #include "net/spdy/core/spdy_framer_decoder_adapter.h" |
| 32 #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" | 31 #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" |
| 33 #include "net/spdy/platform/api/spdy_ptr_util.h" | 32 #include "net/spdy/platform/api/spdy_ptr_util.h" |
| 34 #include "net/spdy/platform/api/spdy_string_utils.h" | 33 #include "net/spdy/platform/api/spdy_string_utils.h" |
| 35 | 34 |
| 36 using std::vector; | |
| 37 | |
| 38 namespace net { | 35 namespace net { |
| 39 | 36 |
| 40 namespace { | 37 namespace { |
| 41 | 38 |
| 42 // Pack parent stream ID and exclusive flag into the format used by HTTP/2 | 39 // Pack parent stream ID and exclusive flag into the format used by HTTP/2 |
| 43 // headers and priority frames. | 40 // headers and priority frames. |
| 44 uint32_t PackStreamDependencyValues(bool exclusive, | 41 uint32_t PackStreamDependencyValues(bool exclusive, |
| 45 SpdyStreamId parent_stream_id) { | 42 SpdyStreamId parent_stream_id) { |
| 46 // Make sure the highest-order bit in the parent stream id is zeroed out. | 43 // Make sure the highest-order bit in the parent stream id is zeroed out. |
| 47 uint32_t parent = parent_stream_id & 0x7fffffff; | 44 uint32_t parent = parent_stream_id & 0x7fffffff; |
| (...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1015 expect_continuation_ = current_frame_stream_id_; | 1012 expect_continuation_ = current_frame_stream_id_; |
| 1016 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; | 1013 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; |
| 1017 } | 1014 } |
| 1018 if (current_frame_flags_ & HEADERS_FLAG_PADDED) { | 1015 if (current_frame_flags_ & HEADERS_FLAG_PADDED) { |
| 1019 uint8_t pad_payload_len = 0; | 1016 uint8_t pad_payload_len = 0; |
| 1020 DCHECK_EQ(remaining_padding_payload_length_, 0u); | 1017 DCHECK_EQ(remaining_padding_payload_length_, 0u); |
| 1021 successful_read = reader.ReadUInt8(&pad_payload_len); | 1018 successful_read = reader.ReadUInt8(&pad_payload_len); |
| 1022 DCHECK(successful_read); | 1019 DCHECK(successful_read); |
| 1023 remaining_padding_payload_length_ = pad_payload_len; | 1020 remaining_padding_payload_length_ = pad_payload_len; |
| 1024 } | 1021 } |
| 1025 const bool has_priority = | |
| 1026 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; | |
| 1027 int weight = 0; | 1022 int weight = 0; |
| 1028 uint32_t parent_stream_id = 0; | 1023 uint32_t parent_stream_id = 0; |
| 1029 bool exclusive = false; | 1024 bool exclusive = false; |
| 1030 if (has_priority) { | 1025 if (current_frame_flags_ & HEADERS_FLAG_PRIORITY) { |
| 1031 uint32_t stream_dependency; | 1026 uint32_t stream_dependency; |
| 1032 successful_read = reader.ReadUInt32(&stream_dependency); | 1027 successful_read = reader.ReadUInt32(&stream_dependency); |
| 1033 DCHECK(successful_read); | 1028 DCHECK(successful_read); |
| 1034 UnpackStreamDependencyValues(stream_dependency, &exclusive, | 1029 UnpackStreamDependencyValues(stream_dependency, &exclusive, |
| 1035 &parent_stream_id); | 1030 &parent_stream_id); |
| 1036 | 1031 |
| 1037 uint8_t serialized_weight = 0; | 1032 uint8_t serialized_weight = 0; |
| 1038 successful_read = reader.ReadUInt8(&serialized_weight); | 1033 successful_read = reader.ReadUInt8(&serialized_weight); |
| 1039 if (successful_read) { | 1034 if (successful_read) { |
| 1040 // Per RFC 7540 section 6.3, serialized weight value is actual | 1035 // Per RFC 7540 section 6.3, serialized weight value is actual |
| 1041 // value - 1. | 1036 // value - 1. |
| 1042 weight = serialized_weight + 1; | 1037 weight = serialized_weight + 1; |
| 1043 } | 1038 } |
| 1044 } | 1039 } |
| 1045 DCHECK(reader.IsDoneReading()); | 1040 DCHECK(reader.IsDoneReading()); |
| 1046 if (debug_visitor_) { | 1041 if (debug_visitor_) { |
| 1047 debug_visitor_->OnReceiveCompressedFrame(current_frame_stream_id_, | 1042 debug_visitor_->OnReceiveCompressedFrame(current_frame_stream_id_, |
| 1048 current_frame_type_, | 1043 current_frame_type_, |
| 1049 current_frame_length_); | 1044 current_frame_length_); |
| 1050 } | 1045 } |
| 1051 visitor_->OnHeaders(current_frame_stream_id_, | 1046 visitor_->OnHeaders(current_frame_stream_id_, |
| 1052 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0, | 1047 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0, |
| 1053 weight, parent_stream_id, exclusive, | 1048 weight, parent_stream_id, exclusive, |
| 1054 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, | 1049 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, |
| 1055 expect_continuation_ == 0); | 1050 expect_continuation_ == 0); |
| 1051 } break; | |
|
Biren Roy
2017/05/24 15:25:09
This line looks weird, but I see it's the same in
Bence
2017/05/24 15:38:48
Yeah, I agree. Maybe if I move all local variable
| |
| 1052 case SpdyFrameType::PUSH_PROMISE: { | |
| 1053 if (current_frame_stream_id_ == 0) { | |
| 1054 set_error(SPDY_INVALID_CONTROL_FRAME); | |
| 1055 return original_len - len; | |
| 1056 } | 1056 } |
| 1057 break; | 1057 bool successful_read = true; |
| 1058 case SpdyFrameType::PUSH_PROMISE: { | 1058 if (current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) { |
| 1059 if (current_frame_stream_id_ == 0) { | 1059 DCHECK_EQ(remaining_padding_payload_length_, 0u); |
| 1060 set_error(SPDY_INVALID_CONTROL_FRAME); | 1060 uint8_t pad_payload_len = 0; |
| 1061 return original_len - len; | 1061 successful_read = reader.ReadUInt8(&pad_payload_len); |
| 1062 } | 1062 DCHECK(successful_read); |
| 1063 bool successful_read = true; | 1063 remaining_padding_payload_length_ = pad_payload_len; |
| 1064 if (current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) { | |
| 1065 DCHECK_EQ(remaining_padding_payload_length_, 0u); | |
| 1066 uint8_t pad_payload_len = 0; | |
| 1067 successful_read = reader.ReadUInt8(&pad_payload_len); | |
| 1068 DCHECK(successful_read); | |
| 1069 remaining_padding_payload_length_ = pad_payload_len; | |
| 1070 } | |
| 1071 } | 1064 } |
| 1072 { | 1065 SpdyStreamId promised_stream_id = kInvalidStream; |
| 1073 SpdyStreamId promised_stream_id = kInvalidStream; | 1066 successful_read = reader.ReadUInt31(&promised_stream_id); |
| 1074 bool successful_read = reader.ReadUInt31(&promised_stream_id); | 1067 DCHECK(successful_read); |
| 1075 DCHECK(successful_read); | 1068 DCHECK(reader.IsDoneReading()); |
| 1076 DCHECK(reader.IsDoneReading()); | 1069 if (promised_stream_id == 0) { |
| 1077 if (promised_stream_id == 0) { | 1070 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1078 set_error(SPDY_INVALID_CONTROL_FRAME); | 1071 return original_len - len; |
| 1079 return original_len - len; | |
| 1080 } | |
| 1081 if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) { | |
| 1082 expect_continuation_ = current_frame_stream_id_; | |
| 1083 } | |
| 1084 if (debug_visitor_) { | |
| 1085 debug_visitor_->OnReceiveCompressedFrame( | |
| 1086 current_frame_stream_id_, | |
| 1087 current_frame_type_, | |
| 1088 current_frame_length_); | |
| 1089 } | |
| 1090 visitor_->OnPushPromise(current_frame_stream_id_, | |
| 1091 promised_stream_id, | |
| 1092 (current_frame_flags_ & | |
| 1093 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0); | |
| 1094 } | 1072 } |
| 1095 break; | 1073 if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) { |
| 1096 case SpdyFrameType::CONTINUATION: { | 1074 expect_continuation_ = current_frame_stream_id_; |
| 1097 // Check to make sure the stream id of the current frame is | |
| 1098 // the same as that of the preceding frame. | |
| 1099 // If we're at this point we should already know that | |
| 1100 // expect_continuation_ != 0, so this doubles as a check | |
| 1101 // that current_frame_stream_id != 0. | |
| 1102 if (current_frame_stream_id_ != expect_continuation_) { | |
| 1103 set_error(SPDY_UNEXPECTED_FRAME); | |
| 1104 return original_len - len; | |
| 1105 } | |
| 1106 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) { | |
| 1107 expect_continuation_ = 0; | |
| 1108 } | |
| 1109 if (debug_visitor_) { | |
| 1110 debug_visitor_->OnReceiveCompressedFrame( | |
| 1111 current_frame_stream_id_, | |
| 1112 current_frame_type_, | |
| 1113 current_frame_length_); | |
| 1114 } | |
| 1115 visitor_->OnContinuation(current_frame_stream_id_, | |
| 1116 (current_frame_flags_ & | |
| 1117 HEADERS_FLAG_END_HEADERS) != 0); | |
| 1118 } | 1075 } |
| 1119 break; | 1076 if (debug_visitor_) { |
| 1077 debug_visitor_->OnReceiveCompressedFrame(current_frame_stream_id_, | |
| 1078 current_frame_type_, | |
| 1079 current_frame_length_); | |
| 1080 } | |
| 1081 visitor_->OnPushPromise( | |
| 1082 current_frame_stream_id_, promised_stream_id, | |
| 1083 (current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0); | |
| 1084 } break; | |
| 1085 case SpdyFrameType::CONTINUATION: { | |
| 1086 // Check to make sure the stream id of the current frame is | |
| 1087 // the same as that of the preceding frame. | |
| 1088 // If we're at this point we should already know that | |
| 1089 // expect_continuation_ != 0, so this doubles as a check | |
| 1090 // that current_frame_stream_id != 0. | |
| 1091 if (current_frame_stream_id_ != expect_continuation_) { | |
| 1092 set_error(SPDY_UNEXPECTED_FRAME); | |
| 1093 return original_len - len; | |
| 1094 } | |
| 1095 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) { | |
| 1096 expect_continuation_ = 0; | |
| 1097 } | |
| 1098 if (debug_visitor_) { | |
| 1099 debug_visitor_->OnReceiveCompressedFrame(current_frame_stream_id_, | |
| 1100 current_frame_type_, | |
| 1101 current_frame_length_); | |
| 1102 } | |
| 1103 visitor_->OnContinuation( | |
| 1104 current_frame_stream_id_, | |
| 1105 (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) != 0); | |
| 1106 } break; | |
| 1120 default: | 1107 default: |
| 1121 #ifndef NDEBUG | 1108 #ifndef NDEBUG |
| 1122 LOG(FATAL) << "Invalid control frame type: " << current_frame_type_; | 1109 LOG(FATAL) << "Invalid control frame type: " << current_frame_type_; |
| 1123 #else | 1110 #else |
| 1124 set_error(SPDY_INVALID_CONTROL_FRAME); | 1111 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 1125 return original_len - len; | 1112 return original_len - len; |
| 1126 #endif | 1113 #endif |
| 1127 } | 1114 } |
| 1128 | 1115 |
| 1129 if (current_frame_type_ != SpdyFrameType::CONTINUATION) { | 1116 if (current_frame_type_ != SpdyFrameType::CONTINUATION) { |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1614 ? GetFrameSizeSansBlock() | 1601 ? GetFrameSizeSansBlock() |
| 1615 : framer_->GetContinuationMinimumSize(); | 1602 : framer_->GetContinuationMinimumSize(); |
| 1616 auto encoding = SpdyMakeUnique<SpdyString>(); | 1603 auto encoding = SpdyMakeUnique<SpdyString>(); |
| 1617 encoder_->Next(kMaxControlFrameSize - size_without_block, encoding.get()); | 1604 encoder_->Next(kMaxControlFrameSize - size_without_block, encoding.get()); |
| 1618 has_next_frame_ = encoder_->HasNext(); | 1605 has_next_frame_ = encoder_->HasNext(); |
| 1619 | 1606 |
| 1620 if (framer_->debug_visitor_ != nullptr) { | 1607 if (framer_->debug_visitor_ != nullptr) { |
| 1621 debug_total_size_ += size_without_block; | 1608 debug_total_size_ += size_without_block; |
| 1622 debug_total_size_ += encoding->size(); | 1609 debug_total_size_ += encoding->size(); |
| 1623 if (!has_next_frame_) { | 1610 if (!has_next_frame_) { |
| 1624 auto* header_block_frame_ir = | |
| 1625 static_cast<const SpdyFrameWithHeaderBlockIR*>(frame_ir); | |
| 1626 // TODO(birenroy) are these (here and below) still necessary? | 1611 // TODO(birenroy) are these (here and below) still necessary? |
| 1627 // HTTP2 uses HPACK for header compression. However, continue to | 1612 // HTTP2 uses HPACK for header compression. However, continue to |
| 1628 // use GetSerializedLength() for an apples-to-apples comparision of | 1613 // use GetSerializedLength() for an apples-to-apples comparision of |
| 1629 // compression performance between HPACK and SPDY w/ deflate. | 1614 // compression performance between HPACK and SPDY w/ deflate. |
| 1615 auto* header_block_frame_ir = | |
| 1616 static_cast<const SpdyFrameWithHeaderBlockIR*>(frame_ir); | |
| 1630 size_t debug_payload_len = | 1617 size_t debug_payload_len = |
| 1631 framer_->GetSerializedLength(&header_block_frame_ir->header_block()); | 1618 framer_->GetSerializedLength(&header_block_frame_ir->header_block()); |
| 1632 framer_->debug_visitor_->OnSendCompressedFrame( | 1619 framer_->debug_visitor_->OnSendCompressedFrame( |
| 1633 frame_ir->stream_id(), frame_ir->frame_type(), debug_payload_len, | 1620 frame_ir->stream_id(), frame_ir->frame_type(), debug_payload_len, |
| 1634 debug_total_size_); | 1621 debug_total_size_); |
| 1635 } | 1622 } |
| 1636 } | 1623 } |
| 1637 | 1624 |
| 1638 framer_->SetIsLastFrame(!has_next_frame_); | 1625 framer_->SetIsLastFrame(!has_next_frame_); |
| 1639 const size_t free_bytes_before = output->BytesFree(); | 1626 const size_t free_bytes_before = output->BytesFree(); |
| (...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2837 if (hpack_decoder_.get() == nullptr) { | 2824 if (hpack_decoder_.get() == nullptr) { |
| 2838 if (FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3) { | 2825 if (FLAGS_chromium_http2_flag_spdy_use_hpack_decoder3) { |
| 2839 hpack_decoder_ = SpdyMakeUnique<HpackDecoder3>(); | 2826 hpack_decoder_ = SpdyMakeUnique<HpackDecoder3>(); |
| 2840 } else { | 2827 } else { |
| 2841 hpack_decoder_ = SpdyMakeUnique<HpackDecoder>(); | 2828 hpack_decoder_ = SpdyMakeUnique<HpackDecoder>(); |
| 2842 } | 2829 } |
| 2843 } | 2830 } |
| 2844 return hpack_decoder_.get(); | 2831 return hpack_decoder_.get(); |
| 2845 } | 2832 } |
| 2846 | 2833 |
| 2847 void SpdyFramer::SetDecoderHeaderTableDebugVisitor( | |
| 2848 std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { | |
| 2849 if (decoder_adapter_ != nullptr) { | |
| 2850 decoder_adapter_->SetDecoderHeaderTableDebugVisitor(std::move(visitor)); | |
| 2851 } else { | |
| 2852 GetHpackDecoder()->SetHeaderTableDebugVisitor(std::move(visitor)); | |
| 2853 } | |
| 2854 } | |
| 2855 | |
| 2856 void SpdyFramer::SetEncoderHeaderTableDebugVisitor( | |
| 2857 std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { | |
| 2858 GetHpackEncoder()->SetHeaderTableDebugVisitor(std::move(visitor)); | |
| 2859 } | |
| 2860 | |
| 2861 size_t SpdyFramer::EstimateMemoryUsage() const { | |
| 2862 return SpdyEstimateMemoryUsage(current_frame_buffer_) + | |
| 2863 SpdyEstimateMemoryUsage(settings_scratch_) + | |
| 2864 SpdyEstimateMemoryUsage(altsvc_scratch_) + | |
| 2865 SpdyEstimateMemoryUsage(hpack_encoder_) + | |
| 2866 SpdyEstimateMemoryUsage(hpack_decoder_) + | |
| 2867 SpdyEstimateMemoryUsage(decoder_adapter_); | |
| 2868 } | |
| 2869 | |
| 2870 void SpdyFramer::UpdateHeaderEncoderTableSize(uint32_t value) { | 2834 void SpdyFramer::UpdateHeaderEncoderTableSize(uint32_t value) { |
| 2871 GetHpackEncoder()->ApplyHeaderTableSizeSetting(value); | 2835 GetHpackEncoder()->ApplyHeaderTableSizeSetting(value); |
| 2872 } | 2836 } |
| 2873 | 2837 |
| 2874 void SpdyFramer::UpdateHeaderDecoderTableSize(uint32_t value) { | 2838 void SpdyFramer::UpdateHeaderDecoderTableSize(uint32_t value) { |
| 2875 GetHpackDecoder()->ApplyHeaderTableSizeSetting(value); | 2839 GetHpackDecoder()->ApplyHeaderTableSizeSetting(value); |
| 2876 } | 2840 } |
| 2877 | 2841 |
| 2878 size_t SpdyFramer::header_encoder_table_size() const { | 2842 size_t SpdyFramer::header_encoder_table_size() const { |
| 2879 if (hpack_encoder_ == nullptr) { | 2843 if (hpack_encoder_ == nullptr) { |
| 2880 return kDefaultHeaderTableSizeSetting; | 2844 return kDefaultHeaderTableSizeSetting; |
| 2881 } else { | 2845 } else { |
| 2882 return hpack_encoder_->CurrentHeaderTableSizeSetting(); | 2846 return hpack_encoder_->CurrentHeaderTableSizeSetting(); |
| 2883 } | 2847 } |
| 2884 } | 2848 } |
| 2885 | 2849 |
| 2886 void SpdyFramer::SerializeHeaderBlockWithoutCompression( | 2850 void SpdyFramer::SerializeHeaderBlockWithoutCompression( |
| 2887 SpdyFrameBuilder* builder, | 2851 SpdyFrameBuilder* builder, |
| 2888 const SpdyHeaderBlock& header_block) const { | 2852 const SpdyHeaderBlock& header_block) const { |
| 2889 // Serialize number of headers. | 2853 // Serialize number of headers. |
| 2890 builder->WriteUInt32(header_block.size()); | 2854 builder->WriteUInt32(header_block.size()); |
| 2891 | 2855 |
| 2892 // Serialize each header. | 2856 // Serialize each header. |
| 2893 for (const auto& header : header_block) { | 2857 for (const auto& header : header_block) { |
| 2894 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); | 2858 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); |
| 2895 builder->WriteStringPiece32(header.second); | 2859 builder->WriteStringPiece32(header.second); |
| 2896 } | 2860 } |
| 2897 } | 2861 } |
| 2898 | 2862 |
| 2863 void SpdyFramer::SetDecoderHeaderTableDebugVisitor( | |
| 2864 std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { | |
| 2865 if (decoder_adapter_ != nullptr) { | |
| 2866 decoder_adapter_->SetDecoderHeaderTableDebugVisitor(std::move(visitor)); | |
| 2867 } else { | |
| 2868 GetHpackDecoder()->SetHeaderTableDebugVisitor(std::move(visitor)); | |
| 2869 } | |
| 2870 } | |
| 2871 | |
| 2872 void SpdyFramer::SetEncoderHeaderTableDebugVisitor( | |
| 2873 std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { | |
| 2874 GetHpackEncoder()->SetHeaderTableDebugVisitor(std::move(visitor)); | |
| 2875 } | |
| 2876 | |
| 2877 size_t SpdyFramer::EstimateMemoryUsage() const { | |
| 2878 return SpdyEstimateMemoryUsage(current_frame_buffer_) + | |
| 2879 SpdyEstimateMemoryUsage(settings_scratch_) + | |
| 2880 SpdyEstimateMemoryUsage(altsvc_scratch_) + | |
| 2881 SpdyEstimateMemoryUsage(hpack_encoder_) + | |
| 2882 SpdyEstimateMemoryUsage(hpack_decoder_) + | |
| 2883 SpdyEstimateMemoryUsage(decoder_adapter_); | |
| 2884 } | |
| 2885 | |
| 2899 } // namespace net | 2886 } // namespace net |
| OLD | NEW |