Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: net/spdy/spdy_session.cc

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 const SpdyStreamId kFirstStreamId = 1; 53 const SpdyStreamId kFirstStreamId = 1;
54 54
55 // Minimum seconds that unclaimed pushed streams will be kept in memory. 55 // Minimum seconds that unclaimed pushed streams will be kept in memory.
56 const int kMinPushedStreamLifetimeSeconds = 300; 56 const int kMinPushedStreamLifetimeSeconds = 300;
57 57
58 scoped_ptr<base::ListValue> SpdyHeaderBlockToListValue( 58 scoped_ptr<base::ListValue> SpdyHeaderBlockToListValue(
59 const SpdyHeaderBlock& headers, 59 const SpdyHeaderBlock& headers,
60 net::NetLog::LogLevel log_level) { 60 net::NetLog::LogLevel log_level) {
61 scoped_ptr<base::ListValue> headers_list(new base::ListValue()); 61 scoped_ptr<base::ListValue> headers_list(new base::ListValue());
62 for (SpdyHeaderBlock::const_iterator it = headers.begin(); 62 for (SpdyHeaderBlock::const_iterator it = headers.begin();
63 it != headers.end(); ++it) { 63 it != headers.end();
64 ++it) {
64 headers_list->AppendString( 65 headers_list->AppendString(
65 it->first + ": " + 66 it->first + ": " +
66 ElideHeaderValueForNetLog(log_level, it->first, it->second)); 67 ElideHeaderValueForNetLog(log_level, it->first, it->second));
67 } 68 }
68 return headers_list.Pass(); 69 return headers_list.Pass();
69 } 70 }
70 71
71 base::Value* NetLogSpdySynStreamSentCallback(const SpdyHeaderBlock* headers, 72 base::Value* NetLogSpdySynStreamSentCallback(const SpdyHeaderBlock* headers,
72 bool fin, 73 bool fin,
73 bool unidirectional, 74 bool unidirectional,
74 SpdyPriority spdy_priority, 75 SpdyPriority spdy_priority,
75 SpdyStreamId stream_id, 76 SpdyStreamId stream_id,
76 NetLog::LogLevel log_level) { 77 NetLog::LogLevel log_level) {
77 base::DictionaryValue* dict = new base::DictionaryValue(); 78 base::DictionaryValue* dict = new base::DictionaryValue();
78 dict->Set("headers", 79 dict->Set("headers",
79 SpdyHeaderBlockToListValue(*headers, log_level).release()); 80 SpdyHeaderBlockToListValue(*headers, log_level).release());
80 dict->SetBoolean("fin", fin); 81 dict->SetBoolean("fin", fin);
81 dict->SetBoolean("unidirectional", unidirectional); 82 dict->SetBoolean("unidirectional", unidirectional);
82 dict->SetInteger("spdy_priority", static_cast<int>(spdy_priority)); 83 dict->SetInteger("spdy_priority", static_cast<int>(spdy_priority));
83 dict->SetInteger("stream_id", stream_id); 84 dict->SetInteger("stream_id", stream_id);
84 return dict; 85 return dict;
85 } 86 }
86 87
87 base::Value* NetLogSpdySynStreamReceivedCallback( 88 base::Value* NetLogSpdySynStreamReceivedCallback(const SpdyHeaderBlock* headers,
88 const SpdyHeaderBlock* headers, 89 bool fin,
89 bool fin, 90 bool unidirectional,
90 bool unidirectional, 91 SpdyPriority spdy_priority,
91 SpdyPriority spdy_priority, 92 SpdyStreamId stream_id,
92 SpdyStreamId stream_id, 93 SpdyStreamId associated_stream,
93 SpdyStreamId associated_stream, 94 NetLog::LogLevel log_level) {
94 NetLog::LogLevel log_level) {
95 base::DictionaryValue* dict = new base::DictionaryValue(); 95 base::DictionaryValue* dict = new base::DictionaryValue();
96 dict->Set("headers", 96 dict->Set("headers",
97 SpdyHeaderBlockToListValue(*headers, log_level).release()); 97 SpdyHeaderBlockToListValue(*headers, log_level).release());
98 dict->SetBoolean("fin", fin); 98 dict->SetBoolean("fin", fin);
99 dict->SetBoolean("unidirectional", unidirectional); 99 dict->SetBoolean("unidirectional", unidirectional);
100 dict->SetInteger("spdy_priority", static_cast<int>(spdy_priority)); 100 dict->SetInteger("spdy_priority", static_cast<int>(spdy_priority));
101 dict->SetInteger("stream_id", stream_id); 101 dict->SetInteger("stream_id", stream_id);
102 dict->SetInteger("associated_stream", associated_stream); 102 dict->SetInteger("associated_stream", associated_stream);
103 return dict; 103 return dict;
104 } 104 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 dict->SetInteger("flags", flags); 151 dict->SetInteger("flags", flags);
152 dict->SetInteger("value", value); 152 dict->SetInteger("value", value);
153 return dict; 153 return dict;
154 } 154 }
155 155
156 base::Value* NetLogSpdySendSettingsCallback(const SettingsMap* settings, 156 base::Value* NetLogSpdySendSettingsCallback(const SettingsMap* settings,
157 NetLog::LogLevel /* log_level */) { 157 NetLog::LogLevel /* log_level */) {
158 base::DictionaryValue* dict = new base::DictionaryValue(); 158 base::DictionaryValue* dict = new base::DictionaryValue();
159 base::ListValue* settings_list = new base::ListValue(); 159 base::ListValue* settings_list = new base::ListValue();
160 for (SettingsMap::const_iterator it = settings->begin(); 160 for (SettingsMap::const_iterator it = settings->begin();
161 it != settings->end(); ++it) { 161 it != settings->end();
162 ++it) {
162 const SpdySettingsIds id = it->first; 163 const SpdySettingsIds id = it->first;
163 const SpdySettingsFlags flags = it->second.first; 164 const SpdySettingsFlags flags = it->second.first;
164 const uint32 value = it->second.second; 165 const uint32 value = it->second.second;
165 settings_list->Append(new base::StringValue( 166 settings_list->Append(new base::StringValue(
166 base::StringPrintf("[id:%u flags:%u value:%u]", id, flags, value))); 167 base::StringPrintf("[id:%u flags:%u value:%u]", id, flags, value)));
167 } 168 }
168 dict->Set("settings", settings_list); 169 dict->Set("settings", settings_list);
169 return dict; 170 return dict;
170 } 171 }
171 172
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 dict->SetBoolean("is_ack", is_ack); 222 dict->SetBoolean("is_ack", is_ack);
222 return dict; 223 return dict;
223 } 224 }
224 225
225 base::Value* NetLogSpdyGoAwayCallback(SpdyStreamId last_stream_id, 226 base::Value* NetLogSpdyGoAwayCallback(SpdyStreamId last_stream_id,
226 int active_streams, 227 int active_streams,
227 int unclaimed_streams, 228 int unclaimed_streams,
228 SpdyGoAwayStatus status, 229 SpdyGoAwayStatus status,
229 NetLog::LogLevel /* log_level */) { 230 NetLog::LogLevel /* log_level */) {
230 base::DictionaryValue* dict = new base::DictionaryValue(); 231 base::DictionaryValue* dict = new base::DictionaryValue();
231 dict->SetInteger("last_accepted_stream_id", 232 dict->SetInteger("last_accepted_stream_id", static_cast<int>(last_stream_id));
232 static_cast<int>(last_stream_id));
233 dict->SetInteger("active_streams", active_streams); 233 dict->SetInteger("active_streams", active_streams);
234 dict->SetInteger("unclaimed_streams", unclaimed_streams); 234 dict->SetInteger("unclaimed_streams", unclaimed_streams);
235 dict->SetInteger("status", static_cast<int>(status)); 235 dict->SetInteger("status", static_cast<int>(status));
236 return dict; 236 return dict;
237 } 237 }
238 238
239 // Helper function to return the total size of an array of objects 239 // Helper function to return the total size of an array of objects
240 // with .size() member functions. 240 // with .size() member functions.
241 template <typename T, size_t N> size_t GetTotalSize(const T (&arr)[N]) { 241 template <typename T, size_t N>
242 size_t GetTotalSize(const T (&arr)[N]) {
242 size_t total_size = 0; 243 size_t total_size = 0;
243 for (size_t i = 0; i < N; ++i) { 244 for (size_t i = 0; i < N; ++i) {
244 total_size += arr[i].size(); 245 total_size += arr[i].size();
245 } 246 }
246 return total_size; 247 return total_size;
247 } 248 }
248 249
249 // Helper class for std:find_if on STL container containing 250 // Helper class for std:find_if on STL container containing
250 // SpdyStreamRequest weak pointers. 251 // SpdyStreamRequest weak pointers.
251 class RequestEquals { 252 class RequestEquals {
(...skipping 10 matching lines...) Expand all
262 }; 263 };
263 264
264 // The maximum number of concurrent streams we will ever create. Even if 265 // The maximum number of concurrent streams we will ever create. Even if
265 // the server permits more, we will never exceed this limit. 266 // the server permits more, we will never exceed this limit.
266 const size_t kMaxConcurrentStreamLimit = 256; 267 const size_t kMaxConcurrentStreamLimit = 256;
267 268
268 } // namespace 269 } // namespace
269 270
270 SpdyProtocolErrorDetails MapFramerErrorToProtocolError( 271 SpdyProtocolErrorDetails MapFramerErrorToProtocolError(
271 SpdyFramer::SpdyError err) { 272 SpdyFramer::SpdyError err) {
272 switch(err) { 273 switch (err) {
273 case SpdyFramer::SPDY_NO_ERROR: 274 case SpdyFramer::SPDY_NO_ERROR:
274 return SPDY_ERROR_NO_ERROR; 275 return SPDY_ERROR_NO_ERROR;
275 case SpdyFramer::SPDY_INVALID_CONTROL_FRAME: 276 case SpdyFramer::SPDY_INVALID_CONTROL_FRAME:
276 return SPDY_ERROR_INVALID_CONTROL_FRAME; 277 return SPDY_ERROR_INVALID_CONTROL_FRAME;
277 case SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE: 278 case SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE:
278 return SPDY_ERROR_CONTROL_PAYLOAD_TOO_LARGE; 279 return SPDY_ERROR_CONTROL_PAYLOAD_TOO_LARGE;
279 case SpdyFramer::SPDY_ZLIB_INIT_FAILURE: 280 case SpdyFramer::SPDY_ZLIB_INIT_FAILURE:
280 return SPDY_ERROR_ZLIB_INIT_FAILURE; 281 return SPDY_ERROR_ZLIB_INIT_FAILURE;
281 case SpdyFramer::SPDY_UNSUPPORTED_VERSION: 282 case SpdyFramer::SPDY_UNSUPPORTED_VERSION:
282 return SPDY_ERROR_UNSUPPORTED_VERSION; 283 return SPDY_ERROR_UNSUPPORTED_VERSION;
(...skipping 12 matching lines...) Expand all
295 case SpdyFramer::SPDY_UNEXPECTED_FRAME: 296 case SpdyFramer::SPDY_UNEXPECTED_FRAME:
296 return SPDY_ERROR_UNEXPECTED_FRAME; 297 return SPDY_ERROR_UNEXPECTED_FRAME;
297 default: 298 default:
298 NOTREACHED(); 299 NOTREACHED();
299 return static_cast<SpdyProtocolErrorDetails>(-1); 300 return static_cast<SpdyProtocolErrorDetails>(-1);
300 } 301 }
301 } 302 }
302 303
303 SpdyProtocolErrorDetails MapRstStreamStatusToProtocolError( 304 SpdyProtocolErrorDetails MapRstStreamStatusToProtocolError(
304 SpdyRstStreamStatus status) { 305 SpdyRstStreamStatus status) {
305 switch(status) { 306 switch (status) {
306 case RST_STREAM_PROTOCOL_ERROR: 307 case RST_STREAM_PROTOCOL_ERROR:
307 return STATUS_CODE_PROTOCOL_ERROR; 308 return STATUS_CODE_PROTOCOL_ERROR;
308 case RST_STREAM_INVALID_STREAM: 309 case RST_STREAM_INVALID_STREAM:
309 return STATUS_CODE_INVALID_STREAM; 310 return STATUS_CODE_INVALID_STREAM;
310 case RST_STREAM_REFUSED_STREAM: 311 case RST_STREAM_REFUSED_STREAM:
311 return STATUS_CODE_REFUSED_STREAM; 312 return STATUS_CODE_REFUSED_STREAM;
312 case RST_STREAM_UNSUPPORTED_VERSION: 313 case RST_STREAM_UNSUPPORTED_VERSION:
313 return STATUS_CODE_UNSUPPORTED_VERSION; 314 return STATUS_CODE_UNSUPPORTED_VERSION;
314 case RST_STREAM_CANCEL: 315 case RST_STREAM_CANCEL:
315 return STATUS_CODE_CANCEL; 316 return STATUS_CODE_CANCEL;
(...skipping 22 matching lines...) Expand all
338 } 339 }
339 340
340 SpdyStreamRequest::SpdyStreamRequest() : weak_ptr_factory_(this) { 341 SpdyStreamRequest::SpdyStreamRequest() : weak_ptr_factory_(this) {
341 Reset(); 342 Reset();
342 } 343 }
343 344
344 SpdyStreamRequest::~SpdyStreamRequest() { 345 SpdyStreamRequest::~SpdyStreamRequest() {
345 CancelRequest(); 346 CancelRequest();
346 } 347 }
347 348
348 int SpdyStreamRequest::StartRequest( 349 int SpdyStreamRequest::StartRequest(SpdyStreamType type,
349 SpdyStreamType type, 350 const base::WeakPtr<SpdySession>& session,
350 const base::WeakPtr<SpdySession>& session, 351 const GURL& url,
351 const GURL& url, 352 RequestPriority priority,
352 RequestPriority priority, 353 const BoundNetLog& net_log,
353 const BoundNetLog& net_log, 354 const CompletionCallback& callback) {
354 const CompletionCallback& callback) {
355 DCHECK(session); 355 DCHECK(session);
356 DCHECK(!session_); 356 DCHECK(!session_);
357 DCHECK(!stream_); 357 DCHECK(!stream_);
358 DCHECK(callback_.is_null()); 358 DCHECK(callback_.is_null());
359 359
360 type_ = type; 360 type_ = type;
361 session_ = session; 361 session_ = session;
362 url_ = url; 362 url_ = url;
363 priority_ = priority; 363 priority_ = priority;
364 net_log_ = net_log; 364 net_log_ = net_log;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 type_ = SPDY_BIDIRECTIONAL_STREAM; 415 type_ = SPDY_BIDIRECTIONAL_STREAM;
416 session_.reset(); 416 session_.reset();
417 stream_.reset(); 417 stream_.reset();
418 url_ = GURL(); 418 url_ = GURL();
419 priority_ = MINIMUM_PRIORITY; 419 priority_ = MINIMUM_PRIORITY;
420 net_log_ = BoundNetLog(); 420 net_log_ = BoundNetLog();
421 callback_.Reset(); 421 callback_.Reset();
422 } 422 }
423 423
424 SpdySession::ActiveStreamInfo::ActiveStreamInfo() 424 SpdySession::ActiveStreamInfo::ActiveStreamInfo()
425 : stream(NULL), 425 : stream(NULL), waiting_for_syn_reply(false) {
426 waiting_for_syn_reply(false) {} 426 }
427 427
428 SpdySession::ActiveStreamInfo::ActiveStreamInfo(SpdyStream* stream) 428 SpdySession::ActiveStreamInfo::ActiveStreamInfo(SpdyStream* stream)
429 : stream(stream), 429 : stream(stream),
430 waiting_for_syn_reply(stream->type() != SPDY_PUSH_STREAM) {} 430 waiting_for_syn_reply(stream->type() != SPDY_PUSH_STREAM) {
431 }
431 432
432 SpdySession::ActiveStreamInfo::~ActiveStreamInfo() {} 433 SpdySession::ActiveStreamInfo::~ActiveStreamInfo() {
434 }
433 435
434 SpdySession::PushedStreamInfo::PushedStreamInfo() : stream_id(0) {} 436 SpdySession::PushedStreamInfo::PushedStreamInfo() : stream_id(0) {
437 }
435 438
436 SpdySession::PushedStreamInfo::PushedStreamInfo( 439 SpdySession::PushedStreamInfo::PushedStreamInfo(SpdyStreamId stream_id,
437 SpdyStreamId stream_id, 440 base::TimeTicks creation_time)
438 base::TimeTicks creation_time) 441 : stream_id(stream_id), creation_time(creation_time) {
439 : stream_id(stream_id), 442 }
440 creation_time(creation_time) {}
441 443
442 SpdySession::PushedStreamInfo::~PushedStreamInfo() {} 444 SpdySession::PushedStreamInfo::~PushedStreamInfo() {
445 }
443 446
444 SpdySession::SpdySession( 447 SpdySession::SpdySession(
445 const SpdySessionKey& spdy_session_key, 448 const SpdySessionKey& spdy_session_key,
446 const base::WeakPtr<HttpServerProperties>& http_server_properties, 449 const base::WeakPtr<HttpServerProperties>& http_server_properties,
447 bool verify_domain_authentication, 450 bool verify_domain_authentication,
448 bool enable_sending_initial_data, 451 bool enable_sending_initial_data,
449 bool enable_compression, 452 bool enable_compression,
450 bool enable_ping_based_connection_checking, 453 bool enable_ping_based_connection_checking,
451 NextProto default_protocol, 454 NextProto default_protocol,
452 size_t stream_initial_recv_window_size, 455 size_t stream_initial_recv_window_size,
(...skipping 10 matching lines...) Expand all
463 read_buffer_(new IOBuffer(kReadBufferSize)), 466 read_buffer_(new IOBuffer(kReadBufferSize)),
464 stream_hi_water_mark_(kFirstStreamId), 467 stream_hi_water_mark_(kFirstStreamId),
465 in_flight_write_frame_type_(DATA), 468 in_flight_write_frame_type_(DATA),
466 in_flight_write_frame_size_(0), 469 in_flight_write_frame_size_(0),
467 is_secure_(false), 470 is_secure_(false),
468 certificate_error_code_(OK), 471 certificate_error_code_(OK),
469 availability_state_(STATE_AVAILABLE), 472 availability_state_(STATE_AVAILABLE),
470 read_state_(READ_STATE_DO_READ), 473 read_state_(READ_STATE_DO_READ),
471 write_state_(WRITE_STATE_IDLE), 474 write_state_(WRITE_STATE_IDLE),
472 error_on_close_(OK), 475 error_on_close_(OK),
473 max_concurrent_streams_(initial_max_concurrent_streams == 0 ? 476 max_concurrent_streams_(initial_max_concurrent_streams == 0
474 kInitialMaxConcurrentStreams : 477 ? kInitialMaxConcurrentStreams
475 initial_max_concurrent_streams), 478 : initial_max_concurrent_streams),
476 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ? 479 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0
477 kMaxConcurrentStreamLimit : 480 ? kMaxConcurrentStreamLimit
478 max_concurrent_streams_limit), 481 : max_concurrent_streams_limit),
479 streams_initiated_count_(0), 482 streams_initiated_count_(0),
480 streams_pushed_count_(0), 483 streams_pushed_count_(0),
481 streams_pushed_and_claimed_count_(0), 484 streams_pushed_and_claimed_count_(0),
482 streams_abandoned_count_(0), 485 streams_abandoned_count_(0),
483 total_bytes_received_(0), 486 total_bytes_received_(0),
484 sent_settings_(false), 487 sent_settings_(false),
485 received_settings_(false), 488 received_settings_(false),
486 stalled_streams_(0), 489 stalled_streams_(0),
487 pings_in_flight_(0), 490 pings_in_flight_(0),
488 next_ping_id_(1), 491 next_ping_id_(1),
489 last_activity_time_(time_func()), 492 last_activity_time_(time_func()),
490 last_compressed_frame_len_(0), 493 last_compressed_frame_len_(0),
491 check_ping_status_pending_(false), 494 check_ping_status_pending_(false),
492 send_connection_header_prefix_(false), 495 send_connection_header_prefix_(false),
493 flow_control_state_(FLOW_CONTROL_NONE), 496 flow_control_state_(FLOW_CONTROL_NONE),
494 stream_initial_send_window_size_(kSpdyStreamInitialWindowSize), 497 stream_initial_send_window_size_(kSpdyStreamInitialWindowSize),
495 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 ? 498 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0
496 kDefaultInitialRecvWindowSize : 499 ? kDefaultInitialRecvWindowSize
497 stream_initial_recv_window_size), 500 : stream_initial_recv_window_size),
498 session_send_window_size_(0), 501 session_send_window_size_(0),
499 session_recv_window_size_(0), 502 session_recv_window_size_(0),
500 session_unacked_recv_window_bytes_(0), 503 session_unacked_recv_window_bytes_(0),
501 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)), 504 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)),
502 verify_domain_authentication_(verify_domain_authentication), 505 verify_domain_authentication_(verify_domain_authentication),
503 enable_sending_initial_data_(enable_sending_initial_data), 506 enable_sending_initial_data_(enable_sending_initial_data),
504 enable_compression_(enable_compression), 507 enable_compression_(enable_compression),
505 enable_ping_based_connection_checking_( 508 enable_ping_based_connection_checking_(
506 enable_ping_based_connection_checking), 509 enable_ping_based_connection_checking),
507 protocol_(default_protocol), 510 protocol_(default_protocol),
508 connection_at_risk_of_loss_time_( 511 connection_at_risk_of_loss_time_(
509 base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)), 512 base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)),
510 hung_interval_( 513 hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
511 base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
512 trusted_spdy_proxy_(trusted_spdy_proxy), 514 trusted_spdy_proxy_(trusted_spdy_proxy),
513 time_func_(time_func) { 515 time_func_(time_func) {
514 DCHECK_GE(protocol_, kProtoSPDYMinimumVersion); 516 DCHECK_GE(protocol_, kProtoSPDYMinimumVersion);
515 DCHECK_LE(protocol_, kProtoSPDYMaximumVersion); 517 DCHECK_LE(protocol_, kProtoSPDYMaximumVersion);
516 DCHECK(HttpStreamFactory::spdy_enabled()); 518 DCHECK(HttpStreamFactory::spdy_enabled());
517 net_log_.BeginEvent( 519 net_log_.BeginEvent(
518 NetLog::TYPE_SPDY_SESSION, 520 NetLog::TYPE_SPDY_SESSION,
519 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair())); 521 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair()));
520 next_unclaimed_push_stream_sweep_time_ = time_func_() + 522 next_unclaimed_push_stream_sweep_time_ =
523 time_func_() +
521 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); 524 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
522 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. 525 // TODO(mbelshe): consider randomization of the stream_hi_water_mark.
523 } 526 }
524 527
525 SpdySession::~SpdySession() { 528 SpdySession::~SpdySession() {
526 CHECK(!in_io_loop_); 529 CHECK(!in_io_loop_);
527 DCHECK(!pool_); 530 DCHECK(!pool_);
528 DcheckClosed(); 531 DcheckClosed();
529 532
530 // TODO(akalin): Check connection->is_initialized() instead. This 533 // TODO(akalin): Check connection->is_initialized() instead. This
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 if (protocol_ >= kProtoSPDY31) { 579 if (protocol_ >= kProtoSPDY31) {
577 flow_control_state_ = FLOW_CONTROL_STREAM_AND_SESSION; 580 flow_control_state_ = FLOW_CONTROL_STREAM_AND_SESSION;
578 session_send_window_size_ = kSpdySessionInitialWindowSize; 581 session_send_window_size_ = kSpdySessionInitialWindowSize;
579 session_recv_window_size_ = kSpdySessionInitialWindowSize; 582 session_recv_window_size_ = kSpdySessionInitialWindowSize;
580 } else if (protocol_ >= kProtoSPDY3) { 583 } else if (protocol_ >= kProtoSPDY3) {
581 flow_control_state_ = FLOW_CONTROL_STREAM; 584 flow_control_state_ = FLOW_CONTROL_STREAM;
582 } else { 585 } else {
583 flow_control_state_ = FLOW_CONTROL_NONE; 586 flow_control_state_ = FLOW_CONTROL_NONE;
584 } 587 }
585 588
586 buffered_spdy_framer_.reset( 589 buffered_spdy_framer_.reset(new BufferedSpdyFramer(
587 new BufferedSpdyFramer(NextProtoToSpdyMajorVersion(protocol_), 590 NextProtoToSpdyMajorVersion(protocol_), enable_compression_));
588 enable_compression_));
589 buffered_spdy_framer_->set_visitor(this); 591 buffered_spdy_framer_->set_visitor(this);
590 buffered_spdy_framer_->set_debug_visitor(this); 592 buffered_spdy_framer_->set_debug_visitor(this);
591 UMA_HISTOGRAM_ENUMERATION("Net.SpdyVersion", protocol_, kProtoMaximumVersion); 593 UMA_HISTOGRAM_ENUMERATION("Net.SpdyVersion", protocol_, kProtoMaximumVersion);
592 #if defined(SPDY_PROXY_AUTH_ORIGIN) 594 #if defined(SPDY_PROXY_AUTH_ORIGIN)
593 UMA_HISTOGRAM_BOOLEAN("Net.SpdySessions_DataReductionProxy", 595 UMA_HISTOGRAM_BOOLEAN("Net.SpdySessions_DataReductionProxy",
594 host_port_pair().Equals(HostPortPair::FromURL( 596 host_port_pair().Equals(HostPortPair::FromURL(
595 GURL(SPDY_PROXY_AUTH_ORIGIN)))); 597 GURL(SPDY_PROXY_AUTH_ORIGIN))));
596 #endif 598 #endif
597 599
598 net_log_.AddEvent( 600 net_log_.AddEvent(
599 NetLog::TYPE_SPDY_SESSION_INITIALIZED, 601 NetLog::TYPE_SPDY_SESSION_INITIALIZED,
600 connection_->socket()->NetLog().source().ToEventParametersCallback()); 602 connection_->socket()->NetLog().source().ToEventParametersCallback());
601 603
602 DCHECK_NE(availability_state_, STATE_CLOSED); 604 DCHECK_NE(availability_state_, STATE_CLOSED);
603 connection_->AddHigherLayeredPool(this); 605 connection_->AddHigherLayeredPool(this);
604 if (enable_sending_initial_data_) 606 if (enable_sending_initial_data_)
605 SendInitialData(); 607 SendInitialData();
606 pool_ = pool; 608 pool_ = pool;
607 609
608 // Bootstrap the read loop. 610 // Bootstrap the read loop.
609 base::MessageLoop::current()->PostTask( 611 base::MessageLoop::current()->PostTask(FROM_HERE,
610 FROM_HERE, 612 base::Bind(&SpdySession::PumpReadLoop,
611 base::Bind(&SpdySession::PumpReadLoop, 613 weak_factory_.GetWeakPtr(),
612 weak_factory_.GetWeakPtr(), READ_STATE_DO_READ, OK)); 614 READ_STATE_DO_READ,
615 OK));
613 } 616 }
614 617
615 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) { 618 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) {
616 if (!verify_domain_authentication_) 619 if (!verify_domain_authentication_)
617 return true; 620 return true;
618 621
619 if (availability_state_ == STATE_CLOSED) 622 if (availability_state_ == STATE_CLOSED)
620 return false; 623 return false;
621 624
622 SSLInfo ssl_info; 625 SSLInfo ssl_info;
623 bool was_npn_negotiated; 626 bool was_npn_negotiated;
624 NextProto protocol_negotiated = kProtoUnknown; 627 NextProto protocol_negotiated = kProtoUnknown;
625 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) 628 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated))
626 return true; // This is not a secure session, so all domains are okay. 629 return true; // This is not a secure session, so all domains are okay.
627 630
628 bool unused = false; 631 bool unused = false;
629 return 632 return !ssl_info.client_cert_sent &&
630 !ssl_info.client_cert_sent && 633 (!ssl_info.channel_id_sent ||
631 (!ssl_info.channel_id_sent || 634 (ServerBoundCertService::GetDomainForHost(domain) ==
632 (ServerBoundCertService::GetDomainForHost(domain) == 635 ServerBoundCertService::GetDomainForHost(
633 ServerBoundCertService::GetDomainForHost(host_port_pair().host()))) && 636 host_port_pair().host()))) &&
634 ssl_info.cert->VerifyNameMatch(domain, &unused); 637 ssl_info.cert->VerifyNameMatch(domain, &unused);
635 } 638 }
636 639
637 int SpdySession::GetPushStream( 640 int SpdySession::GetPushStream(const GURL& url,
638 const GURL& url, 641 base::WeakPtr<SpdyStream>* stream,
639 base::WeakPtr<SpdyStream>* stream, 642 const BoundNetLog& stream_net_log) {
640 const BoundNetLog& stream_net_log) {
641 CHECK(!in_io_loop_); 643 CHECK(!in_io_loop_);
642 644
643 stream->reset(); 645 stream->reset();
644 646
645 // TODO(akalin): Add unit test exercising this code path. 647 // TODO(akalin): Add unit test exercising this code path.
646 if (availability_state_ == STATE_CLOSED) 648 if (availability_state_ == STATE_CLOSED)
647 return ERR_CONNECTION_CLOSED; 649 return ERR_CONNECTION_CLOSED;
648 650
649 Error err = TryAccessStream(url); 651 Error err = TryAccessStream(url);
650 if (err != OK) 652 if (err != OK)
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 if (!connection_->socket()->IsConnected()) { 739 if (!connection_->socket()->IsConnected()) {
738 CloseSessionResult result = DoCloseSession( 740 CloseSessionResult result = DoCloseSession(
739 ERR_CONNECTION_CLOSED, 741 ERR_CONNECTION_CLOSED,
740 "Tried to create SPDY stream for a closed socket connection."); 742 "Tried to create SPDY stream for a closed socket connection.");
741 DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED); 743 DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED);
742 return ERR_CONNECTION_CLOSED; 744 return ERR_CONNECTION_CLOSED;
743 } 745 }
744 } 746 }
745 747
746 scoped_ptr<SpdyStream> new_stream( 748 scoped_ptr<SpdyStream> new_stream(
747 new SpdyStream(request.type(), GetWeakPtr(), request.url(), 749 new SpdyStream(request.type(),
750 GetWeakPtr(),
751 request.url(),
748 request.priority(), 752 request.priority(),
749 stream_initial_send_window_size_, 753 stream_initial_send_window_size_,
750 stream_initial_recv_window_size_, 754 stream_initial_recv_window_size_,
751 request.net_log())); 755 request.net_log()));
752 *stream = new_stream->GetWeakPtr(); 756 *stream = new_stream->GetWeakPtr();
753 InsertCreatedStream(new_stream.Pass()); 757 InsertCreatedStream(new_stream.Pass());
754 758
755 UMA_HISTOGRAM_CUSTOM_COUNTS( 759 UMA_HISTOGRAM_CUSTOM_COUNTS(
756 "Net.SpdyPriorityCount", 760 "Net.SpdyPriorityCount", static_cast<int>(request.priority()), 0, 10, 11);
757 static_cast<int>(request.priority()), 0, 10, 11);
758 761
759 return OK; 762 return OK;
760 } 763 }
761 764
762 void SpdySession::CancelStreamRequest( 765 void SpdySession::CancelStreamRequest(
763 const base::WeakPtr<SpdyStreamRequest>& request) { 766 const base::WeakPtr<SpdyStreamRequest>& request) {
764 DCHECK(request); 767 DCHECK(request);
765 RequestPriority priority = request->priority(); 768 RequestPriority priority = request->priority();
766 CHECK_GE(priority, MINIMUM_PRIORITY); 769 CHECK_GE(priority, MINIMUM_PRIORITY);
767 CHECK_LE(priority, MAXIMUM_PRIORITY); 770 CHECK_LE(priority, MAXIMUM_PRIORITY);
768 771
769 #if DCHECK_IS_ON 772 #if DCHECK_IS_ON
770 // |request| should not be in a queue not matching its priority. 773 // |request| should not be in a queue not matching its priority.
771 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { 774 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
772 if (priority == i) 775 if (priority == i)
773 continue; 776 continue;
774 PendingStreamRequestQueue* queue = &pending_create_stream_queues_[i]; 777 PendingStreamRequestQueue* queue = &pending_create_stream_queues_[i];
775 DCHECK(std::find_if(queue->begin(), 778 DCHECK(std::find_if(queue->begin(), queue->end(), RequestEquals(request)) ==
776 queue->end(), 779 queue->end());
777 RequestEquals(request)) == queue->end());
778 } 780 }
779 #endif 781 #endif
780 782
781 PendingStreamRequestQueue* queue = 783 PendingStreamRequestQueue* queue = &pending_create_stream_queues_[priority];
782 &pending_create_stream_queues_[priority];
783 // Remove |request| from |queue| while preserving the order of the 784 // Remove |request| from |queue| while preserving the order of the
784 // other elements. 785 // other elements.
785 PendingStreamRequestQueue::iterator it = 786 PendingStreamRequestQueue::iterator it =
786 std::find_if(queue->begin(), queue->end(), RequestEquals(request)); 787 std::find_if(queue->begin(), queue->end(), RequestEquals(request));
787 // The request may already be removed if there's a 788 // The request may already be removed if there's a
788 // CompleteStreamRequest() in flight. 789 // CompleteStreamRequest() in flight.
789 if (it != queue->end()) { 790 if (it != queue->end()) {
790 it = queue->erase(it); 791 it = queue->erase(it);
791 // |request| should be in the queue at most once, and if it is 792 // |request| should be in the queue at most once, and if it is
792 // present, should not be pending completion. 793 // present, should not be pending completion.
(...skipping 19 matching lines...) Expand all
812 void SpdySession::ProcessPendingStreamRequests() { 813 void SpdySession::ProcessPendingStreamRequests() {
813 // Like |max_concurrent_streams_|, 0 means infinite for 814 // Like |max_concurrent_streams_|, 0 means infinite for
814 // |max_requests_to_process|. 815 // |max_requests_to_process|.
815 size_t max_requests_to_process = 0; 816 size_t max_requests_to_process = 0;
816 if (max_concurrent_streams_ != 0) { 817 if (max_concurrent_streams_ != 0) {
817 max_requests_to_process = 818 max_requests_to_process =
818 max_concurrent_streams_ - 819 max_concurrent_streams_ -
819 (active_streams_.size() + created_streams_.size()); 820 (active_streams_.size() + created_streams_.size());
820 } 821 }
821 for (size_t i = 0; 822 for (size_t i = 0;
822 max_requests_to_process == 0 || i < max_requests_to_process; ++i) { 823 max_requests_to_process == 0 || i < max_requests_to_process;
824 ++i) {
823 base::WeakPtr<SpdyStreamRequest> pending_request = 825 base::WeakPtr<SpdyStreamRequest> pending_request =
824 GetNextPendingStreamRequest(); 826 GetNextPendingStreamRequest();
825 if (!pending_request) 827 if (!pending_request)
826 break; 828 break;
827 829
828 base::MessageLoop::current()->PostTask( 830 base::MessageLoop::current()->PostTask(
829 FROM_HERE, 831 FROM_HERE,
830 base::Bind(&SpdySession::CompleteStreamRequest, 832 base::Bind(&SpdySession::CompleteStreamRequest,
831 weak_factory_.GetWeakPtr(), 833 weak_factory_.GetWeakPtr(),
832 pending_request)); 834 pending_request));
(...skipping 21 matching lines...) Expand all
854 return false; 856 return false;
855 CloseSessionResult result = 857 CloseSessionResult result =
856 DoCloseSession(ERR_CONNECTION_CLOSED, "Closing one idle connection."); 858 DoCloseSession(ERR_CONNECTION_CLOSED, "Closing one idle connection.");
857 if (result != SESSION_CLOSED_AND_REMOVED) { 859 if (result != SESSION_CLOSED_AND_REMOVED) {
858 NOTREACHED(); 860 NOTREACHED();
859 return false; 861 return false;
860 } 862 }
861 return true; 863 return true;
862 } 864 }
863 865
864 void SpdySession::EnqueueStreamWrite( 866 void SpdySession::EnqueueStreamWrite(const base::WeakPtr<SpdyStream>& stream,
865 const base::WeakPtr<SpdyStream>& stream, 867 SpdyFrameType frame_type,
866 SpdyFrameType frame_type, 868 scoped_ptr<SpdyBufferProducer> producer) {
867 scoped_ptr<SpdyBufferProducer> producer) { 869 DCHECK(frame_type == HEADERS || frame_type == DATA ||
868 DCHECK(frame_type == HEADERS || 870 frame_type == CREDENTIAL || frame_type == SYN_STREAM);
869 frame_type == DATA ||
870 frame_type == CREDENTIAL ||
871 frame_type == SYN_STREAM);
872 EnqueueWrite(stream->priority(), frame_type, producer.Pass(), stream); 871 EnqueueWrite(stream->priority(), frame_type, producer.Pass(), stream);
873 } 872 }
874 873
875 scoped_ptr<SpdyFrame> SpdySession::CreateSynStream( 874 scoped_ptr<SpdyFrame> SpdySession::CreateSynStream(
876 SpdyStreamId stream_id, 875 SpdyStreamId stream_id,
877 RequestPriority priority, 876 RequestPriority priority,
878 SpdyControlFlags flags, 877 SpdyControlFlags flags,
879 const SpdyHeaderBlock& headers) { 878 const SpdyHeaderBlock& headers) {
880 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); 879 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id);
881 CHECK(it != active_streams_.end()); 880 CHECK(it != active_streams_.end());
882 CHECK_EQ(it->second.stream->stream_id(), stream_id); 881 CHECK_EQ(it->second.stream->stream_id(), stream_id);
883 882
884 SendPrefacePingIfNoneInFlight(); 883 SendPrefacePingIfNoneInFlight();
885 884
886 DCHECK(buffered_spdy_framer_.get()); 885 DCHECK(buffered_spdy_framer_.get());
887 SpdyPriority spdy_priority = 886 SpdyPriority spdy_priority =
888 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()); 887 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion());
889 scoped_ptr<SpdyFrame> syn_frame( 888 scoped_ptr<SpdyFrame> syn_frame(buffered_spdy_framer_->CreateSynStream(
890 buffered_spdy_framer_->CreateSynStream(stream_id, 0, spdy_priority, flags, 889 stream_id, 0, spdy_priority, flags, &headers));
891 &headers));
892 890
893 base::StatsCounter spdy_requests("spdy.requests"); 891 base::StatsCounter spdy_requests("spdy.requests");
894 spdy_requests.Increment(); 892 spdy_requests.Increment();
895 streams_initiated_count_++; 893 streams_initiated_count_++;
896 894
897 if (net_log().IsLogging()) { 895 if (net_log().IsLogging()) {
898 net_log().AddEvent( 896 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_SYN_STREAM,
899 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, 897 base::Bind(&NetLogSpdySynStreamSentCallback,
900 base::Bind(&NetLogSpdySynStreamSentCallback, &headers, 898 &headers,
901 (flags & CONTROL_FLAG_FIN) != 0, 899 (flags & CONTROL_FLAG_FIN) != 0,
902 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0, 900 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0,
903 spdy_priority, 901 spdy_priority,
904 stream_id)); 902 stream_id));
905 } 903 }
906 904
907 return syn_frame.Pass(); 905 return syn_frame.Pass();
908 } 906 }
909 907
910 scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, 908 scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id,
911 IOBuffer* data, 909 IOBuffer* data,
912 int len, 910 int len,
913 SpdyDataFlags flags) { 911 SpdyDataFlags flags) {
914 if (availability_state_ == STATE_CLOSED) { 912 if (availability_state_ == STATE_CLOSED) {
915 NOTREACHED(); 913 NOTREACHED();
916 return scoped_ptr<SpdyBuffer>(); 914 return scoped_ptr<SpdyBuffer>();
917 } 915 }
918 916
919 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); 917 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id);
920 CHECK(it != active_streams_.end()); 918 CHECK(it != active_streams_.end());
921 SpdyStream* stream = it->second.stream; 919 SpdyStream* stream = it->second.stream;
922 CHECK_EQ(stream->stream_id(), stream_id); 920 CHECK_EQ(stream->stream_id(), stream_id);
923 921
924 if (len < 0) { 922 if (len < 0) {
925 NOTREACHED(); 923 NOTREACHED();
926 return scoped_ptr<SpdyBuffer>(); 924 return scoped_ptr<SpdyBuffer>();
927 } 925 }
928 926
929 int effective_len = std::min(len, kMaxSpdyFrameChunkSize); 927 int effective_len = std::min(len, kMaxSpdyFrameChunkSize);
930 928
931 bool send_stalled_by_stream = 929 bool send_stalled_by_stream = (flow_control_state_ >= FLOW_CONTROL_STREAM) &&
932 (flow_control_state_ >= FLOW_CONTROL_STREAM) && 930 (stream->send_window_size() <= 0);
933 (stream->send_window_size() <= 0);
934 bool send_stalled_by_session = IsSendStalled(); 931 bool send_stalled_by_session = IsSendStalled();
935 932
936 // NOTE: There's an enum of the same name in histograms.xml. 933 // NOTE: There's an enum of the same name in histograms.xml.
937 enum SpdyFrameFlowControlState { 934 enum SpdyFrameFlowControlState {
938 SEND_NOT_STALLED, 935 SEND_NOT_STALLED,
939 SEND_STALLED_BY_STREAM, 936 SEND_STALLED_BY_STREAM,
940 SEND_STALLED_BY_SESSION, 937 SEND_STALLED_BY_SESSION,
941 SEND_STALLED_BY_STREAM_AND_SESSION, 938 SEND_STALLED_BY_STREAM_AND_SESSION,
942 }; 939 };
943 940
944 SpdyFrameFlowControlState frame_flow_control_state = SEND_NOT_STALLED; 941 SpdyFrameFlowControlState frame_flow_control_state = SEND_NOT_STALLED;
945 if (send_stalled_by_stream) { 942 if (send_stalled_by_stream) {
946 if (send_stalled_by_session) { 943 if (send_stalled_by_session) {
947 frame_flow_control_state = SEND_STALLED_BY_STREAM_AND_SESSION; 944 frame_flow_control_state = SEND_STALLED_BY_STREAM_AND_SESSION;
948 } else { 945 } else {
949 frame_flow_control_state = SEND_STALLED_BY_STREAM; 946 frame_flow_control_state = SEND_STALLED_BY_STREAM;
950 } 947 }
951 } else if (send_stalled_by_session) { 948 } else if (send_stalled_by_session) {
952 frame_flow_control_state = SEND_STALLED_BY_SESSION; 949 frame_flow_control_state = SEND_STALLED_BY_SESSION;
953 } 950 }
954 951
955 if (flow_control_state_ == FLOW_CONTROL_STREAM) { 952 if (flow_control_state_ == FLOW_CONTROL_STREAM) {
956 UMA_HISTOGRAM_ENUMERATION( 953 UMA_HISTOGRAM_ENUMERATION("Net.SpdyFrameStreamFlowControlState",
957 "Net.SpdyFrameStreamFlowControlState", 954 frame_flow_control_state,
958 frame_flow_control_state, 955 SEND_STALLED_BY_STREAM + 1);
959 SEND_STALLED_BY_STREAM + 1);
960 } else if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { 956 } else if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
961 UMA_HISTOGRAM_ENUMERATION( 957 UMA_HISTOGRAM_ENUMERATION("Net.SpdyFrameStreamAndSessionFlowControlState",
962 "Net.SpdyFrameStreamAndSessionFlowControlState", 958 frame_flow_control_state,
963 frame_flow_control_state, 959 SEND_STALLED_BY_STREAM_AND_SESSION + 1);
964 SEND_STALLED_BY_STREAM_AND_SESSION + 1);
965 } 960 }
966 961
967 // Obey send window size of the stream if stream flow control is 962 // Obey send window size of the stream if stream flow control is
968 // enabled. 963 // enabled.
969 if (flow_control_state_ >= FLOW_CONTROL_STREAM) { 964 if (flow_control_state_ >= FLOW_CONTROL_STREAM) {
970 if (send_stalled_by_stream) { 965 if (send_stalled_by_stream) {
971 stream->set_send_stalled_by_flow_control(true); 966 stream->set_send_stalled_by_flow_control(true);
972 // Even though we're currently stalled only by the stream, we 967 // Even though we're currently stalled only by the stream, we
973 // might end up being stalled by the session also. 968 // might end up being stalled by the session also.
974 QueueSendStalledStream(*stream); 969 QueueSendStalledStream(*stream);
(...skipping 22 matching lines...) Expand all
997 } 992 }
998 993
999 DCHECK_GE(effective_len, 0); 994 DCHECK_GE(effective_len, 0);
1000 995
1001 // Clear FIN flag if only some of the data will be in the data 996 // Clear FIN flag if only some of the data will be in the data
1002 // frame. 997 // frame.
1003 if (effective_len < len) 998 if (effective_len < len)
1004 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); 999 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN);
1005 1000
1006 if (net_log().IsLogging()) { 1001 if (net_log().IsLogging()) {
1007 net_log().AddEvent( 1002 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_SEND_DATA,
1008 NetLog::TYPE_SPDY_SESSION_SEND_DATA, 1003 base::Bind(&NetLogSpdyDataCallback,
1009 base::Bind(&NetLogSpdyDataCallback, stream_id, effective_len, 1004 stream_id,
1010 (flags & DATA_FLAG_FIN) != 0)); 1005 effective_len,
1006 (flags & DATA_FLAG_FIN) != 0));
1011 } 1007 }
1012 1008
1013 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. 1009 // Send PrefacePing for DATA_FRAMEs with nonzero payload size.
1014 if (effective_len > 0) 1010 if (effective_len > 0)
1015 SendPrefacePingIfNoneInFlight(); 1011 SendPrefacePingIfNoneInFlight();
1016 1012
1017 // TODO(mbelshe): reduce memory copies here. 1013 // TODO(mbelshe): reduce memory copies here.
1018 DCHECK(buffered_spdy_framer_.get()); 1014 DCHECK(buffered_spdy_framer_.get());
1019 scoped_ptr<SpdyFrame> frame( 1015 scoped_ptr<SpdyFrame> frame(buffered_spdy_framer_->CreateDataFrame(
1020 buffered_spdy_framer_->CreateDataFrame( 1016 stream_id, data->data(), static_cast<uint32>(effective_len), flags));
1021 stream_id, data->data(),
1022 static_cast<uint32>(effective_len), flags));
1023 1017
1024 scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(frame.Pass())); 1018 scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(frame.Pass()));
1025 1019
1026 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { 1020 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
1027 DecreaseSendWindowSize(static_cast<int32>(effective_len)); 1021 DecreaseSendWindowSize(static_cast<int32>(effective_len));
1028 data_buffer->AddConsumeCallback( 1022 data_buffer->AddConsumeCallback(
1029 base::Bind(&SpdySession::OnWriteBufferConsumed, 1023 base::Bind(&SpdySession::OnWriteBufferConsumed,
1030 weak_factory_.GetWeakPtr(), 1024 weak_factory_.GetWeakPtr(),
1031 static_cast<size_t>(effective_len))); 1025 static_cast<size_t>(effective_len)));
1032 } 1026 }
1033 1027
1034 return data_buffer.Pass(); 1028 return data_buffer.Pass();
1035 } 1029 }
1036 1030
1037 void SpdySession::CloseActiveStream(SpdyStreamId stream_id, int status) { 1031 void SpdySession::CloseActiveStream(SpdyStreamId stream_id, int status) {
1038 DCHECK_NE(stream_id, 0u); 1032 DCHECK_NE(stream_id, 0u);
1039 1033
1040 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 1034 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
1041 if (it == active_streams_.end()) { 1035 if (it == active_streams_.end()) {
1042 NOTREACHED(); 1036 NOTREACHED();
1043 return; 1037 return;
1044 } 1038 }
1045 1039
1046 CloseActiveStreamIterator(it, status); 1040 CloseActiveStreamIterator(it, status);
1047 } 1041 }
1048 1042
1049 void SpdySession::CloseCreatedStream( 1043 void SpdySession::CloseCreatedStream(const base::WeakPtr<SpdyStream>& stream,
1050 const base::WeakPtr<SpdyStream>& stream, int status) { 1044 int status) {
1051 DCHECK_EQ(stream->stream_id(), 0u); 1045 DCHECK_EQ(stream->stream_id(), 0u);
1052 1046
1053 CreatedStreamSet::iterator it = created_streams_.find(stream.get()); 1047 CreatedStreamSet::iterator it = created_streams_.find(stream.get());
1054 if (it == created_streams_.end()) { 1048 if (it == created_streams_.end()) {
1055 NOTREACHED(); 1049 NOTREACHED();
1056 return; 1050 return;
1057 } 1051 }
1058 1052
1059 CloseCreatedStreamIterator(it, status); 1053 CloseCreatedStreamIterator(it, status);
1060 } 1054 }
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 } 1204 }
1211 1205
1212 if (result == ERR_IO_PENDING) 1206 if (result == ERR_IO_PENDING)
1213 break; 1207 break;
1214 1208
1215 if (bytes_read_without_yielding > kMaxReadBytesWithoutYielding) { 1209 if (bytes_read_without_yielding > kMaxReadBytesWithoutYielding) {
1216 read_state_ = READ_STATE_DO_READ; 1210 read_state_ = READ_STATE_DO_READ;
1217 base::MessageLoop::current()->PostTask( 1211 base::MessageLoop::current()->PostTask(
1218 FROM_HERE, 1212 FROM_HERE,
1219 base::Bind(&SpdySession::PumpReadLoop, 1213 base::Bind(&SpdySession::PumpReadLoop,
1220 weak_factory_.GetWeakPtr(), READ_STATE_DO_READ, OK)); 1214 weak_factory_.GetWeakPtr(),
1215 READ_STATE_DO_READ,
1216 OK));
1221 result = ERR_IO_PENDING; 1217 result = ERR_IO_PENDING;
1222 break; 1218 break;
1223 } 1219 }
1224 } 1220 }
1225 1221
1226 CHECK(in_io_loop_); 1222 CHECK(in_io_loop_);
1227 in_io_loop_ = false; 1223 in_io_loop_ = false;
1228 1224
1229 return result; 1225 return result;
1230 } 1226 }
1231 1227
1232 int SpdySession::DoRead() { 1228 int SpdySession::DoRead() {
1233 CHECK(in_io_loop_); 1229 CHECK(in_io_loop_);
1234 CHECK_NE(availability_state_, STATE_CLOSED); 1230 CHECK_NE(availability_state_, STATE_CLOSED);
1235 1231
1236 CHECK(connection_); 1232 CHECK(connection_);
1237 CHECK(connection_->socket()); 1233 CHECK(connection_->socket());
1238 read_state_ = READ_STATE_DO_READ_COMPLETE; 1234 read_state_ = READ_STATE_DO_READ_COMPLETE;
1239 return connection_->socket()->Read( 1235 return connection_->socket()->Read(read_buffer_.get(),
1240 read_buffer_.get(), 1236 kReadBufferSize,
1241 kReadBufferSize, 1237 base::Bind(&SpdySession::PumpReadLoop,
1242 base::Bind(&SpdySession::PumpReadLoop, 1238 weak_factory_.GetWeakPtr(),
1243 weak_factory_.GetWeakPtr(), READ_STATE_DO_READ_COMPLETE)); 1239 READ_STATE_DO_READ_COMPLETE));
1244 } 1240 }
1245 1241
1246 int SpdySession::DoReadComplete(int result) { 1242 int SpdySession::DoReadComplete(int result) {
1247 CHECK(in_io_loop_); 1243 CHECK(in_io_loop_);
1248 DCHECK_NE(availability_state_, STATE_CLOSED); 1244 DCHECK_NE(availability_state_, STATE_CLOSED);
1249 1245
1250 // Parse a frame. For now this code requires that the frame fit into our 1246 // Parse a frame. For now this code requires that the frame fit into our
1251 // buffer (kReadBufferSize). 1247 // buffer (kReadBufferSize).
1252 // TODO(mbelshe): support arbitrarily large frames! 1248 // TODO(mbelshe): support arbitrarily large frames!
1253 1249
1254 if (result == 0) { 1250 if (result == 0) {
1255 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.EOF", 1251 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.EOF",
1256 total_bytes_received_, 1, 100000000, 50); 1252 total_bytes_received_,
1253 1,
1254 100000000,
1255 50);
1257 CloseSessionResult close_session_result = 1256 CloseSessionResult close_session_result =
1258 DoCloseSession(ERR_CONNECTION_CLOSED, "Connection closed"); 1257 DoCloseSession(ERR_CONNECTION_CLOSED, "Connection closed");
1259 DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED); 1258 DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED);
1260 DCHECK_EQ(availability_state_, STATE_CLOSED); 1259 DCHECK_EQ(availability_state_, STATE_CLOSED);
1261 DCHECK_EQ(error_on_close_, ERR_CONNECTION_CLOSED); 1260 DCHECK_EQ(error_on_close_, ERR_CONNECTION_CLOSED);
1262 return ERR_CONNECTION_CLOSED; 1261 return ERR_CONNECTION_CLOSED;
1263 } 1262 }
1264 1263
1265 if (result < 0) { 1264 if (result < 0) {
1266 CloseSessionResult close_session_result = 1265 CloseSessionResult close_session_result =
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 } 1373 }
1375 1374
1376 if (stream.get()) 1375 if (stream.get())
1377 CHECK(!stream->IsClosed()); 1376 CHECK(!stream->IsClosed());
1378 1377
1379 // Activate the stream only when sending the SYN_STREAM frame to 1378 // Activate the stream only when sending the SYN_STREAM frame to
1380 // guarantee monotonically-increasing stream IDs. 1379 // guarantee monotonically-increasing stream IDs.
1381 if (frame_type == SYN_STREAM) { 1380 if (frame_type == SYN_STREAM) {
1382 CHECK(stream.get()); 1381 CHECK(stream.get());
1383 CHECK_EQ(stream->stream_id(), 0u); 1382 CHECK_EQ(stream->stream_id(), 0u);
1384 scoped_ptr<SpdyStream> owned_stream = 1383 scoped_ptr<SpdyStream> owned_stream = ActivateCreatedStream(stream.get());
1385 ActivateCreatedStream(stream.get());
1386 InsertActivatedStream(owned_stream.Pass()); 1384 InsertActivatedStream(owned_stream.Pass());
1387 } 1385 }
1388 1386
1389 in_flight_write_ = producer->ProduceBuffer(); 1387 in_flight_write_ = producer->ProduceBuffer();
1390 if (!in_flight_write_) { 1388 if (!in_flight_write_) {
1391 NOTREACHED(); 1389 NOTREACHED();
1392 return ERR_UNEXPECTED; 1390 return ERR_UNEXPECTED;
1393 } 1391 }
1394 in_flight_write_frame_type_ = frame_type; 1392 in_flight_write_frame_type_ = frame_type;
1395 in_flight_write_frame_size_ = in_flight_write_->GetRemainingSize(); 1393 in_flight_write_frame_size_ = in_flight_write_->GetRemainingSize();
1396 DCHECK_GE(in_flight_write_frame_size_, 1394 DCHECK_GE(in_flight_write_frame_size_,
1397 buffered_spdy_framer_->GetFrameMinimumSize()); 1395 buffered_spdy_framer_->GetFrameMinimumSize());
1398 in_flight_write_stream_ = stream; 1396 in_flight_write_stream_ = stream;
1399 } 1397 }
1400 1398
1401 write_state_ = WRITE_STATE_DO_WRITE_COMPLETE; 1399 write_state_ = WRITE_STATE_DO_WRITE_COMPLETE;
1402 1400
1403 // Explicitly store in a scoped_refptr<IOBuffer> to avoid problems 1401 // Explicitly store in a scoped_refptr<IOBuffer> to avoid problems
1404 // with Socket implementations that don't store their IOBuffer 1402 // with Socket implementations that don't store their IOBuffer
1405 // argument in a scoped_refptr<IOBuffer> (see crbug.com/232345). 1403 // argument in a scoped_refptr<IOBuffer> (see crbug.com/232345).
1406 scoped_refptr<IOBuffer> write_io_buffer = 1404 scoped_refptr<IOBuffer> write_io_buffer =
1407 in_flight_write_->GetIOBufferForRemainingData(); 1405 in_flight_write_->GetIOBufferForRemainingData();
1408 return connection_->socket()->Write( 1406 return connection_->socket()->Write(
1409 write_io_buffer.get(), 1407 write_io_buffer.get(),
1410 in_flight_write_->GetRemainingSize(), 1408 in_flight_write_->GetRemainingSize(),
1411 base::Bind(&SpdySession::PumpWriteLoop, 1409 base::Bind(&SpdySession::PumpWriteLoop,
1412 weak_factory_.GetWeakPtr(), WRITE_STATE_DO_WRITE_COMPLETE)); 1410 weak_factory_.GetWeakPtr(),
1411 WRITE_STATE_DO_WRITE_COMPLETE));
1413 } 1412 }
1414 1413
1415 int SpdySession::DoWriteComplete(int result) { 1414 int SpdySession::DoWriteComplete(int result) {
1416 CHECK(in_io_loop_); 1415 CHECK(in_io_loop_);
1417 DCHECK_NE(availability_state_, STATE_CLOSED); 1416 DCHECK_NE(availability_state_, STATE_CLOSED);
1418 DCHECK_NE(result, ERR_IO_PENDING); 1417 DCHECK_NE(result, ERR_IO_PENDING);
1419 DCHECK_GT(in_flight_write_->GetRemainingSize(), 0u); 1418 DCHECK_GT(in_flight_write_->GetRemainingSize(), 0u);
1420 1419
1421 last_activity_time_ = time_func_(); 1420 last_activity_time_ = time_func_();
1422 1421
1423 if (result < 0) { 1422 if (result < 0) {
1424 DCHECK_NE(result, ERR_IO_PENDING); 1423 DCHECK_NE(result, ERR_IO_PENDING);
1425 in_flight_write_.reset(); 1424 in_flight_write_.reset();
1426 in_flight_write_frame_type_ = DATA; 1425 in_flight_write_frame_type_ = DATA;
1427 in_flight_write_frame_size_ = 0; 1426 in_flight_write_frame_size_ = 0;
1428 in_flight_write_stream_.reset(); 1427 in_flight_write_stream_.reset();
1429 CloseSessionResult close_session_result = 1428 CloseSessionResult close_session_result =
1430 DoCloseSession(static_cast<Error>(result), "Write error"); 1429 DoCloseSession(static_cast<Error>(result), "Write error");
1431 DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED); 1430 DCHECK_EQ(close_session_result, SESSION_CLOSED_BUT_NOT_REMOVED);
1432 DCHECK_EQ(availability_state_, STATE_CLOSED); 1431 DCHECK_EQ(availability_state_, STATE_CLOSED);
1433 DCHECK_EQ(error_on_close_, result); 1432 DCHECK_EQ(error_on_close_, result);
1434 return result; 1433 return result;
1435 } 1434 }
1436 1435
1437 // It should not be possible to have written more bytes than our 1436 // It should not be possible to have written more bytes than our
1438 // in_flight_write_. 1437 // in_flight_write_.
1439 DCHECK_LE(static_cast<size_t>(result), 1438 DCHECK_LE(static_cast<size_t>(result), in_flight_write_->GetRemainingSize());
1440 in_flight_write_->GetRemainingSize());
1441 1439
1442 if (result > 0) { 1440 if (result > 0) {
1443 in_flight_write_->Consume(static_cast<size_t>(result)); 1441 in_flight_write_->Consume(static_cast<size_t>(result));
1444 1442
1445 // We only notify the stream when we've fully written the pending frame. 1443 // We only notify the stream when we've fully written the pending frame.
1446 if (in_flight_write_->GetRemainingSize() == 0) { 1444 if (in_flight_write_->GetRemainingSize() == 0) {
1447 // It is possible that the stream was cancelled while we were 1445 // It is possible that the stream was cancelled while we were
1448 // writing to the socket. 1446 // writing to the socket.
1449 if (in_flight_write_stream_.get()) { 1447 if (in_flight_write_stream_.get()) {
1450 DCHECK_GT(in_flight_write_frame_size_, 0u); 1448 DCHECK_GT(in_flight_write_frame_size_, 0u);
1451 in_flight_write_stream_->OnFrameWriteComplete( 1449 in_flight_write_stream_->OnFrameWriteComplete(
1452 in_flight_write_frame_type_, 1450 in_flight_write_frame_type_, in_flight_write_frame_size_);
1453 in_flight_write_frame_size_);
1454 } 1451 }
1455 1452
1456 // Cleanup the write which just completed. 1453 // Cleanup the write which just completed.
1457 in_flight_write_.reset(); 1454 in_flight_write_.reset();
1458 in_flight_write_frame_type_ = DATA; 1455 in_flight_write_frame_type_ = DATA;
1459 in_flight_write_frame_size_ = 0; 1456 in_flight_write_frame_size_ = 0;
1460 in_flight_write_stream_.reset(); 1457 in_flight_write_stream_.reset();
1461 } 1458 }
1462 } 1459 }
1463 1460
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 1543
1547 if (availability_state_ == STATE_CLOSED) 1544 if (availability_state_ == STATE_CLOSED)
1548 return SESSION_ALREADY_CLOSED; 1545 return SESSION_ALREADY_CLOSED;
1549 1546
1550 net_log_.AddEvent( 1547 net_log_.AddEvent(
1551 NetLog::TYPE_SPDY_SESSION_CLOSE, 1548 NetLog::TYPE_SPDY_SESSION_CLOSE,
1552 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); 1549 base::Bind(&NetLogSpdySessionCloseCallback, err, &description));
1553 1550
1554 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err); 1551 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err);
1555 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors", 1552 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors",
1556 total_bytes_received_, 1, 100000000, 50); 1553 total_bytes_received_,
1554 1,
1555 100000000,
1556 50);
1557 1557
1558 CHECK(pool_); 1558 CHECK(pool_);
1559 if (availability_state_ != STATE_GOING_AWAY) 1559 if (availability_state_ != STATE_GOING_AWAY)
1560 pool_->MakeSessionUnavailable(GetWeakPtr()); 1560 pool_->MakeSessionUnavailable(GetWeakPtr());
1561 1561
1562 availability_state_ = STATE_CLOSED; 1562 availability_state_ = STATE_CLOSED;
1563 error_on_close_ = err; 1563 error_on_close_ = err;
1564 1564
1565 StartGoingAway(0, err); 1565 StartGoingAway(0, err);
1566 write_queue_.Clear(); 1566 write_queue_.Clear();
(...skipping 11 matching lines...) Expand all
1578 DcheckClosed(); 1578 DcheckClosed();
1579 CHECK(pool_); 1579 CHECK(pool_);
1580 1580
1581 SpdySessionPool* pool = pool_; 1581 SpdySessionPool* pool = pool_;
1582 pool_ = NULL; 1582 pool_ = NULL;
1583 pool->RemoveUnavailableSession(GetWeakPtr()); 1583 pool->RemoveUnavailableSession(GetWeakPtr());
1584 } 1584 }
1585 1585
1586 void SpdySession::LogAbandonedStream(SpdyStream* stream, Error status) { 1586 void SpdySession::LogAbandonedStream(SpdyStream* stream, Error status) {
1587 DCHECK(stream); 1587 DCHECK(stream);
1588 std::string description = base::StringPrintf( 1588 std::string description =
1589 "ABANDONED (stream_id=%d): ", stream->stream_id()) + 1589 base::StringPrintf("ABANDONED (stream_id=%d): ", stream->stream_id()) +
1590 stream->url().spec(); 1590 stream->url().spec();
1591 stream->LogStreamError(status, description); 1591 stream->LogStreamError(status, description);
1592 // We don't increment the streams abandoned counter here. If the 1592 // We don't increment the streams abandoned counter here. If the
1593 // stream isn't active (i.e., it hasn't written anything to the wire 1593 // stream isn't active (i.e., it hasn't written anything to the wire
1594 // yet) then it's as if it never existed. If it is active, then 1594 // yet) then it's as if it never existed. If it is active, then
1595 // LogAbandonedActiveStream() will increment the counters. 1595 // LogAbandonedActiveStream() will increment the counters.
1596 } 1596 }
1597 1597
1598 void SpdySession::LogAbandonedActiveStream(ActiveStreamMap::const_iterator it, 1598 void SpdySession::LogAbandonedActiveStream(ActiveStreamMap::const_iterator it,
1599 Error status) { 1599 Error status) {
1600 DCHECK_GT(it->first, 0u); 1600 DCHECK_GT(it->first, 0u);
1601 LogAbandonedStream(it->second.stream, status); 1601 LogAbandonedStream(it->second.stream, status);
1602 ++streams_abandoned_count_; 1602 ++streams_abandoned_count_;
1603 base::StatsCounter abandoned_streams("spdy.abandoned_streams"); 1603 base::StatsCounter abandoned_streams("spdy.abandoned_streams");
1604 abandoned_streams.Increment(); 1604 abandoned_streams.Increment();
1605 if (it->second.stream->type() == SPDY_PUSH_STREAM && 1605 if (it->second.stream->type() == SPDY_PUSH_STREAM &&
1606 unclaimed_pushed_streams_.find(it->second.stream->url()) != 1606 unclaimed_pushed_streams_.find(it->second.stream->url()) !=
1607 unclaimed_pushed_streams_.end()) { 1607 unclaimed_pushed_streams_.end()) {
1608 base::StatsCounter abandoned_push_streams("spdy.abandoned_push_streams"); 1608 base::StatsCounter abandoned_push_streams("spdy.abandoned_push_streams");
1609 abandoned_push_streams.Increment(); 1609 abandoned_push_streams.Increment();
1610 } 1610 }
1611 } 1611 }
1612 1612
1613 int SpdySession::GetNewStreamId() { 1613 int SpdySession::GetNewStreamId() {
1614 int id = stream_hi_water_mark_; 1614 int id = stream_hi_water_mark_;
1615 stream_hi_water_mark_ += 2; 1615 stream_hi_water_mark_ += 2;
1616 if (stream_hi_water_mark_ > 0x7fff) 1616 if (stream_hi_water_mark_ > 0x7fff)
1617 stream_hi_water_mark_ = 1; 1617 stream_hi_water_mark_ = 1;
(...skipping 16 matching lines...) Expand all
1634 } 1634 }
1635 1635
1636 base::Value* SpdySession::GetInfoAsValue() const { 1636 base::Value* SpdySession::GetInfoAsValue() const {
1637 base::DictionaryValue* dict = new base::DictionaryValue(); 1637 base::DictionaryValue* dict = new base::DictionaryValue();
1638 1638
1639 dict->SetInteger("source_id", net_log_.source().id); 1639 dict->SetInteger("source_id", net_log_.source().id);
1640 1640
1641 dict->SetString("host_port_pair", host_port_pair().ToString()); 1641 dict->SetString("host_port_pair", host_port_pair().ToString());
1642 if (!pooled_aliases_.empty()) { 1642 if (!pooled_aliases_.empty()) {
1643 base::ListValue* alias_list = new base::ListValue(); 1643 base::ListValue* alias_list = new base::ListValue();
1644 for (std::set<SpdySessionKey>::const_iterator it = 1644 for (std::set<SpdySessionKey>::const_iterator it = pooled_aliases_.begin();
1645 pooled_aliases_.begin(); 1645 it != pooled_aliases_.end();
1646 it != pooled_aliases_.end(); it++) { 1646 it++) {
1647 alias_list->Append(new base::StringValue( 1647 alias_list->Append(
1648 it->host_port_pair().ToString())); 1648 new base::StringValue(it->host_port_pair().ToString()));
1649 } 1649 }
1650 dict->Set("aliases", alias_list); 1650 dict->Set("aliases", alias_list);
1651 } 1651 }
1652 dict->SetString("proxy", host_port_proxy_pair().second.ToURI()); 1652 dict->SetString("proxy", host_port_proxy_pair().second.ToURI());
1653 1653
1654 dict->SetInteger("active_streams", active_streams_.size()); 1654 dict->SetInteger("active_streams", active_streams_.size());
1655 1655
1656 dict->SetInteger("unclaimed_pushed_streams", 1656 dict->SetInteger("unclaimed_pushed_streams",
1657 unclaimed_pushed_streams_.size()); 1657 unclaimed_pushed_streams_.size());
1658 1658
1659 dict->SetBoolean("is_secure", is_secure_); 1659 dict->SetBoolean("is_secure", is_secure_);
1660 1660
1661 dict->SetString("protocol_negotiated", 1661 dict->SetString("protocol_negotiated",
1662 SSLClientSocket::NextProtoToString( 1662 SSLClientSocket::NextProtoToString(
1663 connection_->socket()->GetNegotiatedProtocol())); 1663 connection_->socket()->GetNegotiatedProtocol()));
1664 1664
1665 dict->SetInteger("error", error_on_close_); 1665 dict->SetInteger("error", error_on_close_);
1666 dict->SetInteger("max_concurrent_streams", max_concurrent_streams_); 1666 dict->SetInteger("max_concurrent_streams", max_concurrent_streams_);
1667 1667
1668 dict->SetInteger("streams_initiated_count", streams_initiated_count_); 1668 dict->SetInteger("streams_initiated_count", streams_initiated_count_);
1669 dict->SetInteger("streams_pushed_count", streams_pushed_count_); 1669 dict->SetInteger("streams_pushed_count", streams_pushed_count_);
1670 dict->SetInteger("streams_pushed_and_claimed_count", 1670 dict->SetInteger("streams_pushed_and_claimed_count",
1671 streams_pushed_and_claimed_count_); 1671 streams_pushed_and_claimed_count_);
1672 dict->SetInteger("streams_abandoned_count", streams_abandoned_count_); 1672 dict->SetInteger("streams_abandoned_count", streams_abandoned_count_);
1673 DCHECK(buffered_spdy_framer_.get()); 1673 DCHECK(buffered_spdy_framer_.get());
1674 dict->SetInteger("frames_received", buffered_spdy_framer_->frames_received()); 1674 dict->SetInteger("frames_received", buffered_spdy_framer_->frames_received());
1675 1675
1676 dict->SetBoolean("sent_settings", sent_settings_); 1676 dict->SetBoolean("sent_settings", sent_settings_);
1677 dict->SetBoolean("received_settings", received_settings_); 1677 dict->SetBoolean("received_settings", received_settings_);
1678 1678
1679 dict->SetInteger("send_window_size", session_send_window_size_); 1679 dict->SetInteger("send_window_size", session_send_window_size_);
1680 dict->SetInteger("recv_window_size", session_recv_window_size_); 1680 dict->SetInteger("recv_window_size", session_recv_window_size_);
1681 dict->SetInteger("unacked_recv_window_bytes", 1681 dict->SetInteger("unacked_recv_window_bytes",
1682 session_unacked_recv_window_bytes_); 1682 session_unacked_recv_window_bytes_);
1683 return dict; 1683 return dict;
1684 } 1684 }
1685 1685
1686 bool SpdySession::IsReused() const { 1686 bool SpdySession::IsReused() const {
1687 return buffered_spdy_framer_->frames_received() > 0 || 1687 return buffered_spdy_framer_->frames_received() > 0 ||
1688 connection_->reuse_type() == ClientSocketHandle::UNUSED_IDLE; 1688 connection_->reuse_type() == ClientSocketHandle::UNUSED_IDLE;
1689 } 1689 }
1690 1690
1691 bool SpdySession::GetLoadTimingInfo(SpdyStreamId stream_id, 1691 bool SpdySession::GetLoadTimingInfo(SpdyStreamId stream_id,
1692 LoadTimingInfo* load_timing_info) const { 1692 LoadTimingInfo* load_timing_info) const {
1693 return connection_->GetLoadTimingInfo(stream_id != kFirstStreamId, 1693 return connection_->GetLoadTimingInfo(stream_id != kFirstStreamId,
1694 load_timing_info); 1694 load_timing_info);
1695 } 1695 }
1696 1696
1697 int SpdySession::GetPeerAddress(IPEndPoint* address) const { 1697 int SpdySession::GetPeerAddress(IPEndPoint* address) const {
1698 int rv = ERR_SOCKET_NOT_CONNECTED; 1698 int rv = ERR_SOCKET_NOT_CONNECTED;
(...skipping 15 matching lines...) Expand all
1714 1714
1715 UMA_HISTOGRAM_BOOLEAN("Net.SpdySessionSocketNotConnectedGetLocalAddress", 1715 UMA_HISTOGRAM_BOOLEAN("Net.SpdySessionSocketNotConnectedGetLocalAddress",
1716 rv == ERR_SOCKET_NOT_CONNECTED); 1716 rv == ERR_SOCKET_NOT_CONNECTED);
1717 1717
1718 return rv; 1718 return rv;
1719 } 1719 }
1720 1720
1721 void SpdySession::EnqueueSessionWrite(RequestPriority priority, 1721 void SpdySession::EnqueueSessionWrite(RequestPriority priority,
1722 SpdyFrameType frame_type, 1722 SpdyFrameType frame_type,
1723 scoped_ptr<SpdyFrame> frame) { 1723 scoped_ptr<SpdyFrame> frame) {
1724 DCHECK(frame_type == RST_STREAM || 1724 DCHECK(frame_type == RST_STREAM || frame_type == SETTINGS ||
1725 frame_type == SETTINGS || 1725 frame_type == WINDOW_UPDATE || frame_type == PING);
1726 frame_type == WINDOW_UPDATE || 1726 EnqueueWrite(priority,
1727 frame_type == PING); 1727 frame_type,
1728 EnqueueWrite( 1728 scoped_ptr<SpdyBufferProducer>(new SimpleBufferProducer(
1729 priority, frame_type, 1729 scoped_ptr<SpdyBuffer>(new SpdyBuffer(frame.Pass())))),
1730 scoped_ptr<SpdyBufferProducer>( 1730 base::WeakPtr<SpdyStream>());
1731 new SimpleBufferProducer(
1732 scoped_ptr<SpdyBuffer>(new SpdyBuffer(frame.Pass())))),
1733 base::WeakPtr<SpdyStream>());
1734 } 1731 }
1735 1732
1736 void SpdySession::EnqueueWrite(RequestPriority priority, 1733 void SpdySession::EnqueueWrite(RequestPriority priority,
1737 SpdyFrameType frame_type, 1734 SpdyFrameType frame_type,
1738 scoped_ptr<SpdyBufferProducer> producer, 1735 scoped_ptr<SpdyBufferProducer> producer,
1739 const base::WeakPtr<SpdyStream>& stream) { 1736 const base::WeakPtr<SpdyStream>& stream) {
1740 if (availability_state_ == STATE_CLOSED) 1737 if (availability_state_ == STATE_CLOSED)
1741 return; 1738 return;
1742 1739
1743 bool was_idle = write_queue_.IsEmpty(); 1740 bool was_idle = write_queue_.IsEmpty();
1744 write_queue_.Enqueue(priority, frame_type, producer.Pass(), stream); 1741 write_queue_.Enqueue(priority, frame_type, producer.Pass(), stream);
1745 if (write_state_ == WRITE_STATE_IDLE) { 1742 if (write_state_ == WRITE_STATE_IDLE) {
1746 DCHECK(was_idle); 1743 DCHECK(was_idle);
1747 DCHECK(!in_flight_write_); 1744 DCHECK(!in_flight_write_);
1748 write_state_ = WRITE_STATE_DO_WRITE; 1745 write_state_ = WRITE_STATE_DO_WRITE;
1749 base::MessageLoop::current()->PostTask( 1746 base::MessageLoop::current()->PostTask(
1750 FROM_HERE, 1747 FROM_HERE,
1751 base::Bind(&SpdySession::PumpWriteLoop, 1748 base::Bind(&SpdySession::PumpWriteLoop,
1752 weak_factory_.GetWeakPtr(), WRITE_STATE_DO_WRITE, OK)); 1749 weak_factory_.GetWeakPtr(),
1750 WRITE_STATE_DO_WRITE,
1751 OK));
1753 } 1752 }
1754 } 1753 }
1755 1754
1756 void SpdySession::InsertCreatedStream(scoped_ptr<SpdyStream> stream) { 1755 void SpdySession::InsertCreatedStream(scoped_ptr<SpdyStream> stream) {
1757 CHECK_EQ(stream->stream_id(), 0u); 1756 CHECK_EQ(stream->stream_id(), 0u);
1758 CHECK(created_streams_.find(stream.get()) == created_streams_.end()); 1757 CHECK(created_streams_.find(stream.get()) == created_streams_.end());
1759 created_streams_.insert(stream.release()); 1758 created_streams_.insert(stream.release());
1760 } 1759 }
1761 1760
1762 scoped_ptr<SpdyStream> SpdySession::ActivateCreatedStream(SpdyStream* stream) { 1761 scoped_ptr<SpdyStream> SpdySession::ActivateCreatedStream(SpdyStream* stream) {
1763 CHECK_EQ(stream->stream_id(), 0u); 1762 CHECK_EQ(stream->stream_id(), 0u);
1764 CHECK(created_streams_.find(stream) != created_streams_.end()); 1763 CHECK(created_streams_.find(stream) != created_streams_.end());
1765 stream->set_stream_id(GetNewStreamId()); 1764 stream->set_stream_id(GetNewStreamId());
1766 scoped_ptr<SpdyStream> owned_stream(stream); 1765 scoped_ptr<SpdyStream> owned_stream(stream);
1767 created_streams_.erase(stream); 1766 created_streams_.erase(stream);
1768 return owned_stream.Pass(); 1767 return owned_stream.Pass();
1769 } 1768 }
1770 1769
1771 void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) { 1770 void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) {
1772 SpdyStreamId stream_id = stream->stream_id(); 1771 SpdyStreamId stream_id = stream->stream_id();
1773 CHECK_NE(stream_id, 0u); 1772 CHECK_NE(stream_id, 0u);
1774 std::pair<ActiveStreamMap::iterator, bool> result = 1773 std::pair<ActiveStreamMap::iterator, bool> result = active_streams_.insert(
1775 active_streams_.insert( 1774 std::make_pair(stream_id, ActiveStreamInfo(stream.get())));
1776 std::make_pair(stream_id, ActiveStreamInfo(stream.get())));
1777 CHECK(result.second); 1775 CHECK(result.second);
1778 ignore_result(stream.release()); 1776 ignore_result(stream.release());
1779 } 1777 }
1780 1778
1781 void SpdySession::DeleteStream(scoped_ptr<SpdyStream> stream, int status) { 1779 void SpdySession::DeleteStream(scoped_ptr<SpdyStream> stream, int status) {
1782 if (in_flight_write_stream_.get() == stream.get()) { 1780 if (in_flight_write_stream_.get() == stream.get()) {
1783 // If we're deleting the stream for the in-flight write, we still 1781 // If we're deleting the stream for the in-flight write, we still
1784 // need to let the write complete, so we clear 1782 // need to let the write complete, so we clear
1785 // |in_flight_write_stream_| and let the write finish on its own 1783 // |in_flight_write_stream_| and let the write finish on its own
1786 // without notifying |in_flight_write_stream_|. 1784 // without notifying |in_flight_write_stream_|.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 } 1831 }
1834 1832
1835 bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, 1833 bool SpdySession::GetSSLInfo(SSLInfo* ssl_info,
1836 bool* was_npn_negotiated, 1834 bool* was_npn_negotiated,
1837 NextProto* protocol_negotiated) { 1835 NextProto* protocol_negotiated) {
1838 *was_npn_negotiated = connection_->socket()->WasNpnNegotiated(); 1836 *was_npn_negotiated = connection_->socket()->WasNpnNegotiated();
1839 *protocol_negotiated = connection_->socket()->GetNegotiatedProtocol(); 1837 *protocol_negotiated = connection_->socket()->GetNegotiatedProtocol();
1840 return connection_->socket()->GetSSLInfo(ssl_info); 1838 return connection_->socket()->GetSSLInfo(ssl_info);
1841 } 1839 }
1842 1840
1843 bool SpdySession::GetSSLCertRequestInfo( 1841 bool SpdySession::GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) {
1844 SSLCertRequestInfo* cert_request_info) {
1845 if (!is_secure_) 1842 if (!is_secure_)
1846 return false; 1843 return false;
1847 GetSSLClientSocket()->GetSSLCertRequestInfo(cert_request_info); 1844 GetSSLClientSocket()->GetSSLCertRequestInfo(cert_request_info);
1848 return true; 1845 return true;
1849 } 1846 }
1850 1847
1851 void SpdySession::OnError(SpdyFramer::SpdyError error_code) { 1848 void SpdySession::OnError(SpdyFramer::SpdyError error_code) {
1852 CHECK(in_io_loop_); 1849 CHECK(in_io_loop_);
1853 1850
1854 if (availability_state_ == STATE_CLOSED) 1851 if (availability_state_ == STATE_CLOSED)
1855 return; 1852 return;
1856 1853
1857 RecordProtocolErrorHistogram(MapFramerErrorToProtocolError(error_code)); 1854 RecordProtocolErrorHistogram(MapFramerErrorToProtocolError(error_code));
1858 std::string description = base::StringPrintf( 1855 std::string description =
1859 "SPDY_ERROR error_code: %d.", error_code); 1856 base::StringPrintf("SPDY_ERROR error_code: %d.", error_code);
1860 CloseSessionResult result = 1857 CloseSessionResult result =
1861 DoCloseSession(ERR_SPDY_PROTOCOL_ERROR, description); 1858 DoCloseSession(ERR_SPDY_PROTOCOL_ERROR, description);
1862 DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED); 1859 DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
1863 } 1860 }
1864 1861
1865 void SpdySession::OnStreamError(SpdyStreamId stream_id, 1862 void SpdySession::OnStreamError(SpdyStreamId stream_id,
1866 const std::string& description) { 1863 const std::string& description) {
1867 CHECK(in_io_loop_); 1864 CHECK(in_io_loop_);
1868 1865
1869 if (availability_state_ == STATE_CLOSED) 1866 if (availability_state_ == STATE_CLOSED)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 // inactive (since the other side has still reduced its session send 1929 // inactive (since the other side has still reduced its session send
1933 // window). 1930 // window).
1934 scoped_ptr<SpdyBuffer> buffer; 1931 scoped_ptr<SpdyBuffer> buffer;
1935 if (data) { 1932 if (data) {
1936 DCHECK_GT(len, 0u); 1933 DCHECK_GT(len, 0u);
1937 CHECK_LE(len, static_cast<size_t>(kReadBufferSize)); 1934 CHECK_LE(len, static_cast<size_t>(kReadBufferSize));
1938 buffer.reset(new SpdyBuffer(data, len)); 1935 buffer.reset(new SpdyBuffer(data, len));
1939 1936
1940 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { 1937 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
1941 DecreaseRecvWindowSize(static_cast<int32>(len)); 1938 DecreaseRecvWindowSize(static_cast<int32>(len));
1942 buffer->AddConsumeCallback( 1939 buffer->AddConsumeCallback(base::Bind(&SpdySession::OnReadBufferConsumed,
1943 base::Bind(&SpdySession::OnReadBufferConsumed, 1940 weak_factory_.GetWeakPtr()));
1944 weak_factory_.GetWeakPtr()));
1945 } 1941 }
1946 } else { 1942 } else {
1947 DCHECK_EQ(len, 0u); 1943 DCHECK_EQ(len, 0u);
1948 } 1944 }
1949 1945
1950 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 1946 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
1951 1947
1952 // By the time data comes in, the stream may already be inactive. 1948 // By the time data comes in, the stream may already be inactive.
1953 if (it == active_streams_.end()) 1949 if (it == active_streams_.end())
1954 return; 1950 return;
(...skipping 18 matching lines...) Expand all
1973 1969
1974 if (availability_state_ == STATE_CLOSED) 1970 if (availability_state_ == STATE_CLOSED)
1975 return; 1971 return;
1976 1972
1977 if (clear_persisted) 1973 if (clear_persisted)
1978 http_server_properties_->ClearSpdySettings(host_port_pair()); 1974 http_server_properties_->ClearSpdySettings(host_port_pair());
1979 1975
1980 if (net_log_.IsLogging()) { 1976 if (net_log_.IsLogging()) {
1981 net_log_.AddEvent( 1977 net_log_.AddEvent(
1982 NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS, 1978 NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS,
1983 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), 1979 base::Bind(
1984 clear_persisted)); 1980 &NetLogSpdySettingsCallback, host_port_pair(), clear_persisted));
1985 } 1981 }
1986 } 1982 }
1987 1983
1988 void SpdySession::OnSetting(SpdySettingsIds id, 1984 void SpdySession::OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
1989 uint8 flags,
1990 uint32 value) {
1991 CHECK(in_io_loop_); 1985 CHECK(in_io_loop_);
1992 1986
1993 if (availability_state_ == STATE_CLOSED) 1987 if (availability_state_ == STATE_CLOSED)
1994 return; 1988 return;
1995 1989
1996 HandleSetting(id, value); 1990 HandleSetting(id, value);
1997 http_server_properties_->SetSpdySetting( 1991 http_server_properties_->SetSpdySetting(
1998 host_port_pair(), 1992 host_port_pair(), id, static_cast<SpdySettingsFlags>(flags), value);
1999 id,
2000 static_cast<SpdySettingsFlags>(flags),
2001 value);
2002 received_settings_ = true; 1993 received_settings_ = true;
2003 1994
2004 // Log the setting. 1995 // Log the setting.
2005 net_log_.AddEvent( 1996 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_RECV_SETTING,
2006 NetLog::TYPE_SPDY_SESSION_RECV_SETTING, 1997 base::Bind(&NetLogSpdySettingCallback,
2007 base::Bind(&NetLogSpdySettingCallback, 1998 id,
2008 id, static_cast<SpdySettingsFlags>(flags), value)); 1999 static_cast<SpdySettingsFlags>(flags),
2000 value));
2009 } 2001 }
2010 2002
2011 void SpdySession::OnSendCompressedFrame( 2003 void SpdySession::OnSendCompressedFrame(SpdyStreamId stream_id,
2012 SpdyStreamId stream_id, 2004 SpdyFrameType type,
2013 SpdyFrameType type, 2005 size_t payload_len,
2014 size_t payload_len, 2006 size_t frame_len) {
2015 size_t frame_len) {
2016 if (type != SYN_STREAM) 2007 if (type != SYN_STREAM)
2017 return; 2008 return;
2018 2009
2019 DCHECK(buffered_spdy_framer_.get()); 2010 DCHECK(buffered_spdy_framer_.get());
2020 size_t compressed_len = 2011 size_t compressed_len =
2021 frame_len - buffered_spdy_framer_->GetSynStreamMinimumSize(); 2012 frame_len - buffered_spdy_framer_->GetSynStreamMinimumSize();
2022 2013
2023 if (payload_len) { 2014 if (payload_len) {
2024 // Make sure we avoid early decimal truncation. 2015 // Make sure we avoid early decimal truncation.
2025 int compression_pct = 100 - (100 * compressed_len) / payload_len; 2016 int compression_pct = 100 - (100 * compressed_len) / payload_len;
2026 UMA_HISTOGRAM_PERCENTAGE("Net.SpdySynStreamCompressionPercentage", 2017 UMA_HISTOGRAM_PERCENTAGE("Net.SpdySynStreamCompressionPercentage",
2027 compression_pct); 2018 compression_pct);
2028 } 2019 }
2029 } 2020 }
2030 2021
2031 void SpdySession::OnReceiveCompressedFrame( 2022 void SpdySession::OnReceiveCompressedFrame(SpdyStreamId stream_id,
2032 SpdyStreamId stream_id, 2023 SpdyFrameType type,
2033 SpdyFrameType type, 2024 size_t frame_len) {
2034 size_t frame_len) {
2035 last_compressed_frame_len_ = frame_len; 2025 last_compressed_frame_len_ = frame_len;
2036 } 2026 }
2037 2027
2038 int SpdySession::OnInitialResponseHeadersReceived( 2028 int SpdySession::OnInitialResponseHeadersReceived(
2039 const SpdyHeaderBlock& response_headers, 2029 const SpdyHeaderBlock& response_headers,
2040 base::Time response_time, 2030 base::Time response_time,
2041 base::TimeTicks recv_first_byte_time, 2031 base::TimeTicks recv_first_byte_time,
2042 SpdyStream* stream) { 2032 SpdyStream* stream) {
2043 CHECK(in_io_loop_); 2033 CHECK(in_io_loop_);
2044 SpdyStreamId stream_id = stream->stream_id(); 2034 SpdyStreamId stream_id = stream->stream_id();
(...skipping 15 matching lines...) Expand all
2060 const SpdyHeaderBlock& headers) { 2050 const SpdyHeaderBlock& headers) {
2061 CHECK(in_io_loop_); 2051 CHECK(in_io_loop_);
2062 2052
2063 if (availability_state_ == STATE_CLOSED) 2053 if (availability_state_ == STATE_CLOSED)
2064 return; 2054 return;
2065 2055
2066 base::Time response_time = base::Time::Now(); 2056 base::Time response_time = base::Time::Now();
2067 base::TimeTicks recv_first_byte_time = time_func_(); 2057 base::TimeTicks recv_first_byte_time = time_func_();
2068 2058
2069 if (net_log_.IsLogging()) { 2059 if (net_log_.IsLogging()) {
2070 net_log_.AddEvent( 2060 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM,
2071 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, 2061 base::Bind(&NetLogSpdySynStreamReceivedCallback,
2072 base::Bind(&NetLogSpdySynStreamReceivedCallback, 2062 &headers,
2073 &headers, fin, unidirectional, priority, 2063 fin,
2074 stream_id, associated_stream_id)); 2064 unidirectional,
2065 priority,
2066 stream_id,
2067 associated_stream_id));
2075 } 2068 }
2076 2069
2077 // Server-initiated streams should have even sequence numbers. 2070 // Server-initiated streams should have even sequence numbers.
2078 if ((stream_id & 0x1) != 0) { 2071 if ((stream_id & 0x1) != 0) {
2079 LOG(WARNING) << "Received invalid OnSyn stream id " << stream_id; 2072 LOG(WARNING) << "Received invalid OnSyn stream id " << stream_id;
2080 return; 2073 return;
2081 } 2074 }
2082 2075
2083 if (IsStreamActive(stream_id)) { 2076 if (IsStreamActive(stream_id)) {
2084 LOG(WARNING) << "Received OnSyn for active stream " << stream_id; 2077 LOG(WARNING) << "Received OnSyn for active stream " << stream_id;
2085 return; 2078 return;
2086 } 2079 }
2087 2080
2088 RequestPriority request_priority = 2081 RequestPriority request_priority =
2089 ConvertSpdyPriorityToRequestPriority(priority, GetProtocolVersion()); 2082 ConvertSpdyPriorityToRequestPriority(priority, GetProtocolVersion());
2090 2083
2091 if (availability_state_ == STATE_GOING_AWAY) { 2084 if (availability_state_ == STATE_GOING_AWAY) {
2092 // TODO(akalin): This behavior isn't in the SPDY spec, although it 2085 // TODO(akalin): This behavior isn't in the SPDY spec, although it
2093 // probably should be. 2086 // probably should be.
2094 EnqueueResetStreamFrame(stream_id, request_priority, 2087 EnqueueResetStreamFrame(stream_id,
2088 request_priority,
2095 RST_STREAM_REFUSED_STREAM, 2089 RST_STREAM_REFUSED_STREAM,
2096 "OnSyn received when going away"); 2090 "OnSyn received when going away");
2097 return; 2091 return;
2098 } 2092 }
2099 2093
2100 // TODO(jgraettinger): SpdyFramer simulates OnSynStream() from HEADERS 2094 // TODO(jgraettinger): SpdyFramer simulates OnSynStream() from HEADERS
2101 // frames, which don't convey associated stream ID. Disable this check 2095 // frames, which don't convey associated stream ID. Disable this check
2102 // for now, and re-enable when PUSH_PROMISE is implemented properly. 2096 // for now, and re-enable when PUSH_PROMISE is implemented properly.
2103 if (associated_stream_id == 0 && GetProtocolVersion() < SPDY4) { 2097 if (associated_stream_id == 0 && GetProtocolVersion() < SPDY4) {
2104 std::string description = base::StringPrintf( 2098 std::string description = base::StringPrintf(
2105 "Received invalid OnSyn associated stream id %d for stream %d", 2099 "Received invalid OnSyn associated stream id %d for stream %d",
2106 associated_stream_id, stream_id); 2100 associated_stream_id,
2107 EnqueueResetStreamFrame(stream_id, request_priority, 2101 stream_id);
2108 RST_STREAM_REFUSED_STREAM, description); 2102 EnqueueResetStreamFrame(
2103 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, description);
2109 return; 2104 return;
2110 } 2105 }
2111 2106
2112 streams_pushed_count_++; 2107 streams_pushed_count_++;
2113 2108
2114 // TODO(mbelshe): DCHECK that this is a GET method? 2109 // TODO(mbelshe): DCHECK that this is a GET method?
2115 2110
2116 // Verify that the response had a URL for us. 2111 // Verify that the response had a URL for us.
2117 GURL gurl = GetUrlFromHeaderBlock(headers, GetProtocolVersion(), true); 2112 GURL gurl = GetUrlFromHeaderBlock(headers, GetProtocolVersion(), true);
2118 if (!gurl.is_valid()) { 2113 if (!gurl.is_valid()) {
2119 EnqueueResetStreamFrame( 2114 EnqueueResetStreamFrame(stream_id,
2120 stream_id, request_priority, RST_STREAM_PROTOCOL_ERROR, 2115 request_priority,
2121 "Pushed stream url was invalid: " + gurl.spec()); 2116 RST_STREAM_PROTOCOL_ERROR,
2117 "Pushed stream url was invalid: " + gurl.spec());
2122 return; 2118 return;
2123 } 2119 }
2124 2120
2125 // Verify we have a valid stream association. 2121 // Verify we have a valid stream association.
2126 ActiveStreamMap::iterator associated_it = 2122 ActiveStreamMap::iterator associated_it =
2127 active_streams_.find(associated_stream_id); 2123 active_streams_.find(associated_stream_id);
2128 // TODO(jgraettinger): (See PUSH_PROMISE comment above). 2124 // TODO(jgraettinger): (See PUSH_PROMISE comment above).
2129 if (GetProtocolVersion() < SPDY4 && associated_it == active_streams_.end()) { 2125 if (GetProtocolVersion() < SPDY4 && associated_it == active_streams_.end()) {
2130 EnqueueResetStreamFrame( 2126 EnqueueResetStreamFrame(
2131 stream_id, request_priority, RST_STREAM_INVALID_STREAM, 2127 stream_id,
2132 base::StringPrintf( 2128 request_priority,
2133 "Received OnSyn with inactive associated stream %d", 2129 RST_STREAM_INVALID_STREAM,
2134 associated_stream_id)); 2130 base::StringPrintf("Received OnSyn with inactive associated stream %d",
2131 associated_stream_id));
2135 return; 2132 return;
2136 } 2133 }
2137 2134
2138 // Check that the SYN advertises the same origin as its associated stream. 2135 // Check that the SYN advertises the same origin as its associated stream.
2139 // Bypass this check if and only if this session is with a SPDY proxy that 2136 // Bypass this check if and only if this session is with a SPDY proxy that
2140 // is trusted explicitly via the --trusted-spdy-proxy switch. 2137 // is trusted explicitly via the --trusted-spdy-proxy switch.
2141 if (trusted_spdy_proxy_.Equals(host_port_pair())) { 2138 if (trusted_spdy_proxy_.Equals(host_port_pair())) {
2142 // Disallow pushing of HTTPS content. 2139 // Disallow pushing of HTTPS content.
2143 if (gurl.SchemeIs("https")) { 2140 if (gurl.SchemeIs("https")) {
2144 EnqueueResetStreamFrame( 2141 EnqueueResetStreamFrame(
2145 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, 2142 stream_id,
2146 base::StringPrintf( 2143 request_priority,
2147 "Rejected push of Cross Origin HTTPS content %d", 2144 RST_STREAM_REFUSED_STREAM,
2148 associated_stream_id)); 2145 base::StringPrintf("Rejected push of Cross Origin HTTPS content %d",
2146 associated_stream_id));
2149 } 2147 }
2150 } else if (GetProtocolVersion() < SPDY4) { 2148 } else if (GetProtocolVersion() < SPDY4) {
2151 // TODO(jgraettinger): (See PUSH_PROMISE comment above). 2149 // TODO(jgraettinger): (See PUSH_PROMISE comment above).
2152 GURL associated_url(associated_it->second.stream->GetUrlFromHeaders()); 2150 GURL associated_url(associated_it->second.stream->GetUrlFromHeaders());
2153 if (associated_url.GetOrigin() != gurl.GetOrigin()) { 2151 if (associated_url.GetOrigin() != gurl.GetOrigin()) {
2154 EnqueueResetStreamFrame( 2152 EnqueueResetStreamFrame(
2155 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, 2153 stream_id,
2156 base::StringPrintf( 2154 request_priority,
2157 "Rejected Cross Origin Push Stream %d", 2155 RST_STREAM_REFUSED_STREAM,
2158 associated_stream_id)); 2156 base::StringPrintf("Rejected Cross Origin Push Stream %d",
2157 associated_stream_id));
2159 return; 2158 return;
2160 } 2159 }
2161 } 2160 }
2162 2161
2163 // There should not be an existing pushed stream with the same path. 2162 // There should not be an existing pushed stream with the same path.
2164 PushedStreamMap::iterator pushed_it = 2163 PushedStreamMap::iterator pushed_it =
2165 unclaimed_pushed_streams_.lower_bound(gurl); 2164 unclaimed_pushed_streams_.lower_bound(gurl);
2166 if (pushed_it != unclaimed_pushed_streams_.end() && 2165 if (pushed_it != unclaimed_pushed_streams_.end() &&
2167 pushed_it->first == gurl) { 2166 pushed_it->first == gurl) {
2168 EnqueueResetStreamFrame( 2167 EnqueueResetStreamFrame(
2169 stream_id, request_priority, RST_STREAM_PROTOCOL_ERROR, 2168 stream_id,
2170 "Received duplicate pushed stream with url: " + 2169 request_priority,
2171 gurl.spec()); 2170 RST_STREAM_PROTOCOL_ERROR,
2171 "Received duplicate pushed stream with url: " + gurl.spec());
2172 return; 2172 return;
2173 } 2173 }
2174 2174
2175 scoped_ptr<SpdyStream> stream( 2175 scoped_ptr<SpdyStream> stream(new SpdyStream(SPDY_PUSH_STREAM,
2176 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, 2176 GetWeakPtr(),
2177 request_priority, 2177 gurl,
2178 stream_initial_send_window_size_, 2178 request_priority,
2179 stream_initial_recv_window_size_, 2179 stream_initial_send_window_size_,
2180 net_log_)); 2180 stream_initial_recv_window_size_,
2181 net_log_));
2181 stream->set_stream_id(stream_id); 2182 stream->set_stream_id(stream_id);
2182 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); 2183 stream->IncrementRawReceivedBytes(last_compressed_frame_len_);
2183 last_compressed_frame_len_ = 0; 2184 last_compressed_frame_len_ = 0;
2184 2185
2185 DeleteExpiredPushedStreams(); 2186 DeleteExpiredPushedStreams();
2186 PushedStreamMap::iterator inserted_pushed_it = 2187 PushedStreamMap::iterator inserted_pushed_it =
2187 unclaimed_pushed_streams_.insert( 2188 unclaimed_pushed_streams_.insert(
2188 pushed_it, 2189 pushed_it,
2189 std::make_pair(gurl, PushedStreamInfo(stream_id, time_func_()))); 2190 std::make_pair(gurl, PushedStreamInfo(stream_id, time_func_())));
2190 DCHECK(inserted_pushed_it != pushed_it); 2191 DCHECK(inserted_pushed_it != pushed_it);
2191 2192
2192 InsertActivatedStream(stream.Pass()); 2193 InsertActivatedStream(stream.Pass());
2193 2194
2194 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id); 2195 ActiveStreamMap::iterator active_it = active_streams_.find(stream_id);
2195 if (active_it == active_streams_.end()) { 2196 if (active_it == active_streams_.end()) {
2196 NOTREACHED(); 2197 NOTREACHED();
2197 return; 2198 return;
2198 } 2199 }
2199 2200
2200 // Parse the headers. 2201 // Parse the headers.
2201 if (OnInitialResponseHeadersReceived( 2202 if (OnInitialResponseHeadersReceived(headers,
2202 headers, response_time, 2203 response_time,
2203 recv_first_byte_time, active_it->second.stream) != OK) 2204 recv_first_byte_time,
2205 active_it->second.stream) != OK)
2204 return; 2206 return;
2205 2207
2206 base::StatsCounter push_requests("spdy.pushed_streams"); 2208 base::StatsCounter push_requests("spdy.pushed_streams");
2207 push_requests.Increment(); 2209 push_requests.Increment();
2208 } 2210 }
2209 2211
2210 void SpdySession::DeleteExpiredPushedStreams() { 2212 void SpdySession::DeleteExpiredPushedStreams() {
2211 if (unclaimed_pushed_streams_.empty()) 2213 if (unclaimed_pushed_streams_.empty())
2212 return; 2214 return;
2213 2215
2214 // Check that adequate time has elapsed since the last sweep. 2216 // Check that adequate time has elapsed since the last sweep.
2215 if (time_func_() < next_unclaimed_push_stream_sweep_time_) 2217 if (time_func_() < next_unclaimed_push_stream_sweep_time_)
2216 return; 2218 return;
2217 2219
2218 // Gather old streams to delete. 2220 // Gather old streams to delete.
2219 base::TimeTicks minimum_freshness = time_func_() - 2221 base::TimeTicks minimum_freshness =
2222 time_func_() -
2220 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); 2223 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
2221 std::vector<SpdyStreamId> streams_to_close; 2224 std::vector<SpdyStreamId> streams_to_close;
2222 for (PushedStreamMap::iterator it = unclaimed_pushed_streams_.begin(); 2225 for (PushedStreamMap::iterator it = unclaimed_pushed_streams_.begin();
2223 it != unclaimed_pushed_streams_.end(); ++it) { 2226 it != unclaimed_pushed_streams_.end();
2227 ++it) {
2224 if (minimum_freshness > it->second.creation_time) 2228 if (minimum_freshness > it->second.creation_time)
2225 streams_to_close.push_back(it->second.stream_id); 2229 streams_to_close.push_back(it->second.stream_id);
2226 } 2230 }
2227 2231
2228 for (std::vector<SpdyStreamId>::const_iterator to_close_it = 2232 for (std::vector<SpdyStreamId>::const_iterator to_close_it =
2229 streams_to_close.begin(); 2233 streams_to_close.begin();
2230 to_close_it != streams_to_close.end(); ++to_close_it) { 2234 to_close_it != streams_to_close.end();
2235 ++to_close_it) {
2231 ActiveStreamMap::iterator active_it = active_streams_.find(*to_close_it); 2236 ActiveStreamMap::iterator active_it = active_streams_.find(*to_close_it);
2232 if (active_it == active_streams_.end()) 2237 if (active_it == active_streams_.end())
2233 continue; 2238 continue;
2234 2239
2235 LogAbandonedActiveStream(active_it, ERR_INVALID_SPDY_STREAM); 2240 LogAbandonedActiveStream(active_it, ERR_INVALID_SPDY_STREAM);
2236 // CloseActiveStreamIterator() will remove the stream from 2241 // CloseActiveStreamIterator() will remove the stream from
2237 // |unclaimed_pushed_streams_|. 2242 // |unclaimed_pushed_streams_|.
2238 ResetStreamIterator( 2243 ResetStreamIterator(
2239 active_it, RST_STREAM_REFUSED_STREAM, "Stream not claimed."); 2244 active_it, RST_STREAM_REFUSED_STREAM, "Stream not claimed.");
2240 } 2245 }
2241 2246
2242 next_unclaimed_push_stream_sweep_time_ = time_func_() + 2247 next_unclaimed_push_stream_sweep_time_ =
2248 time_func_() +
2243 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); 2249 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
2244 } 2250 }
2245 2251
2246 void SpdySession::OnSynReply(SpdyStreamId stream_id, 2252 void SpdySession::OnSynReply(SpdyStreamId stream_id,
2247 bool fin, 2253 bool fin,
2248 const SpdyHeaderBlock& headers) { 2254 const SpdyHeaderBlock& headers) {
2249 CHECK(in_io_loop_); 2255 CHECK(in_io_loop_);
2250 2256
2251 if (availability_state_ == STATE_CLOSED) 2257 if (availability_state_ == STATE_CLOSED)
2252 return; 2258 return;
2253 2259
2254 base::Time response_time = base::Time::Now(); 2260 base::Time response_time = base::Time::Now();
2255 base::TimeTicks recv_first_byte_time = time_func_(); 2261 base::TimeTicks recv_first_byte_time = time_func_();
2256 2262
2257 if (net_log().IsLogging()) { 2263 if (net_log().IsLogging()) {
2258 net_log().AddEvent( 2264 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_SYN_REPLY,
2259 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, 2265 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback,
2260 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, 2266 &headers,
2261 &headers, fin, stream_id)); 2267 fin,
2268 stream_id));
2262 } 2269 }
2263 2270
2264 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 2271 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
2265 if (it == active_streams_.end()) { 2272 if (it == active_streams_.end()) {
2266 // NOTE: it may just be that the stream was cancelled. 2273 // NOTE: it may just be that the stream was cancelled.
2267 return; 2274 return;
2268 } 2275 }
2269 2276
2270 SpdyStream* stream = it->second.stream; 2277 SpdyStream* stream = it->second.stream;
2271 CHECK_EQ(stream->stream_id(), stream_id); 2278 CHECK_EQ(stream->stream_id(), stream_id);
2272 2279
2273 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); 2280 stream->IncrementRawReceivedBytes(last_compressed_frame_len_);
2274 last_compressed_frame_len_ = 0; 2281 last_compressed_frame_len_ = 0;
2275 2282
2276 if (GetProtocolVersion() >= SPDY4) { 2283 if (GetProtocolVersion() >= SPDY4) {
2277 const std::string& error = 2284 const std::string& error = "SPDY4 wasn't expecting SYN_REPLY.";
2278 "SPDY4 wasn't expecting SYN_REPLY.";
2279 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); 2285 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
2280 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); 2286 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error);
2281 return; 2287 return;
2282 } 2288 }
2283 if (!it->second.waiting_for_syn_reply) { 2289 if (!it->second.waiting_for_syn_reply) {
2284 const std::string& error = 2290 const std::string& error = "Received duplicate SYN_REPLY for stream.";
2285 "Received duplicate SYN_REPLY for stream.";
2286 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); 2291 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
2287 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); 2292 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error);
2288 return; 2293 return;
2289 } 2294 }
2290 it->second.waiting_for_syn_reply = false; 2295 it->second.waiting_for_syn_reply = false;
2291 2296
2292 ignore_result(OnInitialResponseHeadersReceived( 2297 ignore_result(OnInitialResponseHeadersReceived(
2293 headers, response_time, recv_first_byte_time, stream)); 2298 headers, response_time, recv_first_byte_time, stream));
2294 } 2299 }
2295 2300
2296 void SpdySession::OnHeaders(SpdyStreamId stream_id, 2301 void SpdySession::OnHeaders(SpdyStreamId stream_id,
2297 bool fin, 2302 bool fin,
2298 const SpdyHeaderBlock& headers) { 2303 const SpdyHeaderBlock& headers) {
2299 CHECK(in_io_loop_); 2304 CHECK(in_io_loop_);
2300 2305
2301 if (availability_state_ == STATE_CLOSED) 2306 if (availability_state_ == STATE_CLOSED)
2302 return; 2307 return;
2303 2308
2304 if (net_log().IsLogging()) { 2309 if (net_log().IsLogging()) {
2305 net_log().AddEvent( 2310 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_RECV_HEADERS,
2306 NetLog::TYPE_SPDY_SESSION_RECV_HEADERS, 2311 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback,
2307 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, 2312 &headers,
2308 &headers, fin, stream_id)); 2313 fin,
2314 stream_id));
2309 } 2315 }
2310 2316
2311 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 2317 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
2312 if (it == active_streams_.end()) { 2318 if (it == active_streams_.end()) {
2313 // NOTE: it may just be that the stream was cancelled. 2319 // NOTE: it may just be that the stream was cancelled.
2314 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; 2320 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id;
2315 return; 2321 return;
2316 } 2322 }
2317 2323
2318 SpdyStream* stream = it->second.stream; 2324 SpdyStream* stream = it->second.stream;
2319 CHECK_EQ(stream->stream_id(), stream_id); 2325 CHECK_EQ(stream->stream_id(), stream_id);
2320 2326
2321 stream->IncrementRawReceivedBytes(last_compressed_frame_len_); 2327 stream->IncrementRawReceivedBytes(last_compressed_frame_len_);
2322 last_compressed_frame_len_ = 0; 2328 last_compressed_frame_len_ = 0;
2323 2329
2324 if (it->second.waiting_for_syn_reply) { 2330 if (it->second.waiting_for_syn_reply) {
2325 if (GetProtocolVersion() < SPDY4) { 2331 if (GetProtocolVersion() < SPDY4) {
2326 const std::string& error = 2332 const std::string& error = "Was expecting SYN_REPLY, not HEADERS.";
2327 "Was expecting SYN_REPLY, not HEADERS.";
2328 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); 2333 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error);
2329 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); 2334 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error);
2330 return; 2335 return;
2331 } 2336 }
2332 base::Time response_time = base::Time::Now(); 2337 base::Time response_time = base::Time::Now();
2333 base::TimeTicks recv_first_byte_time = time_func_(); 2338 base::TimeTicks recv_first_byte_time = time_func_();
2334 2339
2335 it->second.waiting_for_syn_reply = false; 2340 it->second.waiting_for_syn_reply = false;
2336 ignore_result(OnInitialResponseHeadersReceived( 2341 ignore_result(OnInitialResponseHeadersReceived(
2337 headers, response_time, recv_first_byte_time, stream)); 2342 headers, response_time, recv_first_byte_time, stream));
2338 } else { 2343 } else {
2339 int rv = stream->OnAdditionalResponseHeadersReceived(headers); 2344 int rv = stream->OnAdditionalResponseHeadersReceived(headers);
2340 if (rv < 0) { 2345 if (rv < 0) {
2341 DCHECK_NE(rv, ERR_IO_PENDING); 2346 DCHECK_NE(rv, ERR_IO_PENDING);
2342 DCHECK(active_streams_.find(stream_id) == active_streams_.end()); 2347 DCHECK(active_streams_.find(stream_id) == active_streams_.end());
2343 } 2348 }
2344 } 2349 }
2345 } 2350 }
2346 2351
2347 void SpdySession::OnRstStream(SpdyStreamId stream_id, 2352 void SpdySession::OnRstStream(SpdyStreamId stream_id,
2348 SpdyRstStreamStatus status) { 2353 SpdyRstStreamStatus status) {
2349 CHECK(in_io_loop_); 2354 CHECK(in_io_loop_);
2350 2355
2351 if (availability_state_ == STATE_CLOSED) 2356 if (availability_state_ == STATE_CLOSED)
2352 return; 2357 return;
2353 2358
2354 std::string description; 2359 std::string description;
2355 net_log().AddEvent( 2360 net_log().AddEvent(
2356 NetLog::TYPE_SPDY_SESSION_RST_STREAM, 2361 NetLog::TYPE_SPDY_SESSION_RST_STREAM,
2357 base::Bind(&NetLogSpdyRstCallback, 2362 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description));
2358 stream_id, status, &description));
2359 2363
2360 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 2364 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
2361 if (it == active_streams_.end()) { 2365 if (it == active_streams_.end()) {
2362 // NOTE: it may just be that the stream was cancelled. 2366 // NOTE: it may just be that the stream was cancelled.
2363 LOG(WARNING) << "Received RST for invalid stream" << stream_id; 2367 LOG(WARNING) << "Received RST for invalid stream" << stream_id;
2364 return; 2368 return;
2365 } 2369 }
2366 2370
2367 CHECK_EQ(it->second.stream->stream_id(), stream_id); 2371 CHECK_EQ(it->second.stream->stream_id(), stream_id);
2368 2372
(...skipping 14 matching lines...) Expand all
2383 } 2387 }
2384 2388
2385 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, 2389 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id,
2386 SpdyGoAwayStatus status) { 2390 SpdyGoAwayStatus status) {
2387 CHECK(in_io_loop_); 2391 CHECK(in_io_loop_);
2388 2392
2389 if (availability_state_ == STATE_CLOSED) 2393 if (availability_state_ == STATE_CLOSED)
2390 return; 2394 return;
2391 2395
2392 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_GOAWAY, 2396 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_GOAWAY,
2393 base::Bind(&NetLogSpdyGoAwayCallback, 2397 base::Bind(&NetLogSpdyGoAwayCallback,
2394 last_accepted_stream_id, 2398 last_accepted_stream_id,
2395 active_streams_.size(), 2399 active_streams_.size(),
2396 unclaimed_pushed_streams_.size(), 2400 unclaimed_pushed_streams_.size(),
2397 status)); 2401 status));
2398 MakeUnavailable(); 2402 MakeUnavailable();
2399 StartGoingAway(last_accepted_stream_id, ERR_ABORTED); 2403 StartGoingAway(last_accepted_stream_id, ERR_ABORTED);
2400 // This is to handle the case when we already don't have any active 2404 // This is to handle the case when we already don't have any active
2401 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have 2405 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have
2402 // active streams and so the last one being closed will finish the 2406 // active streams and so the last one being closed will finish the
2403 // going away process (see DeleteStream()). 2407 // going away process (see DeleteStream()).
2404 MaybeFinishGoingAway(); 2408 MaybeFinishGoingAway();
2405 } 2409 }
2406 2410
2407 void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) { 2411 void SpdySession::OnPing(SpdyPingId unique_id, bool is_ack) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 void SpdySession::OnWindowUpdate(SpdyStreamId stream_id, 2446 void SpdySession::OnWindowUpdate(SpdyStreamId stream_id,
2443 uint32 delta_window_size) { 2447 uint32 delta_window_size) {
2444 CHECK(in_io_loop_); 2448 CHECK(in_io_loop_);
2445 2449
2446 if (availability_state_ == STATE_CLOSED) 2450 if (availability_state_ == STATE_CLOSED)
2447 return; 2451 return;
2448 2452
2449 DCHECK_LE(delta_window_size, static_cast<uint32>(kint32max)); 2453 DCHECK_LE(delta_window_size, static_cast<uint32>(kint32max));
2450 net_log_.AddEvent( 2454 net_log_.AddEvent(
2451 NetLog::TYPE_SPDY_SESSION_RECEIVED_WINDOW_UPDATE_FRAME, 2455 NetLog::TYPE_SPDY_SESSION_RECEIVED_WINDOW_UPDATE_FRAME,
2452 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, 2456 base::Bind(
2453 stream_id, delta_window_size)); 2457 &NetLogSpdyWindowUpdateFrameCallback, stream_id, delta_window_size));
2454 2458
2455 if (stream_id == kSessionFlowControlStreamId) { 2459 if (stream_id == kSessionFlowControlStreamId) {
2456 // WINDOW_UPDATE for the session. 2460 // WINDOW_UPDATE for the session.
2457 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) { 2461 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) {
2458 LOG(WARNING) << "Received WINDOW_UPDATE for session when " 2462 LOG(WARNING) << "Received WINDOW_UPDATE for session when "
2459 << "session flow control is not turned on"; 2463 << "session flow control is not turned on";
2460 // TODO(akalin): Record an error and close the session. 2464 // TODO(akalin): Record an error and close the session.
2461 return; 2465 return;
2462 } 2466 }
2463 2467
2464 if (delta_window_size < 1u) { 2468 if (delta_window_size < 1u) {
2465 RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE); 2469 RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE);
2466 CloseSessionResult result = DoCloseSession( 2470 CloseSessionResult result = DoCloseSession(
2467 ERR_SPDY_PROTOCOL_ERROR, 2471 ERR_SPDY_PROTOCOL_ERROR,
2468 "Received WINDOW_UPDATE with an invalid delta_window_size " + 2472 "Received WINDOW_UPDATE with an invalid delta_window_size " +
2469 base::UintToString(delta_window_size)); 2473 base::UintToString(delta_window_size));
2470 DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED); 2474 DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
2471 return; 2475 return;
2472 } 2476 }
2473 2477
2474 IncreaseSendWindowSize(static_cast<int32>(delta_window_size)); 2478 IncreaseSendWindowSize(static_cast<int32>(delta_window_size));
2475 } else { 2479 } else {
2476 // WINDOW_UPDATE for a stream. 2480 // WINDOW_UPDATE for a stream.
2477 if (flow_control_state_ < FLOW_CONTROL_STREAM) { 2481 if (flow_control_state_ < FLOW_CONTROL_STREAM) {
2478 // TODO(akalin): Record an error and close the session. 2482 // TODO(akalin): Record an error and close the session.
2479 LOG(WARNING) << "Received WINDOW_UPDATE for stream " << stream_id 2483 LOG(WARNING) << "Received WINDOW_UPDATE for stream " << stream_id
(...skipping 10 matching lines...) Expand all
2490 } 2494 }
2491 2495
2492 SpdyStream* stream = it->second.stream; 2496 SpdyStream* stream = it->second.stream;
2493 CHECK_EQ(stream->stream_id(), stream_id); 2497 CHECK_EQ(stream->stream_id(), stream_id);
2494 2498
2495 if (delta_window_size < 1u) { 2499 if (delta_window_size < 1u) {
2496 ResetStreamIterator(it, 2500 ResetStreamIterator(it,
2497 RST_STREAM_FLOW_CONTROL_ERROR, 2501 RST_STREAM_FLOW_CONTROL_ERROR,
2498 base::StringPrintf( 2502 base::StringPrintf(
2499 "Received WINDOW_UPDATE with an invalid " 2503 "Received WINDOW_UPDATE with an invalid "
2500 "delta_window_size %ud", delta_window_size)); 2504 "delta_window_size %ud",
2505 delta_window_size));
2501 return; 2506 return;
2502 } 2507 }
2503 2508
2504 CHECK_EQ(it->second.stream->stream_id(), stream_id); 2509 CHECK_EQ(it->second.stream->stream_id(), stream_id);
2505 it->second.stream->IncreaseSendWindowSize( 2510 it->second.stream->IncreaseSendWindowSize(
2506 static_cast<int32>(delta_window_size)); 2511 static_cast<int32>(delta_window_size));
2507 } 2512 }
2508 } 2513 }
2509 2514
2510 void SpdySession::OnPushPromise(SpdyStreamId stream_id, 2515 void SpdySession::OnPushPromise(SpdyStreamId stream_id,
(...skipping 15 matching lines...) Expand all
2526 DCHECK(enable_sending_initial_data_); 2531 DCHECK(enable_sending_initial_data_);
2527 DCHECK_NE(availability_state_, STATE_CLOSED); 2532 DCHECK_NE(availability_state_, STATE_CLOSED);
2528 2533
2529 if (send_connection_header_prefix_) { 2534 if (send_connection_header_prefix_) {
2530 DCHECK_EQ(protocol_, kProtoSPDY4); 2535 DCHECK_EQ(protocol_, kProtoSPDY4);
2531 scoped_ptr<SpdyFrame> connection_header_prefix_frame( 2536 scoped_ptr<SpdyFrame> connection_header_prefix_frame(
2532 new SpdyFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix), 2537 new SpdyFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix),
2533 kHttp2ConnectionHeaderPrefixSize, 2538 kHttp2ConnectionHeaderPrefixSize,
2534 false /* take_ownership */)); 2539 false /* take_ownership */));
2535 // Count the prefix as part of the subsequent SETTINGS frame. 2540 // Count the prefix as part of the subsequent SETTINGS frame.
2536 EnqueueSessionWrite(HIGHEST, SETTINGS, 2541 EnqueueSessionWrite(
2537 connection_header_prefix_frame.Pass()); 2542 HIGHEST, SETTINGS, connection_header_prefix_frame.Pass());
2538 } 2543 }
2539 2544
2540 // First, notify the server about the settings they should use when 2545 // First, notify the server about the settings they should use when
2541 // communicating with us. 2546 // communicating with us.
2542 SettingsMap settings_map; 2547 SettingsMap settings_map;
2543 // Create a new settings frame notifying the server of our 2548 // Create a new settings frame notifying the server of our
2544 // max concurrent streams and initial window size. 2549 // max concurrent streams and initial window size.
2545 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] = 2550 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] =
2546 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); 2551 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
2547 if (flow_control_state_ >= FLOW_CONTROL_STREAM && 2552 if (flow_control_state_ >= FLOW_CONTROL_STREAM &&
2548 stream_initial_recv_window_size_ != kSpdyStreamInitialWindowSize) { 2553 stream_initial_recv_window_size_ != kSpdyStreamInitialWindowSize) {
2549 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] = 2554 settings_map[SETTINGS_INITIAL_WINDOW_SIZE] = SettingsFlagsAndValue(
2550 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 2555 SETTINGS_FLAG_NONE, stream_initial_recv_window_size_);
2551 stream_initial_recv_window_size_);
2552 } 2556 }
2553 SendSettings(settings_map); 2557 SendSettings(settings_map);
2554 2558
2555 // Next, notify the server about our initial recv window size. 2559 // Next, notify the server about our initial recv window size.
2556 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { 2560 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) {
2557 // Bump up the receive window size to the real initial value. This 2561 // Bump up the receive window size to the real initial value. This
2558 // has to go here since the WINDOW_UPDATE frame sent by 2562 // has to go here since the WINDOW_UPDATE frame sent by
2559 // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|. 2563 // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|.
2560 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_); 2564 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_);
2561 // This condition implies that |kDefaultInitialRecvWindowSize| - 2565 // This condition implies that |kDefaultInitialRecvWindowSize| -
2562 // |session_recv_window_size_| doesn't overflow. 2566 // |session_recv_window_size_| doesn't overflow.
2563 DCHECK_GT(session_recv_window_size_, 0); 2567 DCHECK_GT(session_recv_window_size_, 0);
2564 IncreaseRecvWindowSize( 2568 IncreaseRecvWindowSize(kDefaultInitialRecvWindowSize -
2565 kDefaultInitialRecvWindowSize - session_recv_window_size_); 2569 session_recv_window_size_);
2566 } 2570 }
2567 2571
2568 // Finally, notify the server about the settings they have 2572 // Finally, notify the server about the settings they have
2569 // previously told us to use when communicating with them (after 2573 // previously told us to use when communicating with them (after
2570 // applying them). 2574 // applying them).
2571 const SettingsMap& server_settings_map = 2575 const SettingsMap& server_settings_map =
2572 http_server_properties_->GetSpdySettings(host_port_pair()); 2576 http_server_properties_->GetSpdySettings(host_port_pair());
2573 if (server_settings_map.empty()) 2577 if (server_settings_map.empty())
2574 return; 2578 return;
2575 2579
2576 SettingsMap::const_iterator it = 2580 SettingsMap::const_iterator it =
2577 server_settings_map.find(SETTINGS_CURRENT_CWND); 2581 server_settings_map.find(SETTINGS_CURRENT_CWND);
2578 uint32 cwnd = (it != server_settings_map.end()) ? it->second.second : 0; 2582 uint32 cwnd = (it != server_settings_map.end()) ? it->second.second : 0;
2579 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", cwnd, 1, 200, 100); 2583 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwndSent", cwnd, 1, 200, 100);
2580 2584
2581 for (SettingsMap::const_iterator it = server_settings_map.begin(); 2585 for (SettingsMap::const_iterator it = server_settings_map.begin();
2582 it != server_settings_map.end(); ++it) { 2586 it != server_settings_map.end();
2587 ++it) {
2583 const SpdySettingsIds new_id = it->first; 2588 const SpdySettingsIds new_id = it->first;
2584 const uint32 new_val = it->second.second; 2589 const uint32 new_val = it->second.second;
2585 HandleSetting(new_id, new_val); 2590 HandleSetting(new_id, new_val);
2586 } 2591 }
2587 2592
2588 SendSettings(server_settings_map); 2593 SendSettings(server_settings_map);
2589 } 2594 }
2590 2595
2591
2592 void SpdySession::SendSettings(const SettingsMap& settings) { 2596 void SpdySession::SendSettings(const SettingsMap& settings) {
2593 DCHECK_NE(availability_state_, STATE_CLOSED); 2597 DCHECK_NE(availability_state_, STATE_CLOSED);
2594 2598
2595 net_log_.AddEvent( 2599 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS,
2596 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, 2600 base::Bind(&NetLogSpdySendSettingsCallback, &settings));
2597 base::Bind(&NetLogSpdySendSettingsCallback, &settings));
2598 2601
2599 // Create the SETTINGS frame and send it. 2602 // Create the SETTINGS frame and send it.
2600 DCHECK(buffered_spdy_framer_.get()); 2603 DCHECK(buffered_spdy_framer_.get());
2601 scoped_ptr<SpdyFrame> settings_frame( 2604 scoped_ptr<SpdyFrame> settings_frame(
2602 buffered_spdy_framer_->CreateSettings(settings)); 2605 buffered_spdy_framer_->CreateSettings(settings));
2603 sent_settings_ = true; 2606 sent_settings_ = true;
2604 EnqueueSessionWrite(HIGHEST, SETTINGS, settings_frame.Pass()); 2607 EnqueueSessionWrite(HIGHEST, SETTINGS, settings_frame.Pass());
2605 } 2608 }
2606 2609
2607 void SpdySession::HandleSetting(uint32 id, uint32 value) { 2610 void SpdySession::HandleSetting(uint32 id, uint32 value) {
2608 switch (id) { 2611 switch (id) {
2609 case SETTINGS_MAX_CONCURRENT_STREAMS: 2612 case SETTINGS_MAX_CONCURRENT_STREAMS:
2610 max_concurrent_streams_ = std::min(static_cast<size_t>(value), 2613 max_concurrent_streams_ =
2611 kMaxConcurrentStreamLimit); 2614 std::min(static_cast<size_t>(value), kMaxConcurrentStreamLimit);
2612 ProcessPendingStreamRequests(); 2615 ProcessPendingStreamRequests();
2613 break; 2616 break;
2614 case SETTINGS_INITIAL_WINDOW_SIZE: { 2617 case SETTINGS_INITIAL_WINDOW_SIZE: {
2615 if (flow_control_state_ < FLOW_CONTROL_STREAM) { 2618 if (flow_control_state_ < FLOW_CONTROL_STREAM) {
2616 net_log().AddEvent( 2619 net_log().AddEvent(
2617 NetLog::TYPE_SPDY_SESSION_INITIAL_WINDOW_SIZE_NO_FLOW_CONTROL); 2620 NetLog::TYPE_SPDY_SESSION_INITIAL_WINDOW_SIZE_NO_FLOW_CONTROL);
2618 return; 2621 return;
2619 } 2622 }
2620 2623
2621 if (value > static_cast<uint32>(kint32max)) { 2624 if (value > static_cast<uint32>(kint32max)) {
(...skipping 12 matching lines...) Expand all
2634 NetLog::TYPE_SPDY_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE, 2637 NetLog::TYPE_SPDY_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE,
2635 NetLog::IntegerCallback("delta_window_size", delta_window_size)); 2638 NetLog::IntegerCallback("delta_window_size", delta_window_size));
2636 break; 2639 break;
2637 } 2640 }
2638 } 2641 }
2639 } 2642 }
2640 2643
2641 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { 2644 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) {
2642 DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); 2645 DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM);
2643 for (ActiveStreamMap::iterator it = active_streams_.begin(); 2646 for (ActiveStreamMap::iterator it = active_streams_.begin();
2644 it != active_streams_.end(); ++it) { 2647 it != active_streams_.end();
2648 ++it) {
2645 it->second.stream->AdjustSendWindowSize(delta_window_size); 2649 it->second.stream->AdjustSendWindowSize(delta_window_size);
2646 } 2650 }
2647 2651
2648 for (CreatedStreamSet::const_iterator it = created_streams_.begin(); 2652 for (CreatedStreamSet::const_iterator it = created_streams_.begin();
2649 it != created_streams_.end(); it++) { 2653 it != created_streams_.end();
2654 it++) {
2650 (*it)->AdjustSendWindowSize(delta_window_size); 2655 (*it)->AdjustSendWindowSize(delta_window_size);
2651 } 2656 }
2652 } 2657 }
2653 2658
2654 void SpdySession::SendPrefacePingIfNoneInFlight() { 2659 void SpdySession::SendPrefacePingIfNoneInFlight() {
2655 if (pings_in_flight_ || !enable_ping_based_connection_checking_) 2660 if (pings_in_flight_ || !enable_ping_based_connection_checking_)
2656 return; 2661 return;
2657 2662
2658 base::TimeTicks now = time_func_(); 2663 base::TimeTicks now = time_func_();
2659 // If there is no activity in the session, then send a preface-PING. 2664 // If there is no activity in the session, then send a preface-PING.
(...skipping 12 matching lines...) Expand all
2672 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); 2677 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id);
2673 if (it != active_streams_.end()) { 2678 if (it != active_streams_.end()) {
2674 CHECK_EQ(it->second.stream->stream_id(), stream_id); 2679 CHECK_EQ(it->second.stream->stream_id(), stream_id);
2675 } else { 2680 } else {
2676 CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); 2681 CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
2677 CHECK_EQ(stream_id, kSessionFlowControlStreamId); 2682 CHECK_EQ(stream_id, kSessionFlowControlStreamId);
2678 } 2683 }
2679 2684
2680 net_log_.AddEvent( 2685 net_log_.AddEvent(
2681 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE_FRAME, 2686 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE_FRAME,
2682 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, 2687 base::Bind(
2683 stream_id, delta_window_size)); 2688 &NetLogSpdyWindowUpdateFrameCallback, stream_id, delta_window_size));
2684 2689
2685 DCHECK(buffered_spdy_framer_.get()); 2690 DCHECK(buffered_spdy_framer_.get());
2686 scoped_ptr<SpdyFrame> window_update_frame( 2691 scoped_ptr<SpdyFrame> window_update_frame(
2687 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); 2692 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size));
2688 EnqueueSessionWrite(priority, WINDOW_UPDATE, window_update_frame.Pass()); 2693 EnqueueSessionWrite(priority, WINDOW_UPDATE, window_update_frame.Pass());
2689 } 2694 }
2690 2695
2691 void SpdySession::WritePingFrame(uint32 unique_id, bool is_ack) { 2696 void SpdySession::WritePingFrame(uint32 unique_id, bool is_ack) {
2692 DCHECK(buffered_spdy_framer_.get()); 2697 DCHECK(buffered_spdy_framer_.get());
2693 scoped_ptr<SpdyFrame> ping_frame( 2698 scoped_ptr<SpdyFrame> ping_frame(
(...skipping 13 matching lines...) Expand all
2707 } 2712 }
2708 } 2713 }
2709 2714
2710 void SpdySession::PlanToCheckPingStatus() { 2715 void SpdySession::PlanToCheckPingStatus() {
2711 if (check_ping_status_pending_) 2716 if (check_ping_status_pending_)
2712 return; 2717 return;
2713 2718
2714 check_ping_status_pending_ = true; 2719 check_ping_status_pending_ = true;
2715 base::MessageLoop::current()->PostDelayedTask( 2720 base::MessageLoop::current()->PostDelayedTask(
2716 FROM_HERE, 2721 FROM_HERE,
2717 base::Bind(&SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(), 2722 base::Bind(&SpdySession::CheckPingStatus,
2718 time_func_()), hung_interval_); 2723 weak_factory_.GetWeakPtr(),
2724 time_func_()),
2725 hung_interval_);
2719 } 2726 }
2720 2727
2721 void SpdySession::CheckPingStatus(base::TimeTicks last_check_time) { 2728 void SpdySession::CheckPingStatus(base::TimeTicks last_check_time) {
2722 CHECK(!in_io_loop_); 2729 CHECK(!in_io_loop_);
2723 DCHECK_NE(availability_state_, STATE_CLOSED); 2730 DCHECK_NE(availability_state_, STATE_CLOSED);
2724 2731
2725 // Check if we got a response back for all PINGs we had sent. 2732 // Check if we got a response back for all PINGs we had sent.
2726 if (pings_in_flight_ == 0) { 2733 if (pings_in_flight_ == 0) {
2727 check_ping_status_pending_ = false; 2734 check_ping_status_pending_ = false;
2728 return; 2735 return;
2729 } 2736 }
2730 2737
2731 DCHECK(check_ping_status_pending_); 2738 DCHECK(check_ping_status_pending_);
2732 2739
2733 base::TimeTicks now = time_func_(); 2740 base::TimeTicks now = time_func_();
2734 base::TimeDelta delay = hung_interval_ - (now - last_activity_time_); 2741 base::TimeDelta delay = hung_interval_ - (now - last_activity_time_);
2735 2742
2736 if (delay.InMilliseconds() < 0 || last_activity_time_ < last_check_time) { 2743 if (delay.InMilliseconds() < 0 || last_activity_time_ < last_check_time) {
2737 // Track all failed PING messages in a separate bucket. 2744 // Track all failed PING messages in a separate bucket.
2738 RecordPingRTTHistogram(base::TimeDelta::Max()); 2745 RecordPingRTTHistogram(base::TimeDelta::Max());
2739 CloseSessionResult result = 2746 CloseSessionResult result =
2740 DoCloseSession(ERR_SPDY_PING_FAILED, "Failed ping."); 2747 DoCloseSession(ERR_SPDY_PING_FAILED, "Failed ping.");
2741 DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED); 2748 DCHECK_EQ(result, SESSION_CLOSED_AND_REMOVED);
2742 return; 2749 return;
2743 } 2750 }
2744 2751
2745 // Check the status of connection after a delay. 2752 // Check the status of connection after a delay.
2746 base::MessageLoop::current()->PostDelayedTask( 2753 base::MessageLoop::current()->PostDelayedTask(
2747 FROM_HERE, 2754 FROM_HERE,
2748 base::Bind(&SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(), 2755 base::Bind(
2749 now), 2756 &SpdySession::CheckPingStatus, weak_factory_.GetWeakPtr(), now),
2750 delay); 2757 delay);
2751 } 2758 }
2752 2759
2753 void SpdySession::RecordPingRTTHistogram(base::TimeDelta duration) { 2760 void SpdySession::RecordPingRTTHistogram(base::TimeDelta duration) {
2754 UMA_HISTOGRAM_TIMES("Net.SpdyPing.RTT", duration); 2761 UMA_HISTOGRAM_TIMES("Net.SpdyPing.RTT", duration);
2755 } 2762 }
2756 2763
2757 void SpdySession::RecordProtocolErrorHistogram( 2764 void SpdySession::RecordProtocolErrorHistogram(
2758 SpdyProtocolErrorDetails details) { 2765 SpdyProtocolErrorDetails details) {
2759 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails2", details, 2766 UMA_HISTOGRAM_ENUMERATION(
2760 NUM_SPDY_PROTOCOL_ERROR_DETAILS); 2767 "Net.SpdySessionErrorDetails2", details, NUM_SPDY_PROTOCOL_ERROR_DETAILS);
2761 if (EndsWith(host_port_pair().host(), "google.com", false)) { 2768 if (EndsWith(host_port_pair().host(), "google.com", false)) {
2762 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails_Google2", details, 2769 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionErrorDetails_Google2",
2770 details,
2763 NUM_SPDY_PROTOCOL_ERROR_DETAILS); 2771 NUM_SPDY_PROTOCOL_ERROR_DETAILS);
2764 } 2772 }
2765 } 2773 }
2766 2774
2767 void SpdySession::RecordHistograms() { 2775 void SpdySession::RecordHistograms() {
2768 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPerSession", 2776 UMA_HISTOGRAM_CUSTOM_COUNTS(
2769 streams_initiated_count_, 2777 "Net.SpdyStreamsPerSession", streams_initiated_count_, 0, 300, 50);
2770 0, 300, 50); 2778 UMA_HISTOGRAM_CUSTOM_COUNTS(
2771 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedPerSession", 2779 "Net.SpdyStreamsPushedPerSession", streams_pushed_count_, 0, 300, 50);
2772 streams_pushed_count_,
2773 0, 300, 50);
2774 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession", 2780 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsPushedAndClaimedPerSession",
2775 streams_pushed_and_claimed_count_, 2781 streams_pushed_and_claimed_count_,
2776 0, 300, 50); 2782 0,
2783 300,
2784 50);
2777 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsAbandonedPerSession", 2785 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamsAbandonedPerSession",
2778 streams_abandoned_count_, 2786 streams_abandoned_count_,
2779 0, 300, 50); 2787 0,
2780 UMA_HISTOGRAM_ENUMERATION("Net.SpdySettingsSent", 2788 300,
2781 sent_settings_ ? 1 : 0, 2); 2789 50);
2782 UMA_HISTOGRAM_ENUMERATION("Net.SpdySettingsReceived", 2790 UMA_HISTOGRAM_ENUMERATION("Net.SpdySettingsSent", sent_settings_ ? 1 : 0, 2);
2783 received_settings_ ? 1 : 0, 2); 2791 UMA_HISTOGRAM_ENUMERATION(
2784 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyStreamStallsPerSession", 2792 "Net.SpdySettingsReceived", received_settings_ ? 1 : 0, 2);
2785 stalled_streams_, 2793 UMA_HISTOGRAM_CUSTOM_COUNTS(
2786 0, 300, 50); 2794 "Net.SpdyStreamStallsPerSession", stalled_streams_, 0, 300, 50);
2787 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionsWithStalls", 2795 UMA_HISTOGRAM_ENUMERATION(
2788 stalled_streams_ > 0 ? 1 : 0, 2); 2796 "Net.SpdySessionsWithStalls", stalled_streams_ > 0 ? 1 : 0, 2);
2789 2797
2790 if (received_settings_) { 2798 if (received_settings_) {
2791 // Enumerate the saved settings, and set histograms for it. 2799 // Enumerate the saved settings, and set histograms for it.
2792 const SettingsMap& settings_map = 2800 const SettingsMap& settings_map =
2793 http_server_properties_->GetSpdySettings(host_port_pair()); 2801 http_server_properties_->GetSpdySettings(host_port_pair());
2794 2802
2795 SettingsMap::const_iterator it; 2803 SettingsMap::const_iterator it;
2796 for (it = settings_map.begin(); it != settings_map.end(); ++it) { 2804 for (it = settings_map.begin(); it != settings_map.end(); ++it) {
2797 const SpdySettingsIds id = it->first; 2805 const SpdySettingsIds id = it->first;
2798 const uint32 val = it->second.second; 2806 const uint32 val = it->second.second;
2799 switch (id) { 2807 switch (id) {
2800 case SETTINGS_CURRENT_CWND: 2808 case SETTINGS_CURRENT_CWND:
2801 // Record several different histograms to see if cwnd converges 2809 // Record several different histograms to see if cwnd converges
2802 // for larger volumes of data being sent. 2810 // for larger volumes of data being sent.
2803 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", 2811 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", val, 1, 200, 100);
2804 val, 1, 200, 100);
2805 if (total_bytes_received_ > 10 * 1024) { 2812 if (total_bytes_received_ > 10 * 1024) {
2806 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", 2813 UMA_HISTOGRAM_CUSTOM_COUNTS(
2807 val, 1, 200, 100); 2814 "Net.SpdySettingsCwnd10K", val, 1, 200, 100);
2808 if (total_bytes_received_ > 25 * 1024) { 2815 if (total_bytes_received_ > 25 * 1024) {
2809 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K", 2816 UMA_HISTOGRAM_CUSTOM_COUNTS(
2810 val, 1, 200, 100); 2817 "Net.SpdySettingsCwnd25K", val, 1, 200, 100);
2811 if (total_bytes_received_ > 50 * 1024) { 2818 if (total_bytes_received_ > 50 * 1024) {
2812 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K", 2819 UMA_HISTOGRAM_CUSTOM_COUNTS(
2813 val, 1, 200, 100); 2820 "Net.SpdySettingsCwnd50K", val, 1, 200, 100);
2814 if (total_bytes_received_ > 100 * 1024) { 2821 if (total_bytes_received_ > 100 * 1024) {
2815 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K", 2822 UMA_HISTOGRAM_CUSTOM_COUNTS(
2816 val, 1, 200, 100); 2823 "Net.SpdySettingsCwnd100K", val, 1, 200, 100);
2817 } 2824 }
2818 } 2825 }
2819 } 2826 }
2820 } 2827 }
2821 break; 2828 break;
2822 case SETTINGS_ROUND_TRIP_TIME: 2829 case SETTINGS_ROUND_TRIP_TIME:
2823 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT", 2830 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT", val, 1, 1200, 100);
2824 val, 1, 1200, 100);
2825 break; 2831 break;
2826 case SETTINGS_DOWNLOAD_RETRANS_RATE: 2832 case SETTINGS_DOWNLOAD_RETRANS_RATE:
2827 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate", 2833 UMA_HISTOGRAM_CUSTOM_COUNTS(
2828 val, 1, 100, 50); 2834 "Net.SpdySettingsRetransRate", val, 1, 100, 50);
2829 break; 2835 break;
2830 default: 2836 default:
2831 break; 2837 break;
2832 } 2838 }
2833 } 2839 }
2834 } 2840 }
2835 } 2841 }
2836 2842
2837 void SpdySession::CompleteStreamRequest( 2843 void SpdySession::CompleteStreamRequest(
2838 const base::WeakPtr<SpdyStreamRequest>& pending_request) { 2844 const base::WeakPtr<SpdyStreamRequest>& pending_request) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2894 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); 2900 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
2895 DCHECK_GE(delta_window_size, 1); 2901 DCHECK_GE(delta_window_size, 1);
2896 2902
2897 // Check for overflow. 2903 // Check for overflow.
2898 int32 max_delta_window_size = kint32max - session_send_window_size_; 2904 int32 max_delta_window_size = kint32max - session_send_window_size_;
2899 if (delta_window_size > max_delta_window_size) { 2905 if (delta_window_size > max_delta_window_size) {
2900 RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE); 2906 RecordProtocolErrorHistogram(PROTOCOL_ERROR_INVALID_WINDOW_UPDATE_SIZE);
2901 CloseSessionResult result = DoCloseSession( 2907 CloseSessionResult result = DoCloseSession(
2902 ERR_SPDY_PROTOCOL_ERROR, 2908 ERR_SPDY_PROTOCOL_ERROR,
2903 "Received WINDOW_UPDATE [delta: " + 2909 "Received WINDOW_UPDATE [delta: " +
2904 base::IntToString(delta_window_size) + 2910 base::IntToString(delta_window_size) +
2905 "] for session overflows session_send_window_size_ [current: " + 2911 "] for session overflows session_send_window_size_ [current: " +
2906 base::IntToString(session_send_window_size_) + "]"); 2912 base::IntToString(session_send_window_size_) + "]");
2907 DCHECK_NE(result, SESSION_ALREADY_CLOSED); 2913 DCHECK_NE(result, SESSION_ALREADY_CLOSED);
2908 return; 2914 return;
2909 } 2915 }
2910 2916
2911 session_send_window_size_ += delta_window_size; 2917 session_send_window_size_ += delta_window_size;
2912 2918
2913 net_log_.AddEvent( 2919 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW,
2914 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, 2920 base::Bind(&NetLogSpdySessionWindowUpdateCallback,
2915 base::Bind(&NetLogSpdySessionWindowUpdateCallback, 2921 delta_window_size,
2916 delta_window_size, session_send_window_size_)); 2922 session_send_window_size_));
2917 2923
2918 DCHECK(!IsSendStalled()); 2924 DCHECK(!IsSendStalled());
2919 ResumeSendStalledStreams(); 2925 ResumeSendStalledStreams();
2920 } 2926 }
2921 2927
2922 void SpdySession::DecreaseSendWindowSize(int32 delta_window_size) { 2928 void SpdySession::DecreaseSendWindowSize(int32 delta_window_size) {
2923 DCHECK_NE(availability_state_, STATE_CLOSED); 2929 DCHECK_NE(availability_state_, STATE_CLOSED);
2924 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); 2930 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
2925 2931
2926 // We only call this method when sending a frame. Therefore, 2932 // We only call this method when sending a frame. Therefore,
2927 // |delta_window_size| should be within the valid frame size range. 2933 // |delta_window_size| should be within the valid frame size range.
2928 DCHECK_GE(delta_window_size, 1); 2934 DCHECK_GE(delta_window_size, 1);
2929 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize); 2935 DCHECK_LE(delta_window_size, kMaxSpdyFrameChunkSize);
2930 2936
2931 // |send_window_size_| should have been at least |delta_window_size| for 2937 // |send_window_size_| should have been at least |delta_window_size| for
2932 // this call to happen. 2938 // this call to happen.
2933 DCHECK_GE(session_send_window_size_, delta_window_size); 2939 DCHECK_GE(session_send_window_size_, delta_window_size);
2934 2940
2935 session_send_window_size_ -= delta_window_size; 2941 session_send_window_size_ -= delta_window_size;
2936 2942
2937 net_log_.AddEvent( 2943 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW,
2938 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, 2944 base::Bind(&NetLogSpdySessionWindowUpdateCallback,
2939 base::Bind(&NetLogSpdySessionWindowUpdateCallback, 2945 -delta_window_size,
2940 -delta_window_size, session_send_window_size_)); 2946 session_send_window_size_));
2941 } 2947 }
2942 2948
2943 void SpdySession::OnReadBufferConsumed( 2949 void SpdySession::OnReadBufferConsumed(
2944 size_t consume_size, 2950 size_t consume_size,
2945 SpdyBuffer::ConsumeSource consume_source) { 2951 SpdyBuffer::ConsumeSource consume_source) {
2946 // We can be called with |in_io_loop_| set if a read SpdyBuffer is 2952 // We can be called with |in_io_loop_| set if a read SpdyBuffer is
2947 // deleted (e.g., discarded by a SpdyReadQueue). 2953 // deleted (e.g., discarded by a SpdyReadQueue).
2948 2954
2949 if (availability_state_ == STATE_CLOSED) 2955 if (availability_state_ == STATE_CLOSED)
2950 return; 2956 return;
2951 2957
2952 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); 2958 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
2953 DCHECK_GE(consume_size, 1u); 2959 DCHECK_GE(consume_size, 1u);
2954 DCHECK_LE(consume_size, static_cast<size_t>(kint32max)); 2960 DCHECK_LE(consume_size, static_cast<size_t>(kint32max));
2955 2961
2956 IncreaseRecvWindowSize(static_cast<int32>(consume_size)); 2962 IncreaseRecvWindowSize(static_cast<int32>(consume_size));
2957 } 2963 }
2958 2964
2959 void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) { 2965 void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) {
2960 DCHECK_NE(availability_state_, STATE_CLOSED); 2966 DCHECK_NE(availability_state_, STATE_CLOSED);
2961 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); 2967 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION);
2962 DCHECK_GE(session_unacked_recv_window_bytes_, 0); 2968 DCHECK_GE(session_unacked_recv_window_bytes_, 0);
2963 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); 2969 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_);
2964 DCHECK_GE(delta_window_size, 1); 2970 DCHECK_GE(delta_window_size, 1);
2965 // Check for overflow. 2971 // Check for overflow.
2966 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); 2972 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_);
2967 2973
2968 session_recv_window_size_ += delta_window_size; 2974 session_recv_window_size_ += delta_window_size;
2969 net_log_.AddEvent( 2975 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW,
2970 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, 2976 base::Bind(&NetLogSpdySessionWindowUpdateCallback,
2971 base::Bind(&NetLogSpdySessionWindowUpdateCallback, 2977 delta_window_size,
2972 delta_window_size, session_recv_window_size_)); 2978 session_recv_window_size_));
2973 2979
2974 session_unacked_recv_window_bytes_ += delta_window_size; 2980 session_unacked_recv_window_bytes_ += delta_window_size;
2975 if (session_unacked_recv_window_bytes_ > kSpdySessionInitialWindowSize / 2) { 2981 if (session_unacked_recv_window_bytes_ > kSpdySessionInitialWindowSize / 2) {
2976 SendWindowUpdateFrame(kSessionFlowControlStreamId, 2982 SendWindowUpdateFrame(kSessionFlowControlStreamId,
2977 session_unacked_recv_window_bytes_, 2983 session_unacked_recv_window_bytes_,
2978 HIGHEST); 2984 HIGHEST);
2979 session_unacked_recv_window_bytes_ = 0; 2985 session_unacked_recv_window_bytes_ = 0;
2980 } 2986 }
2981 } 2987 }
2982 2988
(...skipping 10 matching lines...) Expand all
2993 CloseSessionResult result = DoCloseSession( 2999 CloseSessionResult result = DoCloseSession(
2994 ERR_SPDY_PROTOCOL_ERROR, 3000 ERR_SPDY_PROTOCOL_ERROR,
2995 "delta_window_size is " + base::IntToString(delta_window_size) + 3001 "delta_window_size is " + base::IntToString(delta_window_size) +
2996 " in DecreaseRecvWindowSize, which is larger than the receive " + 3002 " in DecreaseRecvWindowSize, which is larger than the receive " +
2997 "window size of " + base::IntToString(session_recv_window_size_)); 3003 "window size of " + base::IntToString(session_recv_window_size_));
2998 DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED); 3004 DCHECK_EQ(result, SESSION_CLOSED_BUT_NOT_REMOVED);
2999 return; 3005 return;
3000 } 3006 }
3001 3007
3002 session_recv_window_size_ -= delta_window_size; 3008 session_recv_window_size_ -= delta_window_size;
3003 net_log_.AddEvent( 3009 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW,
3004 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, 3010 base::Bind(&NetLogSpdySessionWindowUpdateCallback,
3005 base::Bind(&NetLogSpdySessionWindowUpdateCallback, 3011 -delta_window_size,
3006 -delta_window_size, session_recv_window_size_)); 3012 session_recv_window_size_));
3007 } 3013 }
3008 3014
3009 void SpdySession::QueueSendStalledStream(const SpdyStream& stream) { 3015 void SpdySession::QueueSendStalledStream(const SpdyStream& stream) {
3010 DCHECK(stream.send_stalled_by_flow_control()); 3016 DCHECK(stream.send_stalled_by_flow_control());
3011 RequestPriority priority = stream.priority(); 3017 RequestPriority priority = stream.priority();
3012 CHECK_GE(priority, MINIMUM_PRIORITY); 3018 CHECK_GE(priority, MINIMUM_PRIORITY);
3013 CHECK_LE(priority, MAXIMUM_PRIORITY); 3019 CHECK_LE(priority, MAXIMUM_PRIORITY);
3014 stream_send_unstall_queue_[priority].push_back(stream.stream_id()); 3020 stream_send_unstall_queue_[priority].push_back(stream.stream_id());
3015 } 3021 }
3016 3022
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3050 if (!queue->empty()) { 3056 if (!queue->empty()) {
3051 SpdyStreamId stream_id = queue->front(); 3057 SpdyStreamId stream_id = queue->front();
3052 queue->pop_front(); 3058 queue->pop_front();
3053 return stream_id; 3059 return stream_id;
3054 } 3060 }
3055 } 3061 }
3056 return 0; 3062 return 0;
3057 } 3063 }
3058 3064
3059 } // namespace net 3065 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698