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 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 | 601 |
602 SpdySession::SpdySession( | 602 SpdySession::SpdySession( |
603 const SpdySessionKey& spdy_session_key, | 603 const SpdySessionKey& spdy_session_key, |
604 const base::WeakPtr<HttpServerProperties>& http_server_properties, | 604 const base::WeakPtr<HttpServerProperties>& http_server_properties, |
605 TransportSecurityState* transport_security_state, | 605 TransportSecurityState* transport_security_state, |
606 bool verify_domain_authentication, | 606 bool verify_domain_authentication, |
607 bool enable_sending_initial_data, | 607 bool enable_sending_initial_data, |
608 bool enable_compression, | 608 bool enable_compression, |
609 bool enable_ping_based_connection_checking, | 609 bool enable_ping_based_connection_checking, |
610 NextProto default_protocol, | 610 NextProto default_protocol, |
611 size_t stream_initial_recv_window_size, | 611 size_t session_max_recv_window_size, |
| 612 size_t stream_max_recv_window_size, |
612 size_t initial_max_concurrent_streams, | 613 size_t initial_max_concurrent_streams, |
613 size_t max_concurrent_streams_limit, | 614 size_t max_concurrent_streams_limit, |
614 TimeFunc time_func, | 615 TimeFunc time_func, |
615 const HostPortPair& trusted_spdy_proxy, | 616 const HostPortPair& trusted_spdy_proxy, |
616 NetLog* net_log) | 617 NetLog* net_log) |
617 : in_io_loop_(false), | 618 : in_io_loop_(false), |
618 spdy_session_key_(spdy_session_key), | 619 spdy_session_key_(spdy_session_key), |
619 pool_(NULL), | 620 pool_(NULL), |
620 http_server_properties_(http_server_properties), | 621 http_server_properties_(http_server_properties), |
621 transport_security_state_(transport_security_state), | 622 transport_security_state_(transport_security_state), |
(...skipping 25 matching lines...) Expand all Loading... |
647 sent_settings_(false), | 648 sent_settings_(false), |
648 received_settings_(false), | 649 received_settings_(false), |
649 stalled_streams_(0), | 650 stalled_streams_(0), |
650 pings_in_flight_(0), | 651 pings_in_flight_(0), |
651 next_ping_id_(1), | 652 next_ping_id_(1), |
652 last_activity_time_(time_func()), | 653 last_activity_time_(time_func()), |
653 last_compressed_frame_len_(0), | 654 last_compressed_frame_len_(0), |
654 check_ping_status_pending_(false), | 655 check_ping_status_pending_(false), |
655 send_connection_header_prefix_(false), | 656 send_connection_header_prefix_(false), |
656 flow_control_state_(FLOW_CONTROL_NONE), | 657 flow_control_state_(FLOW_CONTROL_NONE), |
657 stream_initial_send_window_size_(GetInitialWindowSize(default_protocol)), | |
658 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 | |
659 ? kDefaultInitialRecvWindowSize | |
660 : stream_initial_recv_window_size), | |
661 session_send_window_size_(0), | 658 session_send_window_size_(0), |
| 659 session_max_recv_window_size_(session_max_recv_window_size), |
662 session_recv_window_size_(0), | 660 session_recv_window_size_(0), |
663 session_unacked_recv_window_bytes_(0), | 661 session_unacked_recv_window_bytes_(0), |
| 662 stream_initial_send_window_size_(GetInitialWindowSize(default_protocol)), |
| 663 stream_max_recv_window_size_(stream_max_recv_window_size), |
664 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP2_SESSION)), | 664 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_HTTP2_SESSION)), |
665 verify_domain_authentication_(verify_domain_authentication), | 665 verify_domain_authentication_(verify_domain_authentication), |
666 enable_sending_initial_data_(enable_sending_initial_data), | 666 enable_sending_initial_data_(enable_sending_initial_data), |
667 enable_compression_(enable_compression), | 667 enable_compression_(enable_compression), |
668 enable_ping_based_connection_checking_( | 668 enable_ping_based_connection_checking_( |
669 enable_ping_based_connection_checking), | 669 enable_ping_based_connection_checking), |
670 protocol_(default_protocol), | 670 protocol_(default_protocol), |
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)), |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 connection_->socket()->IsConnected()); | 883 connection_->socket()->IsConnected()); |
884 if (!connection_->socket()->IsConnected()) { | 884 if (!connection_->socket()->IsConnected()) { |
885 DoDrainSession( | 885 DoDrainSession( |
886 ERR_CONNECTION_CLOSED, | 886 ERR_CONNECTION_CLOSED, |
887 "Tried to create SPDY stream for a closed socket connection."); | 887 "Tried to create SPDY stream for a closed socket connection."); |
888 return ERR_CONNECTION_CLOSED; | 888 return ERR_CONNECTION_CLOSED; |
889 } | 889 } |
890 | 890 |
891 scoped_ptr<SpdyStream> new_stream( | 891 scoped_ptr<SpdyStream> new_stream( |
892 new SpdyStream(request.type(), GetWeakPtr(), request.url(), | 892 new SpdyStream(request.type(), GetWeakPtr(), request.url(), |
893 request.priority(), | 893 request.priority(), stream_initial_send_window_size_, |
894 stream_initial_send_window_size_, | 894 stream_max_recv_window_size_, request.net_log())); |
895 stream_initial_recv_window_size_, | |
896 request.net_log())); | |
897 *stream = new_stream->GetWeakPtr(); | 895 *stream = new_stream->GetWeakPtr(); |
898 InsertCreatedStream(new_stream.Pass()); | 896 InsertCreatedStream(new_stream.Pass()); |
899 | 897 |
900 UMA_HISTOGRAM_CUSTOM_COUNTS( | 898 UMA_HISTOGRAM_CUSTOM_COUNTS( |
901 "Net.SpdyPriorityCount", | 899 "Net.SpdyPriorityCount", |
902 static_cast<int>(request.priority()), 0, 10, 11); | 900 static_cast<int>(request.priority()), 0, 10, 11); |
903 | 901 |
904 return OK; | 902 return OK; |
905 } | 903 } |
906 | 904 |
(...skipping 1773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2680 if (pushed_it != unclaimed_pushed_streams_.end() && | 2678 if (pushed_it != unclaimed_pushed_streams_.end() && |
2681 pushed_it->first == gurl) { | 2679 pushed_it->first == gurl) { |
2682 EnqueueResetStreamFrame( | 2680 EnqueueResetStreamFrame( |
2683 stream_id, | 2681 stream_id, |
2684 request_priority, | 2682 request_priority, |
2685 RST_STREAM_PROTOCOL_ERROR, | 2683 RST_STREAM_PROTOCOL_ERROR, |
2686 "Received duplicate pushed stream with url: " + gurl.spec()); | 2684 "Received duplicate pushed stream with url: " + gurl.spec()); |
2687 return false; | 2685 return false; |
2688 } | 2686 } |
2689 | 2687 |
2690 scoped_ptr<SpdyStream> stream(new SpdyStream(SPDY_PUSH_STREAM, | 2688 scoped_ptr<SpdyStream> stream( |
2691 GetWeakPtr(), | 2689 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority, |
2692 gurl, | 2690 stream_initial_send_window_size_, |
2693 request_priority, | 2691 stream_max_recv_window_size_, net_log_)); |
2694 stream_initial_send_window_size_, | |
2695 stream_initial_recv_window_size_, | |
2696 net_log_)); | |
2697 stream->set_stream_id(stream_id); | 2692 stream->set_stream_id(stream_id); |
2698 | 2693 |
2699 // In spdy4/http2 PUSH_PROMISE arrives on associated stream. | 2694 // In spdy4/http2 PUSH_PROMISE arrives on associated stream. |
2700 if (associated_it != active_streams_.end() && GetProtocolVersion() >= SPDY4) { | 2695 if (associated_it != active_streams_.end() && GetProtocolVersion() >= SPDY4) { |
2701 associated_it->second.stream->IncrementRawReceivedBytes( | 2696 associated_it->second.stream->IncrementRawReceivedBytes( |
2702 last_compressed_frame_len_); | 2697 last_compressed_frame_len_); |
2703 } else { | 2698 } else { |
2704 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); | 2699 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); |
2705 } | 2700 } |
2706 | 2701 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2770 } | 2765 } |
2771 | 2766 |
2772 // First, notify the server about the settings they should use when | 2767 // First, notify the server about the settings they should use when |
2773 // communicating with us. | 2768 // communicating with us. |
2774 SettingsMap settings_map; | 2769 SettingsMap settings_map; |
2775 // Create a new settings frame notifying the server of our | 2770 // Create a new settings frame notifying the server of our |
2776 // max concurrent streams and initial window size. | 2771 // max concurrent streams and initial window size. |
2777 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] = | 2772 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] = |
2778 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); | 2773 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); |
2779 if (flow_control_state_ >= FLOW_CONTROL_STREAM && | 2774 if (flow_control_state_ >= FLOW_CONTROL_STREAM && |
2780 stream_initial_recv_window_size_ != GetInitialWindowSize(protocol_)) { | 2775 stream_max_recv_window_size_ != GetInitialWindowSize(protocol_)) { |
2781 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] = | 2776 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] = |
2782 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, | 2777 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, stream_max_recv_window_size_); |
2783 stream_initial_recv_window_size_); | |
2784 } | 2778 } |
2785 SendSettings(settings_map); | 2779 SendSettings(settings_map); |
2786 | 2780 |
2787 // Next, notify the server about our initial recv window size. | 2781 // Next, notify the server about our initial recv window size. |
2788 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { | 2782 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { |
2789 // Bump up the receive window size to the real initial value. This | 2783 // Bump up the receive window size to the real initial value. This |
2790 // has to go here since the WINDOW_UPDATE frame sent by | 2784 // has to go here since the WINDOW_UPDATE frame sent by |
2791 // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|. | 2785 // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|. |
2792 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_); | 2786 // This condition implies that |session_max_recv_window_size_| - |
2793 // This condition implies that |kDefaultInitialRecvWindowSize| - | |
2794 // |session_recv_window_size_| doesn't overflow. | 2787 // |session_recv_window_size_| doesn't overflow. |
2795 DCHECK_GT(session_recv_window_size_, 0); | 2788 DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_); |
2796 IncreaseRecvWindowSize( | 2789 DCHECK_GE(session_recv_window_size_, 0); |
2797 kDefaultInitialRecvWindowSize - session_recv_window_size_); | 2790 if (session_max_recv_window_size_ > session_recv_window_size_) { |
| 2791 IncreaseRecvWindowSize(session_max_recv_window_size_ - |
| 2792 session_recv_window_size_); |
| 2793 } |
2798 } | 2794 } |
2799 | 2795 |
2800 if (protocol_ <= kProtoSPDY31) { | 2796 if (protocol_ <= kProtoSPDY31) { |
2801 // Finally, notify the server about the settings they have | 2797 // Finally, notify the server about the settings they have |
2802 // previously told us to use when communicating with them (after | 2798 // previously told us to use when communicating with them (after |
2803 // applying them). | 2799 // applying them). |
2804 const SettingsMap& server_settings_map = | 2800 const SettingsMap& server_settings_map = |
2805 http_server_properties_->GetSpdySettings(host_port_pair()); | 2801 http_server_properties_->GetSpdySettings(host_port_pair()); |
2806 if (server_settings_map.empty()) | 2802 if (server_settings_map.empty()) |
2807 return; | 2803 return; |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3183 DCHECK_GE(delta_window_size, 1); | 3179 DCHECK_GE(delta_window_size, 1); |
3184 // Check for overflow. | 3180 // Check for overflow. |
3185 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); | 3181 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); |
3186 | 3182 |
3187 session_recv_window_size_ += delta_window_size; | 3183 session_recv_window_size_ += delta_window_size; |
3188 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, | 3184 net_log_.AddEvent(NetLog::TYPE_HTTP2_STREAM_UPDATE_RECV_WINDOW, |
3189 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 3185 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
3190 delta_window_size, session_recv_window_size_)); | 3186 delta_window_size, session_recv_window_size_)); |
3191 | 3187 |
3192 session_unacked_recv_window_bytes_ += delta_window_size; | 3188 session_unacked_recv_window_bytes_ += delta_window_size; |
3193 if (session_unacked_recv_window_bytes_ > | 3189 if (session_unacked_recv_window_bytes_ > session_max_recv_window_size_ / 2) { |
3194 GetInitialWindowSize(protocol_) / 2) { | |
3195 SendWindowUpdateFrame(kSessionFlowControlStreamId, | 3190 SendWindowUpdateFrame(kSessionFlowControlStreamId, |
3196 session_unacked_recv_window_bytes_, | 3191 session_unacked_recv_window_bytes_, |
3197 HIGHEST); | 3192 HIGHEST); |
3198 session_unacked_recv_window_bytes_ = 0; | 3193 session_unacked_recv_window_bytes_ = 0; |
3199 } | 3194 } |
3200 } | 3195 } |
3201 | 3196 |
3202 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { | 3197 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { |
3203 CHECK(in_io_loop_); | 3198 CHECK(in_io_loop_); |
3204 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 3199 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3267 if (!queue->empty()) { | 3262 if (!queue->empty()) { |
3268 SpdyStreamId stream_id = queue->front(); | 3263 SpdyStreamId stream_id = queue->front(); |
3269 queue->pop_front(); | 3264 queue->pop_front(); |
3270 return stream_id; | 3265 return stream_id; |
3271 } | 3266 } |
3272 } | 3267 } |
3273 return 0; | 3268 return 0; |
3274 } | 3269 } |
3275 | 3270 |
3276 } // namespace net | 3271 } // namespace net |
OLD | NEW |