| Index: net/spdy/spdy_session.cc
|
| ===================================================================
|
| --- net/spdy/spdy_session.cc (revision 126086)
|
| +++ net/spdy/spdy_session.cc (working copy)
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "net/spdy/spdy_session.h"
|
|
|
| +#include <map>
|
| +
|
| #include "base/basictypes.h"
|
| #include "base/logging.h"
|
| #include "base/memory/linked_ptr.h"
|
| @@ -27,7 +29,6 @@
|
| #include "net/base/origin_bound_cert_service.h"
|
| #include "net/http/http_network_session.h"
|
| #include "net/http/http_server_properties.h"
|
| -#include "net/socket/ssl_client_socket.h"
|
| #include "net/spdy/spdy_frame_builder.h"
|
| #include "net/spdy/spdy_http_utils.h"
|
| #include "net/spdy/spdy_protocol.h"
|
| @@ -270,6 +271,9 @@
|
| SpdySession::FlowControl SpdySession::use_flow_control_ =
|
| SpdySession::kFlowControlBasedOnNPN;
|
|
|
| +SSLClientSocket::NextProto SpdySession::default_protocol_ =
|
| + SSLClientSocket::kProtoUnknown;
|
| +
|
| // static
|
| size_t SpdySession::init_max_concurrent_streams_ = 10;
|
|
|
| @@ -288,6 +292,13 @@
|
| // static
|
| int SpdySession::hung_interval_ms_ = 10000; // 10 seconds
|
|
|
| +// static
|
| +void SpdySession::ResetStaticSettingsToInit() {
|
| + // WARNING: These must match the initializers above.
|
| + use_flow_control_ = SpdySession::kFlowControlBasedOnNPN;
|
| + default_protocol_ = SSLClientSocket::kProtoUnknown;
|
| +}
|
| +
|
| SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair,
|
| SpdySessionPool* spdy_session_pool,
|
| HttpServerProperties* http_server_properties,
|
| @@ -381,13 +392,16 @@
|
| is_secure_ = is_secure;
|
| certificate_error_code_ = certificate_error_code;
|
|
|
| + SSLClientSocket::NextProto protocol = default_protocol_;
|
| if (is_secure_) {
|
| SSLClientSocket* ssl_socket = GetSSLClientSocket();
|
|
|
| SSLClientSocket::NextProto protocol_negotiated =
|
| ssl_socket->protocol_negotiated();
|
| - if (protocol_negotiated != SSLClientSocket::kProtoUnknown)
|
| + if (protocol_negotiated != SSLClientSocket::kProtoUnknown) {
|
| + protocol = protocol_negotiated;
|
| flow_control_ = (protocol_negotiated >= SSLClientSocket::kProtoSPDY21);
|
| + }
|
|
|
| if (ssl_socket->WasOriginBoundCertSent()) {
|
| // According to the SPDY spec, the credential associated with the TLS
|
| @@ -396,7 +410,21 @@
|
| }
|
| }
|
|
|
| - buffered_spdy_framer_.reset(new spdy::BufferedSpdyFramer(2));
|
| + int version = 2;
|
| + switch (protocol) {
|
| + case SSLClientSocket::kProtoSPDY2:
|
| + case SSLClientSocket::kProtoSPDY21:
|
| + version = 2;
|
| + break;
|
| + case SSLClientSocket::kProtoSPDY3:
|
| + version = 3;
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +
|
| + buffered_spdy_framer_.reset(new spdy::BufferedSpdyFramer(version));
|
| buffered_spdy_framer_->set_visitor(this);
|
| SendSettings();
|
|
|
| @@ -1274,6 +1302,24 @@
|
| stream->OnDataReceived(data, len);
|
| }
|
|
|
| +void SpdySession::OnSetting(spdy::SpdySettingsIds id,
|
| + uint8 flags,
|
| + uint32 value) {
|
| + HandleSetting(id, value);
|
| + spdy::SettingsFlagsAndId flags_and_id(flags, id);
|
| + http_server_properties_->SetSpdySetting(
|
| + host_port_pair(), std::make_pair(flags_and_id, value));
|
| +
|
| + received_settings_ = true;
|
| +
|
| + // Log the settings.
|
| + spdy::SpdySettings settings;
|
| + settings.insert(settings.end(), std::make_pair(flags_and_id, value));
|
| + net_log_.AddEvent(
|
| + NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS,
|
| + make_scoped_refptr(new NetLogSpdySettingsParameter(settings)));
|
| +}
|
| +
|
| bool SpdySession::Respond(const spdy::SpdyHeaderBlock& headers,
|
| const scoped_refptr<SpdyStream> stream) {
|
| int rv = OK;
|
| @@ -1535,20 +1581,6 @@
|
| PlanToSendTrailingPing();
|
| }
|
|
|
| -void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) {
|
| - spdy::SpdySettings settings;
|
| - if (spdy::SpdyFramer::ParseSettings(&frame, &settings)) {
|
| - HandleSettings(settings);
|
| - http_server_properties_->SetSpdySettings(host_port_pair(), settings);
|
| - }
|
| -
|
| - received_settings_ = true;
|
| -
|
| - net_log_.AddEvent(
|
| - NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS,
|
| - make_scoped_refptr(new NetLogSpdySettingsParameter(settings)));
|
| -}
|
| -
|
| void SpdySession::OnWindowUpdate(
|
| const spdy::SpdyWindowUpdateControlFrame& frame) {
|
| spdy::SpdyStreamId stream_id = frame.stream_id();
|
| @@ -1627,6 +1659,9 @@
|
| if (settings.empty())
|
| return;
|
|
|
| + typedef std::map<uint32, spdy::SpdySetting> SpdySettingsMap;
|
| + SpdySettingsMap unique_settings;
|
| +
|
| // Record Histogram Data and Apply the SpdyCwnd FieldTrial if applicable.
|
| for (spdy::SpdySettings::iterator i = settings.begin(),
|
| end = settings.end(); i != end; ++i) {
|
| @@ -1640,12 +1675,17 @@
|
| cwnd,
|
| 1, 200, 100);
|
| if (cwnd != val) {
|
| + spdy::SettingsFlagsAndId new_id(spdy::SETTINGS_FLAG_PLEASE_PERSIST,
|
| + id);
|
| i->second = cwnd;
|
| - i->first.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST);
|
| - http_server_properties_->SetSpdySettings(host_port_pair(), settings);
|
| + i->first = new_id;
|
| + spdy::SpdySetting setting(new_id, val);
|
| + http_server_properties_->SetSpdySetting(host_port_pair(), setting);
|
| + unique_settings[id] = setting;
|
| + continue;
|
| }
|
| - break;
|
| }
|
| + unique_settings[id] = *i;
|
| }
|
|
|
| HandleSettings(settings);
|
| @@ -1654,10 +1694,17 @@
|
| NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS,
|
| make_scoped_refptr(new NetLogSpdySettingsParameter(settings)));
|
|
|
| + spdy::SpdySettings sorted_settings;
|
| + for (SpdySettingsMap::iterator it = unique_settings.begin();
|
| + unique_settings.end() != it;
|
| + ++it) {
|
| + sorted_settings.push_back(it->second);
|
| + }
|
| +
|
| // Create the SETTINGS frame and send it.
|
| DCHECK(buffered_spdy_framer_.get());
|
| scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame(
|
| - buffered_spdy_framer_->CreateSettings(settings));
|
| + buffered_spdy_framer_->CreateSettings(sorted_settings));
|
| sent_settings_ = true;
|
| QueueFrame(settings_frame.get(), 0, NULL);
|
| }
|
| @@ -1665,28 +1712,30 @@
|
| void SpdySession::HandleSettings(const spdy::SpdySettings& settings) {
|
| for (spdy::SpdySettings::const_iterator i = settings.begin(),
|
| end = settings.end(); i != end; ++i) {
|
| - const uint32 id = i->first.id();
|
| - const uint32 val = i->second;
|
| - switch (id) {
|
| - case spdy::SETTINGS_MAX_CONCURRENT_STREAMS:
|
| - max_concurrent_streams_ = std::min(static_cast<size_t>(val),
|
| - max_concurrent_stream_limit_);
|
| - ProcessPendingCreateStreams();
|
| - break;
|
| - case spdy::SETTINGS_INITIAL_WINDOW_SIZE:
|
| - // INITIAL_WINDOW_SIZE updates initial_send_window_size_ only.
|
| - // TODO(rtenneti): discuss with the server team about
|
| - // initial_recv_window_size_.
|
| - int32 prev_initial_send_window_size = initial_send_window_size_;
|
| - initial_send_window_size_ = val;
|
| - int32 delta_window_size =
|
| - initial_send_window_size_ - prev_initial_send_window_size;
|
| - UpdateStreamsSendWindowSize(delta_window_size);
|
| - break;
|
| - }
|
| + HandleSetting(i->first.id(), i->second);
|
| }
|
| }
|
|
|
| +void SpdySession::HandleSetting(uint32 id, uint32 value) {
|
| + switch (id) {
|
| + case spdy::SETTINGS_MAX_CONCURRENT_STREAMS:
|
| + max_concurrent_streams_ = std::min(static_cast<size_t>(value),
|
| + max_concurrent_stream_limit_);
|
| + ProcessPendingCreateStreams();
|
| + break;
|
| + case spdy::SETTINGS_INITIAL_WINDOW_SIZE:
|
| + // INITIAL_WINDOW_SIZE updates initial_send_window_size_ only.
|
| + // TODO(rtenneti): discuss with the server team about
|
| + // initial_recv_window_size_.
|
| + int32 prev_initial_send_window_size = initial_send_window_size_;
|
| + initial_send_window_size_ = value;
|
| + int32 delta_window_size =
|
| + initial_send_window_size_ - prev_initial_send_window_size;
|
| + UpdateStreamsSendWindowSize(delta_window_size);
|
| + break;
|
| + }
|
| +}
|
| +
|
| void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) {
|
| ActiveStreamMap::iterator it;
|
| for (it = active_streams_.begin(); it != active_streams_.end(); ++it) {
|
| @@ -1736,8 +1785,9 @@
|
| void SpdySession::WritePingFrame(uint32 unique_id) {
|
| DCHECK(buffered_spdy_framer_.get());
|
| scoped_ptr<spdy::SpdyPingControlFrame> ping_frame(
|
| - spdy::SpdyFramer::CreatePingFrame(next_ping_id_));
|
| - QueueFrame(ping_frame.get(), SPDY_PRIORITY_HIGHEST, NULL);
|
| + buffered_spdy_framer_->CreatePingFrame(next_ping_id_));
|
| + QueueFrame(
|
| + ping_frame.get(), buffered_spdy_framer_->GetHighestPriority(), NULL);
|
|
|
| if (net_log().IsLoggingAllEvents()) {
|
| net_log().AddEvent(
|
|
|