| 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_session.h" | 5 #include "net/spdy/spdy_session.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 connection_at_risk_of_loss_time_( | 671 connection_at_risk_of_loss_time_( |
| 672 base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)), | 672 base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)), |
| 673 hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)), | 673 hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)), |
| 674 trusted_spdy_proxy_(trusted_spdy_proxy), | 674 trusted_spdy_proxy_(trusted_spdy_proxy), |
| 675 time_func_(time_func), | 675 time_func_(time_func), |
| 676 weak_factory_(this) { | 676 weak_factory_(this) { |
| 677 DCHECK_GE(protocol_, kProtoSPDYMinimumVersion); | 677 DCHECK_GE(protocol_, kProtoSPDYMinimumVersion); |
| 678 DCHECK_LE(protocol_, kProtoSPDYMaximumVersion); | 678 DCHECK_LE(protocol_, kProtoSPDYMaximumVersion); |
| 679 DCHECK(HttpStreamFactory::spdy_enabled()); | 679 DCHECK(HttpStreamFactory::spdy_enabled()); |
| 680 net_log_.BeginEvent( | 680 net_log_.BeginEvent( |
| 681 NetLog::TYPE_SPDY_SESSION, | 681 NetLog::TYPE_HTTP2_SESSION, |
| 682 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair())); | 682 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair())); |
| 683 next_unclaimed_push_stream_sweep_time_ = time_func_() + | 683 next_unclaimed_push_stream_sweep_time_ = time_func_() + |
| 684 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); | 684 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); |
| 685 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. | 685 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. |
| 686 } | 686 } |
| 687 | 687 |
| 688 SpdySession::~SpdySession() { | 688 SpdySession::~SpdySession() { |
| 689 CHECK(!in_io_loop_); | 689 CHECK(!in_io_loop_); |
| 690 DcheckDraining(); | 690 DcheckDraining(); |
| 691 | 691 |
| 692 // TODO(akalin): Check connection->is_initialized() instead. This | 692 // TODO(akalin): Check connection->is_initialized() instead. This |
| 693 // requires re-working CreateFakeSpdySession(), though. | 693 // requires re-working CreateFakeSpdySession(), though. |
| 694 DCHECK(connection_->socket()); | 694 DCHECK(connection_->socket()); |
| 695 // With SPDY we can't recycle sockets. | 695 // With SPDY we can't recycle sockets. |
| 696 connection_->socket()->Disconnect(); | 696 connection_->socket()->Disconnect(); |
| 697 | 697 |
| 698 RecordHistograms(); | 698 RecordHistograms(); |
| 699 | 699 |
| 700 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); | 700 net_log_.EndEvent(NetLog::TYPE_HTTP2_SESSION); |
| 701 } | 701 } |
| 702 | 702 |
| 703 void SpdySession::InitializeWithSocket( | 703 void SpdySession::InitializeWithSocket( |
| 704 scoped_ptr<ClientSocketHandle> connection, | 704 scoped_ptr<ClientSocketHandle> connection, |
| 705 SpdySessionPool* pool, | 705 SpdySessionPool* pool, |
| 706 bool is_secure, | 706 bool is_secure, |
| 707 int certificate_error_code) { | 707 int certificate_error_code) { |
| 708 CHECK(!in_io_loop_); | 708 CHECK(!in_io_loop_); |
| 709 DCHECK_EQ(availability_state_, STATE_AVAILABLE); | 709 DCHECK_EQ(availability_state_, STATE_AVAILABLE); |
| 710 DCHECK_EQ(read_state_, READ_STATE_DO_READ); | 710 DCHECK_EQ(read_state_, READ_STATE_DO_READ); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 buffered_spdy_framer_.reset( | 747 buffered_spdy_framer_.reset( |
| 748 new BufferedSpdyFramer(NextProtoToSpdyMajorVersion(protocol_), | 748 new BufferedSpdyFramer(NextProtoToSpdyMajorVersion(protocol_), |
| 749 enable_compression_)); | 749 enable_compression_)); |
| 750 buffered_spdy_framer_->set_visitor(this); | 750 buffered_spdy_framer_->set_visitor(this); |
| 751 buffered_spdy_framer_->set_debug_visitor(this); | 751 buffered_spdy_framer_->set_debug_visitor(this); |
| 752 UMA_HISTOGRAM_ENUMERATION( | 752 UMA_HISTOGRAM_ENUMERATION( |
| 753 "Net.SpdyVersion2", | 753 "Net.SpdyVersion2", |
| 754 protocol_ - kProtoSPDYHistogramOffset, | 754 protocol_ - kProtoSPDYHistogramOffset, |
| 755 kProtoSPDYMaximumVersion - kProtoSPDYMinimumVersion + 1); | 755 kProtoSPDYMaximumVersion - kProtoSPDYMinimumVersion + 1); |
| 756 | 756 |
| 757 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_INITIALIZED, | 757 net_log_.AddEvent( |
| 758 base::Bind(&NetLogSpdyInitializedCallback, | 758 NetLog::TYPE_HTTP2_SESSION_INITIALIZED, |
| 759 connection_->socket()->NetLog().source(), | 759 base::Bind(&NetLogSpdyInitializedCallback, |
| 760 protocol_)); | 760 connection_->socket()->NetLog().source(), protocol_)); |
| 761 | 761 |
| 762 DCHECK_EQ(availability_state_, STATE_AVAILABLE); | 762 DCHECK_EQ(availability_state_, STATE_AVAILABLE); |
| 763 connection_->AddHigherLayeredPool(this); | 763 connection_->AddHigherLayeredPool(this); |
| 764 if (enable_sending_initial_data_) | 764 if (enable_sending_initial_data_) |
| 765 SendInitialData(); | 765 SendInitialData(); |
| 766 pool_ = pool; | 766 pool_ = pool; |
| 767 | 767 |
| 768 // Bootstrap the read loop. | 768 // Bootstrap the read loop. |
| 769 base::MessageLoop::current()->PostTask( | 769 base::MessageLoop::current()->PostTask( |
| 770 FROM_HERE, | 770 FROM_HERE, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 if (err != OK) | 845 if (err != OK) |
| 846 return err; | 846 return err; |
| 847 | 847 |
| 848 if (!max_concurrent_streams_ || | 848 if (!max_concurrent_streams_ || |
| 849 (active_streams_.size() + created_streams_.size() - num_pushed_streams_ < | 849 (active_streams_.size() + created_streams_.size() - num_pushed_streams_ < |
| 850 max_concurrent_streams_)) { | 850 max_concurrent_streams_)) { |
| 851 return CreateStream(*request, stream); | 851 return CreateStream(*request, stream); |
| 852 } | 852 } |
| 853 | 853 |
| 854 stalled_streams_++; | 854 stalled_streams_++; |
| 855 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS); | 855 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_STALLED_MAX_STREAMS); |
| 856 RequestPriority priority = request->priority(); | 856 RequestPriority priority = request->priority(); |
| 857 CHECK_GE(priority, MINIMUM_PRIORITY); | 857 CHECK_GE(priority, MINIMUM_PRIORITY); |
| 858 CHECK_LE(priority, MAXIMUM_PRIORITY); | 858 CHECK_LE(priority, MAXIMUM_PRIORITY); |
| 859 pending_create_stream_queues_[priority].push_back(request); | 859 pending_create_stream_queues_[priority].push_back(request); |
| 860 return ERR_IO_PENDING; | 860 return ERR_IO_PENDING; |
| 861 } | 861 } |
| 862 | 862 |
| 863 int SpdySession::CreateStream(const SpdyStreamRequest& request, | 863 int SpdySession::CreateStream(const SpdyStreamRequest& request, |
| 864 base::WeakPtr<SpdyStream>* stream) { | 864 base::WeakPtr<SpdyStream>* stream) { |
| 865 DCHECK_GE(request.priority(), MINIMUM_PRIORITY); | 865 DCHECK_GE(request.priority(), MINIMUM_PRIORITY); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 headers.set_priority(spdy_priority); | 1076 headers.set_priority(spdy_priority); |
| 1077 headers.set_has_priority(true); | 1077 headers.set_has_priority(true); |
| 1078 headers.set_fin((flags & CONTROL_FLAG_FIN) != 0); | 1078 headers.set_fin((flags & CONTROL_FLAG_FIN) != 0); |
| 1079 headers.set_name_value_block(block); | 1079 headers.set_name_value_block(block); |
| 1080 syn_frame.reset(buffered_spdy_framer_->SerializeFrame(headers)); | 1080 syn_frame.reset(buffered_spdy_framer_->SerializeFrame(headers)); |
| 1081 } | 1081 } |
| 1082 | 1082 |
| 1083 streams_initiated_count_++; | 1083 streams_initiated_count_++; |
| 1084 | 1084 |
| 1085 if (net_log().IsLogging()) { | 1085 if (net_log().IsLogging()) { |
| 1086 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_SYN_STREAM, | 1086 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SYN_STREAM, |
| 1087 base::Bind(&NetLogSpdySynStreamSentCallback, | 1087 base::Bind(&NetLogSpdySynStreamSentCallback, &block, |
| 1088 &block, | |
| 1089 (flags & CONTROL_FLAG_FIN) != 0, | 1088 (flags & CONTROL_FLAG_FIN) != 0, |
| 1090 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0, | 1089 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0, |
| 1091 spdy_priority, | 1090 spdy_priority, stream_id)); |
| 1092 stream_id)); | |
| 1093 } | 1091 } |
| 1094 | 1092 |
| 1095 return syn_frame.Pass(); | 1093 return syn_frame.Pass(); |
| 1096 } | 1094 } |
| 1097 | 1095 |
| 1098 scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, | 1096 scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, |
| 1099 IOBuffer* data, | 1097 IOBuffer* data, |
| 1100 int len, | 1098 int len, |
| 1101 SpdyDataFlags flags) { | 1099 SpdyDataFlags flags) { |
| 1102 if (availability_state_ == STATE_DRAINING) { | 1100 if (availability_state_ == STATE_DRAINING) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1153 | 1151 |
| 1154 // Obey send window size of the stream if stream flow control is | 1152 // Obey send window size of the stream if stream flow control is |
| 1155 // enabled. | 1153 // enabled. |
| 1156 if (flow_control_state_ >= FLOW_CONTROL_STREAM) { | 1154 if (flow_control_state_ >= FLOW_CONTROL_STREAM) { |
| 1157 if (send_stalled_by_stream) { | 1155 if (send_stalled_by_stream) { |
| 1158 stream->set_send_stalled_by_flow_control(true); | 1156 stream->set_send_stalled_by_flow_control(true); |
| 1159 // Even though we're currently stalled only by the stream, we | 1157 // Even though we're currently stalled only by the stream, we |
| 1160 // might end up being stalled by the session also. | 1158 // might end up being stalled by the session also. |
| 1161 QueueSendStalledStream(*stream); | 1159 QueueSendStalledStream(*stream); |
| 1162 net_log().AddEvent( | 1160 net_log().AddEvent( |
| 1163 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW, | 1161 NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW, |
| 1164 NetLog::IntegerCallback("stream_id", stream_id)); | 1162 NetLog::IntegerCallback("stream_id", stream_id)); |
| 1165 return scoped_ptr<SpdyBuffer>(); | 1163 return scoped_ptr<SpdyBuffer>(); |
| 1166 } | 1164 } |
| 1167 | 1165 |
| 1168 effective_len = std::min(effective_len, stream->send_window_size()); | 1166 effective_len = std::min(effective_len, stream->send_window_size()); |
| 1169 } | 1167 } |
| 1170 | 1168 |
| 1171 // Obey send window size of the session if session flow control is | 1169 // Obey send window size of the session if session flow control is |
| 1172 // enabled. | 1170 // enabled. |
| 1173 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { | 1171 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { |
| 1174 if (send_stalled_by_session) { | 1172 if (send_stalled_by_session) { |
| 1175 stream->set_send_stalled_by_flow_control(true); | 1173 stream->set_send_stalled_by_flow_control(true); |
| 1176 QueueSendStalledStream(*stream); | 1174 QueueSendStalledStream(*stream); |
| 1177 net_log().AddEvent( | 1175 net_log().AddEvent( |
| 1178 NetLog::TYPE_SPDY_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW, | 1176 NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW, |
| 1179 NetLog::IntegerCallback("stream_id", stream_id)); | 1177 NetLog::IntegerCallback("stream_id", stream_id)); |
| 1180 return scoped_ptr<SpdyBuffer>(); | 1178 return scoped_ptr<SpdyBuffer>(); |
| 1181 } | 1179 } |
| 1182 | 1180 |
| 1183 effective_len = std::min(effective_len, session_send_window_size_); | 1181 effective_len = std::min(effective_len, session_send_window_size_); |
| 1184 } | 1182 } |
| 1185 | 1183 |
| 1186 DCHECK_GE(effective_len, 0); | 1184 DCHECK_GE(effective_len, 0); |
| 1187 | 1185 |
| 1188 // Clear FIN flag if only some of the data will be in the data | 1186 // Clear FIN flag if only some of the data will be in the data |
| 1189 // frame. | 1187 // frame. |
| 1190 if (effective_len < len) | 1188 if (effective_len < len) |
| 1191 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); | 1189 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); |
| 1192 | 1190 |
| 1193 if (net_log().IsLogging()) { | 1191 if (net_log().IsLogging()) { |
| 1194 net_log().AddEvent( | 1192 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SEND_DATA, |
| 1195 NetLog::TYPE_SPDY_SESSION_SEND_DATA, | 1193 base::Bind(&NetLogSpdyDataCallback, stream_id, |
| 1196 base::Bind(&NetLogSpdyDataCallback, stream_id, effective_len, | 1194 effective_len, (flags & DATA_FLAG_FIN) != 0)); |
| 1197 (flags & DATA_FLAG_FIN) != 0)); | |
| 1198 } | 1195 } |
| 1199 | 1196 |
| 1200 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. | 1197 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. |
| 1201 if (effective_len > 0) | 1198 if (effective_len > 0) |
| 1202 SendPrefacePingIfNoneInFlight(); | 1199 SendPrefacePingIfNoneInFlight(); |
| 1203 | 1200 |
| 1204 // TODO(mbelshe): reduce memory copies here. | 1201 // TODO(mbelshe): reduce memory copies here. |
| 1205 DCHECK(buffered_spdy_framer_.get()); | 1202 DCHECK(buffered_spdy_framer_.get()); |
| 1206 scoped_ptr<SpdyFrame> frame( | 1203 scoped_ptr<SpdyFrame> frame( |
| 1207 buffered_spdy_framer_->CreateDataFrame( | 1204 buffered_spdy_framer_->CreateDataFrame( |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1326 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR); | 1323 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR); |
| 1327 } | 1324 } |
| 1328 | 1325 |
| 1329 void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id, | 1326 void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id, |
| 1330 RequestPriority priority, | 1327 RequestPriority priority, |
| 1331 SpdyRstStreamStatus status, | 1328 SpdyRstStreamStatus status, |
| 1332 const std::string& description) { | 1329 const std::string& description) { |
| 1333 DCHECK_NE(stream_id, 0u); | 1330 DCHECK_NE(stream_id, 0u); |
| 1334 | 1331 |
| 1335 net_log().AddEvent( | 1332 net_log().AddEvent( |
| 1336 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, | 1333 NetLog::TYPE_HTTP2_SESSION_SEND_RST_STREAM, |
| 1337 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); | 1334 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); |
| 1338 | 1335 |
| 1339 DCHECK(buffered_spdy_framer_.get()); | 1336 DCHECK(buffered_spdy_framer_.get()); |
| 1340 scoped_ptr<SpdyFrame> rst_frame( | 1337 scoped_ptr<SpdyFrame> rst_frame( |
| 1341 buffered_spdy_framer_->CreateRstStream(stream_id, status)); | 1338 buffered_spdy_framer_->CreateRstStream(stream_id, status)); |
| 1342 | 1339 |
| 1343 EnqueueSessionWrite(priority, RST_STREAM, rst_frame.Pass()); | 1340 EnqueueSessionWrite(priority, RST_STREAM, rst_frame.Pass()); |
| 1344 RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status)); | 1341 RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status)); |
| 1345 } | 1342 } |
| 1346 | 1343 |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 EnqueueSessionWrite(HIGHEST, | 1730 EnqueueSessionWrite(HIGHEST, |
| 1734 GOAWAY, | 1731 GOAWAY, |
| 1735 scoped_ptr<SpdyFrame>( | 1732 scoped_ptr<SpdyFrame>( |
| 1736 buffered_spdy_framer_->SerializeFrame(goaway_ir))); | 1733 buffered_spdy_framer_->SerializeFrame(goaway_ir))); |
| 1737 } | 1734 } |
| 1738 | 1735 |
| 1739 availability_state_ = STATE_DRAINING; | 1736 availability_state_ = STATE_DRAINING; |
| 1740 error_on_close_ = err; | 1737 error_on_close_ = err; |
| 1741 | 1738 |
| 1742 net_log_.AddEvent( | 1739 net_log_.AddEvent( |
| 1743 NetLog::TYPE_SPDY_SESSION_CLOSE, | 1740 NetLog::TYPE_HTTP2_SESSION_CLOSE, |
| 1744 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); | 1741 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); |
| 1745 | 1742 |
| 1746 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err); | 1743 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err); |
| 1747 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors", | 1744 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors", |
| 1748 total_bytes_received_, 1, 100000000, 50); | 1745 total_bytes_received_, 1, 100000000, 50); |
| 1749 | 1746 |
| 1750 if (err == OK) { | 1747 if (err == OK) { |
| 1751 // We ought to be going away already, as this is a graceful close. | 1748 // We ought to be going away already, as this is a graceful close. |
| 1752 DcheckGoingAway(); | 1749 DcheckGoingAway(); |
| 1753 } else { | 1750 } else { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1970 | 1967 |
| 1971 SpdyStreamId stream_id = unclaimed_it->second.stream_id; | 1968 SpdyStreamId stream_id = unclaimed_it->second.stream_id; |
| 1972 unclaimed_pushed_streams_.erase(unclaimed_it); | 1969 unclaimed_pushed_streams_.erase(unclaimed_it); |
| 1973 | 1970 |
| 1974 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); | 1971 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); |
| 1975 if (active_it == active_streams_.end()) { | 1972 if (active_it == active_streams_.end()) { |
| 1976 NOTREACHED(); | 1973 NOTREACHED(); |
| 1977 return base::WeakPtr<SpdyStream>(); | 1974 return base::WeakPtr<SpdyStream>(); |
| 1978 } | 1975 } |
| 1979 | 1976 |
| 1980 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM, | 1977 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_ADOPTED_PUSH_STREAM, |
| 1981 base::Bind(&NetLogSpdyAdoptedPushStreamCallback, | 1978 base::Bind(&NetLogSpdyAdoptedPushStreamCallback, |
| 1982 active_it->second.stream->stream_id(), &url)); | 1979 active_it->second.stream->stream_id(), &url)); |
| 1983 return active_it->second.stream->GetWeakPtr(); | 1980 return active_it->second.stream->GetWeakPtr(); |
| 1984 } | 1981 } |
| 1985 | 1982 |
| 1986 bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, | 1983 bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, |
| 1987 bool* was_npn_negotiated, | 1984 bool* was_npn_negotiated, |
| 1988 NextProto* protocol_negotiated) { | 1985 NextProto* protocol_negotiated) { |
| 1989 *was_npn_negotiated = connection_->socket()->WasNpnNegotiated(); | 1986 *was_npn_negotiated = connection_->socket()->WasNpnNegotiated(); |
| 1990 *protocol_negotiated = connection_->socket()->GetNegotiatedProtocol(); | 1987 *protocol_negotiated = connection_->socket()->GetNegotiatedProtocol(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2054 if (data == NULL && len != 0) { | 2051 if (data == NULL && len != 0) { |
| 2055 // This is notification of consumed data padding. | 2052 // This is notification of consumed data padding. |
| 2056 // TODO(jgraettinger): Properly flow padding into WINDOW_UPDATE frames. | 2053 // TODO(jgraettinger): Properly flow padding into WINDOW_UPDATE frames. |
| 2057 // See crbug.com/353012. | 2054 // See crbug.com/353012. |
| 2058 return; | 2055 return; |
| 2059 } | 2056 } |
| 2060 | 2057 |
| 2061 DCHECK_LT(len, 1u << 24); | 2058 DCHECK_LT(len, 1u << 24); |
| 2062 if (net_log().IsLogging()) { | 2059 if (net_log().IsLogging()) { |
| 2063 net_log().AddEvent( | 2060 net_log().AddEvent( |
| 2064 NetLog::TYPE_SPDY_SESSION_RECV_DATA, | 2061 NetLog::TYPE_HTTP2_SESSION_RECV_DATA, |
| 2065 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); | 2062 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); |
| 2066 } | 2063 } |
| 2067 | 2064 |
| 2068 // Build the buffer as early as possible so that we go through the | 2065 // Build the buffer as early as possible so that we go through the |
| 2069 // session flow control checks and update | 2066 // session flow control checks and update |
| 2070 // |unacked_recv_window_bytes_| properly even when the stream is | 2067 // |unacked_recv_window_bytes_| properly even when the stream is |
| 2071 // inactive (since the other side has still reduced its session send | 2068 // inactive (since the other side has still reduced its session send |
| 2072 // window). | 2069 // window). |
| 2073 scoped_ptr<SpdyBuffer> buffer; | 2070 scoped_ptr<SpdyBuffer> buffer; |
| 2074 if (data) { | 2071 if (data) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2107 stream->OnDataReceived(buffer.Pass()); | 2104 stream->OnDataReceived(buffer.Pass()); |
| 2108 } | 2105 } |
| 2109 | 2106 |
| 2110 void SpdySession::OnSettings(bool clear_persisted) { | 2107 void SpdySession::OnSettings(bool clear_persisted) { |
| 2111 CHECK(in_io_loop_); | 2108 CHECK(in_io_loop_); |
| 2112 | 2109 |
| 2113 if (clear_persisted) | 2110 if (clear_persisted) |
| 2114 http_server_properties_->ClearSpdySettings(host_port_pair()); | 2111 http_server_properties_->ClearSpdySettings(host_port_pair()); |
| 2115 | 2112 |
| 2116 if (net_log_.IsLogging()) { | 2113 if (net_log_.IsLogging()) { |
| 2117 net_log_.AddEvent( | 2114 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTINGS, |
| 2118 NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS, | 2115 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), |
| 2119 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), | 2116 clear_persisted)); |
| 2120 clear_persisted)); | |
| 2121 } | 2117 } |
| 2122 | 2118 |
| 2123 if (GetProtocolVersion() >= SPDY4) { | 2119 if (GetProtocolVersion() >= SPDY4) { |
| 2124 // Send an acknowledgment of the setting. | 2120 // Send an acknowledgment of the setting. |
| 2125 SpdySettingsIR settings_ir; | 2121 SpdySettingsIR settings_ir; |
| 2126 settings_ir.set_is_ack(true); | 2122 settings_ir.set_is_ack(true); |
| 2127 EnqueueSessionWrite( | 2123 EnqueueSessionWrite( |
| 2128 HIGHEST, | 2124 HIGHEST, |
| 2129 SETTINGS, | 2125 SETTINGS, |
| 2130 scoped_ptr<SpdyFrame>( | 2126 scoped_ptr<SpdyFrame>( |
| 2131 buffered_spdy_framer_->SerializeFrame(settings_ir))); | 2127 buffered_spdy_framer_->SerializeFrame(settings_ir))); |
| 2132 } | 2128 } |
| 2133 } | 2129 } |
| 2134 | 2130 |
| 2135 void SpdySession::OnSetting(SpdySettingsIds id, | 2131 void SpdySession::OnSetting(SpdySettingsIds id, |
| 2136 uint8 flags, | 2132 uint8 flags, |
| 2137 uint32 value) { | 2133 uint32 value) { |
| 2138 CHECK(in_io_loop_); | 2134 CHECK(in_io_loop_); |
| 2139 | 2135 |
| 2140 HandleSetting(id, value); | 2136 HandleSetting(id, value); |
| 2141 http_server_properties_->SetSpdySetting( | 2137 http_server_properties_->SetSpdySetting( |
| 2142 host_port_pair(), | 2138 host_port_pair(), |
| 2143 id, | 2139 id, |
| 2144 static_cast<SpdySettingsFlags>(flags), | 2140 static_cast<SpdySettingsFlags>(flags), |
| 2145 value); | 2141 value); |
| 2146 received_settings_ = true; | 2142 received_settings_ = true; |
| 2147 | 2143 |
| 2148 // Log the setting. | 2144 // Log the setting. |
| 2149 const SpdyMajorVersion protocol_version = GetProtocolVersion(); | 2145 const SpdyMajorVersion protocol_version = GetProtocolVersion(); |
| 2150 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_RECV_SETTING, | 2146 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTING, |
| 2151 base::Bind(&NetLogSpdySettingCallback, | 2147 base::Bind(&NetLogSpdySettingCallback, id, protocol_version, |
| 2152 id, | 2148 static_cast<SpdySettingsFlags>(flags), value)); |
| 2153 protocol_version, | |
| 2154 static_cast<SpdySettingsFlags>(flags), | |
| 2155 value)); | |
| 2156 } | 2149 } |
| 2157 | 2150 |
| 2158 void SpdySession::OnSendCompressedFrame( | 2151 void SpdySession::OnSendCompressedFrame( |
| 2159 SpdyStreamId stream_id, | 2152 SpdyStreamId stream_id, |
| 2160 SpdyFrameType type, | 2153 SpdyFrameType type, |
| 2161 size_t payload_len, | 2154 size_t payload_len, |
| 2162 size_t frame_len) { | 2155 size_t frame_len) { |
| 2163 if (type != SYN_STREAM && type != HEADERS) | 2156 if (type != SYN_STREAM && type != HEADERS) |
| 2164 return; | 2157 return; |
| 2165 | 2158 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2225 const SpdyHeaderBlock& headers) { | 2218 const SpdyHeaderBlock& headers) { |
| 2226 CHECK(in_io_loop_); | 2219 CHECK(in_io_loop_); |
| 2227 | 2220 |
| 2228 DCHECK_LE(GetProtocolVersion(), SPDY3); | 2221 DCHECK_LE(GetProtocolVersion(), SPDY3); |
| 2229 | 2222 |
| 2230 base::Time response_time = base::Time::Now(); | 2223 base::Time response_time = base::Time::Now(); |
| 2231 base::TimeTicks recv_first_byte_time = time_func_(); | 2224 base::TimeTicks recv_first_byte_time = time_func_(); |
| 2232 | 2225 |
| 2233 if (net_log_.IsLogging()) { | 2226 if (net_log_.IsLogging()) { |
| 2234 net_log_.AddEvent( | 2227 net_log_.AddEvent( |
| 2235 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, | 2228 NetLog::TYPE_HTTP2_SESSION_PUSHED_SYN_STREAM, |
| 2236 base::Bind(&NetLogSpdySynStreamReceivedCallback, | 2229 base::Bind(&NetLogSpdySynStreamReceivedCallback, &headers, fin, |
| 2237 &headers, fin, unidirectional, priority, | 2230 unidirectional, priority, stream_id, associated_stream_id)); |
| 2238 stream_id, associated_stream_id)); | |
| 2239 } | 2231 } |
| 2240 | 2232 |
| 2241 // Split headers to simulate push promise and response. | 2233 // Split headers to simulate push promise and response. |
| 2242 SpdyHeaderBlock request_headers; | 2234 SpdyHeaderBlock request_headers; |
| 2243 SpdyHeaderBlock response_headers; | 2235 SpdyHeaderBlock response_headers; |
| 2244 SplitPushedHeadersToRequestAndResponse( | 2236 SplitPushedHeadersToRequestAndResponse( |
| 2245 headers, GetProtocolVersion(), &request_headers, &response_headers); | 2237 headers, GetProtocolVersion(), &request_headers, &response_headers); |
| 2246 | 2238 |
| 2247 if (!TryCreatePushStream( | 2239 if (!TryCreatePushStream( |
| 2248 stream_id, associated_stream_id, priority, request_headers)) | 2240 stream_id, associated_stream_id, priority, request_headers)) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2297 | 2289 |
| 2298 void SpdySession::OnSynReply(SpdyStreamId stream_id, | 2290 void SpdySession::OnSynReply(SpdyStreamId stream_id, |
| 2299 bool fin, | 2291 bool fin, |
| 2300 const SpdyHeaderBlock& headers) { | 2292 const SpdyHeaderBlock& headers) { |
| 2301 CHECK(in_io_loop_); | 2293 CHECK(in_io_loop_); |
| 2302 | 2294 |
| 2303 base::Time response_time = base::Time::Now(); | 2295 base::Time response_time = base::Time::Now(); |
| 2304 base::TimeTicks recv_first_byte_time = time_func_(); | 2296 base::TimeTicks recv_first_byte_time = time_func_(); |
| 2305 | 2297 |
| 2306 if (net_log().IsLogging()) { | 2298 if (net_log().IsLogging()) { |
| 2307 net_log().AddEvent( | 2299 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SYN_REPLY, |
| 2308 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, | 2300 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, |
| 2309 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, | 2301 &headers, fin, stream_id)); |
| 2310 &headers, fin, stream_id)); | |
| 2311 } | 2302 } |
| 2312 | 2303 |
| 2313 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2304 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
| 2314 if (it == active_streams_.end()) { | 2305 if (it == active_streams_.end()) { |
| 2315 // NOTE: it may just be that the stream was cancelled. | 2306 // NOTE: it may just be that the stream was cancelled. |
| 2316 return; | 2307 return; |
| 2317 } | 2308 } |
| 2318 | 2309 |
| 2319 SpdyStream* stream = it->second.stream; | 2310 SpdyStream* stream = it->second.stream; |
| 2320 CHECK_EQ(stream->stream_id(), stream_id); | 2311 CHECK_EQ(stream->stream_id(), stream_id); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2343 } | 2334 } |
| 2344 | 2335 |
| 2345 void SpdySession::OnHeaders(SpdyStreamId stream_id, | 2336 void SpdySession::OnHeaders(SpdyStreamId stream_id, |
| 2346 bool has_priority, | 2337 bool has_priority, |
| 2347 SpdyPriority priority, | 2338 SpdyPriority priority, |
| 2348 bool fin, | 2339 bool fin, |
| 2349 const SpdyHeaderBlock& headers) { | 2340 const SpdyHeaderBlock& headers) { |
| 2350 CHECK(in_io_loop_); | 2341 CHECK(in_io_loop_); |
| 2351 | 2342 |
| 2352 if (net_log().IsLogging()) { | 2343 if (net_log().IsLogging()) { |
| 2353 net_log().AddEvent( | 2344 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_HEADERS, |
| 2354 NetLog::TYPE_SPDY_SESSION_RECV_HEADERS, | 2345 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, |
| 2355 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, | 2346 &headers, fin, stream_id)); |
| 2356 &headers, fin, stream_id)); | |
| 2357 } | 2347 } |
| 2358 | 2348 |
| 2359 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2349 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
| 2360 if (it == active_streams_.end()) { | 2350 if (it == active_streams_.end()) { |
| 2361 // NOTE: it may just be that the stream was cancelled. | 2351 // NOTE: it may just be that the stream was cancelled. |
| 2362 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; | 2352 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; |
| 2363 return; | 2353 return; |
| 2364 } | 2354 } |
| 2365 | 2355 |
| 2366 SpdyStream* stream = it->second.stream; | 2356 SpdyStream* stream = it->second.stream; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2407 | 2397 |
| 2408 return true; | 2398 return true; |
| 2409 } | 2399 } |
| 2410 | 2400 |
| 2411 void SpdySession::OnRstStream(SpdyStreamId stream_id, | 2401 void SpdySession::OnRstStream(SpdyStreamId stream_id, |
| 2412 SpdyRstStreamStatus status) { | 2402 SpdyRstStreamStatus status) { |
| 2413 CHECK(in_io_loop_); | 2403 CHECK(in_io_loop_); |
| 2414 | 2404 |
| 2415 std::string description; | 2405 std::string description; |
| 2416 net_log().AddEvent( | 2406 net_log().AddEvent( |
| 2417 NetLog::TYPE_SPDY_SESSION_RST_STREAM, | 2407 NetLog::TYPE_HTTP2_SESSION_RST_STREAM, |
| 2418 base::Bind(&NetLogSpdyRstCallback, | 2408 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); |
| 2419 stream_id, status, &description)); | |
| 2420 | 2409 |
| 2421 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2410 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
| 2422 if (it == active_streams_.end()) { | 2411 if (it == active_streams_.end()) { |
| 2423 // NOTE: it may just be that the stream was cancelled. | 2412 // NOTE: it may just be that the stream was cancelled. |
| 2424 LOG(WARNING) << "Received RST for invalid stream" << stream_id; | 2413 LOG(WARNING) << "Received RST for invalid stream" << stream_id; |
| 2425 return; | 2414 return; |
| 2426 } | 2415 } |
| 2427 | 2416 |
| 2428 CHECK_EQ(it->second.stream->stream_id(), stream_id); | 2417 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
| 2429 | 2418 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2449 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR); | 2438 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR); |
| 2450 } | 2439 } |
| 2451 } | 2440 } |
| 2452 | 2441 |
| 2453 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, | 2442 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, |
| 2454 SpdyGoAwayStatus status) { | 2443 SpdyGoAwayStatus status) { |
| 2455 CHECK(in_io_loop_); | 2444 CHECK(in_io_loop_); |
| 2456 | 2445 |
| 2457 // TODO(jgraettinger): UMA histogram on |status|. | 2446 // TODO(jgraettinger): UMA histogram on |status|. |
| 2458 | 2447 |
| 2459 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_GOAWAY, | 2448 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_GOAWAY, |
| 2460 base::Bind(&NetLogSpdyGoAwayCallback, | 2449 base::Bind(&NetLogSpdyGoAwayCallback, |
| 2461 last_accepted_stream_id, | 2450 last_accepted_stream_id, active_streams_.size(), |
| 2462 active_streams_.size(), | 2451 unclaimed_pushed_streams_.size(), status)); |
| 2463 unclaimed_pushed_streams_.size(), | |
| 2464 status)); | |
| 2465 MakeUnavailable(); | 2452 MakeUnavailable(); |
| 2466 if (status == GOAWAY_HTTP_1_1_REQUIRED) { | 2453 if (status == GOAWAY_HTTP_1_1_REQUIRED) { |
| 2467 // TODO(bnc): Record histogram with number of open streams capped at 50. | 2454 // TODO(bnc): Record histogram with number of open streams capped at 50. |
| 2468 DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream."); | 2455 DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream."); |
| 2469 } else { | 2456 } else { |
| 2470 StartGoingAway(last_accepted_stream_id, ERR_ABORTED); | 2457 StartGoingAway(last_accepted_stream_id, ERR_ABORTED); |
| 2471 } | 2458 } |
| 2472 // This is to handle the case when we already don't have any active | 2459 // This is to handle the case when we already don't have any active |
| 2473 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have | 2460 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have |
| 2474 // active streams and so the last one being closed will finish the | 2461 // active streams and so the last one being closed will finish the |
| 2475 // going away process (see DeleteStream()). | 2462 // going away process (see DeleteStream()). |
| 2476 MaybeFinishGoingAway(); | 2463 MaybeFinishGoingAway(); |
| 2477 } | 2464 } |
| 2478 | 2465 |
| 2479 void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) { | 2466 void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) { |
| 2480 CHECK(in_io_loop_); | 2467 CHECK(in_io_loop_); |
| 2481 | 2468 |
| 2482 net_log_.AddEvent( | 2469 net_log_.AddEvent( |
| 2483 NetLog::TYPE_SPDY_SESSION_PING, | 2470 NetLog::TYPE_HTTP2_SESSION_PING, |
| 2484 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received")); | 2471 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received")); |
| 2485 | 2472 |
| 2486 // Send response to a PING from server. | 2473 // Send response to a PING from server. |
| 2487 if ((protocol_ >= kProtoSPDY4MinimumVersion && !is_ack) || | 2474 if ((protocol_ >= kProtoSPDY4MinimumVersion && !is_ack) || |
| 2488 (protocol_ < kProtoSPDY4MinimumVersion && unique_id % 2 == 0)) { | 2475 (protocol_ < kProtoSPDY4MinimumVersion && unique_id % 2 == 0)) { |
| 2489 WritePingFrame(unique_id, true); | 2476 WritePingFrame(unique_id, true); |
| 2490 return; | 2477 return; |
| 2491 } | 2478 } |
| 2492 | 2479 |
| 2493 --pings_in_flight_; | 2480 --pings_in_flight_; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2504 // We will record RTT in histogram when there are no more client sent | 2491 // We will record RTT in histogram when there are no more client sent |
| 2505 // pings_in_flight_. | 2492 // pings_in_flight_. |
| 2506 RecordPingRTTHistogram(time_func_() - last_ping_sent_time_); | 2493 RecordPingRTTHistogram(time_func_() - last_ping_sent_time_); |
| 2507 } | 2494 } |
| 2508 | 2495 |
| 2509 void SpdySession::OnWindowUpdate(SpdyStreamId stream_id, | 2496 void SpdySession::OnWindowUpdate(SpdyStreamId stream_id, |
| 2510 uint32 delta_window_size) { | 2497 uint32 delta_window_size) { |
| 2511 CHECK(in_io_loop_); | 2498 CHECK(in_io_loop_); |
| 2512 | 2499 |
| 2513 DCHECK_LE(delta_window_size, static_cast<uint32>(kint32max)); | 2500 DCHECK_LE(delta_window_size, static_cast<uint32>(kint32max)); |
| 2514 net_log_.AddEvent( | 2501 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECEIVED_WINDOW_UPDATE_FRAME, |
| 2515 NetLog::TYPE_SPDY_SESSION_RECEIVED_WINDOW_UPDATE_FRAME, | 2502 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, stream_id, |
| 2516 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, | 2503 delta_window_size)); |
| 2517 stream_id, delta_window_size)); | |
| 2518 | 2504 |
| 2519 if (stream_id == kSessionFlowControlStreamId) { | 2505 if (stream_id == kSessionFlowControlStreamId) { |
| 2520 // WINDOW_UPDATE for the session. | 2506 // WINDOW_UPDATE for the session. |
| 2521 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) { | 2507 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) { |
| 2522 LOG(WARNING) << "Received WINDOW_UPDATE for session when " | 2508 LOG(WARNING) << "Received WINDOW_UPDATE for session when " |
| 2523 << "session flow control is not turned on"; | 2509 << "session flow control is not turned on"; |
| 2524 // TODO(akalin): Record an error and close the session. | 2510 // TODO(akalin): Record an error and close the session. |
| 2525 return; | 2511 return; |
| 2526 } | 2512 } |
| 2527 | 2513 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2734 num_pushed_streams_++; | 2720 num_pushed_streams_++; |
| 2735 return true; | 2721 return true; |
| 2736 } | 2722 } |
| 2737 | 2723 |
| 2738 void SpdySession::OnPushPromise(SpdyStreamId stream_id, | 2724 void SpdySession::OnPushPromise(SpdyStreamId stream_id, |
| 2739 SpdyStreamId promised_stream_id, | 2725 SpdyStreamId promised_stream_id, |
| 2740 const SpdyHeaderBlock& headers) { | 2726 const SpdyHeaderBlock& headers) { |
| 2741 CHECK(in_io_loop_); | 2727 CHECK(in_io_loop_); |
| 2742 | 2728 |
| 2743 if (net_log_.IsLogging()) { | 2729 if (net_log_.IsLogging()) { |
| 2744 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_RECV_PUSH_PROMISE, | 2730 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_PUSH_PROMISE, |
| 2745 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, | 2731 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, |
| 2746 &headers, | 2732 &headers, stream_id, promised_stream_id)); |
| 2747 stream_id, | |
| 2748 promised_stream_id)); | |
| 2749 } | 2733 } |
| 2750 | 2734 |
| 2751 // Any priority will do. | 2735 // Any priority will do. |
| 2752 // TODO(baranovich): pass parent stream id priority? | 2736 // TODO(baranovich): pass parent stream id priority? |
| 2753 if (!TryCreatePushStream(promised_stream_id, stream_id, 0, headers)) | 2737 if (!TryCreatePushStream(promised_stream_id, stream_id, 0, headers)) |
| 2754 return; | 2738 return; |
| 2755 } | 2739 } |
| 2756 | 2740 |
| 2757 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, | 2741 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, |
| 2758 uint32 delta_window_size) { | 2742 uint32 delta_window_size) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2829 } | 2813 } |
| 2830 | 2814 |
| 2831 SendSettings(server_settings_map); | 2815 SendSettings(server_settings_map); |
| 2832 } | 2816 } |
| 2833 } | 2817 } |
| 2834 | 2818 |
| 2835 | 2819 |
| 2836 void SpdySession::SendSettings(const SettingsMap& settings) { | 2820 void SpdySession::SendSettings(const SettingsMap& settings) { |
| 2837 const SpdyMajorVersion protocol_version = GetProtocolVersion(); | 2821 const SpdyMajorVersion protocol_version = GetProtocolVersion(); |
| 2838 net_log_.AddEvent( | 2822 net_log_.AddEvent( |
| 2839 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, | 2823 NetLog::TYPE_HTTP2_SESSION_SEND_SETTINGS, |
| 2840 base::Bind(&NetLogSpdySendSettingsCallback, &settings, protocol_version)); | 2824 base::Bind(&NetLogSpdySendSettingsCallback, &settings, protocol_version)); |
| 2841 // Create the SETTINGS frame and send it. | 2825 // Create the SETTINGS frame and send it. |
| 2842 DCHECK(buffered_spdy_framer_.get()); | 2826 DCHECK(buffered_spdy_framer_.get()); |
| 2843 scoped_ptr<SpdyFrame> settings_frame( | 2827 scoped_ptr<SpdyFrame> settings_frame( |
| 2844 buffered_spdy_framer_->CreateSettings(settings)); | 2828 buffered_spdy_framer_->CreateSettings(settings)); |
| 2845 sent_settings_ = true; | 2829 sent_settings_ = true; |
| 2846 EnqueueSessionWrite(HIGHEST, SETTINGS, settings_frame.Pass()); | 2830 EnqueueSessionWrite(HIGHEST, SETTINGS, settings_frame.Pass()); |
| 2847 } | 2831 } |
| 2848 | 2832 |
| 2849 void SpdySession::HandleSetting(uint32 id, uint32 value) { | 2833 void SpdySession::HandleSetting(uint32 id, uint32 value) { |
| 2850 switch (id) { | 2834 switch (id) { |
| 2851 case SETTINGS_MAX_CONCURRENT_STREAMS: | 2835 case SETTINGS_MAX_CONCURRENT_STREAMS: |
| 2852 max_concurrent_streams_ = std::min(static_cast<size_t>(value), | 2836 max_concurrent_streams_ = std::min(static_cast<size_t>(value), |
| 2853 kMaxConcurrentStreamLimit); | 2837 kMaxConcurrentStreamLimit); |
| 2854 ProcessPendingStreamRequests(); | 2838 ProcessPendingStreamRequests(); |
| 2855 break; | 2839 break; |
| 2856 case SETTINGS_INITIAL_WINDOW_SIZE: { | 2840 case SETTINGS_INITIAL_WINDOW_SIZE: { |
| 2857 if (flow_control_state_ < FLOW_CONTROL_STREAM) { | 2841 if (flow_control_state_ < FLOW_CONTROL_STREAM) { |
| 2858 net_log().AddEvent( | 2842 net_log().AddEvent( |
| 2859 NetLog::TYPE_SPDY_SESSION_INITIAL_WINDOW_SIZE_NO_FLOW_CONTROL); | 2843 NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_NO_FLOW_CONTROL); |
| 2860 return; | 2844 return; |
| 2861 } | 2845 } |
| 2862 | 2846 |
| 2863 if (value > static_cast<uint32>(kint32max)) { | 2847 if (value > static_cast<uint32>(kint32max)) { |
| 2864 net_log().AddEvent( | 2848 net_log().AddEvent( |
| 2865 NetLog::TYPE_SPDY_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE, | 2849 NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE, |
| 2866 NetLog::IntegerCallback("initial_window_size", value)); | 2850 NetLog::IntegerCallback("initial_window_size", value)); |
| 2867 return; | 2851 return; |
| 2868 } | 2852 } |
| 2869 | 2853 |
| 2870 // SETTINGS_INITIAL_WINDOW_SIZE updates initial_send_window_size_ only. | 2854 // SETTINGS_INITIAL_WINDOW_SIZE updates initial_send_window_size_ only. |
| 2871 int32 delta_window_size = | 2855 int32 delta_window_size = |
| 2872 static_cast<int32>(value) - stream_initial_send_window_size_; | 2856 static_cast<int32>(value) - stream_initial_send_window_size_; |
| 2873 stream_initial_send_window_size_ = static_cast<int32>(value); | 2857 stream_initial_send_window_size_ = static_cast<int32>(value); |
| 2874 UpdateStreamsSendWindowSize(delta_window_size); | 2858 UpdateStreamsSendWindowSize(delta_window_size); |
| 2875 net_log().AddEvent( | 2859 net_log().AddEvent( |
| 2876 NetLog::TYPE_SPDY_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE, | 2860 NetLog::TYPE_HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE, |
| 2877 NetLog::IntegerCallback("delta_window_size", delta_window_size)); | 2861 NetLog::IntegerCallback("delta_window_size", delta_window_size)); |
| 2878 break; | 2862 break; |
| 2879 } | 2863 } |
| 2880 } | 2864 } |
| 2881 } | 2865 } |
| 2882 | 2866 |
| 2883 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { | 2867 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { |
| 2884 DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 2868 DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
| 2885 for (ActiveStreamMap::iterator it = active_streams_.begin(); | 2869 for (ActiveStreamMap::iterator it = active_streams_.begin(); |
| 2886 it != active_streams_.end(); ++it) { | 2870 it != active_streams_.end(); ++it) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2912 RequestPriority priority) { | 2896 RequestPriority priority) { |
| 2913 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 2897 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
| 2914 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 2898 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
| 2915 if (it != active_streams_.end()) { | 2899 if (it != active_streams_.end()) { |
| 2916 CHECK_EQ(it->second.stream->stream_id(), stream_id); | 2900 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
| 2917 } else { | 2901 } else { |
| 2918 CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 2902 CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
| 2919 CHECK_EQ(stream_id, kSessionFlowControlStreamId); | 2903 CHECK_EQ(stream_id, kSessionFlowControlStreamId); |
| 2920 } | 2904 } |
| 2921 | 2905 |
| 2922 net_log_.AddEvent( | 2906 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_SENT_WINDOW_UPDATE_FRAME, |
| 2923 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE_FRAME, | 2907 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, stream_id, |
| 2924 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, | 2908 delta_window_size)); |
| 2925 stream_id, delta_window_size)); | |
| 2926 | 2909 |
| 2927 DCHECK(buffered_spdy_framer_.get()); | 2910 DCHECK(buffered_spdy_framer_.get()); |
| 2928 scoped_ptr<SpdyFrame> window_update_frame( | 2911 scoped_ptr<SpdyFrame> window_update_frame( |
| 2929 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); | 2912 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); |
| 2930 EnqueueSessionWrite(priority, WINDOW_UPDATE, window_update_frame.Pass()); | 2913 EnqueueSessionWrite(priority, WINDOW_UPDATE, window_update_frame.Pass()); |
| 2931 } | 2914 } |
| 2932 | 2915 |
| 2933 void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) { | 2916 void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) { |
| 2934 DCHECK(buffered_spdy_framer_.get()); | 2917 DCHECK(buffered_spdy_framer_.get()); |
| 2935 scoped_ptr<SpdyFrame> ping_frame( | 2918 scoped_ptr<SpdyFrame> ping_frame( |
| 2936 buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack)); | 2919 buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack)); |
| 2937 EnqueueSessionWrite(HIGHEST, PING, ping_frame.Pass()); | 2920 EnqueueSessionWrite(HIGHEST, PING, ping_frame.Pass()); |
| 2938 | 2921 |
| 2939 if (net_log().IsLogging()) { | 2922 if (net_log().IsLogging()) { |
| 2940 net_log().AddEvent( | 2923 net_log().AddEvent( |
| 2941 NetLog::TYPE_SPDY_SESSION_PING, | 2924 NetLog::TYPE_HTTP2_SESSION_PING, |
| 2942 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent")); | 2925 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent")); |
| 2943 } | 2926 } |
| 2944 if (!is_ack) { | 2927 if (!is_ack) { |
| 2945 next_ping_id_ += 2; | 2928 next_ping_id_ += 2; |
| 2946 ++pings_in_flight_; | 2929 ++pings_in_flight_; |
| 2947 PlanToCheckPingStatus(); | 2930 PlanToCheckPingStatus(); |
| 2948 last_ping_sent_time_ = time_func_(); | 2931 last_ping_sent_time_ = time_func_(); |
| 2949 } | 2932 } |
| 2950 } | 2933 } |
| 2951 | 2934 |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3140 ERR_SPDY_PROTOCOL_ERROR, | 3123 ERR_SPDY_PROTOCOL_ERROR, |
| 3141 "Received WINDOW_UPDATE [delta: " + | 3124 "Received WINDOW_UPDATE [delta: " + |
| 3142 base::IntToString(delta_window_size) + | 3125 base::IntToString(delta_window_size) + |
| 3143 "] for session overflows session_send_window_size_ [current: " + | 3126 "] for session overflows session_send_window_size_ [current: " + |
| 3144 base::IntToString(session_send_window_size_) + "]"); | 3127 base::IntToString(session_send_window_size_) + "]"); |
| 3145 return; | 3128 return; |
| 3146 } | 3129 } |
| 3147 | 3130 |
| 3148 session_send_window_size_ += delta_window_size; | 3131 session_send_window_size_ += delta_window_size; |
| 3149 | 3132 |
| 3150 net_log_.AddEvent( | 3133 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_SEND_WINDOW, |
| 3151 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, | 3134 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 3152 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3135 delta_window_size, session_send_window_size_)); |
| 3153 delta_window_size, session_send_window_size_)); | |
| 3154 | 3136 |
| 3155 DCHECK(!IsSendStalled()); | 3137 DCHECK(!IsSendStalled()); |
| 3156 ResumeSendStalledStreams(); | 3138 ResumeSendStalledStreams(); |
| 3157 } | 3139 } |
| 3158 | 3140 |
| 3159 void SpdySession::DecreaseSendWindowSize(int32 delta_window_size) { | 3141 void SpdySession::DecreaseSendWindowSize(int32 delta_window_size) { |
| 3160 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3142 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
| 3161 | 3143 |
| 3162 // We only call this method when sending a frame. Therefore, | 3144 // We only call this method when sending a frame. Therefore, |
| 3163 // |delta_window_size| should be within the valid frame size range. | 3145 // |delta_window_size| should be within the valid frame size range. |
| 3164 DCHECK_GE(delta_window_size, 1); | 3146 DCHECK_GE(delta_window_size, 1); |
| 3165 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); | 3147 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); |
| 3166 | 3148 |
| 3167 // |send_window_size_| should have been at least |delta_window_size| for | 3149 // |send_window_size_| should have been at least |delta_window_size| for |
| 3168 // this call to happen. | 3150 // this call to happen. |
| 3169 DCHECK_GE(session_send_window_size_, delta_window_size); | 3151 DCHECK_GE(session_send_window_size_, delta_window_size); |
| 3170 | 3152 |
| 3171 session_send_window_size_ -= delta_window_size; | 3153 session_send_window_size_ -= delta_window_size; |
| 3172 | 3154 |
| 3173 net_log_.AddEvent( | 3155 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_SEND_WINDOW, |
| 3174 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, | 3156 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 3175 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3157 -delta_window_size, session_send_window_size_)); |
| 3176 -delta_window_size, session_send_window_size_)); | |
| 3177 } | 3158 } |
| 3178 | 3159 |
| 3179 void SpdySession::OnReadBufferConsumed( | 3160 void SpdySession::OnReadBufferConsumed( |
| 3180 size_t consume_size, | 3161 size_t consume_size, |
| 3181 SpdyBuffer::ConsumeSource consume_source) { | 3162 SpdyBuffer::ConsumeSource consume_source) { |
| 3182 // We can be called with |in_io_loop_| set if a read SpdyBuffer is | 3163 // We can be called with |in_io_loop_| set if a read SpdyBuffer is |
| 3183 // deleted (e.g., discarded by a SpdyReadQueue). | 3164 // deleted (e.g., discarded by a SpdyReadQueue). |
| 3184 | 3165 |
| 3185 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3166 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
| 3186 DCHECK_GE(consume_size, 1u); | 3167 DCHECK_GE(consume_size, 1u); |
| 3187 DCHECK_LE(consume_size, static_cast<size_t>(kint32max)); | 3168 DCHECK_LE(consume_size, static_cast<size_t>(kint32max)); |
| 3188 | 3169 |
| 3189 IncreaseRecvWindowSize(static_cast<int32>(consume_size)); | 3170 IncreaseRecvWindowSize(static_cast<int32>(consume_size)); |
| 3190 } | 3171 } |
| 3191 | 3172 |
| 3192 void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) { | 3173 void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) { |
| 3193 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3174 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
| 3194 DCHECK_GE(session_unacked_recv_window_bytes_, 0); | 3175 DCHECK_GE(session_unacked_recv_window_bytes_, 0); |
| 3195 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); | 3176 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); |
| 3196 DCHECK_GE(delta_window_size, 1); | 3177 DCHECK_GE(delta_window_size, 1); |
| 3197 // Check for overflow. | 3178 // Check for overflow. |
| 3198 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); | 3179 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); |
| 3199 | 3180 |
| 3200 session_recv_window_size_ += delta_window_size; | 3181 session_recv_window_size_ += delta_window_size; |
| 3201 net_log_.AddEvent( | 3182 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, |
| 3202 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, | 3183 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 3203 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3184 delta_window_size, session_recv_window_size_)); |
| 3204 delta_window_size, session_recv_window_size_)); | |
| 3205 | 3185 |
| 3206 session_unacked_recv_window_bytes_ += delta_window_size; | 3186 session_unacked_recv_window_bytes_ += delta_window_size; |
| 3207 if (session_unacked_recv_window_bytes_ > | 3187 if (session_unacked_recv_window_bytes_ > |
| 3208 GetInitialWindowSize(protocol_) / 2) { | 3188 GetInitialWindowSize(protocol_) / 2) { |
| 3209 SendWindowUpdateFrame(kSessionFlowControlStreamId, | 3189 SendWindowUpdateFrame(kSessionFlowControlStreamId, |
| 3210 session_unacked_recv_window_bytes_, | 3190 session_unacked_recv_window_bytes_, |
| 3211 HIGHEST); | 3191 HIGHEST); |
| 3212 session_unacked_recv_window_bytes_ = 0; | 3192 session_unacked_recv_window_bytes_ = 0; |
| 3213 } | 3193 } |
| 3214 } | 3194 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3225 RecordProtocolErrorHistogram(PROTOCOL_ERROR_RECEIVE_WINDOW_VIOLATION); | 3205 RecordProtocolErrorHistogram(PROTOCOL_ERROR_RECEIVE_WINDOW_VIOLATION); |
| 3226 DoDrainSession( | 3206 DoDrainSession( |
| 3227 ERR_SPDY_FLOW_CONTROL_ERROR, | 3207 ERR_SPDY_FLOW_CONTROL_ERROR, |
| 3228 "delta_window_size is " + base::IntToString(delta_window_size) + | 3208 "delta_window_size is " + base::IntToString(delta_window_size) + |
| 3229 " in DecreaseRecvWindowSize, which is larger than the receive " + | 3209 " in DecreaseRecvWindowSize, which is larger than the receive " + |
| 3230 "window size of " + base::IntToString(session_recv_window_size_)); | 3210 "window size of " + base::IntToString(session_recv_window_size_)); |
| 3231 return; | 3211 return; |
| 3232 } | 3212 } |
| 3233 | 3213 |
| 3234 session_recv_window_size_ -= delta_window_size; | 3214 session_recv_window_size_ -= delta_window_size; |
| 3235 net_log_.AddEvent( | 3215 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_RECV_WINDOW, |
| 3236 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, | 3216 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 3237 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3217 -delta_window_size, session_recv_window_size_)); |
| 3238 -delta_window_size, session_recv_window_size_)); | |
| 3239 } | 3218 } |
| 3240 | 3219 |
| 3241 void SpdySession::QueueSendStalledStream(const SpdyStream& stream) { | 3220 void SpdySession::QueueSendStalledStream(const SpdyStream& stream) { |
| 3242 DCHECK(stream.send_stalled_by_flow_control()); | 3221 DCHECK(stream.send_stalled_by_flow_control()); |
| 3243 RequestPriority priority = stream.priority(); | 3222 RequestPriority priority = stream.priority(); |
| 3244 CHECK_GE(priority, MINIMUM_PRIORITY); | 3223 CHECK_GE(priority, MINIMUM_PRIORITY); |
| 3245 CHECK_LE(priority, MAXIMUM_PRIORITY); | 3224 CHECK_LE(priority, MAXIMUM_PRIORITY); |
| 3246 stream_send_unstall_queue_[priority].push_back(stream.stream_id()); | 3225 stream_send_unstall_queue_[priority].push_back(stream.stream_id()); |
| 3247 } | 3226 } |
| 3248 | 3227 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3282 if (!queue->empty()) { | 3261 if (!queue->empty()) { |
| 3283 SpdyStreamId stream_id = queue->front(); | 3262 SpdyStreamId stream_id = queue->front(); |
| 3284 queue->pop_front(); | 3263 queue->pop_front(); |
| 3285 return stream_id; | 3264 return stream_id; |
| 3286 } | 3265 } |
| 3287 } | 3266 } |
| 3288 return 0; | 3267 return 0; |
| 3289 } | 3268 } |
| 3290 | 3269 |
| 3291 } // namespace net | 3270 } // namespace net |
| OLD | NEW |