summaryrefslogtreecommitdiff
path: root/chromium/net/spdy/spdy_session.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/spdy/spdy_session.cc')
-rw-r--r--chromium/net/spdy/spdy_session.cc243
1 files changed, 127 insertions, 116 deletions
diff --git a/chromium/net/spdy/spdy_session.cc b/chromium/net/spdy/spdy_session.cc
index 7f31cd5cbc6..9508f0e6af4 100644
--- a/chromium/net/spdy/spdy_session.cc
+++ b/chromium/net/spdy/spdy_session.cc
@@ -32,7 +32,6 @@
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties.h"
#include "net/spdy/spdy_buffer_producer.h"
-#include "net/spdy/spdy_credential_builder.h"
#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_protocol.h"
@@ -54,36 +53,60 @@ const SpdyStreamId kFirstStreamId = 1;
// Minimum seconds that unclaimed pushed streams will be kept in memory.
const int kMinPushedStreamLifetimeSeconds = 300;
-base::Value* NetLogSpdySynCallback(const SpdyHeaderBlock* headers,
- bool fin,
- bool unidirectional,
- SpdyStreamId stream_id,
- SpdyStreamId associated_stream,
- NetLog::LogLevel /* log_level */) {
+scoped_ptr<base::ListValue> SpdyHeaderBlockToListValue(
+ const SpdyHeaderBlock& headers) {
+ scoped_ptr<base::ListValue> headers_list(new base::ListValue());
+ for (SpdyHeaderBlock::const_iterator it = headers.begin();
+ it != headers.end(); ++it) {
+ headers_list->AppendString(
+ it->first + ": " +
+ (ShouldShowHttpHeaderValue(it->first) ? it->second : "[elided]"));
+ }
+ return headers_list.Pass();
+}
+
+base::Value* NetLogSpdySynStreamSentCallback(const SpdyHeaderBlock* headers,
+ bool fin,
+ bool unidirectional,
+ SpdyPriority spdy_priority,
+ SpdyStreamId stream_id,
+ NetLog::LogLevel /* log_level */) {
base::DictionaryValue* dict = new base::DictionaryValue();
- base::ListValue* headers_list = new base::ListValue();
- for (SpdyHeaderBlock::const_iterator it = headers->begin();
- it != headers->end(); ++it) {
- headers_list->Append(new base::StringValue(base::StringPrintf(
- "%s: %s", it->first.c_str(),
- (ShouldShowHttpHeaderValue(
- it->first) ? it->second : "[elided]").c_str())));
- }
+ dict->Set("headers", SpdyHeaderBlockToListValue(*headers).release());
+ dict->SetBoolean("fin", fin);
+ dict->SetBoolean("unidirectional", unidirectional);
+ dict->SetInteger("spdy_priority", static_cast<int>(spdy_priority));
+ dict->SetInteger("stream_id", stream_id);
+ return dict;
+}
+
+base::Value* NetLogSpdySynStreamReceivedCallback(
+ const SpdyHeaderBlock* headers,
+ bool fin,
+ bool unidirectional,
+ SpdyPriority spdy_priority,
+ SpdyStreamId stream_id,
+ SpdyStreamId associated_stream,
+ NetLog::LogLevel /* log_level */) {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ dict->Set("headers", SpdyHeaderBlockToListValue(*headers).release());
dict->SetBoolean("fin", fin);
dict->SetBoolean("unidirectional", unidirectional);
- dict->Set("headers", headers_list);
+ dict->SetInteger("spdy_priority", static_cast<int>(spdy_priority));
dict->SetInteger("stream_id", stream_id);
- if (associated_stream)
- dict->SetInteger("associated_stream", associated_stream);
+ dict->SetInteger("associated_stream", associated_stream);
return dict;
}
-base::Value* NetLogSpdyCredentialCallback(size_t slot,
- const std::string* origin,
- NetLog::LogLevel /* log_level */) {
+base::Value* NetLogSpdySynReplyOrHeadersReceivedCallback(
+ const SpdyHeaderBlock* headers,
+ bool fin,
+ SpdyStreamId stream_id,
+ NetLog::LogLevel /* log_level */) {
base::DictionaryValue* dict = new base::DictionaryValue();
- dict->SetInteger("slot", slot);
- dict->SetString("origin", *origin);
+ dict->Set("headers", SpdyHeaderBlockToListValue(*headers).release());
+ dict->SetBoolean("fin", fin);
+ dict->SetInteger("stream_id", stream_id);
return dict;
}
@@ -345,7 +368,6 @@ SpdySession::SpdySession(
const base::WeakPtr<HttpServerProperties>& http_server_properties,
bool verify_domain_authentication,
bool enable_sending_initial_data,
- bool enable_credential_frames,
bool enable_compression,
bool enable_ping_based_connection_checking,
NextProto default_protocol,
@@ -387,6 +409,7 @@ SpdySession::SpdySession(
pings_in_flight_(0),
next_ping_id_(1),
last_activity_time_(time_func()),
+ last_compressed_frame_len_(0),
check_ping_status_pending_(false),
send_connection_header_prefix_(false),
flow_control_state_(FLOW_CONTROL_NONE),
@@ -400,21 +423,17 @@ SpdySession::SpdySession(
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)),
verify_domain_authentication_(verify_domain_authentication),
enable_sending_initial_data_(enable_sending_initial_data),
- enable_credential_frames_(enable_credential_frames),
enable_compression_(enable_compression),
enable_ping_based_connection_checking_(
enable_ping_based_connection_checking),
protocol_(default_protocol),
- credential_state_(SpdyCredentialState::kDefaultNumSlots),
connection_at_risk_of_loss_time_(
base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)),
hung_interval_(
base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
trusted_spdy_proxy_(trusted_spdy_proxy),
time_func_(time_func) {
- // TODO(akalin): Change this to kProtoSPDYMinimumVersion once we
- // stop supporting SPDY/1.
- DCHECK_GE(protocol_, kProtoSPDY2);
+ DCHECK_GE(protocol_, kProtoSPDYMinimumVersion);
DCHECK_LE(protocol_, kProtoSPDYMaximumVersion);
DCHECK(HttpStreamFactory::spdy_enabled());
net_log_.BeginEvent(
@@ -470,19 +489,9 @@ Error SpdySession::InitializeWithSocket(
if (protocol_negotiated != kProtoUnknown) {
protocol_ = protocol_negotiated;
}
- // TODO(akalin): Change this to kProtoSPDYMinimumVersion once we
- // stop supporting SPDY/1.
- DCHECK_GE(protocol_, kProtoSPDY2);
+ DCHECK_GE(protocol_, kProtoSPDYMinimumVersion);
DCHECK_LE(protocol_, kProtoSPDYMaximumVersion);
- SSLClientSocket* ssl_socket = GetSSLClientSocket();
- if (ssl_socket && ssl_socket->WasChannelIDSent()) {
- // According to the SPDY spec, the credential associated with the TLS
- // connection is stored in slot[1].
- credential_state_.SetHasCredential(GURL("https://" +
- host_port_pair().ToString()));
- }
-
if (protocol_ == kProtoHTTP2Draft04)
send_connection_header_prefix_ = true;
@@ -540,11 +549,13 @@ bool SpdySession::VerifyDomainAuthentication(const std::string& domain) {
if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated))
return true; // This is not a secure session, so all domains are okay.
- return !ssl_info.client_cert_sent &&
- (enable_credential_frames_ || !ssl_info.channel_id_sent ||
- ServerBoundCertService::GetDomainForHost(domain) ==
- ServerBoundCertService::GetDomainForHost(host_port_pair().host())) &&
- ssl_info.cert->VerifyNameMatch(domain);
+ bool unused = false;
+ return
+ !ssl_info.client_cert_sent &&
+ (!ssl_info.channel_id_sent ||
+ (ServerBoundCertService::GetDomainForHost(domain) ==
+ ServerBoundCertService::GetDomainForHost(host_port_pair().host()))) &&
+ ssl_info.cert->VerifyNameMatch(domain, &unused);
}
int SpdySession::GetPushStream(
@@ -616,14 +627,17 @@ int SpdySession::TryCreateStream(
stalled_streams_++;
net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_MAX_STREAMS);
- pending_create_stream_queues_[request->priority()].push_back(request);
+ RequestPriority priority = request->priority();
+ CHECK_GE(priority, MINIMUM_PRIORITY);
+ CHECK_LE(priority, MAXIMUM_PRIORITY);
+ pending_create_stream_queues_[priority].push_back(request);
return ERR_IO_PENDING;
}
int SpdySession::CreateStream(const SpdyStreamRequest& request,
base::WeakPtr<SpdyStream>* stream) {
DCHECK_GE(request.priority(), MINIMUM_PRIORITY);
- DCHECK_LT(request.priority(), NUM_PRIORITIES);
+ DCHECK_LE(request.priority(), MAXIMUM_PRIORITY);
if (availability_state_ == STATE_GOING_AWAY)
return ERR_FAILED;
@@ -672,11 +686,14 @@ int SpdySession::CreateStream(const SpdyStreamRequest& request,
void SpdySession::CancelStreamRequest(
const base::WeakPtr<SpdyStreamRequest>& request) {
DCHECK(request);
+ RequestPriority priority = request->priority();
+ CHECK_GE(priority, MINIMUM_PRIORITY);
+ CHECK_LE(priority, MAXIMUM_PRIORITY);
if (DCHECK_IS_ON()) {
// |request| should not be in a queue not matching its priority.
- for (int i = 0; i < NUM_PRIORITIES; ++i) {
- if (request->priority() == i)
+ for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
+ if (priority == i)
continue;
PendingStreamRequestQueue* queue = &pending_create_stream_queues_[i];
DCHECK(std::find_if(queue->begin(),
@@ -686,7 +703,7 @@ void SpdySession::CancelStreamRequest(
}
PendingStreamRequestQueue* queue =
- &pending_create_stream_queues_[request->priority()];
+ &pending_create_stream_queues_[priority];
// Remove |request| from |queue| while preserving the order of the
// other elements.
PendingStreamRequestQueue::iterator it =
@@ -703,7 +720,7 @@ void SpdySession::CancelStreamRequest(
}
base::WeakPtr<SpdyStreamRequest> SpdySession::GetNextPendingStreamRequest() {
- for (int j = NUM_PRIORITIES - 1; j >= MINIMUM_PRIORITY; --j) {
+ for (int j = MAXIMUM_PRIORITY; j >= MINIMUM_PRIORITY; --j) {
if (pending_create_stream_queues_[j].empty())
continue;
@@ -740,20 +757,11 @@ void SpdySession::ProcessPendingStreamRequests() {
}
}
-bool SpdySession::NeedsCredentials() const {
- if (!is_secure_)
- return false;
- SSLClientSocket* ssl_socket = GetSSLClientSocket();
- if (ssl_socket->GetNegotiatedProtocol() < kProtoSPDY3)
- return false;
- return ssl_socket->WasChannelIDSent();
-}
-
void SpdySession::AddPooledAlias(const SpdySessionKey& alias_key) {
pooled_aliases_.insert(alias_key);
}
-int SpdySession::GetProtocolVersion() const {
+SpdyMajorVersion SpdySession::GetProtocolVersion() const {
DCHECK(buffered_spdy_framer_.get());
return buffered_spdy_framer_->protocol_version();
}
@@ -801,11 +809,12 @@ scoped_ptr<SpdyFrame> SpdySession::CreateSynStream(
SendPrefacePingIfNoneInFlight();
DCHECK(buffered_spdy_framer_.get());
+ SpdyPriority spdy_priority =
+ ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion());
scoped_ptr<SpdyFrame> syn_frame(
buffered_spdy_framer_->CreateSynStream(
- stream_id, 0,
- ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()),
- credential_slot, flags, enable_compression_, &headers));
+ stream_id, 0, spdy_priority,
+ credential_slot, flags, &headers));
base::StatsCounter spdy_requests("spdy.requests");
spdy_requests.Increment();
@@ -814,48 +823,16 @@ scoped_ptr<SpdyFrame> SpdySession::CreateSynStream(
if (net_log().IsLoggingAllEvents()) {
net_log().AddEvent(
NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
- base::Bind(&NetLogSpdySynCallback, &headers,
+ base::Bind(&NetLogSpdySynStreamSentCallback, &headers,
(flags & CONTROL_FLAG_FIN) != 0,
(flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0,
- stream_id, 0));
+ spdy_priority,
+ stream_id));
}
return syn_frame.Pass();
}
-int SpdySession::CreateCredentialFrame(
- const std::string& origin,
- const std::string& key,
- const std::string& cert,
- RequestPriority priority,
- scoped_ptr<SpdyFrame>* credential_frame) {
- DCHECK(is_secure_);
- SSLClientSocket* ssl_socket = GetSSLClientSocket();
- DCHECK(ssl_socket);
- DCHECK(ssl_socket->WasChannelIDSent());
-
- SpdyCredential credential;
- std::string tls_unique;
- ssl_socket->GetTLSUniqueChannelBinding(&tls_unique);
- size_t slot = credential_state_.SetHasCredential(GURL(origin));
- int rv = SpdyCredentialBuilder::Build(tls_unique, key, cert, slot,
- &credential);
- DCHECK_NE(rv, ERR_IO_PENDING);
- if (rv != OK)
- return rv;
-
- DCHECK(buffered_spdy_framer_.get());
- credential_frame->reset(
- buffered_spdy_framer_->CreateCredentialFrame(credential));
-
- if (net_log().IsLoggingAllEvents()) {
- net_log().AddEvent(
- NetLog::TYPE_SPDY_SESSION_SEND_CREDENTIAL,
- base::Bind(&NetLogSpdyCredentialCallback, credential.slot, &origin));
- }
- return OK;
-}
-
scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id,
IOBuffer* data,
int len,
@@ -1421,7 +1398,7 @@ int SpdySession::DoWriteComplete(int result) {
void SpdySession::DcheckGoingAway() const {
DCHECK_GE(availability_state_, STATE_GOING_AWAY);
if (DCHECK_IS_ON()) {
- for (int i = 0; i < NUM_PRIORITIES; ++i) {
+ for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
DCHECK(pending_create_stream_queues_[i].empty());
}
}
@@ -1796,12 +1773,6 @@ bool SpdySession::GetSSLCertRequestInfo(
return true;
}
-ServerBoundCertService* SpdySession::GetServerBoundCertService() const {
- if (!is_secure_)
- return NULL;
- return GetSSLClientSocket()->GetServerBoundCertService();
-}
-
void SpdySession::OnError(SpdyFramer::SpdyError error_code) {
CHECK(in_io_loop_);
@@ -1836,6 +1807,28 @@ void SpdySession::OnStreamError(SpdyStreamId stream_id,
ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, description);
}
+void SpdySession::OnDataFrameHeader(SpdyStreamId stream_id,
+ size_t length,
+ bool fin) {
+ CHECK(in_io_loop_);
+
+ if (availability_state_ == STATE_CLOSED)
+ return;
+
+ ActiveStreamMap::iterator it = active_streams_.find(stream_id);
+
+ // By the time data comes in, the stream may already be inactive.
+ if (it == active_streams_.end())
+ return;
+
+ SpdyStream* stream = it->second.stream;
+ CHECK_EQ(stream->stream_id(), stream_id);
+
+ DCHECK(buffered_spdy_framer_);
+ size_t header_len = buffered_spdy_framer_->GetDataFrameMinimumSize();
+ stream->IncrementRawReceivedBytes(header_len);
+}
+
void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
const char* data,
size_t len,
@@ -1881,6 +1874,8 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id,
SpdyStream* stream = it->second.stream;
CHECK_EQ(stream->stream_id(), stream_id);
+ stream->IncrementRawReceivedBytes(len);
+
if (it->second.waiting_for_syn_reply) {
const std::string& error = "Data received before SYN_REPLY.";
stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
@@ -1951,6 +1946,13 @@ void SpdySession::OnSendCompressedFrame(
}
}
+void SpdySession::OnReceiveCompressedFrame(
+ SpdyStreamId stream_id,
+ SpdyFrameType type,
+ size_t frame_len) {
+ last_compressed_frame_len_ = frame_len;
+}
+
int SpdySession::OnInitialResponseHeadersReceived(
const SpdyHeaderBlock& response_headers,
base::Time response_time,
@@ -1986,8 +1988,8 @@ void SpdySession::OnSynStream(SpdyStreamId stream_id,
if (net_log_.IsLoggingAllEvents()) {
net_log_.AddEvent(
NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM,
- base::Bind(&NetLogSpdySynCallback,
- &headers, fin, unidirectional,
+ base::Bind(&NetLogSpdySynStreamReceivedCallback,
+ &headers, fin, unidirectional, priority,
stream_id, associated_stream_id));
}
@@ -2091,6 +2093,8 @@ void SpdySession::OnSynStream(SpdyStreamId stream_id,
stream_initial_recv_window_size_,
net_log_));
stream->set_stream_id(stream_id);
+ stream->IncrementRawReceivedBytes(last_compressed_frame_len_);
+ last_compressed_frame_len_ = 0;
DeleteExpiredPushedStreams();
PushedStreamMap::iterator inserted_pushed_it =
@@ -2166,9 +2170,8 @@ void SpdySession::OnSynReply(SpdyStreamId stream_id,
if (net_log().IsLoggingAllEvents()) {
net_log().AddEvent(
NetLog::TYPE_SPDY_SESSION_SYN_REPLY,
- base::Bind(&NetLogSpdySynCallback,
- &headers, fin, false, // not unidirectional
- stream_id, 0));
+ base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback,
+ &headers, fin, stream_id));
}
ActiveStreamMap::iterator it = active_streams_.find(stream_id);
@@ -2180,6 +2183,9 @@ void SpdySession::OnSynReply(SpdyStreamId stream_id,
SpdyStream* stream = it->second.stream;
CHECK_EQ(stream->stream_id(), stream_id);
+ stream->IncrementRawReceivedBytes(last_compressed_frame_len_);
+ last_compressed_frame_len_ = 0;
+
if (!it->second.waiting_for_syn_reply) {
const std::string& error =
"Received duplicate SYN_REPLY for stream.";
@@ -2204,9 +2210,8 @@ void SpdySession::OnHeaders(SpdyStreamId stream_id,
if (net_log().IsLoggingAllEvents()) {
net_log().AddEvent(
NetLog::TYPE_SPDY_SESSION_RECV_HEADERS,
- base::Bind(&NetLogSpdySynCallback,
- &headers, fin, /*unidirectional=*/false,
- stream_id, 0));
+ base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback,
+ &headers, fin, stream_id));
}
ActiveStreamMap::iterator it = active_streams_.find(stream_id);
@@ -2219,6 +2224,9 @@ void SpdySession::OnHeaders(SpdyStreamId stream_id,
SpdyStream* stream = it->second.stream;
CHECK_EQ(stream->stream_id(), stream_id);
+ stream->IncrementRawReceivedBytes(last_compressed_frame_len_);
+ last_compressed_frame_len_ = 0;
+
int rv = stream->OnAdditionalResponseHeadersReceived(headers);
if (rv < 0) {
DCHECK_NE(rv, ERR_IO_PENDING);
@@ -2897,7 +2905,10 @@ void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) {
void SpdySession::QueueSendStalledStream(const SpdyStream& stream) {
DCHECK(stream.send_stalled_by_flow_control());
- stream_send_unstall_queue_[stream.priority()].push_back(stream.stream_id());
+ RequestPriority priority = stream.priority();
+ CHECK_GE(priority, MINIMUM_PRIORITY);
+ CHECK_LE(priority, MAXIMUM_PRIORITY);
+ stream_send_unstall_queue_[priority].push_back(stream.stream_id());
}
void SpdySession::ResumeSendStalledStreams() {
@@ -2930,7 +2941,7 @@ void SpdySession::ResumeSendStalledStreams() {
}
SpdyStreamId SpdySession::PopStreamToPossiblyResume() {
- for (int i = NUM_PRIORITIES - 1; i >= 0; --i) {
+ for (int i = MAXIMUM_PRIORITY; i >= MINIMUM_PRIORITY; --i) {
std::deque<SpdyStreamId>* queue = &stream_send_unstall_queue_[i];
if (!queue->empty()) {
SpdyStreamId stream_id = queue->front();