| 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 <limits> | 8 #include <limits> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "net/base/proxy_delegate.h" | 31 #include "net/base/proxy_delegate.h" |
| 32 #include "net/cert/asn1_util.h" | 32 #include "net/cert/asn1_util.h" |
| 33 #include "net/cert/cert_verify_result.h" | 33 #include "net/cert/cert_verify_result.h" |
| 34 #include "net/cert/ct_policy_status.h" | 34 #include "net/cert/ct_policy_status.h" |
| 35 #include "net/http/http_log_util.h" | 35 #include "net/http/http_log_util.h" |
| 36 #include "net/http/http_network_session.h" | 36 #include "net/http/http_network_session.h" |
| 37 #include "net/http/http_server_properties.h" | 37 #include "net/http/http_server_properties.h" |
| 38 #include "net/http/http_util.h" | 38 #include "net/http/http_util.h" |
| 39 #include "net/http/transport_security_state.h" | 39 #include "net/http/transport_security_state.h" |
| 40 #include "net/log/net_log.h" | 40 #include "net/log/net_log.h" |
| 41 #include "net/log/net_log_event_type.h" |
| 42 #include "net/log/net_log_source_type.h" |
| 41 #include "net/proxy/proxy_server.h" | 43 #include "net/proxy/proxy_server.h" |
| 42 #include "net/socket/ssl_client_socket.h" | 44 #include "net/socket/ssl_client_socket.h" |
| 43 #include "net/spdy/spdy_buffer_producer.h" | 45 #include "net/spdy/spdy_buffer_producer.h" |
| 44 #include "net/spdy/spdy_frame_builder.h" | 46 #include "net/spdy/spdy_frame_builder.h" |
| 45 #include "net/spdy/spdy_http_utils.h" | 47 #include "net/spdy/spdy_http_utils.h" |
| 46 #include "net/spdy/spdy_protocol.h" | 48 #include "net/spdy/spdy_protocol.h" |
| 47 #include "net/spdy/spdy_session_pool.h" | 49 #include "net/spdy/spdy_session_pool.h" |
| 48 #include "net/spdy/spdy_stream.h" | 50 #include "net/spdy/spdy_stream.h" |
| 49 #include "net/ssl/channel_id_service.h" | 51 #include "net/ssl/channel_id_service.h" |
| 50 #include "net/ssl/ssl_cipher_suite_names.h" | 52 #include "net/ssl/ssl_cipher_suite_names.h" |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 next_ping_id_(1), | 665 next_ping_id_(1), |
| 664 last_activity_time_(time_func()), | 666 last_activity_time_(time_func()), |
| 665 last_compressed_frame_len_(0), | 667 last_compressed_frame_len_(0), |
| 666 check_ping_status_pending_(false), | 668 check_ping_status_pending_(false), |
| 667 session_send_window_size_(0), | 669 session_send_window_size_(0), |
| 668 session_max_recv_window_size_(session_max_recv_window_size), | 670 session_max_recv_window_size_(session_max_recv_window_size), |
| 669 session_recv_window_size_(0), | 671 session_recv_window_size_(0), |
| 670 session_unacked_recv_window_bytes_(0), | 672 session_unacked_recv_window_bytes_(0), |
| 671 stream_initial_send_window_size_(kDefaultInitialWindowSize), | 673 stream_initial_send_window_size_(kDefaultInitialWindowSize), |
| 672 stream_max_recv_window_size_(stream_max_recv_window_size), | 674 stream_max_recv_window_size_(stream_max_recv_window_size), |
| 673 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP2_SESSION)), | 675 net_log_(BoundNetLog::Make(net_log, NetLogSourceType::HTTP2_SESSION)), |
| 674 verify_domain_authentication_(verify_domain_authentication), | 676 verify_domain_authentication_(verify_domain_authentication), |
| 675 enable_sending_initial_data_(enable_sending_initial_data), | 677 enable_sending_initial_data_(enable_sending_initial_data), |
| 676 enable_ping_based_connection_checking_( | 678 enable_ping_based_connection_checking_( |
| 677 enable_ping_based_connection_checking), | 679 enable_ping_based_connection_checking), |
| 678 connection_at_risk_of_loss_time_( | 680 connection_at_risk_of_loss_time_( |
| 679 base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)), | 681 base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)), |
| 680 hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)), | 682 hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)), |
| 681 proxy_delegate_(proxy_delegate), | 683 proxy_delegate_(proxy_delegate), |
| 682 time_func_(time_func), | 684 time_func_(time_func), |
| 683 weak_factory_(this) { | 685 weak_factory_(this) { |
| 684 net_log_.BeginEvent( | 686 net_log_.BeginEvent( |
| 685 NetLog::TYPE_HTTP2_SESSION, | 687 NetLogEventType::HTTP2_SESSION, |
| 686 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair())); | 688 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair())); |
| 687 next_unclaimed_push_stream_sweep_time_ = time_func_() + | 689 next_unclaimed_push_stream_sweep_time_ = time_func_() + |
| 688 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); | 690 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); |
| 689 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. | 691 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. |
| 690 } | 692 } |
| 691 | 693 |
| 692 SpdySession::~SpdySession() { | 694 SpdySession::~SpdySession() { |
| 693 CHECK(!in_io_loop_); | 695 CHECK(!in_io_loop_); |
| 694 DcheckDraining(); | 696 DcheckDraining(); |
| 695 | 697 |
| 696 // TODO(akalin): Check connection->is_initialized() instead. This | 698 // TODO(akalin): Check connection->is_initialized() instead. This |
| 697 // requires re-working CreateFakeSpdySession(), though. | 699 // requires re-working CreateFakeSpdySession(), though. |
| 698 DCHECK(connection_->socket()); | 700 DCHECK(connection_->socket()); |
| 699 // With SPDY we can't recycle sockets. | 701 // With SPDY we can't recycle sockets. |
| 700 connection_->socket()->Disconnect(); | 702 connection_->socket()->Disconnect(); |
| 701 | 703 |
| 702 RecordHistograms(); | 704 RecordHistograms(); |
| 703 | 705 |
| 704 net_log_.EndEvent(NetLog::TYPE_HTTP2_SESSION); | 706 net_log_.EndEvent(NetLogEventType::HTTP2_SESSION); |
| 705 } | 707 } |
| 706 | 708 |
| 707 void SpdySession::InitializeWithSocket( | 709 void SpdySession::InitializeWithSocket( |
| 708 std::unique_ptr<ClientSocketHandle> connection, | 710 std::unique_ptr<ClientSocketHandle> connection, |
| 709 SpdySessionPool* pool, | 711 SpdySessionPool* pool, |
| 710 bool is_secure, | 712 bool is_secure, |
| 711 int certificate_error_code) { | 713 int certificate_error_code) { |
| 712 CHECK(!in_io_loop_); | 714 CHECK(!in_io_loop_); |
| 713 DCHECK_EQ(availability_state_, STATE_AVAILABLE); | 715 DCHECK_EQ(availability_state_, STATE_AVAILABLE); |
| 714 DCHECK_EQ(read_state_, READ_STATE_DO_READ); | 716 DCHECK_EQ(read_state_, READ_STATE_DO_READ); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 726 certificate_error_code_ = certificate_error_code; | 728 certificate_error_code_ = certificate_error_code; |
| 727 | 729 |
| 728 session_send_window_size_ = kDefaultInitialWindowSize; | 730 session_send_window_size_ = kDefaultInitialWindowSize; |
| 729 session_recv_window_size_ = kDefaultInitialWindowSize; | 731 session_recv_window_size_ = kDefaultInitialWindowSize; |
| 730 | 732 |
| 731 buffered_spdy_framer_.reset(new BufferedSpdyFramer()); | 733 buffered_spdy_framer_.reset(new BufferedSpdyFramer()); |
| 732 buffered_spdy_framer_->set_visitor(this); | 734 buffered_spdy_framer_->set_visitor(this); |
| 733 buffered_spdy_framer_->set_debug_visitor(this); | 735 buffered_spdy_framer_->set_debug_visitor(this); |
| 734 buffered_spdy_framer_->UpdateHeaderDecoderTableSize(kMaxHeaderTableSize); | 736 buffered_spdy_framer_->UpdateHeaderDecoderTableSize(kMaxHeaderTableSize); |
| 735 | 737 |
| 736 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_INITIALIZED, | 738 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_INITIALIZED, |
| 737 base::Bind(&NetLogSpdyInitializedCallback, | 739 base::Bind(&NetLogSpdyInitializedCallback, |
| 738 connection_->socket()->NetLog().source())); | 740 connection_->socket()->NetLog().source())); |
| 739 | 741 |
| 740 DCHECK_EQ(availability_state_, STATE_AVAILABLE); | 742 DCHECK_EQ(availability_state_, STATE_AVAILABLE); |
| 741 connection_->AddHigherLayeredPool(this); | 743 connection_->AddHigherLayeredPool(this); |
| 742 if (enable_sending_initial_data_) | 744 if (enable_sending_initial_data_) |
| 743 SendInitialData(); | 745 SendInitialData(); |
| 744 pool_ = pool; | 746 pool_ = pool; |
| 745 | 747 |
| 746 // Bootstrap the read loop. | 748 // Bootstrap the read loop. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 Error err = TryAccessStream(request->url()); | 822 Error err = TryAccessStream(request->url()); |
| 821 if (err != OK) | 823 if (err != OK) |
| 822 return err; | 824 return err; |
| 823 | 825 |
| 824 if ((active_streams_.size() + created_streams_.size() - num_pushed_streams_ < | 826 if ((active_streams_.size() + created_streams_.size() - num_pushed_streams_ < |
| 825 max_concurrent_streams_)) { | 827 max_concurrent_streams_)) { |
| 826 return CreateStream(*request, stream); | 828 return CreateStream(*request, stream); |
| 827 } | 829 } |
| 828 | 830 |
| 829 stalled_streams_++; | 831 stalled_streams_++; |
| 830 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_STALLED_MAX_STREAMS); | 832 net_log().AddEvent(NetLogEventType::HTTP2_SESSION_STALLED_MAX_STREAMS); |
| 831 RequestPriority priority = request->priority(); | 833 RequestPriority priority = request->priority(); |
| 832 CHECK_GE(priority, MINIMUM_PRIORITY); | 834 CHECK_GE(priority, MINIMUM_PRIORITY); |
| 833 CHECK_LE(priority, MAXIMUM_PRIORITY); | 835 CHECK_LE(priority, MAXIMUM_PRIORITY); |
| 834 pending_create_stream_queues_[priority].push_back(request); | 836 pending_create_stream_queues_[priority].push_back(request); |
| 835 return ERR_IO_PENDING; | 837 return ERR_IO_PENDING; |
| 836 } | 838 } |
| 837 | 839 |
| 838 int SpdySession::CreateStream(const SpdyStreamRequest& request, | 840 int SpdySession::CreateStream(const SpdyStreamRequest& request, |
| 839 base::WeakPtr<SpdyStream>* stream) { | 841 base::WeakPtr<SpdyStream>* stream) { |
| 840 DCHECK_GE(request.priority(), MINIMUM_PRIORITY); | 842 DCHECK_GE(request.priority(), MINIMUM_PRIORITY); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 bool has_priority = true; | 1011 bool has_priority = true; |
| 1010 int weight = Spdy3PriorityToHttp2Weight(spdy_priority); | 1012 int weight = Spdy3PriorityToHttp2Weight(spdy_priority); |
| 1011 SpdyStreamId dependent_stream_id = 0; | 1013 SpdyStreamId dependent_stream_id = 0; |
| 1012 bool exclusive = false; | 1014 bool exclusive = false; |
| 1013 | 1015 |
| 1014 priority_dependency_state_.OnStreamSynSent(stream_id, spdy_priority, | 1016 priority_dependency_state_.OnStreamSynSent(stream_id, spdy_priority, |
| 1015 &dependent_stream_id, &exclusive); | 1017 &dependent_stream_id, &exclusive); |
| 1016 | 1018 |
| 1017 if (net_log().IsCapturing()) { | 1019 if (net_log().IsCapturing()) { |
| 1018 net_log().AddEvent( | 1020 net_log().AddEvent( |
| 1019 NetLog::TYPE_HTTP2_SESSION_SEND_HEADERS, | 1021 NetLogEventType::HTTP2_SESSION_SEND_HEADERS, |
| 1020 base::Bind(&NetLogSpdyHeadersSentCallback, &block, | 1022 base::Bind(&NetLogSpdyHeadersSentCallback, &block, |
| 1021 (flags & CONTROL_FLAG_FIN) != 0, stream_id, has_priority, | 1023 (flags & CONTROL_FLAG_FIN) != 0, stream_id, has_priority, |
| 1022 weight, dependent_stream_id, exclusive)); | 1024 weight, dependent_stream_id, exclusive)); |
| 1023 } | 1025 } |
| 1024 | 1026 |
| 1025 SpdyHeadersIR headers(stream_id, std::move(block)); | 1027 SpdyHeadersIR headers(stream_id, std::move(block)); |
| 1026 headers.set_has_priority(has_priority); | 1028 headers.set_has_priority(has_priority); |
| 1027 headers.set_weight(weight); | 1029 headers.set_weight(weight); |
| 1028 headers.set_parent_stream_id(dependent_stream_id); | 1030 headers.set_parent_stream_id(dependent_stream_id); |
| 1029 headers.set_exclusive(exclusive); | 1031 headers.set_exclusive(exclusive); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 frame_flow_control_state, | 1085 frame_flow_control_state, |
| 1084 SEND_STALLED_BY_STREAM_AND_SESSION + 1); | 1086 SEND_STALLED_BY_STREAM_AND_SESSION + 1); |
| 1085 | 1087 |
| 1086 // Obey send window size of the stream. | 1088 // Obey send window size of the stream. |
| 1087 if (send_stalled_by_stream) { | 1089 if (send_stalled_by_stream) { |
| 1088 stream->set_send_stalled_by_flow_control(true); | 1090 stream->set_send_stalled_by_flow_control(true); |
| 1089 // Even though we're currently stalled only by the stream, we | 1091 // Even though we're currently stalled only by the stream, we |
| 1090 // might end up being stalled by the session also. | 1092 // might end up being stalled by the session also. |
| 1091 QueueSendStalledStream(*stream); | 1093 QueueSendStalledStream(*stream); |
| 1092 net_log().AddEvent( | 1094 net_log().AddEvent( |
| 1093 NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW, | 1095 NetLogEventType::HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW, |
| 1094 NetLog::IntCallback("stream_id", stream_id)); | 1096 NetLog::IntCallback("stream_id", stream_id)); |
| 1095 return std::unique_ptr<SpdyBuffer>(); | 1097 return std::unique_ptr<SpdyBuffer>(); |
| 1096 } | 1098 } |
| 1097 | 1099 |
| 1098 effective_len = std::min(effective_len, stream->send_window_size()); | 1100 effective_len = std::min(effective_len, stream->send_window_size()); |
| 1099 | 1101 |
| 1100 // Obey send window size of the session. | 1102 // Obey send window size of the session. |
| 1101 if (send_stalled_by_session) { | 1103 if (send_stalled_by_session) { |
| 1102 stream->set_send_stalled_by_flow_control(true); | 1104 stream->set_send_stalled_by_flow_control(true); |
| 1103 QueueSendStalledStream(*stream); | 1105 QueueSendStalledStream(*stream); |
| 1104 net_log().AddEvent( | 1106 net_log().AddEvent( |
| 1105 NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW, | 1107 NetLogEventType::HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW, |
| 1106 NetLog::IntCallback("stream_id", stream_id)); | 1108 NetLog::IntCallback("stream_id", stream_id)); |
| 1107 return std::unique_ptr<SpdyBuffer>(); | 1109 return std::unique_ptr<SpdyBuffer>(); |
| 1108 } | 1110 } |
| 1109 | 1111 |
| 1110 effective_len = std::min(effective_len, session_send_window_size_); | 1112 effective_len = std::min(effective_len, session_send_window_size_); |
| 1111 | 1113 |
| 1112 DCHECK_GE(effective_len, 0); | 1114 DCHECK_GE(effective_len, 0); |
| 1113 | 1115 |
| 1114 // Clear FIN flag if only some of the data will be in the data | 1116 // Clear FIN flag if only some of the data will be in the data |
| 1115 // frame. | 1117 // frame. |
| 1116 if (effective_len < len) | 1118 if (effective_len < len) |
| 1117 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); | 1119 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); |
| 1118 | 1120 |
| 1119 if (net_log().IsCapturing()) { | 1121 if (net_log().IsCapturing()) { |
| 1120 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SEND_DATA, | 1122 net_log().AddEvent(NetLogEventType::HTTP2_SESSION_SEND_DATA, |
| 1121 base::Bind(&NetLogSpdyDataCallback, stream_id, | 1123 base::Bind(&NetLogSpdyDataCallback, stream_id, |
| 1122 effective_len, (flags & DATA_FLAG_FIN) != 0)); | 1124 effective_len, (flags & DATA_FLAG_FIN) != 0)); |
| 1123 } | 1125 } |
| 1124 | 1126 |
| 1125 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. | 1127 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. |
| 1126 if (effective_len > 0) | 1128 if (effective_len > 0) |
| 1127 SendPrefacePingIfNoneInFlight(); | 1129 SendPrefacePingIfNoneInFlight(); |
| 1128 | 1130 |
| 1129 // TODO(mbelshe): reduce memory copies here. | 1131 // TODO(mbelshe): reduce memory copies here. |
| 1130 DCHECK(buffered_spdy_framer_.get()); | 1132 DCHECK(buffered_spdy_framer_.get()); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR); | 1253 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR); |
| 1252 } | 1254 } |
| 1253 | 1255 |
| 1254 void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id, | 1256 void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id, |
| 1255 RequestPriority priority, | 1257 RequestPriority priority, |
| 1256 SpdyRstStreamStatus status, | 1258 SpdyRstStreamStatus status, |
| 1257 const std::string& description) { | 1259 const std::string& description) { |
| 1258 DCHECK_NE(stream_id, 0u); | 1260 DCHECK_NE(stream_id, 0u); |
| 1259 | 1261 |
| 1260 net_log().AddEvent( | 1262 net_log().AddEvent( |
| 1261 NetLog::TYPE_HTTP2_SESSION_SEND_RST_STREAM, | 1263 NetLogEventType::HTTP2_SESSION_SEND_RST_STREAM, |
| 1262 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); | 1264 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); |
| 1263 | 1265 |
| 1264 DCHECK(buffered_spdy_framer_.get()); | 1266 DCHECK(buffered_spdy_framer_.get()); |
| 1265 std::unique_ptr<SpdySerializedFrame> rst_frame( | 1267 std::unique_ptr<SpdySerializedFrame> rst_frame( |
| 1266 buffered_spdy_framer_->CreateRstStream(stream_id, status)); | 1268 buffered_spdy_framer_->CreateRstStream(stream_id, status)); |
| 1267 | 1269 |
| 1268 EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame)); | 1270 EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame)); |
| 1269 RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status)); | 1271 RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status)); |
| 1270 } | 1272 } |
| 1271 | 1273 |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 EnqueueSessionWrite( | 1666 EnqueueSessionWrite( |
| 1665 HIGHEST, GOAWAY, | 1667 HIGHEST, GOAWAY, |
| 1666 std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame( | 1668 std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame( |
| 1667 buffered_spdy_framer_->SerializeFrame(goaway_ir)))); | 1669 buffered_spdy_framer_->SerializeFrame(goaway_ir)))); |
| 1668 } | 1670 } |
| 1669 | 1671 |
| 1670 availability_state_ = STATE_DRAINING; | 1672 availability_state_ = STATE_DRAINING; |
| 1671 error_on_close_ = err; | 1673 error_on_close_ = err; |
| 1672 | 1674 |
| 1673 net_log_.AddEvent( | 1675 net_log_.AddEvent( |
| 1674 NetLog::TYPE_HTTP2_SESSION_CLOSE, | 1676 NetLogEventType::HTTP2_SESSION_CLOSE, |
| 1675 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); | 1677 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); |
| 1676 | 1678 |
| 1677 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err); | 1679 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err); |
| 1678 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors", | 1680 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors", |
| 1679 total_bytes_received_, 1, 100000000, 50); | 1681 total_bytes_received_, 1, 100000000, 50); |
| 1680 | 1682 |
| 1681 if (err == OK) { | 1683 if (err == OK) { |
| 1682 // We ought to be going away already, as this is a graceful close. | 1684 // We ought to be going away already, as this is a graceful close. |
| 1683 DcheckGoingAway(); | 1685 DcheckGoingAway(); |
| 1684 } else { | 1686 } else { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 | 1911 |
| 1910 SpdyStreamId stream_id = unclaimed_it->second.stream_id; | 1912 SpdyStreamId stream_id = unclaimed_it->second.stream_id; |
| 1911 unclaimed_pushed_streams_.erase(unclaimed_it); | 1913 unclaimed_pushed_streams_.erase(unclaimed_it); |
| 1912 | 1914 |
| 1913 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); | 1915 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); |
| 1914 if (active_it == active_streams_.end()) { | 1916 if (active_it == active_streams_.end()) { |
| 1915 NOTREACHED(); | 1917 NOTREACHED(); |
| 1916 return base::WeakPtr<SpdyStream>(); | 1918 return base::WeakPtr<SpdyStream>(); |
| 1917 } | 1919 } |
| 1918 | 1920 |
| 1919 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_ADOPTED_PUSH_STREAM, | 1921 net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_ADOPTED_PUSH_STREAM, |
| 1920 base::Bind(&NetLogSpdyAdoptedPushStreamCallback, | 1922 base::Bind(&NetLogSpdyAdoptedPushStreamCallback, |
| 1921 active_it->second.stream->stream_id(), &url)); | 1923 active_it->second.stream->stream_id(), &url)); |
| 1922 return active_it->second.stream->GetWeakPtr(); | 1924 return active_it->second.stream->GetWeakPtr(); |
| 1923 } | 1925 } |
| 1924 | 1926 |
| 1925 url::SchemeHostPort SpdySession::GetServer() { | 1927 url::SchemeHostPort SpdySession::GetServer() { |
| 1926 return url::SchemeHostPort(is_secure_ ? "https" : "http", | 1928 return url::SchemeHostPort(is_secure_ ? "https" : "http", |
| 1927 host_port_pair().host(), host_port_pair().port()); | 1929 host_port_pair().host(), host_port_pair().port()); |
| 1928 } | 1930 } |
| 1929 | 1931 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1996 stream->AddRawReceivedBytes(header_len); | 1998 stream->AddRawReceivedBytes(header_len); |
| 1997 } | 1999 } |
| 1998 | 2000 |
| 1999 void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, | 2001 void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, |
| 2000 const char* data, | 2002 const char* data, |
| 2001 size_t len) { | 2003 size_t len) { |
| 2002 CHECK(in_io_loop_); | 2004 CHECK(in_io_loop_); |
| 2003 DCHECK_LT(len, 1u << 24); | 2005 DCHECK_LT(len, 1u << 24); |
| 2004 if (net_log().IsCapturing()) { | 2006 if (net_log().IsCapturing()) { |
| 2005 net_log().AddEvent( | 2007 net_log().AddEvent( |
| 2006 NetLog::TYPE_HTTP2_SESSION_RECV_DATA, | 2008 NetLogEventType::HTTP2_SESSION_RECV_DATA, |
| 2007 base::Bind(&NetLogSpdyDataCallback, stream_id, len, false)); | 2009 base::Bind(&NetLogSpdyDataCallback, stream_id, len, false)); |
| 2008 } | 2010 } |
| 2009 | 2011 |
| 2010 // Build the buffer as early as possible so that we go through the | 2012 // Build the buffer as early as possible so that we go through the |
| 2011 // session flow control checks and update | 2013 // session flow control checks and update |
| 2012 // |unacked_recv_window_bytes_| properly even when the stream is | 2014 // |unacked_recv_window_bytes_| properly even when the stream is |
| 2013 // inactive (since the other side has still reduced its session send | 2015 // inactive (since the other side has still reduced its session send |
| 2014 // window). | 2016 // window). |
| 2015 std::unique_ptr<SpdyBuffer> buffer; | 2017 std::unique_ptr<SpdyBuffer> buffer; |
| 2016 if (data) { | 2018 if (data) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2042 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); | 2044 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); |
| 2043 return; | 2045 return; |
| 2044 } | 2046 } |
| 2045 | 2047 |
| 2046 stream->OnDataReceived(std::move(buffer)); | 2048 stream->OnDataReceived(std::move(buffer)); |
| 2047 } | 2049 } |
| 2048 | 2050 |
| 2049 void SpdySession::OnStreamEnd(SpdyStreamId stream_id) { | 2051 void SpdySession::OnStreamEnd(SpdyStreamId stream_id) { |
| 2050 CHECK(in_io_loop_); | 2052 CHECK(in_io_loop_); |
| 2051 if (net_log().IsCapturing()) { | 2053 if (net_log().IsCapturing()) { |
| 2052 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_DATA, | 2054 net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_DATA, |
| 2053 base::Bind(&NetLogSpdyDataCallback, stream_id, 0, true)); | 2055 base::Bind(&NetLogSpdyDataCallback, stream_id, 0, true)); |
| 2054 } | 2056 } |
| 2055 | 2057 |
| 2056 // Build the buffer as early as possible so that we go through the | 2058 // Build the buffer as early as possible so that we go through the |
| 2057 // session flow control checks and update | 2059 // session flow control checks and update |
| 2058 // |unacked_recv_window_bytes_| properly even when the stream is | 2060 // |unacked_recv_window_bytes_| properly even when the stream is |
| 2059 // inactive (since the other side has still reduced its session send | 2061 // inactive (since the other side has still reduced its session send |
| 2060 // window). | 2062 // window). |
| 2061 std::unique_ptr<SpdyBuffer> buffer; | 2063 std::unique_ptr<SpdyBuffer> buffer; |
| 2062 | 2064 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2095 it->second.stream->OnPaddingConsumed(len); | 2097 it->second.stream->OnPaddingConsumed(len); |
| 2096 } | 2098 } |
| 2097 | 2099 |
| 2098 void SpdySession::OnSettings(bool clear_persisted) { | 2100 void SpdySession::OnSettings(bool clear_persisted) { |
| 2099 CHECK(in_io_loop_); | 2101 CHECK(in_io_loop_); |
| 2100 | 2102 |
| 2101 if (clear_persisted) | 2103 if (clear_persisted) |
| 2102 http_server_properties_->ClearSpdySettings(GetServer()); | 2104 http_server_properties_->ClearSpdySettings(GetServer()); |
| 2103 | 2105 |
| 2104 if (net_log_.IsCapturing()) { | 2106 if (net_log_.IsCapturing()) { |
| 2105 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTINGS, | 2107 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTINGS, |
| 2106 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), | 2108 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), |
| 2107 clear_persisted)); | 2109 clear_persisted)); |
| 2108 } | 2110 } |
| 2109 | 2111 |
| 2110 // Send an acknowledgment of the setting. | 2112 // Send an acknowledgment of the setting. |
| 2111 SpdySettingsIR settings_ir; | 2113 SpdySettingsIR settings_ir; |
| 2112 settings_ir.set_is_ack(true); | 2114 settings_ir.set_is_ack(true); |
| 2113 EnqueueSessionWrite( | 2115 EnqueueSessionWrite( |
| 2114 HIGHEST, SETTINGS, | 2116 HIGHEST, SETTINGS, |
| 2115 std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame( | 2117 std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame( |
| 2116 buffered_spdy_framer_->SerializeFrame(settings_ir)))); | 2118 buffered_spdy_framer_->SerializeFrame(settings_ir)))); |
| 2117 } | 2119 } |
| 2118 | 2120 |
| 2119 void SpdySession::OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) { | 2121 void SpdySession::OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) { |
| 2120 CHECK(in_io_loop_); | 2122 CHECK(in_io_loop_); |
| 2121 | 2123 |
| 2122 HandleSetting(id, value); | 2124 HandleSetting(id, value); |
| 2123 http_server_properties_->SetSpdySetting( | 2125 http_server_properties_->SetSpdySetting( |
| 2124 GetServer(), id, static_cast<SpdySettingsFlags>(flags), value); | 2126 GetServer(), id, static_cast<SpdySettingsFlags>(flags), value); |
| 2125 received_settings_ = true; | 2127 received_settings_ = true; |
| 2126 | 2128 |
| 2127 // Log the setting. | 2129 // Log the setting. |
| 2128 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTING, | 2130 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_SETTING, |
| 2129 base::Bind(&NetLogSpdySettingCallback, id, | 2131 base::Bind(&NetLogSpdySettingCallback, id, |
| 2130 static_cast<SpdySettingsFlags>(flags), value)); | 2132 static_cast<SpdySettingsFlags>(flags), value)); |
| 2131 } | 2133 } |
| 2132 | 2134 |
| 2133 void SpdySession::OnSendCompressedFrame( | 2135 void SpdySession::OnSendCompressedFrame( |
| 2134 SpdyStreamId stream_id, | 2136 SpdyStreamId stream_id, |
| 2135 SpdyFrameType type, | 2137 SpdyFrameType type, |
| 2136 size_t payload_len, | 2138 size_t payload_len, |
| 2137 size_t frame_len) { | 2139 size_t frame_len) { |
| 2138 if (type != HEADERS) | 2140 if (type != HEADERS) |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 void SpdySession::OnHeaders(SpdyStreamId stream_id, | 2234 void SpdySession::OnHeaders(SpdyStreamId stream_id, |
| 2233 bool has_priority, | 2235 bool has_priority, |
| 2234 int weight, | 2236 int weight, |
| 2235 SpdyStreamId parent_stream_id, | 2237 SpdyStreamId parent_stream_id, |
| 2236 bool exclusive, | 2238 bool exclusive, |
| 2237 bool fin, | 2239 bool fin, |
| 2238 SpdyHeaderBlock headers) { | 2240 SpdyHeaderBlock headers) { |
| 2239 CHECK(in_io_loop_); | 2241 CHECK(in_io_loop_); |
| 2240 | 2242 |
| 2241 if (net_log().IsCapturing()) { | 2243 if (net_log().IsCapturing()) { |
| 2242 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_HEADERS, | 2244 net_log().AddEvent(NetLogEventType::HTTP2_SESSION_RECV_HEADERS, |
| 2243 base::Bind(&NetLogSpdyHeadersReceivedCallback, &headers, | 2245 base::Bind(&NetLogSpdyHeadersReceivedCallback, &headers, |
| 2244 fin, stream_id)); | 2246 fin, stream_id)); |
| 2245 } | 2247 } |
| 2246 | 2248 |
| 2247 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2249 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
| 2248 if (it == active_streams_.end()) { | 2250 if (it == active_streams_.end()) { |
| 2249 // NOTE: it may just be that the stream was cancelled. | 2251 // NOTE: it may just be that the stream was cancelled. |
| 2250 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; | 2252 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; |
| 2251 return; | 2253 return; |
| 2252 } | 2254 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2340 | 2342 |
| 2341 return true; | 2343 return true; |
| 2342 } | 2344 } |
| 2343 | 2345 |
| 2344 void SpdySession::OnRstStream(SpdyStreamId stream_id, | 2346 void SpdySession::OnRstStream(SpdyStreamId stream_id, |
| 2345 SpdyRstStreamStatus status) { | 2347 SpdyRstStreamStatus status) { |
| 2346 CHECK(in_io_loop_); | 2348 CHECK(in_io_loop_); |
| 2347 | 2349 |
| 2348 std::string description; | 2350 std::string description; |
| 2349 net_log().AddEvent( | 2351 net_log().AddEvent( |
| 2350 NetLog::TYPE_HTTP2_SESSION_RST_STREAM, | 2352 NetLogEventType::HTTP2_SESSION_RST_STREAM, |
| 2351 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); | 2353 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); |
| 2352 | 2354 |
| 2353 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2355 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
| 2354 if (it == active_streams_.end()) { | 2356 if (it == active_streams_.end()) { |
| 2355 // NOTE: it may just be that the stream was cancelled. | 2357 // NOTE: it may just be that the stream was cancelled. |
| 2356 LOG(WARNING) << "Received RST for invalid stream" << stream_id; | 2358 LOG(WARNING) << "Received RST for invalid stream" << stream_id; |
| 2357 return; | 2359 return; |
| 2358 } | 2360 } |
| 2359 | 2361 |
| 2360 CHECK_EQ(it->second.stream->stream_id(), stream_id); | 2362 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2383 } | 2385 } |
| 2384 | 2386 |
| 2385 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, | 2387 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, |
| 2386 SpdyGoAwayStatus status, | 2388 SpdyGoAwayStatus status, |
| 2387 base::StringPiece debug_data) { | 2389 base::StringPiece debug_data) { |
| 2388 CHECK(in_io_loop_); | 2390 CHECK(in_io_loop_); |
| 2389 | 2391 |
| 2390 // TODO(jgraettinger): UMA histogram on |status|. | 2392 // TODO(jgraettinger): UMA histogram on |status|. |
| 2391 | 2393 |
| 2392 net_log_.AddEvent( | 2394 net_log_.AddEvent( |
| 2393 NetLog::TYPE_HTTP2_SESSION_GOAWAY, | 2395 NetLogEventType::HTTP2_SESSION_GOAWAY, |
| 2394 base::Bind(&NetLogSpdyGoAwayCallback, last_accepted_stream_id, | 2396 base::Bind(&NetLogSpdyGoAwayCallback, last_accepted_stream_id, |
| 2395 active_streams_.size(), unclaimed_pushed_streams_.size(), | 2397 active_streams_.size(), unclaimed_pushed_streams_.size(), |
| 2396 status, debug_data)); | 2398 status, debug_data)); |
| 2397 MakeUnavailable(); | 2399 MakeUnavailable(); |
| 2398 if (status == GOAWAY_HTTP_1_1_REQUIRED) { | 2400 if (status == GOAWAY_HTTP_1_1_REQUIRED) { |
| 2399 // TODO(bnc): Record histogram with number of open streams capped at 50. | 2401 // TODO(bnc): Record histogram with number of open streams capped at 50. |
| 2400 DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream."); | 2402 DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream."); |
| 2401 } else { | 2403 } else { |
| 2402 StartGoingAway(last_accepted_stream_id, ERR_ABORTED); | 2404 StartGoingAway(last_accepted_stream_id, ERR_ABORTED); |
| 2403 } | 2405 } |
| 2404 // This is to handle the case when we already don't have any active | 2406 // This is to handle the case when we already don't have any active |
| 2405 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have | 2407 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have |
| 2406 // active streams and so the last one being closed will finish the | 2408 // active streams and so the last one being closed will finish the |
| 2407 // going away process (see DeleteStream()). | 2409 // going away process (see DeleteStream()). |
| 2408 MaybeFinishGoingAway(); | 2410 MaybeFinishGoingAway(); |
| 2409 } | 2411 } |
| 2410 | 2412 |
| 2411 void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) { | 2413 void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) { |
| 2412 CHECK(in_io_loop_); | 2414 CHECK(in_io_loop_); |
| 2413 | 2415 |
| 2414 net_log_.AddEvent( | 2416 net_log_.AddEvent( |
| 2415 NetLog::TYPE_HTTP2_SESSION_PING, | 2417 NetLogEventType::HTTP2_SESSION_PING, |
| 2416 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received")); | 2418 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "received")); |
| 2417 | 2419 |
| 2418 // Send response to a PING from server. | 2420 // Send response to a PING from server. |
| 2419 if (!is_ack) { | 2421 if (!is_ack) { |
| 2420 WritePingFrame(unique_id, true); | 2422 WritePingFrame(unique_id, true); |
| 2421 return; | 2423 return; |
| 2422 } | 2424 } |
| 2423 | 2425 |
| 2424 --pings_in_flight_; | 2426 --pings_in_flight_; |
| 2425 if (pings_in_flight_ < 0) { | 2427 if (pings_in_flight_ < 0) { |
| 2426 RecordProtocolErrorHistogram(PROTOCOL_ERROR_UNEXPECTED_PING); | 2428 RecordProtocolErrorHistogram(PROTOCOL_ERROR_UNEXPECTED_PING); |
| 2427 DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, "pings_in_flight_ is < 0."); | 2429 DoDrainSession(ERR_SPDY_PROTOCOL_ERROR, "pings_in_flight_ is < 0."); |
| 2428 pings_in_flight_ = 0; | 2430 pings_in_flight_ = 0; |
| 2429 return; | 2431 return; |
| 2430 } | 2432 } |
| 2431 | 2433 |
| 2432 if (pings_in_flight_ > 0) | 2434 if (pings_in_flight_ > 0) |
| 2433 return; | 2435 return; |
| 2434 | 2436 |
| 2435 // We will record RTT in histogram when there are no more client sent | 2437 // We will record RTT in histogram when there are no more client sent |
| 2436 // pings_in_flight_. | 2438 // pings_in_flight_. |
| 2437 RecordPingRTTHistogram(time_func_() - last_ping_sent_time_); | 2439 RecordPingRTTHistogram(time_func_() - last_ping_sent_time_); |
| 2438 } | 2440 } |
| 2439 | 2441 |
| 2440 void SpdySession::OnWindowUpdate(SpdyStreamId stream_id, | 2442 void SpdySession::OnWindowUpdate(SpdyStreamId stream_id, |
| 2441 int delta_window_size) { | 2443 int delta_window_size) { |
| 2442 CHECK(in_io_loop_); | 2444 CHECK(in_io_loop_); |
| 2443 | 2445 |
| 2444 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECEIVED_WINDOW_UPDATE_FRAME, | 2446 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECEIVED_WINDOW_UPDATE_FRAME, |
| 2445 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, stream_id, | 2447 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, stream_id, |
| 2446 delta_window_size)); | 2448 delta_window_size)); |
| 2447 | 2449 |
| 2448 if (stream_id == kSessionFlowControlStreamId) { | 2450 if (stream_id == kSessionFlowControlStreamId) { |
| 2449 // WINDOW_UPDATE for the session. | 2451 // WINDOW_UPDATE for the session. |
| 2450 if (delta_window_size < 1) { | 2452 if (delta_window_size < 1) { |
| 2451 RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE); | 2453 RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE); |
| 2452 DoDrainSession( | 2454 DoDrainSession( |
| 2453 ERR_SPDY_PROTOCOL_ERROR, | 2455 ERR_SPDY_PROTOCOL_ERROR, |
| 2454 "Received WINDOW_UPDATE with an invalid delta_window_size " + | 2456 "Received WINDOW_UPDATE with an invalid delta_window_size " + |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2667 num_pushed_streams_++; | 2669 num_pushed_streams_++; |
| 2668 return true; | 2670 return true; |
| 2669 } | 2671 } |
| 2670 | 2672 |
| 2671 void SpdySession::OnPushPromise(SpdyStreamId stream_id, | 2673 void SpdySession::OnPushPromise(SpdyStreamId stream_id, |
| 2672 SpdyStreamId promised_stream_id, | 2674 SpdyStreamId promised_stream_id, |
| 2673 SpdyHeaderBlock headers) { | 2675 SpdyHeaderBlock headers) { |
| 2674 CHECK(in_io_loop_); | 2676 CHECK(in_io_loop_); |
| 2675 | 2677 |
| 2676 if (net_log_.IsCapturing()) { | 2678 if (net_log_.IsCapturing()) { |
| 2677 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_PUSH_PROMISE, | 2679 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_PUSH_PROMISE, |
| 2678 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, | 2680 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, |
| 2679 &headers, stream_id, promised_stream_id)); | 2681 &headers, stream_id, promised_stream_id)); |
| 2680 } | 2682 } |
| 2681 | 2683 |
| 2682 // Any priority will do. | 2684 // Any priority will do. |
| 2683 // TODO(baranovich): pass parent stream id priority? | 2685 // TODO(baranovich): pass parent stream id priority? |
| 2684 if (!TryCreatePushStream(promised_stream_id, stream_id, 0, | 2686 if (!TryCreatePushStream(promised_stream_id, stream_id, 0, |
| 2685 std::move(headers))) | 2687 std::move(headers))) |
| 2686 return; | 2688 return; |
| 2687 } | 2689 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2727 // |session_recv_window_size_| doesn't overflow. | 2729 // |session_recv_window_size_| doesn't overflow. |
| 2728 DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_); | 2730 DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_); |
| 2729 DCHECK_GE(session_recv_window_size_, 0); | 2731 DCHECK_GE(session_recv_window_size_, 0); |
| 2730 if (session_max_recv_window_size_ > session_recv_window_size_) { | 2732 if (session_max_recv_window_size_ > session_recv_window_size_) { |
| 2731 IncreaseRecvWindowSize(session_max_recv_window_size_ - | 2733 IncreaseRecvWindowSize(session_max_recv_window_size_ - |
| 2732 session_recv_window_size_); | 2734 session_recv_window_size_); |
| 2733 } | 2735 } |
| 2734 } | 2736 } |
| 2735 | 2737 |
| 2736 void SpdySession::SendSettings(const SettingsMap& settings) { | 2738 void SpdySession::SendSettings(const SettingsMap& settings) { |
| 2737 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_SEND_SETTINGS, | 2739 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS, |
| 2738 base::Bind(&NetLogSpdySendSettingsCallback, &settings)); | 2740 base::Bind(&NetLogSpdySendSettingsCallback, &settings)); |
| 2739 // Create the SETTINGS frame and send it. | 2741 // Create the SETTINGS frame and send it. |
| 2740 DCHECK(buffered_spdy_framer_.get()); | 2742 DCHECK(buffered_spdy_framer_.get()); |
| 2741 std::unique_ptr<SpdySerializedFrame> settings_frame( | 2743 std::unique_ptr<SpdySerializedFrame> settings_frame( |
| 2742 buffered_spdy_framer_->CreateSettings(settings)); | 2744 buffered_spdy_framer_->CreateSettings(settings)); |
| 2743 sent_settings_ = true; | 2745 sent_settings_ = true; |
| 2744 EnqueueSessionWrite(HIGHEST, SETTINGS, std::move(settings_frame)); | 2746 EnqueueSessionWrite(HIGHEST, SETTINGS, std::move(settings_frame)); |
| 2745 } | 2747 } |
| 2746 | 2748 |
| 2747 void SpdySession::HandleSetting(uint32_t id, uint32_t value) { | 2749 void SpdySession::HandleSetting(uint32_t id, uint32_t value) { |
| 2748 switch (id) { | 2750 switch (id) { |
| 2749 case SETTINGS_MAX_CONCURRENT_STREAMS: | 2751 case SETTINGS_MAX_CONCURRENT_STREAMS: |
| 2750 max_concurrent_streams_ = std::min(static_cast<size_t>(value), | 2752 max_concurrent_streams_ = std::min(static_cast<size_t>(value), |
| 2751 kMaxConcurrentStreamLimit); | 2753 kMaxConcurrentStreamLimit); |
| 2752 ProcessPendingStreamRequests(); | 2754 ProcessPendingStreamRequests(); |
| 2753 break; | 2755 break; |
| 2754 case SETTINGS_INITIAL_WINDOW_SIZE: { | 2756 case SETTINGS_INITIAL_WINDOW_SIZE: { |
| 2755 if (value > static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) { | 2757 if (value > static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) { |
| 2756 net_log().AddEvent( | 2758 net_log().AddEvent( |
| 2757 NetLog::TYPE_HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE, | 2759 NetLogEventType::HTTP2_SESSION_INITIAL_WINDOW_SIZE_OUT_OF_RANGE, |
| 2758 NetLog::IntCallback("initial_window_size", value)); | 2760 NetLog::IntCallback("initial_window_size", value)); |
| 2759 return; | 2761 return; |
| 2760 } | 2762 } |
| 2761 | 2763 |
| 2762 // SETTINGS_INITIAL_WINDOW_SIZE updates initial_send_window_size_ only. | 2764 // SETTINGS_INITIAL_WINDOW_SIZE updates initial_send_window_size_ only. |
| 2763 int32_t delta_window_size = | 2765 int32_t delta_window_size = |
| 2764 static_cast<int32_t>(value) - stream_initial_send_window_size_; | 2766 static_cast<int32_t>(value) - stream_initial_send_window_size_; |
| 2765 stream_initial_send_window_size_ = static_cast<int32_t>(value); | 2767 stream_initial_send_window_size_ = static_cast<int32_t>(value); |
| 2766 UpdateStreamsSendWindowSize(delta_window_size); | 2768 UpdateStreamsSendWindowSize(delta_window_size); |
| 2767 net_log().AddEvent( | 2769 net_log().AddEvent( |
| 2768 NetLog::TYPE_HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE, | 2770 NetLogEventType::HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE, |
| 2769 NetLog::IntCallback("delta_window_size", delta_window_size)); | 2771 NetLog::IntCallback("delta_window_size", delta_window_size)); |
| 2770 break; | 2772 break; |
| 2771 } | 2773 } |
| 2772 } | 2774 } |
| 2773 } | 2775 } |
| 2774 | 2776 |
| 2775 void SpdySession::UpdateStreamsSendWindowSize(int32_t delta_window_size) { | 2777 void SpdySession::UpdateStreamsSendWindowSize(int32_t delta_window_size) { |
| 2776 for (ActiveStreamMap::iterator it = active_streams_.begin(); | 2778 for (ActiveStreamMap::iterator it = active_streams_.begin(); |
| 2777 it != active_streams_.end(); ++it) { | 2779 it != active_streams_.end(); ++it) { |
| 2778 it->second.stream->AdjustSendWindowSize(delta_window_size); | 2780 it->second.stream->AdjustSendWindowSize(delta_window_size); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2801 void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id, | 2803 void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id, |
| 2802 uint32_t delta_window_size, | 2804 uint32_t delta_window_size, |
| 2803 RequestPriority priority) { | 2805 RequestPriority priority) { |
| 2804 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 2806 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
| 2805 if (it != active_streams_.end()) { | 2807 if (it != active_streams_.end()) { |
| 2806 CHECK_EQ(it->second.stream->stream_id(), stream_id); | 2808 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
| 2807 } else { | 2809 } else { |
| 2808 CHECK_EQ(stream_id, kSessionFlowControlStreamId); | 2810 CHECK_EQ(stream_id, kSessionFlowControlStreamId); |
| 2809 } | 2811 } |
| 2810 | 2812 |
| 2811 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_SENT_WINDOW_UPDATE_FRAME, | 2813 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SENT_WINDOW_UPDATE_FRAME, |
| 2812 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, stream_id, | 2814 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, stream_id, |
| 2813 delta_window_size)); | 2815 delta_window_size)); |
| 2814 | 2816 |
| 2815 DCHECK(buffered_spdy_framer_.get()); | 2817 DCHECK(buffered_spdy_framer_.get()); |
| 2816 std::unique_ptr<SpdySerializedFrame> window_update_frame( | 2818 std::unique_ptr<SpdySerializedFrame> window_update_frame( |
| 2817 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); | 2819 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); |
| 2818 EnqueueSessionWrite(priority, WINDOW_UPDATE, std::move(window_update_frame)); | 2820 EnqueueSessionWrite(priority, WINDOW_UPDATE, std::move(window_update_frame)); |
| 2819 } | 2821 } |
| 2820 | 2822 |
| 2821 void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) { | 2823 void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) { |
| 2822 DCHECK(buffered_spdy_framer_.get()); | 2824 DCHECK(buffered_spdy_framer_.get()); |
| 2823 std::unique_ptr<SpdySerializedFrame> ping_frame( | 2825 std::unique_ptr<SpdySerializedFrame> ping_frame( |
| 2824 buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack)); | 2826 buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack)); |
| 2825 EnqueueSessionWrite(HIGHEST, PING, std::move(ping_frame)); | 2827 EnqueueSessionWrite(HIGHEST, PING, std::move(ping_frame)); |
| 2826 | 2828 |
| 2827 if (net_log().IsCapturing()) { | 2829 if (net_log().IsCapturing()) { |
| 2828 net_log().AddEvent( | 2830 net_log().AddEvent( |
| 2829 NetLog::TYPE_HTTP2_SESSION_PING, | 2831 NetLogEventType::HTTP2_SESSION_PING, |
| 2830 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent")); | 2832 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent")); |
| 2831 } | 2833 } |
| 2832 if (!is_ack) { | 2834 if (!is_ack) { |
| 2833 next_ping_id_ += 2; | 2835 next_ping_id_ += 2; |
| 2834 ++pings_in_flight_; | 2836 ++pings_in_flight_; |
| 2835 PlanToCheckPingStatus(); | 2837 PlanToCheckPingStatus(); |
| 2836 last_ping_sent_time_ = time_func_(); | 2838 last_ping_sent_time_ = time_func_(); |
| 2837 } | 2839 } |
| 2838 } | 2840 } |
| 2839 | 2841 |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3010 ERR_SPDY_PROTOCOL_ERROR, | 3012 ERR_SPDY_PROTOCOL_ERROR, |
| 3011 "Received WINDOW_UPDATE [delta: " + | 3013 "Received WINDOW_UPDATE [delta: " + |
| 3012 base::IntToString(delta_window_size) + | 3014 base::IntToString(delta_window_size) + |
| 3013 "] for session overflows session_send_window_size_ [current: " + | 3015 "] for session overflows session_send_window_size_ [current: " + |
| 3014 base::IntToString(session_send_window_size_) + "]"); | 3016 base::IntToString(session_send_window_size_) + "]"); |
| 3015 return; | 3017 return; |
| 3016 } | 3018 } |
| 3017 | 3019 |
| 3018 session_send_window_size_ += delta_window_size; | 3020 session_send_window_size_ += delta_window_size; |
| 3019 | 3021 |
| 3020 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_SEND_WINDOW, | 3022 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_SEND_WINDOW, |
| 3021 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3023 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 3022 delta_window_size, session_send_window_size_)); | 3024 delta_window_size, session_send_window_size_)); |
| 3023 | 3025 |
| 3024 DCHECK(!IsSendStalled()); | 3026 DCHECK(!IsSendStalled()); |
| 3025 ResumeSendStalledStreams(); | 3027 ResumeSendStalledStreams(); |
| 3026 } | 3028 } |
| 3027 | 3029 |
| 3028 void SpdySession::DecreaseSendWindowSize(int32_t delta_window_size) { | 3030 void SpdySession::DecreaseSendWindowSize(int32_t delta_window_size) { |
| 3029 // We only call this method when sending a frame. Therefore, | 3031 // We only call this method when sending a frame. Therefore, |
| 3030 // |delta_window_size| should be within the valid frame size range. | 3032 // |delta_window_size| should be within the valid frame size range. |
| 3031 DCHECK_GE(delta_window_size, 1); | 3033 DCHECK_GE(delta_window_size, 1); |
| 3032 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); | 3034 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); |
| 3033 | 3035 |
| 3034 // |send_window_size_| should have been at least |delta_window_size| for | 3036 // |send_window_size_| should have been at least |delta_window_size| for |
| 3035 // this call to happen. | 3037 // this call to happen. |
| 3036 DCHECK_GE(session_send_window_size_, delta_window_size); | 3038 DCHECK_GE(session_send_window_size_, delta_window_size); |
| 3037 | 3039 |
| 3038 session_send_window_size_ -= delta_window_size; | 3040 session_send_window_size_ -= delta_window_size; |
| 3039 | 3041 |
| 3040 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_SEND_WINDOW, | 3042 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_SEND_WINDOW, |
| 3041 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3043 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 3042 -delta_window_size, session_send_window_size_)); | 3044 -delta_window_size, session_send_window_size_)); |
| 3043 } | 3045 } |
| 3044 | 3046 |
| 3045 void SpdySession::OnReadBufferConsumed( | 3047 void SpdySession::OnReadBufferConsumed( |
| 3046 size_t consume_size, | 3048 size_t consume_size, |
| 3047 SpdyBuffer::ConsumeSource consume_source) { | 3049 SpdyBuffer::ConsumeSource consume_source) { |
| 3048 // We can be called with |in_io_loop_| set if a read SpdyBuffer is | 3050 // We can be called with |in_io_loop_| set if a read SpdyBuffer is |
| 3049 // deleted (e.g., discarded by a SpdyReadQueue). | 3051 // deleted (e.g., discarded by a SpdyReadQueue). |
| 3050 DCHECK_GE(consume_size, 1u); | 3052 DCHECK_GE(consume_size, 1u); |
| 3051 DCHECK_LE(consume_size, | 3053 DCHECK_LE(consume_size, |
| 3052 static_cast<size_t>(std::numeric_limits<int32_t>::max())); | 3054 static_cast<size_t>(std::numeric_limits<int32_t>::max())); |
| 3053 | 3055 |
| 3054 IncreaseRecvWindowSize(static_cast<int32_t>(consume_size)); | 3056 IncreaseRecvWindowSize(static_cast<int32_t>(consume_size)); |
| 3055 } | 3057 } |
| 3056 | 3058 |
| 3057 void SpdySession::IncreaseRecvWindowSize(int32_t delta_window_size) { | 3059 void SpdySession::IncreaseRecvWindowSize(int32_t delta_window_size) { |
| 3058 DCHECK_GE(session_unacked_recv_window_bytes_, 0); | 3060 DCHECK_GE(session_unacked_recv_window_bytes_, 0); |
| 3059 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); | 3061 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); |
| 3060 DCHECK_GE(delta_window_size, 1); | 3062 DCHECK_GE(delta_window_size, 1); |
| 3061 // Check for overflow. | 3063 // Check for overflow. |
| 3062 DCHECK_LE(delta_window_size, | 3064 DCHECK_LE(delta_window_size, |
| 3063 std::numeric_limits<int32_t>::max() - session_recv_window_size_); | 3065 std::numeric_limits<int32_t>::max() - session_recv_window_size_); |
| 3064 | 3066 |
| 3065 session_recv_window_size_ += delta_window_size; | 3067 session_recv_window_size_ += delta_window_size; |
| 3066 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, | 3068 net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_UPDATE_RECV_WINDOW, |
| 3067 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3069 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 3068 delta_window_size, session_recv_window_size_)); | 3070 delta_window_size, session_recv_window_size_)); |
| 3069 | 3071 |
| 3070 session_unacked_recv_window_bytes_ += delta_window_size; | 3072 session_unacked_recv_window_bytes_ += delta_window_size; |
| 3071 if (session_unacked_recv_window_bytes_ > session_max_recv_window_size_ / 2) { | 3073 if (session_unacked_recv_window_bytes_ > session_max_recv_window_size_ / 2) { |
| 3072 SendWindowUpdateFrame(kSessionFlowControlStreamId, | 3074 SendWindowUpdateFrame(kSessionFlowControlStreamId, |
| 3073 session_unacked_recv_window_bytes_, | 3075 session_unacked_recv_window_bytes_, |
| 3074 HIGHEST); | 3076 HIGHEST); |
| 3075 session_unacked_recv_window_bytes_ = 0; | 3077 session_unacked_recv_window_bytes_ = 0; |
| 3076 } | 3078 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3089 RecordProtocolErrorHistogram(PROTOCOL_ERROR_RECEIVE_WINDOW_VIOLATION); | 3091 RecordProtocolErrorHistogram(PROTOCOL_ERROR_RECEIVE_WINDOW_VIOLATION); |
| 3090 DoDrainSession( | 3092 DoDrainSession( |
| 3091 ERR_SPDY_FLOW_CONTROL_ERROR, | 3093 ERR_SPDY_FLOW_CONTROL_ERROR, |
| 3092 "delta_window_size is " + base::IntToString(delta_window_size) + | 3094 "delta_window_size is " + base::IntToString(delta_window_size) + |
| 3093 " in DecreaseRecvWindowSize, which is larger than the receive " + | 3095 " in DecreaseRecvWindowSize, which is larger than the receive " + |
| 3094 "window size of " + base::IntToString(session_recv_window_size_)); | 3096 "window size of " + base::IntToString(session_recv_window_size_)); |
| 3095 return; | 3097 return; |
| 3096 } | 3098 } |
| 3097 | 3099 |
| 3098 session_recv_window_size_ -= delta_window_size; | 3100 session_recv_window_size_ -= delta_window_size; |
| 3099 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_UPDATE_RECV_WINDOW, | 3101 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_UPDATE_RECV_WINDOW, |
| 3100 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3102 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 3101 -delta_window_size, session_recv_window_size_)); | 3103 -delta_window_size, session_recv_window_size_)); |
| 3102 } | 3104 } |
| 3103 | 3105 |
| 3104 void SpdySession::QueueSendStalledStream(const SpdyStream& stream) { | 3106 void SpdySession::QueueSendStalledStream(const SpdyStream& stream) { |
| 3105 DCHECK(stream.send_stalled_by_flow_control()); | 3107 DCHECK(stream.send_stalled_by_flow_control()); |
| 3106 RequestPriority priority = stream.priority(); | 3108 RequestPriority priority = stream.priority(); |
| 3107 CHECK_GE(priority, MINIMUM_PRIORITY); | 3109 CHECK_GE(priority, MINIMUM_PRIORITY); |
| 3108 CHECK_LE(priority, MAXIMUM_PRIORITY); | 3110 CHECK_LE(priority, MAXIMUM_PRIORITY); |
| 3109 stream_send_unstall_queue_[priority].push_back(stream.stream_id()); | 3111 stream_send_unstall_queue_[priority].push_back(stream.stream_id()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3143 if (!queue->empty()) { | 3145 if (!queue->empty()) { |
| 3144 SpdyStreamId stream_id = queue->front(); | 3146 SpdyStreamId stream_id = queue->front(); |
| 3145 queue->pop_front(); | 3147 queue->pop_front(); |
| 3146 return stream_id; | 3148 return stream_id; |
| 3147 } | 3149 } |
| 3148 } | 3150 } |
| 3149 return 0; | 3151 return 0; |
| 3150 } | 3152 } |
| 3151 | 3153 |
| 3152 } // namespace net | 3154 } // namespace net |
| OLD | NEW |