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

Side by Side Diff: net/spdy/spdy_session.cc

Issue 2141993002: Remove many-many SpdyMajorVersion and NextProto arguments and members. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove OnSynStream() and OnSynReply(). Created 4 years, 5 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
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_pool.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/spdy_session.h" 5 #include "net/spdy/spdy_session.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <map> 9 #include <map>
10 #include <utility> 10 #include <utility>
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 54
55 namespace { 55 namespace {
56 56
57 const int kReadBufferSize = 8 * 1024; 57 const int kReadBufferSize = 8 * 1024;
58 const int kDefaultConnectionAtRiskOfLossSeconds = 10; 58 const int kDefaultConnectionAtRiskOfLossSeconds = 10;
59 const int kHungIntervalSeconds = 10; 59 const int kHungIntervalSeconds = 10;
60 60
61 // Minimum seconds that unclaimed pushed streams will be kept in memory. 61 // Minimum seconds that unclaimed pushed streams will be kept in memory.
62 const int kMinPushedStreamLifetimeSeconds = 300; 62 const int kMinPushedStreamLifetimeSeconds = 300;
63 63
64 std::unique_ptr<base::Value> NetLogSpdySynStreamSentCallback(
65 const SpdyHeaderBlock* headers,
66 bool fin,
67 bool unidirectional,
68 SpdyPriority spdy_priority,
69 SpdyStreamId stream_id,
70 NetLogCaptureMode capture_mode) {
71 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
72 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
73 dict->SetBoolean("fin", fin);
74 dict->SetBoolean("unidirectional", unidirectional);
75 dict->SetInteger("priority", static_cast<int>(spdy_priority));
76 dict->SetInteger("stream_id", stream_id);
77 return std::move(dict);
78 }
79
80 std::unique_ptr<base::Value> NetLogSpdyHeadersSentCallback( 64 std::unique_ptr<base::Value> NetLogSpdyHeadersSentCallback(
81 const SpdyHeaderBlock* headers, 65 const SpdyHeaderBlock* headers,
82 bool fin, 66 bool fin,
83 SpdyStreamId stream_id, 67 SpdyStreamId stream_id,
84 bool has_priority, 68 bool has_priority,
85 int weight, 69 int weight,
86 SpdyStreamId parent_stream_id, 70 SpdyStreamId parent_stream_id,
87 bool exclusive, 71 bool exclusive,
88 NetLogCaptureMode capture_mode) { 72 NetLogCaptureMode capture_mode) {
89 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 73 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
90 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); 74 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
91 dict->SetBoolean("fin", fin); 75 dict->SetBoolean("fin", fin);
92 dict->SetInteger("stream_id", stream_id); 76 dict->SetInteger("stream_id", stream_id);
93 dict->SetBoolean("has_priority", has_priority); 77 dict->SetBoolean("has_priority", has_priority);
94 if (has_priority) { 78 if (has_priority) {
95 dict->SetInteger("parent_stream_id", parent_stream_id); 79 dict->SetInteger("parent_stream_id", parent_stream_id);
96 dict->SetInteger("weight", weight); 80 dict->SetInteger("weight", weight);
97 dict->SetBoolean("exclusive", exclusive); 81 dict->SetBoolean("exclusive", exclusive);
98 } 82 }
99 return std::move(dict); 83 return std::move(dict);
100 } 84 }
101 85
102 std::unique_ptr<base::Value> NetLogSpdySynStreamReceivedCallback(
103 const SpdyHeaderBlock* headers,
104 bool fin,
105 bool unidirectional,
106 SpdyPriority spdy_priority,
107 SpdyStreamId stream_id,
108 SpdyStreamId associated_stream,
109 NetLogCaptureMode capture_mode) {
110 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
111 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
112 dict->SetBoolean("fin", fin);
113 dict->SetBoolean("unidirectional", unidirectional);
114 dict->SetInteger("priority", static_cast<int>(spdy_priority));
115 dict->SetInteger("stream_id", stream_id);
116 dict->SetInteger("associated_stream", associated_stream);
117 return std::move(dict);
118 }
119
120 std::unique_ptr<base::Value> NetLogSpdySynReplyOrHeadersReceivedCallback( 86 std::unique_ptr<base::Value> NetLogSpdySynReplyOrHeadersReceivedCallback(
121 const SpdyHeaderBlock* headers, 87 const SpdyHeaderBlock* headers,
122 bool fin, 88 bool fin,
123 SpdyStreamId stream_id, 89 SpdyStreamId stream_id,
124 NetLogCaptureMode capture_mode) { 90 NetLogCaptureMode capture_mode) {
125 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 91 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
126 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); 92 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
127 dict->SetBoolean("fin", fin); 93 dict->SetBoolean("fin", fin);
128 dict->SetInteger("stream_id", stream_id); 94 dict->SetInteger("stream_id", stream_id);
129 return std::move(dict); 95 return std::move(dict);
(...skipping 13 matching lines...) Expand all
143 const HostPortProxyPair* host_pair, 109 const HostPortProxyPair* host_pair,
144 NetLogCaptureMode /* capture_mode */) { 110 NetLogCaptureMode /* capture_mode */) {
145 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 111 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
146 dict->SetString("host", host_pair->first.ToString()); 112 dict->SetString("host", host_pair->first.ToString());
147 dict->SetString("proxy", host_pair->second.ToPacString()); 113 dict->SetString("proxy", host_pair->second.ToPacString());
148 return std::move(dict); 114 return std::move(dict);
149 } 115 }
150 116
151 std::unique_ptr<base::Value> NetLogSpdyInitializedCallback( 117 std::unique_ptr<base::Value> NetLogSpdyInitializedCallback(
152 NetLog::Source source, 118 NetLog::Source source,
153 const NextProto protocol_version,
154 NetLogCaptureMode /* capture_mode */) { 119 NetLogCaptureMode /* capture_mode */) {
155 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 120 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
156 if (source.IsValid()) { 121 if (source.IsValid()) {
157 source.AddToEventParameters(dict.get()); 122 source.AddToEventParameters(dict.get());
158 } 123 }
159 dict->SetString("protocol", 124 dict->SetString("protocol", SSLClientSocket::NextProtoToString(kProtoHTTP2));
160 SSLClientSocket::NextProtoToString(protocol_version));
161 return std::move(dict); 125 return std::move(dict);
162 } 126 }
163 127
164 std::unique_ptr<base::Value> NetLogSpdySettingsCallback( 128 std::unique_ptr<base::Value> NetLogSpdySettingsCallback(
165 const HostPortPair& host_port_pair, 129 const HostPortPair& host_port_pair,
166 bool clear_persisted, 130 bool clear_persisted,
167 NetLogCaptureMode /* capture_mode */) { 131 NetLogCaptureMode /* capture_mode */) {
168 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 132 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
169 dict->SetString("host", host_port_pair.ToString()); 133 dict->SetString("host", host_port_pair.ToString());
170 dict->SetBoolean("clear_persisted", clear_persisted); 134 dict->SetBoolean("clear_persisted", clear_persisted);
171 return std::move(dict); 135 return std::move(dict);
172 } 136 }
173 137
174 std::unique_ptr<base::Value> NetLogSpdySettingCallback( 138 std::unique_ptr<base::Value> NetLogSpdySettingCallback(
175 SpdySettingsIds id, 139 SpdySettingsIds id,
176 const SpdyMajorVersion protocol_version,
177 SpdySettingsFlags flags, 140 SpdySettingsFlags flags,
178 uint32_t value, 141 uint32_t value,
179 NetLogCaptureMode /* capture_mode */) { 142 NetLogCaptureMode /* capture_mode */) {
180 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 143 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
181 dict->SetInteger("id", 144 dict->SetInteger("id", SpdyConstants::SerializeSettingId(HTTP2, id));
182 SpdyConstants::SerializeSettingId(protocol_version, id));
183 dict->SetInteger("flags", flags); 145 dict->SetInteger("flags", flags);
184 dict->SetInteger("value", value); 146 dict->SetInteger("value", value);
185 return std::move(dict); 147 return std::move(dict);
186 } 148 }
187 149
188 std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback( 150 std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback(
189 const SettingsMap* settings, 151 const SettingsMap* settings,
190 const SpdyMajorVersion protocol_version,
191 NetLogCaptureMode /* capture_mode */) { 152 NetLogCaptureMode /* capture_mode */) {
192 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 153 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
193 std::unique_ptr<base::ListValue> settings_list(new base::ListValue()); 154 std::unique_ptr<base::ListValue> settings_list(new base::ListValue());
194 for (SettingsMap::const_iterator it = settings->begin(); 155 for (SettingsMap::const_iterator it = settings->begin();
195 it != settings->end(); ++it) { 156 it != settings->end(); ++it) {
196 const SpdySettingsIds id = it->first; 157 const SpdySettingsIds id = it->first;
197 const SpdySettingsFlags flags = it->second.first; 158 const SpdySettingsFlags flags = it->second.first;
198 const uint32_t value = it->second.second; 159 const uint32_t value = it->second.second;
199 settings_list->AppendString(base::StringPrintf( 160 settings_list->AppendString(base::StringPrintf(
200 "[id:%u flags:%u value:%u]", 161 "[id:%u flags:%u value:%u]",
201 SpdyConstants::SerializeSettingId(protocol_version, id), flags, value)); 162 SpdyConstants::SerializeSettingId(HTTP2, id), flags, value));
202 } 163 }
203 dict->Set("settings", std::move(settings_list)); 164 dict->Set("settings", std::move(settings_list));
204 return std::move(dict); 165 return std::move(dict);
205 } 166 }
206 167
207 std::unique_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback( 168 std::unique_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback(
208 SpdyStreamId stream_id, 169 SpdyStreamId stream_id,
209 uint32_t delta, 170 uint32_t delta,
210 NetLogCaptureMode /* capture_mode */) { 171 NetLogCaptureMode /* capture_mode */) {
211 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 172 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 return GOAWAY_FRAME_SIZE_ERROR; 426 return GOAWAY_FRAME_SIZE_ERROR;
466 case ERR_SPDY_COMPRESSION_ERROR: 427 case ERR_SPDY_COMPRESSION_ERROR:
467 return GOAWAY_COMPRESSION_ERROR; 428 return GOAWAY_COMPRESSION_ERROR;
468 case ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY: 429 case ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY:
469 return GOAWAY_INADEQUATE_SECURITY; 430 return GOAWAY_INADEQUATE_SECURITY;
470 default: 431 default:
471 return GOAWAY_PROTOCOL_ERROR; 432 return GOAWAY_PROTOCOL_ERROR;
472 } 433 }
473 } 434 }
474 435
475 void SplitPushedHeadersToRequestAndResponse(const SpdyHeaderBlock& headers,
476 SpdyMajorVersion protocol_version,
477 SpdyHeaderBlock* request_headers,
478 SpdyHeaderBlock* response_headers) {
479 DCHECK(response_headers);
480 DCHECK(request_headers);
481 for (SpdyHeaderBlock::const_iterator it = headers.begin();
482 it != headers.end();
483 ++it) {
484 SpdyHeaderBlock* to_insert = response_headers;
485 const char* host = protocol_version >= HTTP2 ? ":authority" : ":host";
486 static const char scheme[] = ":scheme";
487 static const char path[] = ":path";
488 if (it->first == host || it->first == scheme || it->first == path) {
489 to_insert = request_headers;
490 }
491 to_insert->insert(*it);
492 }
493 }
494
495 SpdyStreamRequest::SpdyStreamRequest() : weak_ptr_factory_(this) { 436 SpdyStreamRequest::SpdyStreamRequest() : weak_ptr_factory_(this) {
496 Reset(); 437 Reset();
497 } 438 }
498 439
499 SpdyStreamRequest::~SpdyStreamRequest() { 440 SpdyStreamRequest::~SpdyStreamRequest() {
500 CancelRequest(); 441 CancelRequest();
501 } 442 }
502 443
503 int SpdyStreamRequest::StartRequest( 444 int SpdyStreamRequest::StartRequest(
504 SpdyStreamType type, 445 SpdyStreamType type,
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 return true; 621 return true;
681 } 622 }
682 623
683 SpdySession::SpdySession(const SpdySessionKey& spdy_session_key, 624 SpdySession::SpdySession(const SpdySessionKey& spdy_session_key,
684 HttpServerProperties* http_server_properties, 625 HttpServerProperties* http_server_properties,
685 TransportSecurityState* transport_security_state, 626 TransportSecurityState* transport_security_state,
686 bool verify_domain_authentication, 627 bool verify_domain_authentication,
687 bool enable_sending_initial_data, 628 bool enable_sending_initial_data,
688 bool enable_ping_based_connection_checking, 629 bool enable_ping_based_connection_checking,
689 bool enable_priority_dependencies, 630 bool enable_priority_dependencies,
690 NextProto default_protocol,
691 size_t session_max_recv_window_size, 631 size_t session_max_recv_window_size,
692 size_t stream_max_recv_window_size, 632 size_t stream_max_recv_window_size,
693 TimeFunc time_func, 633 TimeFunc time_func,
694 ProxyDelegate* proxy_delegate, 634 ProxyDelegate* proxy_delegate,
695 NetLog* net_log) 635 NetLog* net_log)
696 : in_io_loop_(false), 636 : in_io_loop_(false),
697 spdy_session_key_(spdy_session_key), 637 spdy_session_key_(spdy_session_key),
698 pool_(NULL), 638 pool_(NULL),
699 http_server_properties_(http_server_properties), 639 http_server_properties_(http_server_properties),
700 transport_security_state_(transport_security_state), 640 transport_security_state_(transport_security_state),
(...skipping 19 matching lines...) Expand all
720 streams_abandoned_count_(0), 660 streams_abandoned_count_(0),
721 total_bytes_received_(0), 661 total_bytes_received_(0),
722 sent_settings_(false), 662 sent_settings_(false),
723 received_settings_(false), 663 received_settings_(false),
724 stalled_streams_(0), 664 stalled_streams_(0),
725 pings_in_flight_(0), 665 pings_in_flight_(0),
726 next_ping_id_(1), 666 next_ping_id_(1),
727 last_activity_time_(time_func()), 667 last_activity_time_(time_func()),
728 last_compressed_frame_len_(0), 668 last_compressed_frame_len_(0),
729 check_ping_status_pending_(false), 669 check_ping_status_pending_(false),
730 send_connection_header_prefix_(false),
731 session_send_window_size_(0), 670 session_send_window_size_(0),
732 session_max_recv_window_size_(session_max_recv_window_size), 671 session_max_recv_window_size_(session_max_recv_window_size),
733 session_recv_window_size_(0), 672 session_recv_window_size_(0),
734 session_unacked_recv_window_bytes_(0), 673 session_unacked_recv_window_bytes_(0),
735 stream_initial_send_window_size_( 674 stream_initial_send_window_size_(kDefaultInitialWindowSize),
736 GetDefaultInitialWindowSize(default_protocol)),
737 stream_max_recv_window_size_(stream_max_recv_window_size), 675 stream_max_recv_window_size_(stream_max_recv_window_size),
738 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP2_SESSION)), 676 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP2_SESSION)),
739 verify_domain_authentication_(verify_domain_authentication), 677 verify_domain_authentication_(verify_domain_authentication),
740 enable_sending_initial_data_(enable_sending_initial_data), 678 enable_sending_initial_data_(enable_sending_initial_data),
741 enable_ping_based_connection_checking_( 679 enable_ping_based_connection_checking_(
742 enable_ping_based_connection_checking), 680 enable_ping_based_connection_checking),
743 protocol_(default_protocol),
744 connection_at_risk_of_loss_time_( 681 connection_at_risk_of_loss_time_(
745 base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)), 682 base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)),
746 hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)), 683 hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
747 proxy_delegate_(proxy_delegate), 684 proxy_delegate_(proxy_delegate),
748 time_func_(time_func), 685 time_func_(time_func),
749 priority_dependencies_enabled_(enable_priority_dependencies), 686 priority_dependencies_enabled_(enable_priority_dependencies),
750 weak_factory_(this) { 687 weak_factory_(this) {
751 DCHECK_GE(protocol_, kProtoSPDYMinimumVersion);
752 DCHECK_LE(protocol_, kProtoSPDYMaximumVersion);
753 DCHECK(HttpStreamFactory::spdy_enabled()); 688 DCHECK(HttpStreamFactory::spdy_enabled());
754 net_log_.BeginEvent( 689 net_log_.BeginEvent(
755 NetLog::TYPE_HTTP2_SESSION, 690 NetLog::TYPE_HTTP2_SESSION,
756 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair())); 691 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair()));
757 next_unclaimed_push_stream_sweep_time_ = time_func_() + 692 next_unclaimed_push_stream_sweep_time_ = time_func_() +
758 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); 693 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
759 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. 694 // TODO(mbelshe): consider randomization of the stream_hi_water_mark.
760 } 695 }
761 696
762 SpdySession::~SpdySession() { 697 SpdySession::~SpdySession() {
(...skipping 25 matching lines...) Expand all
788 DCHECK(certificate_error_code == OK || 723 DCHECK(certificate_error_code == OK ||
789 certificate_error_code < ERR_IO_PENDING); 724 certificate_error_code < ERR_IO_PENDING);
790 // TODO(akalin): Check connection->is_initialized() instead. This 725 // TODO(akalin): Check connection->is_initialized() instead. This
791 // requires re-working CreateFakeSpdySession(), though. 726 // requires re-working CreateFakeSpdySession(), though.
792 DCHECK(connection->socket()); 727 DCHECK(connection->socket());
793 728
794 connection_ = std::move(connection); 729 connection_ = std::move(connection);
795 is_secure_ = is_secure; 730 is_secure_ = is_secure;
796 certificate_error_code_ = certificate_error_code; 731 certificate_error_code_ = certificate_error_code;
797 732
798 NextProto protocol_negotiated = 733 session_send_window_size_ = kDefaultInitialWindowSize;
799 connection_->socket()->GetNegotiatedProtocol(); 734 session_recv_window_size_ = kDefaultInitialWindowSize;
800 if (protocol_negotiated != kProtoUnknown) {
801 protocol_ = protocol_negotiated;
802 stream_initial_send_window_size_ = GetDefaultInitialWindowSize(protocol_);
803 }
804 DCHECK_GE(protocol_, kProtoSPDYMinimumVersion);
805 DCHECK_LE(protocol_, kProtoSPDYMaximumVersion);
806 735
807 if (protocol_ == kProtoHTTP2) 736 buffered_spdy_framer_.reset(new BufferedSpdyFramer());
808 send_connection_header_prefix_ = true;
809
810 session_send_window_size_ = GetDefaultInitialWindowSize(protocol_);
811 session_recv_window_size_ = GetDefaultInitialWindowSize(protocol_);
812
813 buffered_spdy_framer_.reset(
814 new BufferedSpdyFramer(NextProtoToSpdyMajorVersion(protocol_)));
815 buffered_spdy_framer_->set_visitor(this); 737 buffered_spdy_framer_->set_visitor(this);
816 buffered_spdy_framer_->set_debug_visitor(this); 738 buffered_spdy_framer_->set_debug_visitor(this);
817 UMA_HISTOGRAM_ENUMERATION(
818 "Net.SpdyVersion3", protocol_ - kProtoSPDYHistogramOffset,
819 kProtoSPDYMaximumVersion - kProtoSPDYHistogramOffset + 1);
820 739
821 net_log_.AddEvent( 740 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_INITIALIZED,
822 NetLog::TYPE_HTTP2_SESSION_INITIALIZED, 741 base::Bind(&NetLogSpdyInitializedCallback,
823 base::Bind(&NetLogSpdyInitializedCallback, 742 connection_->socket()->NetLog().source()));
824 connection_->socket()->NetLog().source(), protocol_));
825 743
826 DCHECK_EQ(availability_state_, STATE_AVAILABLE); 744 DCHECK_EQ(availability_state_, STATE_AVAILABLE);
827 connection_->AddHigherLayeredPool(this); 745 connection_->AddHigherLayeredPool(this);
828 if (enable_sending_initial_data_) 746 if (enable_sending_initial_data_)
829 SendInitialData(); 747 SendInitialData();
830 pool_ = pool; 748 pool_ = pool;
831 749
832 // Bootstrap the read loop. 750 // Bootstrap the read loop.
833 base::ThreadTaskRunnerHandle::Get()->PostTask( 751 base::ThreadTaskRunnerHandle::Get()->PostTask(
834 FROM_HERE, 752 FROM_HERE,
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 base::ThreadTaskRunnerHandle::Get()->PostTask( 945 base::ThreadTaskRunnerHandle::Get()->PostTask(
1028 FROM_HERE, base::Bind(&SpdySession::CompleteStreamRequest, 946 FROM_HERE, base::Bind(&SpdySession::CompleteStreamRequest,
1029 weak_factory_.GetWeakPtr(), pending_request)); 947 weak_factory_.GetWeakPtr(), pending_request));
1030 } 948 }
1031 } 949 }
1032 950
1033 void SpdySession::AddPooledAlias(const SpdySessionKey& alias_key) { 951 void SpdySession::AddPooledAlias(const SpdySessionKey& alias_key) {
1034 pooled_aliases_.insert(alias_key); 952 pooled_aliases_.insert(alias_key);
1035 } 953 }
1036 954
1037 SpdyMajorVersion SpdySession::GetProtocolVersion() const {
1038 DCHECK(buffered_spdy_framer_.get());
1039 return buffered_spdy_framer_->protocol_version();
1040 }
1041
1042 bool SpdySession::HasAcceptableTransportSecurity() const { 955 bool SpdySession::HasAcceptableTransportSecurity() const {
1043 // If we're not even using TLS, we have no standards to meet. 956 // If we're not even using TLS, we have no standards to meet.
1044 if (!is_secure_) { 957 if (!is_secure_) {
1045 return true; 958 return true;
1046 } 959 }
1047 960
1048 // We don't enforce transport security standards for older SPDY versions.
1049 if (GetProtocolVersion() < HTTP2) {
1050 return true;
1051 }
1052
1053 SSLInfo ssl_info; 961 SSLInfo ssl_info;
1054 CHECK(connection_->socket()->GetSSLInfo(&ssl_info)); 962 CHECK(connection_->socket()->GetSSLInfo(&ssl_info));
1055 963
1056 // HTTP/2 requires TLS 1.2+ 964 // HTTP/2 requires TLS 1.2+
1057 if (SSLConnectionStatusToVersion(ssl_info.connection_status) < 965 if (SSLConnectionStatusToVersion(ssl_info.connection_status) <
1058 SSL_CONNECTION_VERSION_TLS1_2) { 966 SSL_CONNECTION_VERSION_TLS1_2) {
1059 return false; 967 return false;
1060 } 968 }
1061 969
1062 if (!IsTLSCipherSuiteAllowedByHTTP2( 970 if (!IsTLSCipherSuiteAllowedByHTTP2(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 RequestPriority priority, 1004 RequestPriority priority,
1097 SpdyControlFlags flags, 1005 SpdyControlFlags flags,
1098 SpdyHeaderBlock block) { 1006 SpdyHeaderBlock block) {
1099 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); 1007 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id);
1100 CHECK(it != active_streams_.end()); 1008 CHECK(it != active_streams_.end());
1101 CHECK_EQ(it->second.stream->stream_id(), stream_id); 1009 CHECK_EQ(it->second.stream->stream_id(), stream_id);
1102 1010
1103 SendPrefacePingIfNoneInFlight(); 1011 SendPrefacePingIfNoneInFlight();
1104 1012
1105 DCHECK(buffered_spdy_framer_.get()); 1013 DCHECK(buffered_spdy_framer_.get());
1106 SpdyPriority spdy_priority = 1014 SpdyPriority spdy_priority = ConvertRequestPriorityToSpdyPriority(priority);
1107 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion());
1108 1015
1109 std::unique_ptr<SpdySerializedFrame> syn_frame; 1016 std::unique_ptr<SpdySerializedFrame> syn_frame;
1110 if (GetProtocolVersion() <= SPDY3) { 1017 bool has_priority = true;
1111 if (net_log().IsCapturing()) { 1018 int weight = Spdy3PriorityToHttp2Weight(spdy_priority);
1112 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SYN_STREAM, 1019 SpdyStreamId dependent_stream_id = 0;
1113 base::Bind(&NetLogSpdySynStreamSentCallback, &block, 1020 bool exclusive = false;
1114 (flags & CONTROL_FLAG_FIN) != 0,
1115 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0,
1116 spdy_priority, stream_id));
1117 }
1118 1021
1119 SpdySynStreamIR syn_stream(stream_id, std::move(block)); 1022 if (priority_dependencies_enabled_) {
1120 syn_stream.set_associated_to_stream_id(0); 1023 priority_dependency_state_.OnStreamSynSent(
1121 syn_stream.set_priority(spdy_priority); 1024 stream_id, spdy_priority, &dependent_stream_id, &exclusive);
1122 syn_stream.set_fin((flags & CONTROL_FLAG_FIN) != 0); 1025 }
1123 syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
1124 syn_frame.reset(new SpdySerializedFrame(
1125 buffered_spdy_framer_->SerializeFrame(syn_stream)));
1126 1026
1127 } else { 1027 if (net_log().IsCapturing()) {
1128 bool has_priority = true; 1028 net_log().AddEvent(
1129 int weight = Spdy3PriorityToHttp2Weight(spdy_priority); 1029 NetLog::TYPE_HTTP2_SESSION_SEND_HEADERS,
1130 SpdyStreamId dependent_stream_id = 0; 1030 base::Bind(&NetLogSpdyHeadersSentCallback, &block,
1131 bool exclusive = false; 1031 (flags & CONTROL_FLAG_FIN) != 0, stream_id, has_priority,
1032 weight, dependent_stream_id, exclusive));
1033 }
1132 1034
1133 if (priority_dependencies_enabled_) { 1035 SpdyHeadersIR headers(stream_id, std::move(block));
1134 priority_dependency_state_.OnStreamSynSent( 1036 headers.set_has_priority(has_priority);
1135 stream_id, spdy_priority, &dependent_stream_id, &exclusive); 1037 headers.set_weight(weight);
1136 } 1038 headers.set_parent_stream_id(dependent_stream_id);
1137 1039 headers.set_exclusive(exclusive);
1138 if (net_log().IsCapturing()) { 1040 headers.set_fin((flags & CONTROL_FLAG_FIN) != 0);
1139 net_log().AddEvent( 1041 syn_frame.reset(
1140 NetLog::TYPE_HTTP2_SESSION_SEND_HEADERS, 1042 new SpdySerializedFrame(buffered_spdy_framer_->SerializeFrame(headers)));
1141 base::Bind(&NetLogSpdyHeadersSentCallback, &block,
1142 (flags & CONTROL_FLAG_FIN) != 0, stream_id, has_priority,
1143 weight, dependent_stream_id, exclusive));
1144 }
1145
1146 SpdyHeadersIR headers(stream_id, std::move(block));
1147 headers.set_has_priority(has_priority);
1148 headers.set_weight(weight);
1149 headers.set_parent_stream_id(dependent_stream_id);
1150 headers.set_exclusive(exclusive);
1151 headers.set_fin((flags & CONTROL_FLAG_FIN) != 0);
1152 syn_frame.reset(new SpdySerializedFrame(
1153 buffered_spdy_framer_->SerializeFrame(headers)));
1154 }
1155 1043
1156 streams_initiated_count_++; 1044 streams_initiated_count_++;
1157 1045
1158 return syn_frame; 1046 return syn_frame;
1159 } 1047 }
1160 1048
1161 std::unique_ptr<SpdyBuffer> SpdySession::CreateDataBuffer( 1049 std::unique_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(
1162 SpdyStreamId stream_id, 1050 SpdyStreamId stream_id,
1163 IOBuffer* data, 1051 IOBuffer* data,
1164 int len, 1052 int len,
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 2107
2220 if (clear_persisted) 2108 if (clear_persisted)
2221 http_server_properties_->ClearSpdySettings(GetServer()); 2109 http_server_properties_->ClearSpdySettings(GetServer());
2222 2110
2223 if (net_log_.IsCapturing()) { 2111 if (net_log_.IsCapturing()) {
2224 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTINGS, 2112 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTINGS,
2225 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), 2113 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(),
2226 clear_persisted)); 2114 clear_persisted));
2227 } 2115 }
2228 2116
2229 if (GetProtocolVersion() >= HTTP2) { 2117 // Send an acknowledgment of the setting.
2230 // Send an acknowledgment of the setting. 2118 SpdySettingsIR settings_ir;
2231 SpdySettingsIR settings_ir; 2119 settings_ir.set_is_ack(true);
2232 settings_ir.set_is_ack(true); 2120 EnqueueSessionWrite(
2233 EnqueueSessionWrite( 2121 HIGHEST, SETTINGS,
2234 HIGHEST, SETTINGS, 2122 std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame(
2235 std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame( 2123 buffered_spdy_framer_->SerializeFrame(settings_ir))));
2236 buffered_spdy_framer_->SerializeFrame(settings_ir))));
2237 }
2238 } 2124 }
2239 2125
2240 void SpdySession::OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) { 2126 void SpdySession::OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) {
2241 CHECK(in_io_loop_); 2127 CHECK(in_io_loop_);
2242 2128
2243 HandleSetting(id, value); 2129 HandleSetting(id, value);
2244 http_server_properties_->SetSpdySetting( 2130 http_server_properties_->SetSpdySetting(
2245 GetServer(), id, static_cast<SpdySettingsFlags>(flags), value); 2131 GetServer(), id, static_cast<SpdySettingsFlags>(flags), value);
2246 received_settings_ = true; 2132 received_settings_ = true;
2247 2133
2248 // Log the setting. 2134 // Log the setting.
2249 const SpdyMajorVersion protocol_version = GetProtocolVersion();
2250 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTING, 2135 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTING,
2251 base::Bind(&NetLogSpdySettingCallback, id, protocol_version, 2136 base::Bind(&NetLogSpdySettingCallback, id,
2252 static_cast<SpdySettingsFlags>(flags), value)); 2137 static_cast<SpdySettingsFlags>(flags), value));
2253 } 2138 }
2254 2139
2255 void SpdySession::OnSendCompressedFrame( 2140 void SpdySession::OnSendCompressedFrame(
2256 SpdyStreamId stream_id, 2141 SpdyStreamId stream_id,
2257 SpdyFrameType type, 2142 SpdyFrameType type,
2258 size_t payload_len, 2143 size_t payload_len,
2259 size_t frame_len) { 2144 size_t frame_len) {
2260 if (type != SYN_STREAM && type != HEADERS) 2145 if (type != SYN_STREAM && type != HEADERS)
2261 return; 2146 return;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2307 int rv = stream->OnInitialResponseHeadersReceived( 2192 int rv = stream->OnInitialResponseHeadersReceived(
2308 response_headers, response_time, recv_first_byte_time); 2193 response_headers, response_time, recv_first_byte_time);
2309 if (rv < 0) { 2194 if (rv < 0) {
2310 DCHECK_NE(rv, ERR_IO_PENDING); 2195 DCHECK_NE(rv, ERR_IO_PENDING);
2311 DCHECK(active_streams_.find(stream_id) == active_streams_.end()); 2196 DCHECK(active_streams_.find(stream_id) == active_streams_.end());
2312 } 2197 }
2313 2198
2314 return rv; 2199 return rv;
2315 } 2200 }
2316 2201
2317 void SpdySession::OnSynStream(SpdyStreamId stream_id,
2318 SpdyStreamId associated_stream_id,
2319 SpdyPriority priority,
2320 bool fin,
2321 bool unidirectional,
2322 const SpdyHeaderBlock& headers) {
2323 CHECK(in_io_loop_);
2324
2325 DCHECK_LE(GetProtocolVersion(), SPDY3);
2326
2327 base::Time response_time = base::Time::Now();
2328 base::TimeTicks recv_first_byte_time = time_func_();
2329
2330 if (net_log_.IsCapturing()) {
2331 net_log_.AddEvent(
2332 NetLog::TYPE_HTTP2_SESSION_PUSHED_SYN_STREAM,
2333 base::Bind(&NetLogSpdySynStreamReceivedCallback, &headers, fin,
2334 unidirectional, priority, stream_id, associated_stream_id));
2335 }
2336
2337 // Split headers to simulate push promise and response.
2338 SpdyHeaderBlock request_headers;
2339 SpdyHeaderBlock response_headers;
2340 SplitPushedHeadersToRequestAndResponse(
2341 headers, GetProtocolVersion(), &request_headers, &response_headers);
2342
2343 if (!TryCreatePushStream(
2344 stream_id, associated_stream_id, priority, request_headers))
2345 return;
2346
2347 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id);
2348 if (active_it == active_streams_.end()) {
2349 NOTREACHED();
2350 return;
2351 }
2352
2353 OnInitialResponseHeadersReceived(response_headers, response_time,
2354 recv_first_byte_time,
2355 active_it->second.stream);
2356 }
2357
2358 void SpdySession::DeleteExpiredPushedStreams() { 2202 void SpdySession::DeleteExpiredPushedStreams() {
2359 if (unclaimed_pushed_streams_.empty()) 2203 if (unclaimed_pushed_streams_.empty())
2360 return; 2204 return;
2361 2205
2362 // Check that adequate time has elapsed since the last sweep. 2206 // Check that adequate time has elapsed since the last sweep.
2363 if (time_func_() < next_unclaimed_push_stream_sweep_time_) 2207 if (time_func_() < next_unclaimed_push_stream_sweep_time_)
2364 return; 2208 return;
2365 2209
2366 // Gather old streams to delete. 2210 // Gather old streams to delete.
2367 base::TimeTicks minimum_freshness = time_func_() - 2211 base::TimeTicks minimum_freshness = time_func_() -
(...skipping 17 matching lines...) Expand all
2385 // CloseActiveStreamIterator() will remove the stream from 2229 // CloseActiveStreamIterator() will remove the stream from
2386 // |unclaimed_pushed_streams_|. 2230 // |unclaimed_pushed_streams_|.
2387 ResetStreamIterator( 2231 ResetStreamIterator(
2388 active_it, RST_STREAM_REFUSED_STREAM, "Stream not claimed."); 2232 active_it, RST_STREAM_REFUSED_STREAM, "Stream not claimed.");
2389 } 2233 }
2390 2234
2391 next_unclaimed_push_stream_sweep_time_ = time_func_() + 2235 next_unclaimed_push_stream_sweep_time_ = time_func_() +
2392 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); 2236 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
2393 } 2237 }
2394 2238
2395 void SpdySession::OnSynReply(SpdyStreamId stream_id,
2396 bool fin,
2397 const SpdyHeaderBlock& headers) {
2398 CHECK(in_io_loop_);
2399
2400 base::Time response_time = base::Time::Now();
2401 base::TimeTicks recv_first_byte_time = time_func_();
2402
2403 if (net_log().IsCapturing()) {
2404 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SYN_REPLY,
2405 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback,
2406 &headers, fin, stream_id));
2407 }
2408
2409 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
2410 if (it == active_streams_.end()) {
2411 // NOTE: it may just be that the stream was cancelled.
2412 return;
2413 }
2414
2415 SpdyStream* stream = it->second.stream;
2416 CHECK_EQ(stream->stream_id(), stream_id);
2417
2418 stream->AddRawReceivedBytes(last_compressed_frame_len_);
2419 last_compressed_frame_len_ = 0;
2420
2421 if (GetProtocolVersion() >= HTTP2) {
2422 const std::string& error = "HTTP/2 wasn't expecting SYN_REPLY.";
2423 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
2424 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error);
2425 return;
2426 }
2427 if (!it->second.waiting_for_syn_reply) {
2428 const std::string& error =
2429 "Received duplicate SYN_REPLY for stream.";
2430 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
2431 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error);
2432 return;
2433 }
2434 it->second.waiting_for_syn_reply = false;
2435
2436 ignore_result(OnInitialResponseHeadersReceived(
2437 headers, response_time, recv_first_byte_time, stream));
2438 }
2439
2440 void SpdySession::OnHeaders(SpdyStreamId stream_id, 2239 void SpdySession::OnHeaders(SpdyStreamId stream_id,
2441 bool has_priority, 2240 bool has_priority,
2442 int weight, 2241 int weight,
2443 SpdyStreamId parent_stream_id, 2242 SpdyStreamId parent_stream_id,
2444 bool exclusive, 2243 bool exclusive,
2445 bool fin, 2244 bool fin,
2446 const SpdyHeaderBlock& headers) { 2245 const SpdyHeaderBlock& headers) {
2447 CHECK(in_io_loop_); 2246 CHECK(in_io_loop_);
2448 2247
2449 if (net_log().IsCapturing()) { 2248 if (net_log().IsCapturing()) {
(...skipping 12 matching lines...) Expand all
2462 SpdyStream* stream = it->second.stream; 2261 SpdyStream* stream = it->second.stream;
2463 CHECK_EQ(stream->stream_id(), stream_id); 2262 CHECK_EQ(stream->stream_id(), stream_id);
2464 2263
2465 stream->AddRawReceivedBytes(last_compressed_frame_len_); 2264 stream->AddRawReceivedBytes(last_compressed_frame_len_);
2466 last_compressed_frame_len_ = 0; 2265 last_compressed_frame_len_ = 0;
2467 2266
2468 base::Time response_time = base::Time::Now(); 2267 base::Time response_time = base::Time::Now();
2469 base::TimeTicks recv_first_byte_time = time_func_(); 2268 base::TimeTicks recv_first_byte_time = time_func_();
2470 2269
2471 if (it->second.waiting_for_syn_reply) { 2270 if (it->second.waiting_for_syn_reply) {
2472 if (GetProtocolVersion() < HTTP2) {
2473 const std::string& error =
2474 "Was expecting SYN_REPLY, not HEADERS.";
2475 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
2476 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error);
2477 return;
2478 }
2479
2480 it->second.waiting_for_syn_reply = false; 2271 it->second.waiting_for_syn_reply = false;
2481 ignore_result(OnInitialResponseHeadersReceived( 2272 ignore_result(OnInitialResponseHeadersReceived(
2482 headers, response_time, recv_first_byte_time, stream)); 2273 headers, response_time, recv_first_byte_time, stream));
2483 } else if (it->second.stream->IsReservedRemote()) { 2274 } else if (it->second.stream->IsReservedRemote()) {
2484 ignore_result(OnInitialResponseHeadersReceived( 2275 ignore_result(OnInitialResponseHeadersReceived(
2485 headers, response_time, recv_first_byte_time, stream)); 2276 headers, response_time, recv_first_byte_time, stream));
2486 } else { 2277 } else {
2487 int rv = stream->OnAdditionalResponseHeadersReceived(headers); 2278 int rv = stream->OnAdditionalResponseHeadersReceived(headers);
2488 if (rv < 0) { 2279 if (rv < 0) {
2489 DCHECK_NE(rv, ERR_IO_PENDING); 2280 DCHECK_NE(rv, ERR_IO_PENDING);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2627 } 2418 }
2628 2419
2629 void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) { 2420 void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) {
2630 CHECK(in_io_loop_); 2421 CHECK(in_io_loop_);
2631 2422
2632 net_log_.AddEvent( 2423 net_log_.AddEvent(
2633 NetLog::TYPE_HTTP2_SESSION_PING, 2424 NetLog::TYPE_HTTP2_SESSION_PING,
2634 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received")); 2425 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received"));
2635 2426
2636 // Send response to a PING from server. 2427 // Send response to a PING from server.
2637 if ((protocol_ == kProtoHTTP2 && !is_ack) || 2428 if (!is_ack) {
2638 (protocol_ < kProtoHTTP2 && unique_id % 2 == 0)) {
2639 WritePingFrame(unique_id, true); 2429 WritePingFrame(unique_id, true);
2640 return; 2430 return;
2641 } 2431 }
2642 2432
2643 --pings_in_flight_; 2433 --pings_in_flight_;
2644 if (pings_in_flight_ < 0) { 2434 if (pings_in_flight_ < 0) {
2645 RecordProtocolErrorHistogram(PROTOCOL_ERROR_UNEXPECTED_PING); 2435 RecordProtocolErrorHistogram(PROTOCOL_ERROR_UNEXPECTED_PING);
2646 DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, "pings_in_flight_ is < 0."); 2436 DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, "pings_in_flight_ is < 0.");
2647 pings_in_flight_ = 0; 2437 pings_in_flight_ = 0;
2648 return; 2438 return;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2724 if (stream_id <= last_accepted_push_stream_id_) { 2514 if (stream_id <= last_accepted_push_stream_id_) {
2725 LOG(WARNING) << "Received push stream id lesser or equal to the last " 2515 LOG(WARNING) << "Received push stream id lesser or equal to the last "
2726 << "accepted before " << stream_id; 2516 << "accepted before " << stream_id;
2727 CloseSessionOnError( 2517 CloseSessionOnError(
2728 ERR_SPDY_PROTOCOL_ERROR, 2518 ERR_SPDY_PROTOCOL_ERROR,
2729 "New push stream id must be greater than the last accepted."); 2519 "New push stream id must be greater than the last accepted.");
2730 return false; 2520 return false;
2731 } 2521 }
2732 2522
2733 if (IsStreamActive(stream_id)) { 2523 if (IsStreamActive(stream_id)) {
2734 // For SPDY3 and higher we should not get here, we'll start going away 2524 // We should not get here, we'll start going away earlier on
2735 // earlier on |last_seen_push_stream_id_| check. 2525 // |last_seen_push_stream_id_| check.
2736 CHECK_GT(SPDY3, GetProtocolVersion());
2737 LOG(WARNING) << "Received push for active stream " << stream_id; 2526 LOG(WARNING) << "Received push for active stream " << stream_id;
2738 return false; 2527 return false;
2739 } 2528 }
2740 2529
2741 last_accepted_push_stream_id_ = stream_id; 2530 last_accepted_push_stream_id_ = stream_id;
2742 2531
2743 RequestPriority request_priority = 2532 RequestPriority request_priority =
2744 ConvertSpdyPriorityToRequestPriority(priority, GetProtocolVersion()); 2533 ConvertSpdyPriorityToRequestPriority(priority);
2745 2534
2746 if (availability_state_ == STATE_GOING_AWAY) { 2535 if (availability_state_ == STATE_GOING_AWAY) {
2747 // TODO(akalin): This behavior isn't in the SPDY spec, although it 2536 // TODO(akalin): This behavior isn't in the SPDY spec, although it
2748 // probably should be. 2537 // probably should be.
2749 EnqueueResetStreamFrame(stream_id, 2538 EnqueueResetStreamFrame(stream_id,
2750 request_priority, 2539 request_priority,
2751 RST_STREAM_REFUSED_STREAM, 2540 RST_STREAM_REFUSED_STREAM,
2752 "push stream request received when going away"); 2541 "push stream request received when going away");
2753 return false; 2542 return false;
2754 } 2543 }
2755 2544
2756 if (associated_stream_id == 0) { 2545 if (associated_stream_id == 0) {
2757 // In HTTP/2 0 stream id in PUSH_PROMISE frame leads to framer error and 2546 // In HTTP/2 0 stream id in PUSH_PROMISE frame leads to framer error and
2758 // session going away. We should never get here. 2547 // session going away. We should never get here.
2759 CHECK_GT(HTTP2, GetProtocolVersion());
2760 std::string description = base::StringPrintf( 2548 std::string description = base::StringPrintf(
2761 "Received invalid associated stream id %d for pushed stream %d", 2549 "Received invalid associated stream id %d for pushed stream %d",
2762 associated_stream_id, 2550 associated_stream_id,
2763 stream_id); 2551 stream_id);
2764 EnqueueResetStreamFrame( 2552 EnqueueResetStreamFrame(
2765 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, description); 2553 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, description);
2766 return false; 2554 return false;
2767 } 2555 }
2768 2556
2769 streams_pushed_count_++; 2557 streams_pushed_count_++;
2770 2558
2771 // TODO(mbelshe): DCHECK that this is a GET method? 2559 // TODO(mbelshe): DCHECK that this is a GET method?
2772 2560
2773 // Verify that the response had a URL for us. 2561 // Verify that the response had a URL for us.
2774 GURL gurl = GetUrlFromHeaderBlock(headers, GetProtocolVersion()); 2562 GURL gurl = GetUrlFromHeaderBlock(headers);
2775 if (!gurl.is_valid()) { 2563 if (!gurl.is_valid()) {
2776 EnqueueResetStreamFrame(stream_id, 2564 EnqueueResetStreamFrame(stream_id,
2777 request_priority, 2565 request_priority,
2778 RST_STREAM_PROTOCOL_ERROR, 2566 RST_STREAM_PROTOCOL_ERROR,
2779 "Pushed stream url was invalid: " + gurl.spec()); 2567 "Pushed stream url was invalid: " + gurl.spec());
2780 return false; 2568 return false;
2781 } 2569 }
2782 2570
2783 // Verify we have a valid stream association. 2571 // Verify we have a valid stream association.
2784 ActiveStreamMap::iterator associated_it = 2572 ActiveStreamMap::iterator associated_it =
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2853 return false; 2641 return false;
2854 } 2642 }
2855 2643
2856 std::unique_ptr<SpdyStream> stream( 2644 std::unique_ptr<SpdyStream> stream(
2857 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority, 2645 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority,
2858 stream_initial_send_window_size_, 2646 stream_initial_send_window_size_,
2859 stream_max_recv_window_size_, net_log_)); 2647 stream_max_recv_window_size_, net_log_));
2860 stream->set_stream_id(stream_id); 2648 stream->set_stream_id(stream_id);
2861 2649
2862 // In spdy4/http2 PUSH_PROMISE arrives on associated stream. 2650 // In spdy4/http2 PUSH_PROMISE arrives on associated stream.
2863 if (associated_it != active_streams_.end() && GetProtocolVersion() >= HTTP2) { 2651 if (associated_it != active_streams_.end()) {
2864 associated_it->second.stream->AddRawReceivedBytes( 2652 associated_it->second.stream->AddRawReceivedBytes(
2865 last_compressed_frame_len_); 2653 last_compressed_frame_len_);
2866 } else { 2654 } else {
2867 stream->AddRawReceivedBytes(last_compressed_frame_len_); 2655 stream->AddRawReceivedBytes(last_compressed_frame_len_);
2868 } 2656 }
2869 2657
2870 last_compressed_frame_len_ = 0; 2658 last_compressed_frame_len_ = 0;
2871 2659
2872 UnclaimedPushedStreamContainer::const_iterator inserted_pushed_it = 2660 UnclaimedPushedStreamContainer::const_iterator inserted_pushed_it =
2873 unclaimed_pushed_streams_.insert(pushed_it, gurl, stream_id, 2661 unclaimed_pushed_streams_.insert(pushed_it, gurl, stream_id,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2911 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); 2699 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id);
2912 CHECK(it != active_streams_.end()); 2700 CHECK(it != active_streams_.end());
2913 CHECK_EQ(it->second.stream->stream_id(), stream_id); 2701 CHECK_EQ(it->second.stream->stream_id(), stream_id);
2914 SendWindowUpdateFrame( 2702 SendWindowUpdateFrame(
2915 stream_id, delta_window_size, it->second.stream->priority()); 2703 stream_id, delta_window_size, it->second.stream->priority());
2916 } 2704 }
2917 2705
2918 void SpdySession::SendInitialData() { 2706 void SpdySession::SendInitialData() {
2919 DCHECK(enable_sending_initial_data_); 2707 DCHECK(enable_sending_initial_data_);
2920 2708
2921 if (send_connection_header_prefix_) { 2709 std::unique_ptr<SpdySerializedFrame> connection_header_prefix_frame(
2922 DCHECK_EQ(protocol_, kProtoHTTP2); 2710 new SpdySerializedFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix),
2923 std::unique_ptr<SpdySerializedFrame> connection_header_prefix_frame( 2711 kHttp2ConnectionHeaderPrefixSize,
2924 new SpdySerializedFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix), 2712 false /* take_ownership */));
2925 kHttp2ConnectionHeaderPrefixSize, 2713 // Count the prefix as part of the subsequent SETTINGS frame.
2926 false /* take_ownership */)); 2714 EnqueueSessionWrite(HIGHEST, SETTINGS,
2927 // Count the prefix as part of the subsequent SETTINGS frame. 2715 std::move(connection_header_prefix_frame));
2928 EnqueueSessionWrite(HIGHEST, SETTINGS,
2929 std::move(connection_header_prefix_frame));
2930 }
2931 2716
2932 // First, notify the server about the settings they should use when 2717 // First, notify the server about the settings they should use when
2933 // communicating with us. 2718 // communicating with us.
2934 SettingsMap settings_map; 2719 SettingsMap settings_map;
2935 // Create a new settings frame notifying the server of our 2720 // Create a new settings frame notifying the server of our
2936 // max concurrent streams and initial window size. 2721 // max concurrent streams and initial window size.
2937 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] = 2722 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] =
2938 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); 2723 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
2939 if (stream_max_recv_window_size_ != GetDefaultInitialWindowSize(protocol_)) { 2724 if (stream_max_recv_window_size_ != kDefaultInitialWindowSize) {
2940 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] = 2725 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] =
2941 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, stream_max_recv_window_size_); 2726 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, stream_max_recv_window_size_);
2942 } 2727 }
2943 SendSettings(settings_map); 2728 SendSettings(settings_map);
2944 2729
2945 // Next, notify the server about our initial recv window size. 2730 // Next, notify the server about our initial recv window size.
2946 // Bump up the receive window size to the real initial value. This 2731 // Bump up the receive window size to the real initial value. This
2947 // has to go here since the WINDOW_UPDATE frame sent by 2732 // has to go here since the WINDOW_UPDATE frame sent by
2948 // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|. 2733 // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|.
2949 // This condition implies that |session_max_recv_window_size_| - 2734 // This condition implies that |session_max_recv_window_size_| -
2950 // |session_recv_window_size_| doesn't overflow. 2735 // |session_recv_window_size_| doesn't overflow.
2951 DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_); 2736 DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_);
2952 DCHECK_GE(session_recv_window_size_, 0); 2737 DCHECK_GE(session_recv_window_size_, 0);
2953 if (session_max_recv_window_size_ > session_recv_window_size_) { 2738 if (session_max_recv_window_size_ > session_recv_window_size_) {
2954 IncreaseRecvWindowSize(session_max_recv_window_size_ - 2739 IncreaseRecvWindowSize(session_max_recv_window_size_ -
2955 session_recv_window_size_); 2740 session_recv_window_size_);
2956 } 2741 }
2957
2958 if (protocol_ == kProtoSPDY31) {
2959 // Finally, notify the server about the settings they have
2960 // previously told us to use when communicating with them (after
2961 // applying them).
2962 const SettingsMap& server_settings_map =
2963 http_server_properties_->GetSpdySettings(GetServer());
2964 if (server_settings_map.empty())
2965 return;
2966
2967 SettingsMap::const_iterator it =
2968 server_settings_map.find(SETTINGS_CURRENT_CWND);
2969 uint32_t cwnd = (it != server_settings_map.end()) ? it->second.second : 0;
2970 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", cwnd, 1, 200, 100);
2971
2972 for (SettingsMap::const_iterator it = server_settings_map.begin();
2973 it != server_settings_map.end(); ++it) {
2974 const SpdySettingsIds new_id = it->first;
2975 const uint32_t new_val = it->second.second;
2976 HandleSetting(new_id, new_val);
2977 }
2978
2979 SendSettings(server_settings_map);
2980 }
2981 } 2742 }
2982 2743
2983
2984 void SpdySession::SendSettings(const SettingsMap& settings) { 2744 void SpdySession::SendSettings(const SettingsMap& settings) {
2985 const SpdyMajorVersion protocol_version = GetProtocolVersion(); 2745 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_SEND_SETTINGS,
2986 net_log_.AddEvent( 2746 base::Bind(&NetLogSpdySendSettingsCallback, &settings));
2987 NetLog::TYPE_HTTP2_SESSION_SEND_SETTINGS,
2988 base::Bind(&NetLogSpdySendSettingsCallback, &settings, protocol_version));
2989 // Create the SETTINGS frame and send it. 2747 // Create the SETTINGS frame and send it.
2990 DCHECK(buffered_spdy_framer_.get()); 2748 DCHECK(buffered_spdy_framer_.get());
2991 std::unique_ptr<SpdySerializedFrame> settings_frame( 2749 std::unique_ptr<SpdySerializedFrame> settings_frame(
2992 buffered_spdy_framer_->CreateSettings(settings)); 2750 buffered_spdy_framer_->CreateSettings(settings));
2993 sent_settings_ = true; 2751 sent_settings_ = true;
2994 EnqueueSessionWrite(HIGHEST, SETTINGS, std::move(settings_frame)); 2752 EnqueueSessionWrite(HIGHEST, SETTINGS, std::move(settings_frame));
2995 } 2753 }
2996 2754
2997 void SpdySession::HandleSetting(uint32_t id, uint32_t value) { 2755 void SpdySession::HandleSetting(uint32_t id, uint32_t value) {
2998 switch (id) { 2756 switch (id) {
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
3398 if (!queue->empty()) { 3156 if (!queue->empty()) {
3399 SpdyStreamId stream_id = queue->front(); 3157 SpdyStreamId stream_id = queue->front();
3400 queue->pop_front(); 3158 queue->pop_front();
3401 return stream_id; 3159 return stream_id;
3402 } 3160 }
3403 } 3161 }
3404 return 0; 3162 return 0;
3405 } 3163 }
3406 3164
3407 } // namespace net 3165 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_pool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698