OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
304 void SpdyStreamRequest::Reset() { | 304 void SpdyStreamRequest::Reset() { |
305 type_ = SPDY_BIDIRECTIONAL_STREAM; | 305 type_ = SPDY_BIDIRECTIONAL_STREAM; |
306 session_ = NULL; | 306 session_ = NULL; |
307 stream_.reset(); | 307 stream_.reset(); |
308 url_ = GURL(); | 308 url_ = GURL(); |
309 priority_ = MINIMUM_PRIORITY; | 309 priority_ = MINIMUM_PRIORITY; |
310 net_log_ = BoundNetLog(); | 310 net_log_ = BoundNetLog(); |
311 callback_.Reset(); | 311 callback_.Reset(); |
312 } | 312 } |
313 | 313 |
314 SpdySession::ActiveStreamInfo::ActiveStreamInfo() | |
315 : stream(NULL), | |
316 waiting_for_syn_reply(false) {} | |
317 | |
318 SpdySession::ActiveStreamInfo::ActiveStreamInfo(SpdyStream* stream) | |
319 : stream(stream), | |
320 waiting_for_syn_reply(stream->type() != SPDY_PUSH_STREAM) {} | |
321 | |
322 SpdySession::ActiveStreamInfo::~ActiveStreamInfo() {} | |
323 | |
324 SpdySession::PushedStreamInfo::PushedStreamInfo() : stream_id(0) {} | |
325 | |
326 SpdySession::PushedStreamInfo::PushedStreamInfo( | |
327 SpdyStreamId stream_id, | |
328 base::TimeTicks creation_time) | |
329 : stream_id(stream_id), | |
330 creation_time(creation_time) {} | |
331 | |
332 SpdySession::PushedStreamInfo::~PushedStreamInfo() {} | |
333 | |
314 SpdySession::SpdySession(const SpdySessionKey& spdy_session_key, | 334 SpdySession::SpdySession(const SpdySessionKey& spdy_session_key, |
315 SpdySessionPool* spdy_session_pool, | 335 SpdySessionPool* spdy_session_pool, |
316 HttpServerProperties* http_server_properties, | 336 HttpServerProperties* http_server_properties, |
317 bool verify_domain_authentication, | 337 bool verify_domain_authentication, |
318 bool enable_sending_initial_settings, | 338 bool enable_sending_initial_settings, |
319 bool enable_credential_frames, | 339 bool enable_credential_frames, |
320 bool enable_compression, | 340 bool enable_compression, |
321 bool enable_ping_based_connection_checking, | 341 bool enable_ping_based_connection_checking, |
322 NextProto default_protocol, | 342 NextProto default_protocol, |
323 size_t stream_initial_recv_window_size, | 343 size_t stream_initial_recv_window_size, |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
698 } | 718 } |
699 | 719 |
700 scoped_ptr<SpdyFrame> SpdySession::CreateSynStream( | 720 scoped_ptr<SpdyFrame> SpdySession::CreateSynStream( |
701 SpdyStreamId stream_id, | 721 SpdyStreamId stream_id, |
702 RequestPriority priority, | 722 RequestPriority priority, |
703 uint8 credential_slot, | 723 uint8 credential_slot, |
704 SpdyControlFlags flags, | 724 SpdyControlFlags flags, |
705 const SpdyHeaderBlock& headers) { | 725 const SpdyHeaderBlock& headers) { |
706 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 726 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
707 CHECK(it != active_streams_.end()); | 727 CHECK(it != active_streams_.end()); |
708 CHECK_EQ(it->second->stream_id(), stream_id); | 728 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
709 | 729 |
710 SendPrefacePingIfNoneInFlight(); | 730 SendPrefacePingIfNoneInFlight(); |
711 | 731 |
712 DCHECK(buffered_spdy_framer_.get()); | 732 DCHECK(buffered_spdy_framer_.get()); |
713 scoped_ptr<SpdyFrame> syn_frame( | 733 scoped_ptr<SpdyFrame> syn_frame( |
714 buffered_spdy_framer_->CreateSynStream( | 734 buffered_spdy_framer_->CreateSynStream( |
715 stream_id, 0, | 735 stream_id, 0, |
716 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()), | 736 ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()), |
717 credential_slot, flags, enable_compression_, &headers)); | 737 credential_slot, flags, enable_compression_, &headers)); |
718 | 738 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
765 } | 785 } |
766 return OK; | 786 return OK; |
767 } | 787 } |
768 | 788 |
769 scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, | 789 scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, |
770 IOBuffer* data, | 790 IOBuffer* data, |
771 int len, | 791 int len, |
772 SpdyDataFlags flags) { | 792 SpdyDataFlags flags) { |
773 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 793 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
774 CHECK(it != active_streams_.end()); | 794 CHECK(it != active_streams_.end()); |
775 SpdyStream* stream = it->second; | 795 SpdyStream* stream = it->second.stream; |
776 CHECK_EQ(stream->stream_id(), stream_id); | 796 CHECK_EQ(stream->stream_id(), stream_id); |
777 | 797 |
778 if (len < 0) { | 798 if (len < 0) { |
779 NOTREACHED(); | 799 NOTREACHED(); |
780 return scoped_ptr<SpdyBuffer>(); | 800 return scoped_ptr<SpdyBuffer>(); |
781 } | 801 } |
782 | 802 |
783 int effective_len = std::min(len, kMaxSpdyFrameChunkSize); | 803 int effective_len = std::min(len, kMaxSpdyFrameChunkSize); |
784 | 804 |
785 bool send_stalled_by_stream = | 805 bool send_stalled_by_stream = |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
893 | 913 |
894 // TODO(mbelshe): We should send a RST_STREAM control frame here | 914 // TODO(mbelshe): We should send a RST_STREAM control frame here |
895 // so that the server can cancel a large send. | 915 // so that the server can cancel a large send. |
896 | 916 |
897 // For push streams, if they are being deleted normally, we leave | 917 // For push streams, if they are being deleted normally, we leave |
898 // the stream in the unclaimed_pushed_streams_ list. However, if | 918 // the stream in the unclaimed_pushed_streams_ list. However, if |
899 // the stream is errored out, clean it up entirely. | 919 // the stream is errored out, clean it up entirely. |
900 if (status != OK) { | 920 if (status != OK) { |
901 for (PushedStreamMap::iterator it = unclaimed_pushed_streams_.begin(); | 921 for (PushedStreamMap::iterator it = unclaimed_pushed_streams_.begin(); |
902 it != unclaimed_pushed_streams_.end(); ++it) { | 922 it != unclaimed_pushed_streams_.end(); ++it) { |
903 if (stream_id == it->second.first->stream_id()) { | 923 if (stream_id == it->second.stream_id) { |
904 unclaimed_pushed_streams_.erase(it); | 924 unclaimed_pushed_streams_.erase(it); |
905 break; | 925 break; |
906 } | 926 } |
907 } | 927 } |
908 } | 928 } |
909 | 929 |
910 // The stream might have been deleted. | 930 // The stream might have been deleted. |
911 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 931 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
912 if (it == active_streams_.end()) | 932 if (it == active_streams_.end()) |
913 return; | 933 return; |
914 | 934 |
915 scoped_ptr<SpdyStream> owned_stream(it->second); | 935 scoped_ptr<SpdyStream> owned_stream(it->second.stream); |
916 active_streams_.erase(it); | 936 active_streams_.erase(it); |
917 | 937 |
918 DeleteStream(owned_stream.Pass(), status); | 938 DeleteStream(owned_stream.Pass(), status); |
919 } | 939 } |
920 | 940 |
921 void SpdySession::CloseCreatedStream( | 941 void SpdySession::CloseCreatedStream( |
922 const base::WeakPtr<SpdyStream>& stream, int status) { | 942 const base::WeakPtr<SpdyStream>& stream, int status) { |
923 DCHECK_EQ(0u, stream->stream_id()); | 943 DCHECK_EQ(0u, stream->stream_id()); |
924 | 944 |
925 scoped_ptr<SpdyStream> owned_stream(stream.get()); | 945 scoped_ptr<SpdyStream> owned_stream(stream.get()); |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1233 // The loops below are carefully written to avoid problems with | 1253 // The loops below are carefully written to avoid problems with |
1234 // streams closing other streams. | 1254 // streams closing other streams. |
1235 | 1255 |
1236 while (true) { | 1256 while (true) { |
1237 ActiveStreamMap::iterator it = | 1257 ActiveStreamMap::iterator it = |
1238 active_streams_.lower_bound(last_good_stream_id + 1); | 1258 active_streams_.lower_bound(last_good_stream_id + 1); |
1239 if (it == active_streams_.end()) | 1259 if (it == active_streams_.end()) |
1240 break; | 1260 break; |
1241 SpdyStreamId stream_id = it->first; | 1261 SpdyStreamId stream_id = it->first; |
1242 streams_abandoned_count_++; | 1262 streams_abandoned_count_++; |
1243 LogAbandonedStream(it->second, status); | 1263 LogAbandonedStream(it->second.stream, status); |
1244 CloseActiveStream(stream_id, status); | 1264 CloseActiveStream(stream_id, status); |
1245 } | 1265 } |
1246 | 1266 |
1247 while (!created_streams_.empty()) { | 1267 while (!created_streams_.empty()) { |
1248 CreatedStreamSet::iterator it = created_streams_.begin(); | 1268 CreatedStreamSet::iterator it = created_streams_.begin(); |
1249 LogAbandonedStream(*it, status); | 1269 LogAbandonedStream(*it, status); |
1250 CloseCreatedStream((*it)->GetWeakPtr(), status); | 1270 CloseCreatedStream((*it)->GetWeakPtr(), status); |
1251 } | 1271 } |
1252 | 1272 |
1253 write_queue_.RemovePendingWritesForStreamsAfter(last_good_stream_id); | 1273 write_queue_.RemovePendingWritesForStreamsAfter(last_good_stream_id); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1429 stream->set_stream_id(GetNewStreamId()); | 1449 stream->set_stream_id(GetNewStreamId()); |
1430 scoped_ptr<SpdyStream> owned_stream(stream); | 1450 scoped_ptr<SpdyStream> owned_stream(stream); |
1431 created_streams_.erase(stream); | 1451 created_streams_.erase(stream); |
1432 return owned_stream.Pass(); | 1452 return owned_stream.Pass(); |
1433 } | 1453 } |
1434 | 1454 |
1435 void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) { | 1455 void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) { |
1436 SpdyStreamId stream_id = stream->stream_id(); | 1456 SpdyStreamId stream_id = stream->stream_id(); |
1437 DCHECK_NE(stream_id, 0u); | 1457 DCHECK_NE(stream_id, 0u); |
1438 std::pair<ActiveStreamMap::iterator, bool> result = | 1458 std::pair<ActiveStreamMap::iterator, bool> result = |
1439 active_streams_.insert(std::make_pair(stream_id, stream.get())); | 1459 active_streams_.insert( |
1460 std::make_pair(stream_id, ActiveStreamInfo(stream.get()))); | |
1440 if (result.second) { | 1461 if (result.second) { |
1441 ignore_result(stream.release()); | 1462 ignore_result(stream.release()); |
1442 } else { | 1463 } else { |
1443 NOTREACHED(); | 1464 NOTREACHED(); |
1444 } | 1465 } |
1445 } | 1466 } |
1446 | 1467 |
1447 void SpdySession::DeleteStream(scoped_ptr<SpdyStream> stream, int status) { | 1468 void SpdySession::DeleteStream(scoped_ptr<SpdyStream> stream, int status) { |
1448 if (in_flight_write_stream_.get() == stream.get()) { | 1469 if (in_flight_write_stream_.get() == stream.get()) { |
1449 // If we're deleting the stream for the in-flight write, we still | 1470 // If we're deleting the stream for the in-flight write, we still |
(...skipping 18 matching lines...) Expand all Loading... | |
1468 spdy_session_pool_ = NULL; | 1489 spdy_session_pool_ = NULL; |
1469 pool->Remove(make_scoped_refptr(this)); | 1490 pool->Remove(make_scoped_refptr(this)); |
1470 } | 1491 } |
1471 } | 1492 } |
1472 | 1493 |
1473 base::WeakPtr<SpdyStream> SpdySession::GetActivePushStream( | 1494 base::WeakPtr<SpdyStream> SpdySession::GetActivePushStream( |
1474 const std::string& path) { | 1495 const std::string& path) { |
1475 base::StatsCounter used_push_streams("spdy.claimed_push_streams"); | 1496 base::StatsCounter used_push_streams("spdy.claimed_push_streams"); |
1476 | 1497 |
1477 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(path); | 1498 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(path); |
1478 if (it != unclaimed_pushed_streams_.end()) { | 1499 if (it == unclaimed_pushed_streams_.end()) |
1479 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM); | 1500 return base::WeakPtr<SpdyStream>(); |
1480 base::WeakPtr<SpdyStream> stream = it->second.first->GetWeakPtr(); | 1501 |
1481 unclaimed_pushed_streams_.erase(it); | 1502 SpdyStreamId stream_id = it->second.stream_id; |
1482 used_push_streams.Increment(); | 1503 unclaimed_pushed_streams_.erase(it); |
1483 return stream; | 1504 |
1505 ActiveStreamMap::iterator it2 = active_streams_.find(stream_id); | |
1506 if (it2 == active_streams_.end()) { | |
1507 NOTREACHED(); | |
1508 return base::WeakPtr<SpdyStream>(); | |
1484 } | 1509 } |
1485 return base::WeakPtr<SpdyStream>(); | 1510 |
1511 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM); | |
1512 used_push_streams.Increment(); | |
1513 return it2->second.stream->GetWeakPtr(); | |
1486 } | 1514 } |
1487 | 1515 |
1488 bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, | 1516 bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, |
1489 bool* was_npn_negotiated, | 1517 bool* was_npn_negotiated, |
1490 NextProto* protocol_negotiated) { | 1518 NextProto* protocol_negotiated) { |
1491 *was_npn_negotiated = connection_->socket()->WasNpnNegotiated(); | 1519 *was_npn_negotiated = connection_->socket()->WasNpnNegotiated(); |
1492 *protocol_negotiated = connection_->socket()->GetNegotiatedProtocol(); | 1520 *protocol_negotiated = connection_->socket()->GetNegotiatedProtocol(); |
1493 return connection_->socket()->GetSSLInfo(ssl_info); | 1521 return connection_->socket()->GetSSLInfo(ssl_info); |
1494 } | 1522 } |
1495 | 1523 |
(...skipping 18 matching lines...) Expand all Loading... | |
1514 "SPDY_ERROR error_code: %d.", error_code); | 1542 "SPDY_ERROR error_code: %d.", error_code); |
1515 CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, true, description); | 1543 CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, true, description); |
1516 } | 1544 } |
1517 | 1545 |
1518 void SpdySession::OnStreamError(SpdyStreamId stream_id, | 1546 void SpdySession::OnStreamError(SpdyStreamId stream_id, |
1519 const std::string& description) { | 1547 const std::string& description) { |
1520 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 1548 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
1521 // We still want to reset the stream even if we don't know anything | 1549 // We still want to reset the stream even if we don't know anything |
1522 // about it. | 1550 // about it. |
1523 RequestPriority priority = | 1551 RequestPriority priority = |
1524 (it == active_streams_.end()) ? IDLE : it->second->priority(); | 1552 (it == active_streams_.end()) ? IDLE : it->second.stream->priority(); |
1525 ResetStream(stream_id, priority, RST_STREAM_PROTOCOL_ERROR, description); | 1553 ResetStream(stream_id, priority, RST_STREAM_PROTOCOL_ERROR, description); |
1526 } | 1554 } |
1527 | 1555 |
1528 void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, | 1556 void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, |
1529 const char* data, | 1557 const char* data, |
1530 size_t len, | 1558 size_t len, |
1531 bool fin) { | 1559 bool fin) { |
1532 DCHECK_LT(len, 1u << 24); | 1560 DCHECK_LT(len, 1u << 24); |
1533 if (net_log().IsLoggingAllEvents()) { | 1561 if (net_log().IsLoggingAllEvents()) { |
1534 net_log().AddEvent( | 1562 net_log().AddEvent( |
1535 NetLog::TYPE_SPDY_SESSION_RECV_DATA, | 1563 NetLog::TYPE_SPDY_SESSION_RECV_DATA, |
1536 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); | 1564 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); |
1537 } | 1565 } |
1538 | 1566 |
1539 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 1567 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
1540 | 1568 |
1541 // By the time data comes in, the stream may already be inactive. | 1569 // By the time data comes in, the stream may already be inactive. |
1542 if (it == active_streams_.end()) | 1570 if (it == active_streams_.end()) |
1543 return; | 1571 return; |
1544 | 1572 |
1573 SpdyStream* stream = it->second.stream; | |
1574 CHECK_EQ(stream->stream_id(), stream_id); | |
1575 | |
1576 if (it->second.waiting_for_syn_reply) { | |
1577 const std::string& error = "Data received before SYN_REPLY."; | |
1578 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); | |
1579 ResetStream(stream_id, stream->priority(), | |
1580 RST_STREAM_PROTOCOL_ERROR, error); | |
1581 return; | |
1582 } | |
1583 | |
1545 scoped_ptr<SpdyBuffer> buffer; | 1584 scoped_ptr<SpdyBuffer> buffer; |
1546 if (data) { | 1585 if (data) { |
1547 DCHECK_GT(len, 0u); | 1586 DCHECK_GT(len, 0u); |
1548 buffer.reset(new SpdyBuffer(data, len)); | 1587 buffer.reset(new SpdyBuffer(data, len)); |
1549 | 1588 |
1550 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { | 1589 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { |
1551 DecreaseRecvWindowSize(static_cast<int32>(len)); | 1590 DecreaseRecvWindowSize(static_cast<int32>(len)); |
1552 buffer->AddConsumeCallback( | 1591 buffer->AddConsumeCallback( |
1553 base::Bind(&SpdySession::OnReadBufferConsumed, | 1592 base::Bind(&SpdySession::OnReadBufferConsumed, |
1554 weak_factory_.GetWeakPtr())); | 1593 weak_factory_.GetWeakPtr())); |
1555 } | 1594 } |
1556 } else { | 1595 } else { |
1557 DCHECK_EQ(len, 0u); | 1596 DCHECK_EQ(len, 0u); |
1558 } | 1597 } |
1559 it->second->OnDataReceived(buffer.Pass()); | 1598 stream->OnDataReceived(buffer.Pass()); |
1560 } | 1599 } |
1561 | 1600 |
1562 void SpdySession::OnSettings(bool clear_persisted) { | 1601 void SpdySession::OnSettings(bool clear_persisted) { |
1563 if (clear_persisted) | 1602 if (clear_persisted) |
1564 http_server_properties_->ClearSpdySettings(host_port_pair()); | 1603 http_server_properties_->ClearSpdySettings(host_port_pair()); |
1565 | 1604 |
1566 if (net_log_.IsLoggingAllEvents()) { | 1605 if (net_log_.IsLoggingAllEvents()) { |
1567 net_log_.AddEvent( | 1606 net_log_.AddEvent( |
1568 NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS, | 1607 NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS, |
1569 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), | 1608 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1679 // is trusted explicitly via the --trusted-spdy-proxy switch. | 1718 // is trusted explicitly via the --trusted-spdy-proxy switch. |
1680 if (trusted_spdy_proxy_.Equals(host_port_pair())) { | 1719 if (trusted_spdy_proxy_.Equals(host_port_pair())) { |
1681 // Disallow pushing of HTTPS content. | 1720 // Disallow pushing of HTTPS content. |
1682 if (gurl.SchemeIs("https")) { | 1721 if (gurl.SchemeIs("https")) { |
1683 ResetStream(stream_id, request_priority, RST_STREAM_REFUSED_STREAM, | 1722 ResetStream(stream_id, request_priority, RST_STREAM_REFUSED_STREAM, |
1684 base::StringPrintf( | 1723 base::StringPrintf( |
1685 "Rejected push of Cross Origin HTTPS content %d", | 1724 "Rejected push of Cross Origin HTTPS content %d", |
1686 associated_stream_id)); | 1725 associated_stream_id)); |
1687 } | 1726 } |
1688 } else { | 1727 } else { |
1689 GURL associated_url(associated_it->second->GetUrl()); | 1728 GURL associated_url(associated_it->second.stream->GetUrl()); |
1690 if (associated_url.GetOrigin() != gurl.GetOrigin()) { | 1729 if (associated_url.GetOrigin() != gurl.GetOrigin()) { |
1691 ResetStream(stream_id, request_priority, RST_STREAM_REFUSED_STREAM, | 1730 ResetStream(stream_id, request_priority, RST_STREAM_REFUSED_STREAM, |
1692 base::StringPrintf( | 1731 base::StringPrintf( |
1693 "Rejected Cross Origin Push Stream %d", | 1732 "Rejected Cross Origin Push Stream %d", |
1694 associated_stream_id)); | 1733 associated_stream_id)); |
1695 return; | 1734 return; |
1696 } | 1735 } |
1697 } | 1736 } |
1698 | 1737 |
1699 // There should not be an existing pushed stream with the same path. | 1738 // There should not be an existing pushed stream with the same path. |
1700 if (unclaimed_pushed_streams_.find(url) != unclaimed_pushed_streams_.end()) { | 1739 if (unclaimed_pushed_streams_.find(url) != unclaimed_pushed_streams_.end()) { |
1701 ResetStream(stream_id, request_priority, RST_STREAM_PROTOCOL_ERROR, | 1740 ResetStream(stream_id, request_priority, RST_STREAM_PROTOCOL_ERROR, |
1702 "Received duplicate pushed stream with url: " + url); | 1741 "Received duplicate pushed stream with url: " + url); |
1703 return; | 1742 return; |
1704 } | 1743 } |
1705 | 1744 |
1706 scoped_ptr<SpdyStream> stream( | 1745 scoped_ptr<SpdyStream> stream( |
1707 new SpdyStream(SPDY_PUSH_STREAM, this, gurl.PathForRequest(), | 1746 new SpdyStream(SPDY_PUSH_STREAM, this, gurl.PathForRequest(), |
1708 request_priority, | 1747 request_priority, |
1709 stream_initial_send_window_size_, | 1748 stream_initial_send_window_size_, |
1710 stream_initial_recv_window_size_, | 1749 stream_initial_recv_window_size_, |
1711 net_log_)); | 1750 net_log_)); |
1712 stream->set_stream_id(stream_id); | 1751 stream->set_stream_id(stream_id); |
1713 | 1752 |
1714 DeleteExpiredPushedStreams(); | 1753 DeleteExpiredPushedStreams(); |
1715 unclaimed_pushed_streams_[url] = | 1754 unclaimed_pushed_streams_[url] = PushedStreamInfo(stream_id, time_func_()); |
1716 std::pair<SpdyStream*, base::TimeTicks>(stream.get(), time_func_()); | |
1717 | 1755 |
1718 stream->set_response_received(); | 1756 stream->set_response_received(); |
1719 InsertActivatedStream(stream.Pass()); | 1757 InsertActivatedStream(stream.Pass()); |
1720 | 1758 |
1721 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1759 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1722 if (it == active_streams_.end()) { | 1760 if (it == active_streams_.end()) { |
1723 NOTREACHED(); | 1761 NOTREACHED(); |
1724 return; | 1762 return; |
1725 } | 1763 } |
1726 | 1764 |
1727 // Parse the headers. | 1765 // Parse the headers. |
1728 if (!Respond(headers, it->second)) | 1766 if (!Respond(headers, it->second.stream)) |
1729 return; | 1767 return; |
1730 | 1768 |
1731 base::StatsCounter push_requests("spdy.pushed_streams"); | 1769 base::StatsCounter push_requests("spdy.pushed_streams"); |
1732 push_requests.Increment(); | 1770 push_requests.Increment(); |
1733 } | 1771 } |
1734 | 1772 |
1735 void SpdySession::DeleteExpiredPushedStreams() { | 1773 void SpdySession::DeleteExpiredPushedStreams() { |
1736 if (unclaimed_pushed_streams_.empty()) | 1774 if (unclaimed_pushed_streams_.empty()) |
1737 return; | 1775 return; |
1738 | 1776 |
1739 // Check that adequate time has elapsed since the last sweep. | 1777 // Check that adequate time has elapsed since the last sweep. |
1740 if (time_func_() < next_unclaimed_push_stream_sweep_time_) | 1778 if (time_func_() < next_unclaimed_push_stream_sweep_time_) |
1741 return; | 1779 return; |
1742 | 1780 |
1743 // Delete old streams. | 1781 // Gather old streams to delete. |
1744 base::TimeTicks minimum_freshness = time_func_() - | 1782 base::TimeTicks minimum_freshness = time_func_() - |
1745 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); | 1783 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); |
1746 PushedStreamMap::iterator it; | 1784 std::vector<SpdyStreamId> streams_to_close; |
1747 for (it = unclaimed_pushed_streams_.begin(); | 1785 for (PushedStreamMap::iterator it = unclaimed_pushed_streams_.begin(); |
1748 it != unclaimed_pushed_streams_.end(); ) { | 1786 it != unclaimed_pushed_streams_.end(); ++it) { |
1749 SpdyStream* stream = it->second.first; | 1787 if (minimum_freshness > it->second.creation_time) |
1750 base::TimeTicks creation_time = it->second.second; | 1788 streams_to_close.push_back(it->second.stream_id); |
1751 // CloseActiveStream() will invalidate the current iterator, so | |
1752 // move to next. | |
1753 ++it; | |
1754 if (minimum_freshness > creation_time) { | |
1755 base::StatsCounter abandoned_push_streams( | |
1756 "spdy.abandoned_push_streams"); | |
1757 base::StatsCounter abandoned_streams("spdy.abandoned_streams"); | |
1758 abandoned_push_streams.Increment(); | |
1759 abandoned_streams.Increment(); | |
1760 streams_abandoned_count_++; | |
1761 CloseActiveStream(stream->stream_id(), ERR_INVALID_SPDY_STREAM); | |
1762 } | |
1763 } | 1789 } |
1790 | |
1791 for (std::vector<SpdyStreamId>::const_iterator it = streams_to_close.begin(); | |
1792 it != streams_to_close.end(); ++it) { | |
1793 base::StatsCounter abandoned_push_streams( | |
1794 "spdy.abandoned_push_streams"); | |
1795 base::StatsCounter abandoned_streams("spdy.abandoned_streams"); | |
1796 abandoned_push_streams.Increment(); | |
1797 abandoned_streams.Increment(); | |
1798 streams_abandoned_count_++; | |
1799 // CloseActiveStream() will remove the stream from | |
1800 // |unclaimed_pushed_streams_|. | |
1801 CloseActiveStream(*it, ERR_INVALID_SPDY_STREAM); | |
1802 } | |
1803 | |
1764 next_unclaimed_push_stream_sweep_time_ = time_func_() + | 1804 next_unclaimed_push_stream_sweep_time_ = time_func_() + |
1765 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); | 1805 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); |
1766 } | 1806 } |
1767 | 1807 |
1768 void SpdySession::OnSynReply(SpdyStreamId stream_id, | 1808 void SpdySession::OnSynReply(SpdyStreamId stream_id, |
1769 bool fin, | 1809 bool fin, |
1770 const SpdyHeaderBlock& headers) { | 1810 const SpdyHeaderBlock& headers) { |
1771 if (net_log().IsLoggingAllEvents()) { | 1811 if (net_log().IsLoggingAllEvents()) { |
1772 net_log().AddEvent( | 1812 net_log().AddEvent( |
1773 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, | 1813 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, |
1774 base::Bind(&NetLogSpdySynCallback, | 1814 base::Bind(&NetLogSpdySynCallback, |
1775 &headers, fin, false, // not unidirectional | 1815 &headers, fin, false, // not unidirectional |
1776 stream_id, 0)); | 1816 stream_id, 0)); |
1777 } | 1817 } |
1778 | 1818 |
1779 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1819 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1780 if (it == active_streams_.end()) { | 1820 if (it == active_streams_.end()) { |
1781 // NOTE: it may just be that the stream was cancelled. | 1821 // NOTE: it may just be that the stream was cancelled. |
1782 return; | 1822 return; |
1783 } | 1823 } |
1784 | 1824 |
1785 SpdyStream* stream = it->second; | 1825 SpdyStream* stream = it->second.stream; |
1786 CHECK_EQ(stream->stream_id(), stream_id); | 1826 CHECK_EQ(stream->stream_id(), stream_id); |
1787 | 1827 |
1788 if (stream->response_received()) { | 1828 if (!it->second.waiting_for_syn_reply) { |
1789 stream->LogStreamError(ERR_SYN_REPLY_NOT_RECEIVED, | 1829 const std::string& error = |
1790 "Received duplicate SYN_REPLY for stream."); | 1830 "Received duplicate SYN_REPLY for stream."; |
1791 RecordProtocolErrorHistogram(PROTOCOL_ERROR_SYN_REPLY_NOT_RECEIVED); | 1831 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); |
Ryan Hamilton
2013/06/21 15:35:37
Did this get lost or is it called by LogStreamErro
akalin
2013/06/21 18:30:44
Called by ResetStream
| |
1792 CloseActiveStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR); | 1832 ResetStream(stream_id, stream->priority(), |
1833 RST_STREAM_STREAM_IN_USE, error); | |
1793 return; | 1834 return; |
1794 } | 1835 } |
1795 stream->set_response_received(); | 1836 stream->set_response_received(); |
1837 it->second.waiting_for_syn_reply = false; | |
1796 | 1838 |
1797 Respond(headers, stream); | 1839 Respond(headers, stream); |
1798 } | 1840 } |
1799 | 1841 |
1800 void SpdySession::OnHeaders(SpdyStreamId stream_id, | 1842 void SpdySession::OnHeaders(SpdyStreamId stream_id, |
1801 bool fin, | 1843 bool fin, |
1802 const SpdyHeaderBlock& headers) { | 1844 const SpdyHeaderBlock& headers) { |
1803 if (net_log().IsLoggingAllEvents()) { | 1845 if (net_log().IsLoggingAllEvents()) { |
1804 net_log().AddEvent( | 1846 net_log().AddEvent( |
1805 NetLog::TYPE_SPDY_SESSION_RECV_HEADERS, | 1847 NetLog::TYPE_SPDY_SESSION_RECV_HEADERS, |
1806 base::Bind(&NetLogSpdySynCallback, | 1848 base::Bind(&NetLogSpdySynCallback, |
1807 &headers, fin, /*unidirectional=*/false, | 1849 &headers, fin, /*unidirectional=*/false, |
1808 stream_id, 0)); | 1850 stream_id, 0)); |
1809 } | 1851 } |
1810 | 1852 |
1811 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1853 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1812 if (it == active_streams_.end()) { | 1854 if (it == active_streams_.end()) { |
1813 // NOTE: it may just be that the stream was cancelled. | 1855 // NOTE: it may just be that the stream was cancelled. |
1814 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; | 1856 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; |
1815 return; | 1857 return; |
1816 } | 1858 } |
1817 | 1859 |
1818 CHECK_EQ(it->second->stream_id(), stream_id); | 1860 SpdyStream* stream = it->second.stream; |
1861 CHECK_EQ(stream->stream_id(), stream_id); | |
1819 | 1862 |
1820 int rv = it->second->OnHeaders(headers); | 1863 int rv = stream->OnHeaders(headers); |
1821 if (rv < 0) { | 1864 if (rv < 0) { |
1822 DCHECK_NE(rv, ERR_IO_PENDING); | 1865 DCHECK_NE(rv, ERR_IO_PENDING); |
1823 CloseActiveStream(stream_id, rv); | 1866 CloseActiveStream(stream_id, rv); |
1824 } | 1867 } |
1825 } | 1868 } |
1826 | 1869 |
1827 void SpdySession::OnRstStream(SpdyStreamId stream_id, | 1870 void SpdySession::OnRstStream(SpdyStreamId stream_id, |
1828 SpdyRstStreamStatus status) { | 1871 SpdyRstStreamStatus status) { |
1829 std::string description; | 1872 std::string description; |
1830 net_log().AddEvent( | 1873 net_log().AddEvent( |
1831 NetLog::TYPE_SPDY_SESSION_RST_STREAM, | 1874 NetLog::TYPE_SPDY_SESSION_RST_STREAM, |
1832 base::Bind(&NetLogSpdyRstCallback, | 1875 base::Bind(&NetLogSpdyRstCallback, |
1833 stream_id, status, &description)); | 1876 stream_id, status, &description)); |
1834 | 1877 |
1835 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1878 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1836 if (it == active_streams_.end()) { | 1879 if (it == active_streams_.end()) { |
1837 // NOTE: it may just be that the stream was cancelled. | 1880 // NOTE: it may just be that the stream was cancelled. |
1838 LOG(WARNING) << "Received RST for invalid stream" << stream_id; | 1881 LOG(WARNING) << "Received RST for invalid stream" << stream_id; |
1839 return; | 1882 return; |
1840 } | 1883 } |
1841 | 1884 |
1842 CHECK_EQ(it->second->stream_id(), stream_id); | 1885 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
1843 | 1886 |
1844 if (status == 0) { | 1887 if (status == 0) { |
1845 it->second->OnDataReceived(scoped_ptr<SpdyBuffer>()); | 1888 it->second.stream->OnDataReceived(scoped_ptr<SpdyBuffer>()); |
1846 } else if (status == RST_STREAM_REFUSED_STREAM) { | 1889 } else if (status == RST_STREAM_REFUSED_STREAM) { |
1847 CloseActiveStream(stream_id, ERR_SPDY_SERVER_REFUSED_STREAM); | 1890 CloseActiveStream(stream_id, ERR_SPDY_SERVER_REFUSED_STREAM); |
1848 } else { | 1891 } else { |
1849 RecordProtocolErrorHistogram( | 1892 RecordProtocolErrorHistogram( |
1850 PROTOCOL_ERROR_RST_STREAM_FOR_NON_ACTIVE_STREAM); | 1893 PROTOCOL_ERROR_RST_STREAM_FOR_NON_ACTIVE_STREAM); |
1851 it->second->LogStreamError( | 1894 it->second.stream->LogStreamError( |
1852 ERR_SPDY_PROTOCOL_ERROR, | 1895 ERR_SPDY_PROTOCOL_ERROR, |
1853 base::StringPrintf("SPDY stream closed with status: %d", status)); | 1896 base::StringPrintf("SPDY stream closed with status: %d", status)); |
1854 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical. | 1897 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical. |
1855 // For now, it doesn't matter much - it is a protocol error. | 1898 // For now, it doesn't matter much - it is a protocol error. |
1856 CloseActiveStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); | 1899 CloseActiveStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); |
1857 } | 1900 } |
1858 } | 1901 } |
1859 | 1902 |
1860 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, | 1903 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, |
1861 SpdyGoAwayStatus status) { | 1904 SpdyGoAwayStatus status) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1930 if (flow_control_state_ < FLOW_CONTROL_STREAM) { | 1973 if (flow_control_state_ < FLOW_CONTROL_STREAM) { |
1931 // TODO(akalin): Record an error and close the session. | 1974 // TODO(akalin): Record an error and close the session. |
1932 LOG(WARNING) << "Received WINDOW_UPDATE for stream " << stream_id | 1975 LOG(WARNING) << "Received WINDOW_UPDATE for stream " << stream_id |
1933 << " when flow control is not turned on"; | 1976 << " when flow control is not turned on"; |
1934 return; | 1977 return; |
1935 } | 1978 } |
1936 | 1979 |
1937 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 1980 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
1938 | 1981 |
1939 if (it == active_streams_.end()) { | 1982 if (it == active_streams_.end()) { |
1940 // TODO(akalin): Record an error and close the session. | 1983 // NOTE: it may just be that the stream was cancelled. |
1941 LOG(WARNING) << "Received WINDOW_UPDATE for invalid stream " << stream_id; | 1984 LOG(WARNING) << "Received WINDOW_UPDATE for invalid stream " << stream_id; |
1942 return; | 1985 return; |
1943 } | 1986 } |
1944 | 1987 |
1988 SpdyStream* stream = it->second.stream; | |
1989 CHECK_EQ(stream->stream_id(), stream_id); | |
1990 | |
1945 if (delta_window_size < 1u) { | 1991 if (delta_window_size < 1u) { |
1946 ResetStream(stream_id, it->second->priority(), | 1992 ResetStream(stream_id, it->second.stream->priority(), |
1947 RST_STREAM_FLOW_CONTROL_ERROR, | 1993 RST_STREAM_FLOW_CONTROL_ERROR, |
1948 base::StringPrintf( | 1994 base::StringPrintf( |
1949 "Received WINDOW_UPDATE with an invalid " | 1995 "Received WINDOW_UPDATE with an invalid " |
1950 "delta_window_size %ud", delta_window_size)); | 1996 "delta_window_size %ud", delta_window_size)); |
1951 return; | 1997 return; |
1952 } | 1998 } |
1953 | 1999 |
1954 CHECK_EQ(it->second->stream_id(), stream_id); | 2000 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
1955 it->second->IncreaseSendWindowSize(static_cast<int32>(delta_window_size)); | 2001 it->second.stream->IncreaseSendWindowSize( |
2002 static_cast<int32>(delta_window_size)); | |
1956 } | 2003 } |
1957 } | 2004 } |
1958 | 2005 |
1959 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, | 2006 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, |
1960 uint32 delta_window_size) { | 2007 uint32 delta_window_size) { |
1961 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 2008 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
1962 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 2009 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
1963 CHECK(it != active_streams_.end()); | 2010 CHECK(it != active_streams_.end()); |
1964 CHECK_EQ(it->second->stream_id(), stream_id); | 2011 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
1965 SendWindowUpdateFrame(stream_id, delta_window_size, it->second->priority()); | 2012 SendWindowUpdateFrame( |
2013 stream_id, delta_window_size, it->second.stream->priority()); | |
1966 } | 2014 } |
1967 | 2015 |
1968 void SpdySession::SendInitialSettings() { | 2016 void SpdySession::SendInitialSettings() { |
1969 // First notify the server about the settings they should use when | 2017 // First notify the server about the settings they should use when |
1970 // communicating with us. | 2018 // communicating with us. |
1971 if (GetProtocolVersion() >= 2 && enable_sending_initial_settings_) { | 2019 if (GetProtocolVersion() >= 2 && enable_sending_initial_settings_) { |
1972 SettingsMap settings_map; | 2020 SettingsMap settings_map; |
1973 // Create a new settings frame notifying the sever of our | 2021 // Create a new settings frame notifying the sever of our |
1974 // max_concurrent_streams_ and initial window size. | 2022 // max_concurrent_streams_ and initial window size. |
1975 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] = | 2023 settings_map[SETTINGS_MAX_CONCURRENT_STREAMS] = |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2054 NetLog::IntegerCallback("delta_window_size", delta_window_size)); | 2102 NetLog::IntegerCallback("delta_window_size", delta_window_size)); |
2055 break; | 2103 break; |
2056 } | 2104 } |
2057 } | 2105 } |
2058 } | 2106 } |
2059 | 2107 |
2060 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { | 2108 void SpdySession::UpdateStreamsSendWindowSize(int32 delta_window_size) { |
2061 DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 2109 DCHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
2062 for (ActiveStreamMap::iterator it = active_streams_.begin(); | 2110 for (ActiveStreamMap::iterator it = active_streams_.begin(); |
2063 it != active_streams_.end(); ++it) { | 2111 it != active_streams_.end(); ++it) { |
2064 it->second->AdjustSendWindowSize(delta_window_size); | 2112 it->second.stream->AdjustSendWindowSize(delta_window_size); |
2065 } | 2113 } |
2066 | 2114 |
2067 for (CreatedStreamSet::const_iterator it = created_streams_.begin(); | 2115 for (CreatedStreamSet::const_iterator it = created_streams_.begin(); |
2068 it != created_streams_.end(); it++) { | 2116 it != created_streams_.end(); it++) { |
2069 (*it)->AdjustSendWindowSize(delta_window_size); | 2117 (*it)->AdjustSendWindowSize(delta_window_size); |
2070 } | 2118 } |
2071 } | 2119 } |
2072 | 2120 |
2073 void SpdySession::SendPrefacePingIfNoneInFlight() { | 2121 void SpdySession::SendPrefacePingIfNoneInFlight() { |
2074 if (pings_in_flight_ || !enable_ping_based_connection_checking_) | 2122 if (pings_in_flight_ || !enable_ping_based_connection_checking_) |
2075 return; | 2123 return; |
2076 | 2124 |
2077 base::TimeTicks now = base::TimeTicks::Now(); | 2125 base::TimeTicks now = base::TimeTicks::Now(); |
2078 // If there is no activity in the session, then send a preface-PING. | 2126 // If there is no activity in the session, then send a preface-PING. |
2079 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_) | 2127 if ((now - last_activity_time_) > connection_at_risk_of_loss_time_) |
2080 SendPrefacePing(); | 2128 SendPrefacePing(); |
2081 } | 2129 } |
2082 | 2130 |
2083 void SpdySession::SendPrefacePing() { | 2131 void SpdySession::SendPrefacePing() { |
2084 WritePingFrame(next_ping_id_); | 2132 WritePingFrame(next_ping_id_); |
2085 } | 2133 } |
2086 | 2134 |
2087 void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id, | 2135 void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id, |
2088 uint32 delta_window_size, | 2136 uint32 delta_window_size, |
2089 RequestPriority priority) { | 2137 RequestPriority priority) { |
2090 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 2138 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
2091 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 2139 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
2092 if (it != active_streams_.end()) { | 2140 if (it != active_streams_.end()) { |
2093 CHECK_EQ(it->second->stream_id(), stream_id); | 2141 CHECK_EQ(it->second.stream->stream_id(), stream_id); |
2094 } else { | 2142 } else { |
2095 CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 2143 CHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
2096 CHECK_EQ(stream_id, kSessionFlowControlStreamId); | 2144 CHECK_EQ(stream_id, kSessionFlowControlStreamId); |
2097 } | 2145 } |
2098 | 2146 |
2099 net_log_.AddEvent( | 2147 net_log_.AddEvent( |
2100 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE_FRAME, | 2148 NetLog::TYPE_SPDY_SESSION_SENT_WINDOW_UPDATE_FRAME, |
2101 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, | 2149 base::Bind(&NetLogSpdyWindowUpdateFrameCallback, |
2102 stream_id, delta_window_size)); | 2150 stream_id, delta_window_size)); |
2103 | 2151 |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2437 old_size = GetTotalSize(stream_send_unstall_queue_); | 2485 old_size = GetTotalSize(stream_send_unstall_queue_); |
2438 | 2486 |
2439 SpdyStreamId stream_id = PopStreamToPossiblyResume(); | 2487 SpdyStreamId stream_id = PopStreamToPossiblyResume(); |
2440 if (stream_id == 0) | 2488 if (stream_id == 0) |
2441 break; | 2489 break; |
2442 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 2490 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
2443 // The stream may actually still be send-stalled after this (due | 2491 // The stream may actually still be send-stalled after this (due |
2444 // to its own send window) but that's okay -- it'll then be | 2492 // to its own send window) but that's okay -- it'll then be |
2445 // resumed once its send window increases. | 2493 // resumed once its send window increases. |
2446 if (it != active_streams_.end()) | 2494 if (it != active_streams_.end()) |
2447 it->second->PossiblyResumeIfSendStalled(); | 2495 it->second.stream->PossiblyResumeIfSendStalled(); |
2448 | 2496 |
2449 // The size should decrease unless we got send-stalled again. | 2497 // The size should decrease unless we got send-stalled again. |
2450 if (!IsSendStalled()) | 2498 if (!IsSendStalled()) |
2451 DCHECK_LT(GetTotalSize(stream_send_unstall_queue_), old_size); | 2499 DCHECK_LT(GetTotalSize(stream_send_unstall_queue_), old_size); |
2452 } | 2500 } |
2453 } | 2501 } |
2454 | 2502 |
2455 SpdyStreamId SpdySession::PopStreamToPossiblyResume() { | 2503 SpdyStreamId SpdySession::PopStreamToPossiblyResume() { |
2456 for (int i = NUM_PRIORITIES - 1; i >= 0; --i) { | 2504 for (int i = NUM_PRIORITIES - 1; i >= 0; --i) { |
2457 std::deque<SpdyStreamId>* queue = &stream_send_unstall_queue_[i]; | 2505 std::deque<SpdyStreamId>* queue = &stream_send_unstall_queue_[i]; |
2458 if (!queue->empty()) { | 2506 if (!queue->empty()) { |
2459 SpdyStreamId stream_id = queue->front(); | 2507 SpdyStreamId stream_id = queue->front(); |
2460 queue->pop_front(); | 2508 queue->pop_front(); |
2461 return stream_id; | 2509 return stream_id; |
2462 } | 2510 } |
2463 } | 2511 } |
2464 return 0; | 2512 return 0; |
2465 } | 2513 } |
2466 | 2514 |
2467 } // namespace net | 2515 } // namespace net |
OLD | NEW |