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 1581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1592 void SpdySession::OnSynStreamCompressed( | 1592 void SpdySession::OnSynStreamCompressed( |
1593 size_t uncompressed_size, | 1593 size_t uncompressed_size, |
1594 size_t compressed_size) { | 1594 size_t compressed_size) { |
1595 // Make sure we avoid early decimal truncation. | 1595 // Make sure we avoid early decimal truncation. |
1596 int compression_pct = 100 - (100 * compressed_size) / uncompressed_size; | 1596 int compression_pct = 100 - (100 * compressed_size) / uncompressed_size; |
1597 UMA_HISTOGRAM_PERCENTAGE("Net.SpdySynStreamCompressionPercentage", | 1597 UMA_HISTOGRAM_PERCENTAGE("Net.SpdySynStreamCompressionPercentage", |
1598 compression_pct); | 1598 compression_pct); |
1599 } | 1599 } |
1600 | 1600 |
1601 | 1601 |
1602 bool SpdySession::Respond(const SpdyHeaderBlock& headers, SpdyStream* stream) { | 1602 bool SpdySession::Respond(const SpdyHeaderBlock& response_headers, |
| 1603 base::Time response_time, |
| 1604 base::TimeTicks recv_first_byte_time, |
| 1605 SpdyStream* stream) { |
1603 int rv = OK; | 1606 int rv = OK; |
1604 SpdyStreamId stream_id = stream->stream_id(); | 1607 SpdyStreamId stream_id = stream->stream_id(); |
1605 // May invalidate |stream|. | 1608 // May invalidate |stream|. |
1606 rv = stream->OnResponseHeadersReceived(headers); | 1609 rv = stream->OnInitialResponseHeadersReceived( |
| 1610 response_headers, response_time, recv_first_byte_time); |
1607 if (rv < 0) { | 1611 if (rv < 0) { |
1608 DCHECK_NE(rv, ERR_IO_PENDING); | 1612 DCHECK_NE(rv, ERR_IO_PENDING); |
1609 CloseActiveStream(stream_id, rv); | 1613 CloseActiveStream(stream_id, rv); |
1610 return false; | 1614 return false; |
1611 } | 1615 } |
1612 return true; | 1616 return true; |
1613 } | 1617 } |
1614 | 1618 |
1615 void SpdySession::OnSynStream(SpdyStreamId stream_id, | 1619 void SpdySession::OnSynStream(SpdyStreamId stream_id, |
1616 SpdyStreamId associated_stream_id, | 1620 SpdyStreamId associated_stream_id, |
1617 SpdyPriority priority, | 1621 SpdyPriority priority, |
1618 uint8 credential_slot, | 1622 uint8 credential_slot, |
1619 bool fin, | 1623 bool fin, |
1620 bool unidirectional, | 1624 bool unidirectional, |
1621 const SpdyHeaderBlock& headers) { | 1625 const SpdyHeaderBlock& headers) { |
| 1626 base::Time response_time = base::Time::Now(); |
| 1627 base::TimeTicks recv_first_byte_time = base::TimeTicks::Now(); |
| 1628 |
1622 if (net_log_.IsLoggingAllEvents()) { | 1629 if (net_log_.IsLoggingAllEvents()) { |
1623 net_log_.AddEvent( | 1630 net_log_.AddEvent( |
1624 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, | 1631 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, |
1625 base::Bind(&NetLogSpdySynCallback, | 1632 base::Bind(&NetLogSpdySynCallback, |
1626 &headers, fin, unidirectional, | 1633 &headers, fin, unidirectional, |
1627 stream_id, associated_stream_id)); | 1634 stream_id, associated_stream_id)); |
1628 } | 1635 } |
1629 | 1636 |
1630 // Server-initiated streams should have even sequence numbers. | 1637 // Server-initiated streams should have even sequence numbers. |
1631 if ((stream_id & 0x1) != 0) { | 1638 if ((stream_id & 0x1) != 0) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 request_priority, | 1715 request_priority, |
1709 stream_initial_send_window_size_, | 1716 stream_initial_send_window_size_, |
1710 stream_initial_recv_window_size_, | 1717 stream_initial_recv_window_size_, |
1711 net_log_)); | 1718 net_log_)); |
1712 stream->set_stream_id(stream_id); | 1719 stream->set_stream_id(stream_id); |
1713 | 1720 |
1714 DeleteExpiredPushedStreams(); | 1721 DeleteExpiredPushedStreams(); |
1715 unclaimed_pushed_streams_[url] = | 1722 unclaimed_pushed_streams_[url] = |
1716 std::pair<SpdyStream*, base::TimeTicks>(stream.get(), time_func_()); | 1723 std::pair<SpdyStream*, base::TimeTicks>(stream.get(), time_func_()); |
1717 | 1724 |
1718 stream->set_response_received(); | |
1719 InsertActivatedStream(stream.Pass()); | 1725 InsertActivatedStream(stream.Pass()); |
1720 | 1726 |
1721 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1727 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1722 if (it == active_streams_.end()) { | 1728 if (it == active_streams_.end()) { |
1723 NOTREACHED(); | 1729 NOTREACHED(); |
1724 return; | 1730 return; |
1725 } | 1731 } |
1726 | 1732 |
1727 // Parse the headers. | 1733 // Parse the headers. |
1728 if (!Respond(headers, it->second)) | 1734 if (!Respond(headers, response_time, recv_first_byte_time, it->second)) |
1729 return; | 1735 return; |
1730 | 1736 |
1731 base::StatsCounter push_requests("spdy.pushed_streams"); | 1737 base::StatsCounter push_requests("spdy.pushed_streams"); |
1732 push_requests.Increment(); | 1738 push_requests.Increment(); |
1733 } | 1739 } |
1734 | 1740 |
1735 void SpdySession::DeleteExpiredPushedStreams() { | 1741 void SpdySession::DeleteExpiredPushedStreams() { |
1736 if (unclaimed_pushed_streams_.empty()) | 1742 if (unclaimed_pushed_streams_.empty()) |
1737 return; | 1743 return; |
1738 | 1744 |
(...skipping 22 matching lines...) Expand all Loading... |
1761 CloseActiveStream(stream->stream_id(), ERR_INVALID_SPDY_STREAM); | 1767 CloseActiveStream(stream->stream_id(), ERR_INVALID_SPDY_STREAM); |
1762 } | 1768 } |
1763 } | 1769 } |
1764 next_unclaimed_push_stream_sweep_time_ = time_func_() + | 1770 next_unclaimed_push_stream_sweep_time_ = time_func_() + |
1765 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); | 1771 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); |
1766 } | 1772 } |
1767 | 1773 |
1768 void SpdySession::OnSynReply(SpdyStreamId stream_id, | 1774 void SpdySession::OnSynReply(SpdyStreamId stream_id, |
1769 bool fin, | 1775 bool fin, |
1770 const SpdyHeaderBlock& headers) { | 1776 const SpdyHeaderBlock& headers) { |
| 1777 base::Time response_time = base::Time::Now(); |
| 1778 base::TimeTicks recv_first_byte_time = base::TimeTicks::Now(); |
| 1779 |
1771 if (net_log().IsLoggingAllEvents()) { | 1780 if (net_log().IsLoggingAllEvents()) { |
1772 net_log().AddEvent( | 1781 net_log().AddEvent( |
1773 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, | 1782 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, |
1774 base::Bind(&NetLogSpdySynCallback, | 1783 base::Bind(&NetLogSpdySynCallback, |
1775 &headers, fin, false, // not unidirectional | 1784 &headers, fin, false, // not unidirectional |
1776 stream_id, 0)); | 1785 stream_id, 0)); |
1777 } | 1786 } |
1778 | 1787 |
1779 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1788 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1780 if (it == active_streams_.end()) { | 1789 if (it == active_streams_.end()) { |
1781 // NOTE: it may just be that the stream was cancelled. | 1790 // NOTE: it may just be that the stream was cancelled. |
1782 return; | 1791 return; |
1783 } | 1792 } |
1784 | 1793 |
1785 SpdyStream* stream = it->second; | 1794 SpdyStream* stream = it->second; |
1786 CHECK_EQ(stream->stream_id(), stream_id); | 1795 CHECK_EQ(stream->stream_id(), stream_id); |
1787 | 1796 |
1788 if (stream->response_received()) { | 1797 if (stream->ReceivedInitialResponseHeaders()) { |
1789 stream->LogStreamError(ERR_SYN_REPLY_NOT_RECEIVED, | 1798 stream->LogStreamError(ERR_SYN_REPLY_NOT_RECEIVED, |
1790 "Received duplicate SYN_REPLY for stream."); | 1799 "Received duplicate SYN_REPLY for stream."); |
1791 RecordProtocolErrorHistogram(PROTOCOL_ERROR_SYN_REPLY_NOT_RECEIVED); | 1800 RecordProtocolErrorHistogram(PROTOCOL_ERROR_SYN_REPLY_NOT_RECEIVED); |
1792 CloseActiveStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR); | 1801 CloseActiveStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR); |
1793 return; | 1802 return; |
1794 } | 1803 } |
1795 stream->set_response_received(); | |
1796 | 1804 |
1797 Respond(headers, stream); | 1805 Respond(headers, response_time, recv_first_byte_time, stream); |
1798 } | 1806 } |
1799 | 1807 |
1800 void SpdySession::OnHeaders(SpdyStreamId stream_id, | 1808 void SpdySession::OnHeaders(SpdyStreamId stream_id, |
1801 bool fin, | 1809 bool fin, |
1802 const SpdyHeaderBlock& headers) { | 1810 const SpdyHeaderBlock& headers) { |
1803 if (net_log().IsLoggingAllEvents()) { | 1811 if (net_log().IsLoggingAllEvents()) { |
1804 net_log().AddEvent( | 1812 net_log().AddEvent( |
1805 NetLog::TYPE_SPDY_SESSION_RECV_HEADERS, | 1813 NetLog::TYPE_SPDY_SESSION_RECV_HEADERS, |
1806 base::Bind(&NetLogSpdySynCallback, | 1814 base::Bind(&NetLogSpdySynCallback, |
1807 &headers, fin, /*unidirectional=*/false, | 1815 &headers, fin, /*unidirectional=*/false, |
1808 stream_id, 0)); | 1816 stream_id, 0)); |
1809 } | 1817 } |
1810 | 1818 |
1811 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1819 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1812 if (it == active_streams_.end()) { | 1820 if (it == active_streams_.end()) { |
1813 // NOTE: it may just be that the stream was cancelled. | 1821 // NOTE: it may just be that the stream was cancelled. |
1814 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; | 1822 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; |
1815 return; | 1823 return; |
1816 } | 1824 } |
1817 | 1825 |
1818 CHECK_EQ(it->second->stream_id(), stream_id); | 1826 CHECK_EQ(it->second->stream_id(), stream_id); |
1819 | 1827 |
1820 int rv = it->second->OnHeaders(headers); | 1828 int rv = it->second->OnAdditionalResponseHeadersReceived(headers); |
1821 if (rv < 0) { | 1829 if (rv < 0) { |
1822 DCHECK_NE(rv, ERR_IO_PENDING); | 1830 DCHECK_NE(rv, ERR_IO_PENDING); |
1823 CloseActiveStream(stream_id, rv); | 1831 CloseActiveStream(stream_id, rv); |
1824 } | 1832 } |
1825 } | 1833 } |
1826 | 1834 |
1827 void SpdySession::OnRstStream(SpdyStreamId stream_id, | 1835 void SpdySession::OnRstStream(SpdyStreamId stream_id, |
1828 SpdyRstStreamStatus status) { | 1836 SpdyRstStreamStatus status) { |
1829 std::string description; | 1837 std::string description; |
1830 net_log().AddEvent( | 1838 net_log().AddEvent( |
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2458 if (!queue->empty()) { | 2466 if (!queue->empty()) { |
2459 SpdyStreamId stream_id = queue->front(); | 2467 SpdyStreamId stream_id = queue->front(); |
2460 queue->pop_front(); | 2468 queue->pop_front(); |
2461 return stream_id; | 2469 return stream_id; |
2462 } | 2470 } |
2463 } | 2471 } |
2464 return 0; | 2472 return 0; |
2465 } | 2473 } |
2466 | 2474 |
2467 } // namespace net | 2475 } // namespace net |
OLD | NEW |