| 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 |