Chromium Code Reviews| 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 |