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 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1631 void SpdySession::OnSynStreamCompressed( | 1631 void SpdySession::OnSynStreamCompressed( |
1632 size_t uncompressed_size, | 1632 size_t uncompressed_size, |
1633 size_t compressed_size) { | 1633 size_t compressed_size) { |
1634 // Make sure we avoid early decimal truncation. | 1634 // Make sure we avoid early decimal truncation. |
1635 int compression_pct = 100 - (100 * compressed_size) / uncompressed_size; | 1635 int compression_pct = 100 - (100 * compressed_size) / uncompressed_size; |
1636 UMA_HISTOGRAM_PERCENTAGE("Net.SpdySynStreamCompressionPercentage", | 1636 UMA_HISTOGRAM_PERCENTAGE("Net.SpdySynStreamCompressionPercentage", |
1637 compression_pct); | 1637 compression_pct); |
1638 } | 1638 } |
1639 | 1639 |
1640 | 1640 |
1641 bool SpdySession::Respond(const SpdyHeaderBlock& headers, SpdyStream* stream) { | 1641 bool SpdySession::Respond(const SpdyHeaderBlock& response_headers, |
| 1642 base::Time response_time, |
| 1643 base::TimeTicks recv_first_byte_time, |
| 1644 SpdyStream* stream) { |
1642 int rv = OK; | 1645 int rv = OK; |
1643 SpdyStreamId stream_id = stream->stream_id(); | 1646 SpdyStreamId stream_id = stream->stream_id(); |
1644 // May invalidate |stream|. | 1647 // May invalidate |stream|. |
1645 rv = stream->OnResponseHeadersReceived(headers); | 1648 rv = stream->OnInitialResponseHeadersReceived( |
| 1649 response_headers, response_time, recv_first_byte_time); |
1646 if (rv < 0) { | 1650 if (rv < 0) { |
1647 DCHECK_NE(rv, ERR_IO_PENDING); | 1651 DCHECK_NE(rv, ERR_IO_PENDING); |
1648 CloseActiveStream(stream_id, rv); | 1652 CloseActiveStream(stream_id, rv); |
1649 return false; | 1653 return false; |
1650 } | 1654 } |
1651 return true; | 1655 return true; |
1652 } | 1656 } |
1653 | 1657 |
1654 void SpdySession::OnSynStream(SpdyStreamId stream_id, | 1658 void SpdySession::OnSynStream(SpdyStreamId stream_id, |
1655 SpdyStreamId associated_stream_id, | 1659 SpdyStreamId associated_stream_id, |
1656 SpdyPriority priority, | 1660 SpdyPriority priority, |
1657 uint8 credential_slot, | 1661 uint8 credential_slot, |
1658 bool fin, | 1662 bool fin, |
1659 bool unidirectional, | 1663 bool unidirectional, |
1660 const SpdyHeaderBlock& headers) { | 1664 const SpdyHeaderBlock& headers) { |
| 1665 base::Time response_time = base::Time::Now(); |
| 1666 base::TimeTicks recv_first_byte_time = base::TimeTicks::Now(); |
| 1667 |
1661 if (net_log_.IsLoggingAllEvents()) { | 1668 if (net_log_.IsLoggingAllEvents()) { |
1662 net_log_.AddEvent( | 1669 net_log_.AddEvent( |
1663 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, | 1670 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, |
1664 base::Bind(&NetLogSpdySynCallback, | 1671 base::Bind(&NetLogSpdySynCallback, |
1665 &headers, fin, unidirectional, | 1672 &headers, fin, unidirectional, |
1666 stream_id, associated_stream_id)); | 1673 stream_id, associated_stream_id)); |
1667 } | 1674 } |
1668 | 1675 |
1669 // Server-initiated streams should have even sequence numbers. | 1676 // Server-initiated streams should have even sequence numbers. |
1670 if ((stream_id & 0x1) != 0) { | 1677 if ((stream_id & 0x1) != 0) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 new SpdyStream(SPDY_PUSH_STREAM, this, gurl.PathForRequest(), | 1753 new SpdyStream(SPDY_PUSH_STREAM, this, gurl.PathForRequest(), |
1747 request_priority, | 1754 request_priority, |
1748 stream_initial_send_window_size_, | 1755 stream_initial_send_window_size_, |
1749 stream_initial_recv_window_size_, | 1756 stream_initial_recv_window_size_, |
1750 net_log_)); | 1757 net_log_)); |
1751 stream->set_stream_id(stream_id); | 1758 stream->set_stream_id(stream_id); |
1752 | 1759 |
1753 DeleteExpiredPushedStreams(); | 1760 DeleteExpiredPushedStreams(); |
1754 unclaimed_pushed_streams_[url] = PushedStreamInfo(stream_id, time_func_()); | 1761 unclaimed_pushed_streams_[url] = PushedStreamInfo(stream_id, time_func_()); |
1755 | 1762 |
1756 stream->set_response_received(); | |
1757 InsertActivatedStream(stream.Pass()); | 1763 InsertActivatedStream(stream.Pass()); |
1758 | 1764 |
1759 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1765 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1760 if (it == active_streams_.end()) { | 1766 if (it == active_streams_.end()) { |
1761 NOTREACHED(); | 1767 NOTREACHED(); |
1762 return; | 1768 return; |
1763 } | 1769 } |
1764 | 1770 |
1765 // Parse the headers. | 1771 // Parse the headers. |
1766 if (!Respond(headers, it->second.stream)) | 1772 if (!Respond(headers, response_time, recv_first_byte_time, it->second.stream)) |
1767 return; | 1773 return; |
1768 | 1774 |
1769 base::StatsCounter push_requests("spdy.pushed_streams"); | 1775 base::StatsCounter push_requests("spdy.pushed_streams"); |
1770 push_requests.Increment(); | 1776 push_requests.Increment(); |
1771 } | 1777 } |
1772 | 1778 |
1773 void SpdySession::DeleteExpiredPushedStreams() { | 1779 void SpdySession::DeleteExpiredPushedStreams() { |
1774 if (unclaimed_pushed_streams_.empty()) | 1780 if (unclaimed_pushed_streams_.empty()) |
1775 return; | 1781 return; |
1776 | 1782 |
(...skipping 24 matching lines...) Expand all Loading... |
1801 CloseActiveStream(*it, ERR_INVALID_SPDY_STREAM); | 1807 CloseActiveStream(*it, ERR_INVALID_SPDY_STREAM); |
1802 } | 1808 } |
1803 | 1809 |
1804 next_unclaimed_push_stream_sweep_time_ = time_func_() + | 1810 next_unclaimed_push_stream_sweep_time_ = time_func_() + |
1805 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); | 1811 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); |
1806 } | 1812 } |
1807 | 1813 |
1808 void SpdySession::OnSynReply(SpdyStreamId stream_id, | 1814 void SpdySession::OnSynReply(SpdyStreamId stream_id, |
1809 bool fin, | 1815 bool fin, |
1810 const SpdyHeaderBlock& headers) { | 1816 const SpdyHeaderBlock& headers) { |
| 1817 base::Time response_time = base::Time::Now(); |
| 1818 base::TimeTicks recv_first_byte_time = base::TimeTicks::Now(); |
| 1819 |
1811 if (net_log().IsLoggingAllEvents()) { | 1820 if (net_log().IsLoggingAllEvents()) { |
1812 net_log().AddEvent( | 1821 net_log().AddEvent( |
1813 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, | 1822 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, |
1814 base::Bind(&NetLogSpdySynCallback, | 1823 base::Bind(&NetLogSpdySynCallback, |
1815 &headers, fin, false, // not unidirectional | 1824 &headers, fin, false, // not unidirectional |
1816 stream_id, 0)); | 1825 stream_id, 0)); |
1817 } | 1826 } |
1818 | 1827 |
1819 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1828 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1820 if (it == active_streams_.end()) { | 1829 if (it == active_streams_.end()) { |
1821 // NOTE: it may just be that the stream was cancelled. | 1830 // NOTE: it may just be that the stream was cancelled. |
1822 return; | 1831 return; |
1823 } | 1832 } |
1824 | 1833 |
1825 SpdyStream* stream = it->second.stream; | 1834 SpdyStream* stream = it->second.stream; |
1826 CHECK_EQ(stream->stream_id(), stream_id); | 1835 CHECK_EQ(stream->stream_id(), stream_id); |
1827 | 1836 |
1828 if (!it->second.waiting_for_syn_reply) { | 1837 if (!it->second.waiting_for_syn_reply) { |
1829 const std::string& error = | 1838 const std::string& error = |
1830 "Received duplicate SYN_REPLY for stream."; | 1839 "Received duplicate SYN_REPLY for stream."; |
1831 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); | 1840 stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); |
1832 ResetStream(stream_id, stream->priority(), | 1841 ResetStream(stream_id, stream->priority(), |
1833 RST_STREAM_STREAM_IN_USE, error); | 1842 RST_STREAM_STREAM_IN_USE, error); |
1834 return; | 1843 return; |
1835 } | 1844 } |
1836 stream->set_response_received(); | |
1837 it->second.waiting_for_syn_reply = false; | 1845 it->second.waiting_for_syn_reply = false; |
1838 | 1846 |
1839 Respond(headers, stream); | 1847 Respond(headers, response_time, recv_first_byte_time, stream); |
1840 } | 1848 } |
1841 | 1849 |
1842 void SpdySession::OnHeaders(SpdyStreamId stream_id, | 1850 void SpdySession::OnHeaders(SpdyStreamId stream_id, |
1843 bool fin, | 1851 bool fin, |
1844 const SpdyHeaderBlock& headers) { | 1852 const SpdyHeaderBlock& headers) { |
1845 if (net_log().IsLoggingAllEvents()) { | 1853 if (net_log().IsLoggingAllEvents()) { |
1846 net_log().AddEvent( | 1854 net_log().AddEvent( |
1847 NetLog::TYPE_SPDY_SESSION_RECV_HEADERS, | 1855 NetLog::TYPE_SPDY_SESSION_RECV_HEADERS, |
1848 base::Bind(&NetLogSpdySynCallback, | 1856 base::Bind(&NetLogSpdySynCallback, |
1849 &headers, fin, /*unidirectional=*/false, | 1857 &headers, fin, /*unidirectional=*/false, |
1850 stream_id, 0)); | 1858 stream_id, 0)); |
1851 } | 1859 } |
1852 | 1860 |
1853 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 1861 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
1854 if (it == active_streams_.end()) { | 1862 if (it == active_streams_.end()) { |
1855 // NOTE: it may just be that the stream was cancelled. | 1863 // NOTE: it may just be that the stream was cancelled. |
1856 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; | 1864 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; |
1857 return; | 1865 return; |
1858 } | 1866 } |
1859 | 1867 |
1860 SpdyStream* stream = it->second.stream; | 1868 SpdyStream* stream = it->second.stream; |
1861 CHECK_EQ(stream->stream_id(), stream_id); | 1869 CHECK_EQ(stream->stream_id(), stream_id); |
1862 | 1870 |
1863 int rv = stream->OnHeaders(headers); | 1871 int rv = stream->OnAdditionalResponseHeadersReceived(headers); |
1864 if (rv < 0) { | 1872 if (rv < 0) { |
1865 DCHECK_NE(rv, ERR_IO_PENDING); | 1873 DCHECK_NE(rv, ERR_IO_PENDING); |
1866 CloseActiveStream(stream_id, rv); | 1874 CloseActiveStream(stream_id, rv); |
1867 } | 1875 } |
1868 } | 1876 } |
1869 | 1877 |
1870 void SpdySession::OnRstStream(SpdyStreamId stream_id, | 1878 void SpdySession::OnRstStream(SpdyStreamId stream_id, |
1871 SpdyRstStreamStatus status) { | 1879 SpdyRstStreamStatus status) { |
1872 std::string description; | 1880 std::string description; |
1873 net_log().AddEvent( | 1881 net_log().AddEvent( |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2506 if (!queue->empty()) { | 2514 if (!queue->empty()) { |
2507 SpdyStreamId stream_id = queue->front(); | 2515 SpdyStreamId stream_id = queue->front(); |
2508 queue->pop_front(); | 2516 queue->pop_front(); |
2509 return stream_id; | 2517 return stream_id; |
2510 } | 2518 } |
2511 } | 2519 } |
2512 return 0; | 2520 return 0; |
2513 } | 2521 } |
2514 | 2522 |
2515 } // namespace net | 2523 } // namespace net |
OLD | NEW |