Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/linked_ptr.h" | 9 #include "base/memory/linked_ptr.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 // static | 230 // static |
| 231 size_t SpdySession::max_concurrent_stream_limit_ = 256; | 231 size_t SpdySession::max_concurrent_stream_limit_ = 256; |
| 232 | 232 |
| 233 // static | 233 // static |
| 234 bool SpdySession::enable_ping_based_connection_checking_ = true; | 234 bool SpdySession::enable_ping_based_connection_checking_ = true; |
| 235 | 235 |
| 236 // static | 236 // static |
| 237 int SpdySession::connection_at_risk_of_loss_ms_ = 0; | 237 int SpdySession::connection_at_risk_of_loss_ms_ = 0; |
| 238 | 238 |
| 239 // static | 239 // static |
| 240 int SpdySession::trailing_ping_delay_time_ms_ = 1000; | 240 int SpdySession::trailing_ping_delay_time_ms_ = 200; |
|
jar (doing other things)
2011/10/17 22:09:28
Will argued for keeping this at 1000, and was pers
ramant (doing other things)
2011/10/17 23:40:57
Done.
| |
| 241 | 241 |
| 242 // static | 242 // static |
| 243 int SpdySession::hung_interval_ms_ = 10000; | 243 int SpdySession::hung_interval_ms_ = 10000; |
| 244 | 244 |
| 245 SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, | 245 SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, |
| 246 SpdySessionPool* spdy_session_pool, | 246 SpdySessionPool* spdy_session_pool, |
| 247 SpdySettingsStorage* spdy_settings, | 247 SpdySettingsStorage* spdy_settings, |
| 248 bool verify_domain_authentication, | 248 bool verify_domain_authentication, |
| 249 NetLog* net_log) | 249 NetLog* net_log) |
| 250 : ALLOW_THIS_IN_INITIALIZER_LIST( | 250 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 273 frames_received_(0), | 273 frames_received_(0), |
| 274 bytes_received_(0), | 274 bytes_received_(0), |
| 275 sent_settings_(false), | 275 sent_settings_(false), |
| 276 received_settings_(false), | 276 received_settings_(false), |
| 277 stalled_streams_(0), | 277 stalled_streams_(0), |
| 278 pings_in_flight_(0), | 278 pings_in_flight_(0), |
| 279 next_ping_id_(1), | 279 next_ping_id_(1), |
| 280 received_data_time_(base::TimeTicks::Now()), | 280 received_data_time_(base::TimeTicks::Now()), |
| 281 trailing_ping_pending_(false), | 281 trailing_ping_pending_(false), |
| 282 check_ping_status_pending_(false), | 282 check_ping_status_pending_(false), |
| 283 last_sent_was_ping_(false), | 283 need_to_send_ping_(false), |
| 284 initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize), | 284 initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize), |
| 285 initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize), | 285 initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize), |
| 286 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)), | 286 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)), |
| 287 verify_domain_authentication_(verify_domain_authentication) { | 287 verify_domain_authentication_(verify_domain_authentication) { |
| 288 DCHECK(HttpStreamFactory::spdy_enabled()); | 288 DCHECK(HttpStreamFactory::spdy_enabled()); |
| 289 net_log_.BeginEvent( | 289 net_log_.BeginEvent( |
| 290 NetLog::TYPE_SPDY_SESSION, | 290 NetLog::TYPE_SPDY_SESSION, |
| 291 make_scoped_refptr( | 291 make_scoped_refptr( |
| 292 new NetLogSpdySessionParameter(host_port_proxy_pair_))); | 292 new NetLogSpdySessionParameter(host_port_proxy_pair_))); |
| 293 | 293 |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 521 base::StatsCounter spdy_requests("spdy.requests"); | 521 base::StatsCounter spdy_requests("spdy.requests"); |
| 522 spdy_requests.Increment(); | 522 spdy_requests.Increment(); |
| 523 streams_initiated_count_++; | 523 streams_initiated_count_++; |
| 524 | 524 |
| 525 if (net_log().IsLoggingAllEvents()) { | 525 if (net_log().IsLoggingAllEvents()) { |
| 526 net_log().AddEvent( | 526 net_log().AddEvent( |
| 527 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, | 527 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, |
| 528 make_scoped_refptr( | 528 make_scoped_refptr( |
| 529 new NetLogSpdySynParameter(headers, flags, stream_id, 0))); | 529 new NetLogSpdySynParameter(headers, flags, stream_id, 0))); |
| 530 } | 530 } |
| 531 last_sent_was_ping_ = false; | 531 need_to_send_ping_ = true; |
|
jar (doing other things)
2011/10/17 22:09:28
Please add comment:
Some servers don't like too ma
ramant (doing other things)
2011/10/17 23:40:57
Done.
| |
| 532 | 532 |
| 533 return ERR_IO_PENDING; | 533 return ERR_IO_PENDING; |
| 534 } | 534 } |
| 535 | 535 |
| 536 int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id, | 536 int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id, |
| 537 net::IOBuffer* data, int len, | 537 net::IOBuffer* data, int len, |
| 538 spdy::SpdyDataFlags flags) { | 538 spdy::SpdyDataFlags flags) { |
| 539 // Find our stream | 539 // Find our stream |
| 540 DCHECK(IsStreamActive(stream_id)); | 540 DCHECK(IsStreamActive(stream_id)); |
| 541 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 541 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 if (net_log().IsLoggingAllEvents()) { | 577 if (net_log().IsLoggingAllEvents()) { |
| 578 net_log().AddEvent( | 578 net_log().AddEvent( |
| 579 NetLog::TYPE_SPDY_SESSION_SEND_DATA, | 579 NetLog::TYPE_SPDY_SESSION_SEND_DATA, |
| 580 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags))); | 580 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags))); |
| 581 } | 581 } |
| 582 | 582 |
| 583 // TODO(mbelshe): reduce memory copies here. | 583 // TODO(mbelshe): reduce memory copies here. |
| 584 scoped_ptr<spdy::SpdyDataFrame> frame( | 584 scoped_ptr<spdy::SpdyDataFrame> frame( |
| 585 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); | 585 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); |
| 586 QueueFrame(frame.get(), stream->priority(), stream); | 586 QueueFrame(frame.get(), stream->priority(), stream); |
| 587 last_sent_was_ping_ = false; | |
| 588 return ERR_IO_PENDING; | 587 return ERR_IO_PENDING; |
| 589 } | 588 } |
| 590 | 589 |
| 591 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { | 590 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { |
| 592 // TODO(mbelshe): We should send a RST_STREAM control frame here | 591 // TODO(mbelshe): We should send a RST_STREAM control frame here |
| 593 // so that the server can cancel a large send. | 592 // so that the server can cancel a large send. |
| 594 | 593 |
| 595 DeleteStream(stream_id, status); | 594 DeleteStream(stream_id, status); |
| 596 } | 595 } |
| 597 | 596 |
| 598 void SpdySession::ResetStream( | 597 void SpdySession::ResetStream( |
| 599 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { | 598 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { |
| 600 | 599 |
| 601 net_log().AddEvent( | 600 net_log().AddEvent( |
| 602 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, | 601 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, |
| 603 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status))); | 602 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status))); |
| 604 | 603 |
| 605 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( | 604 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( |
| 606 spdy_framer_.CreateRstStream(stream_id, status)); | 605 spdy_framer_.CreateRstStream(stream_id, status)); |
| 607 | 606 |
| 608 // Default to lowest priority unless we know otherwise. | 607 // Default to lowest priority unless we know otherwise. |
| 609 int priority = 3; | 608 int priority = 3; |
| 610 if(IsStreamActive(stream_id)) { | 609 if(IsStreamActive(stream_id)) { |
| 611 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 610 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 612 priority = stream->priority(); | 611 priority = stream->priority(); |
| 613 } | 612 } |
| 614 QueueFrame(rst_frame.get(), priority, NULL); | 613 QueueFrame(rst_frame.get(), priority, NULL); |
| 615 last_sent_was_ping_ = false; | |
| 616 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); | 614 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); |
| 617 } | 615 } |
| 618 | 616 |
| 619 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { | 617 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { |
| 620 return ContainsKey(active_streams_, stream_id); | 618 return ContainsKey(active_streams_, stream_id); |
| 621 } | 619 } |
| 622 | 620 |
| 623 LoadState SpdySession::GetLoadState() const { | 621 LoadState SpdySession::GetLoadState() const { |
| 624 // NOTE: The application only queries the LoadState via the | 622 // NOTE: The application only queries the LoadState via the |
| 625 // SpdyNetworkTransaction, and details are only needed when | 623 // SpdyNetworkTransaction, and details are only needed when |
| (...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1376 | 1374 |
| 1377 --pings_in_flight_; | 1375 --pings_in_flight_; |
| 1378 if (pings_in_flight_ < 0) { | 1376 if (pings_in_flight_ < 0) { |
| 1379 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true); | 1377 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true); |
| 1380 return; | 1378 return; |
| 1381 } | 1379 } |
| 1382 | 1380 |
| 1383 if (pings_in_flight_ > 0) | 1381 if (pings_in_flight_ > 0) |
| 1384 return; | 1382 return; |
| 1385 | 1383 |
| 1386 if (last_sent_was_ping_) | 1384 if (!need_to_send_ping_) |
| 1387 return; | 1385 return; |
| 1388 | 1386 |
| 1389 PlanToSendTrailingPing(); | 1387 PlanToSendTrailingPing(); |
| 1390 } | 1388 } |
| 1391 | 1389 |
| 1392 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { | 1390 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { |
| 1393 spdy::SpdySettings settings; | 1391 spdy::SpdySettings settings; |
| 1394 if (spdy_framer_.ParseSettings(&frame, &settings)) { | 1392 if (spdy_framer_.ParseSettings(&frame, &settings)) { |
| 1395 HandleSettings(settings); | 1393 HandleSettings(settings); |
| 1396 spdy_settings_->Set(host_port_pair(), settings); | 1394 spdy_settings_->Set(host_port_pair(), settings); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1439 CHECK_EQ(stream->stream_id(), stream_id); | 1437 CHECK_EQ(stream->stream_id(), stream_id); |
| 1440 | 1438 |
| 1441 net_log_.AddEvent( | 1439 net_log_.AddEvent( |
| 1442 NetLog::TYPE_SPDY_SESSION_RECV_WINDOW_UPDATE, | 1440 NetLog::TYPE_SPDY_SESSION_RECV_WINDOW_UPDATE, |
| 1443 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( | 1441 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( |
| 1444 stream_id, delta_window_size, stream->recv_window_size()))); | 1442 stream_id, delta_window_size, stream->recv_window_size()))); |
| 1445 | 1443 |
| 1446 scoped_ptr<spdy::SpdyWindowUpdateControlFrame> window_update_frame( | 1444 scoped_ptr<spdy::SpdyWindowUpdateControlFrame> window_update_frame( |
| 1447 spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size)); | 1445 spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size)); |
| 1448 QueueFrame(window_update_frame.get(), stream->priority(), stream); | 1446 QueueFrame(window_update_frame.get(), stream->priority(), stream); |
| 1449 last_sent_was_ping_ = false; | |
| 1450 } | 1447 } |
| 1451 | 1448 |
| 1452 // Given a cwnd that we would have sent to the server, modify it based on the | 1449 // Given a cwnd that we would have sent to the server, modify it based on the |
| 1453 // field trial policy. | 1450 // field trial policy. |
| 1454 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { | 1451 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { |
| 1455 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); | 1452 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); |
| 1456 if (!trial) { | 1453 if (!trial) { |
| 1457 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; | 1454 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; |
| 1458 return cwnd; | 1455 return cwnd; |
| 1459 } | 1456 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1504 | 1501 |
| 1505 net_log_.AddEvent( | 1502 net_log_.AddEvent( |
| 1506 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, | 1503 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, |
| 1507 make_scoped_refptr(new NetLogSpdySettingsParameter(settings))); | 1504 make_scoped_refptr(new NetLogSpdySettingsParameter(settings))); |
| 1508 | 1505 |
| 1509 // Create the SETTINGS frame and send it. | 1506 // Create the SETTINGS frame and send it. |
| 1510 scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame( | 1507 scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame( |
| 1511 spdy_framer_.CreateSettings(settings)); | 1508 spdy_framer_.CreateSettings(settings)); |
| 1512 sent_settings_ = true; | 1509 sent_settings_ = true; |
| 1513 QueueFrame(settings_frame.get(), 0, NULL); | 1510 QueueFrame(settings_frame.get(), 0, NULL); |
| 1514 last_sent_was_ping_ = false; | |
| 1515 } | 1511 } |
| 1516 | 1512 |
| 1517 void SpdySession::HandleSettings(const spdy::SpdySettings& settings) { | 1513 void SpdySession::HandleSettings(const spdy::SpdySettings& settings) { |
| 1518 for (spdy::SpdySettings::const_iterator i = settings.begin(), | 1514 for (spdy::SpdySettings::const_iterator i = settings.begin(), |
| 1519 end = settings.end(); i != end; ++i) { | 1515 end = settings.end(); i != end; ++i) { |
| 1520 const uint32 id = i->first.id(); | 1516 const uint32 id = i->first.id(); |
| 1521 const uint32 val = i->second; | 1517 const uint32 val = i->second; |
| 1522 switch (id) { | 1518 switch (id) { |
| 1523 case spdy::SETTINGS_MAX_CONCURRENT_STREAMS: | 1519 case spdy::SETTINGS_MAX_CONCURRENT_STREAMS: |
| 1524 max_concurrent_streams_ = std::min(static_cast<size_t>(val), | 1520 max_concurrent_streams_ = std::min(static_cast<size_t>(val), |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1539 | 1535 |
| 1540 base::TimeTicks now = base::TimeTicks::Now(); | 1536 base::TimeTicks now = base::TimeTicks::Now(); |
| 1541 // If we haven't heard from server, then send a preface-PING. | 1537 // If we haven't heard from server, then send a preface-PING. |
| 1542 if ((now - received_data_time_) > kConnectionAtRiskOfLoss) | 1538 if ((now - received_data_time_) > kConnectionAtRiskOfLoss) |
| 1543 SendPrefacePing(); | 1539 SendPrefacePing(); |
| 1544 | 1540 |
| 1545 PlanToSendTrailingPing(); | 1541 PlanToSendTrailingPing(); |
| 1546 } | 1542 } |
| 1547 | 1543 |
| 1548 void SpdySession::SendPrefacePing() { | 1544 void SpdySession::SendPrefacePing() { |
| 1549 WritePingFrame(next_ping_id_); | 1545 // TODO(rtenneti): Enable sending Preface-PING after server fix. |
|
jar (doing other things)
2011/10/17 22:40:05
Suggest:
TODO(rtenneti): Send preface pings when m
ramant (doing other things)
2011/10/17 23:40:57
Done.
| |
| 1546 // WritePingFrame(next_ping_id_); | |
| 1550 } | 1547 } |
| 1551 | 1548 |
| 1552 void SpdySession::PlanToSendTrailingPing() { | 1549 void SpdySession::PlanToSendTrailingPing() { |
| 1553 if (trailing_ping_pending_) | 1550 if (trailing_ping_pending_) |
| 1554 return; | 1551 return; |
| 1555 | 1552 |
| 1556 trailing_ping_pending_ = true; | 1553 trailing_ping_pending_ = true; |
| 1557 MessageLoop::current()->PostDelayedTask( | 1554 MessageLoop::current()->PostDelayedTask( |
| 1558 FROM_HERE, | 1555 FROM_HERE, |
| 1559 method_factory_.NewRunnableMethod(&SpdySession::SendTrailingPing), | 1556 method_factory_.NewRunnableMethod(&SpdySession::SendTrailingPing), |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1572 QueueFrame(ping_frame.get(), SPDY_PRIORITY_HIGHEST, NULL); | 1569 QueueFrame(ping_frame.get(), SPDY_PRIORITY_HIGHEST, NULL); |
| 1573 | 1570 |
| 1574 if (net_log().IsLoggingAllEvents()) { | 1571 if (net_log().IsLoggingAllEvents()) { |
| 1575 net_log().AddEvent( | 1572 net_log().AddEvent( |
| 1576 NetLog::TYPE_SPDY_SESSION_PING, | 1573 NetLog::TYPE_SPDY_SESSION_PING, |
| 1577 make_scoped_refptr(new NetLogSpdyPingParameter(next_ping_id_))); | 1574 make_scoped_refptr(new NetLogSpdyPingParameter(next_ping_id_))); |
| 1578 } | 1575 } |
| 1579 if (unique_id % 2 != 0) { | 1576 if (unique_id % 2 != 0) { |
| 1580 next_ping_id_ += 2; | 1577 next_ping_id_ += 2; |
| 1581 ++pings_in_flight_; | 1578 ++pings_in_flight_; |
| 1582 last_sent_was_ping_ = true; | 1579 need_to_send_ping_ = false; |
| 1583 PlanToCheckPingStatus(); | 1580 PlanToCheckPingStatus(); |
| 1584 } | 1581 } |
| 1585 } | 1582 } |
| 1586 | 1583 |
| 1587 void SpdySession::PlanToCheckPingStatus() { | 1584 void SpdySession::PlanToCheckPingStatus() { |
| 1588 if (check_ping_status_pending_) | 1585 if (check_ping_status_pending_) |
| 1589 return; | 1586 return; |
| 1590 | 1587 |
| 1591 check_ping_status_pending_ = true; | 1588 check_ping_status_pending_ = true; |
| 1592 MessageLoop::current()->PostDelayedTask( | 1589 MessageLoop::current()->PostDelayedTask( |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1704 if (it == pending_callback_map_.end()) | 1701 if (it == pending_callback_map_.end()) |
| 1705 return; | 1702 return; |
| 1706 | 1703 |
| 1707 OldCompletionCallback* callback = it->second.callback; | 1704 OldCompletionCallback* callback = it->second.callback; |
| 1708 int result = it->second.result; | 1705 int result = it->second.result; |
| 1709 pending_callback_map_.erase(it); | 1706 pending_callback_map_.erase(it); |
| 1710 callback->Run(result); | 1707 callback->Run(result); |
| 1711 } | 1708 } |
| 1712 | 1709 |
| 1713 } // namespace net | 1710 } // namespace net |
| OLD | NEW |