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

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

Issue 2895993003: Misc cleanup in net/spdy/core. (Closed)
Patch Set: Rebase. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698