Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: net/spdy/spdy_session_spdy3_unittest.cc

Issue 13834009: SPDY - Re-land greedy read support for SpdySession (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merging changes from tip Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_session_spdy2_unittest.cc ('k') | net/spdy/spdy_session_test_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/memory/scoped_ptr.h"
8 #include "net/base/io_buffer.h"
7 #include "net/base/ip_endpoint.h" 9 #include "net/base/ip_endpoint.h"
8 #include "net/base/net_log_unittest.h" 10 #include "net/base/net_log_unittest.h"
9 #include "net/base/request_priority.h" 11 #include "net/base/request_priority.h"
10 #include "net/base/test_data_directory.h" 12 #include "net/base/test_data_directory.h"
13 #include "net/base/test_data_stream.h"
11 #include "net/dns/host_cache.h" 14 #include "net/dns/host_cache.h"
12 #include "net/spdy/spdy_http_utils.h" 15 #include "net/spdy/spdy_http_utils.h"
13 #include "net/spdy/spdy_io_buffer.h" 16 #include "net/spdy/spdy_io_buffer.h"
14 #include "net/spdy/spdy_session_pool.h" 17 #include "net/spdy/spdy_session_pool.h"
18 #include "net/spdy/spdy_session_test_util.h"
15 #include "net/spdy/spdy_stream.h" 19 #include "net/spdy/spdy_stream.h"
16 #include "net/spdy/spdy_stream_test_util.h" 20 #include "net/spdy/spdy_stream_test_util.h"
17 #include "net/spdy/spdy_test_util_common.h" 21 #include "net/spdy/spdy_test_util_common.h"
18 #include "net/spdy/spdy_test_util_spdy3.h" 22 #include "net/spdy/spdy_test_util_spdy3.h"
19 #include "net/test/cert_test_util.h" 23 #include "net/test/cert_test_util.h"
20 #include "testing/platform_test.h" 24 #include "testing/platform_test.h"
21 25
22 using namespace net::test_spdy3; 26 using namespace net::test_spdy3;
23 27
24 namespace net { 28 namespace net {
(...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 spdy_stream1 = NULL; 1649 spdy_stream1 = NULL;
1646 1650
1647 scoped_refptr<SpdyStream> spdy_stream2 = 1651 scoped_refptr<SpdyStream> spdy_stream2 =
1648 CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog()); 1652 CreateStreamSynchronously(session, test_url_, MEDIUM, BoundNetLog());
1649 ASSERT_TRUE(spdy_stream2.get() != NULL); 1653 ASSERT_TRUE(spdy_stream2.get() != NULL);
1650 EXPECT_EQ(spdy_stream2->send_window_size(), window_size); 1654 EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
1651 spdy_stream2->Cancel(); 1655 spdy_stream2->Cancel();
1652 spdy_stream2 = NULL; 1656 spdy_stream2 = NULL;
1653 } 1657 }
1654 1658
1659 // Test that SpdySession::DoRead reads data from the socket without yielding.
1660 // This test makes 32k - 1 bytes of data available on the socket for reading. It
1661 // then verifies that it has read all the available data without yielding.
1662 TEST_F(SpdySessionSpdy3Test, ReadDataWithoutYielding) {
1663 MockConnect connect_data(SYNCHRONOUS, OK);
1664 BufferedSpdyFramer framer(3, false);
1665
1666 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
1667 MockWrite writes[] = {
1668 CreateMockWrite(*req1, 0),
1669 };
1670
1671 // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size).
1672 ASSERT_EQ(32 * 1024, kMaxReadBytes);
1673 const int kPayloadSize =
1674 kMaxReadBytes / 4 - framer.GetControlFrameHeaderSize();
1675 TestDataStream test_stream;
1676 scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
1677 char* payload_data = payload->data();
1678 test_stream.GetBytes(payload_data, kPayloadSize);
1679
1680 scoped_ptr<SpdyFrame> partial_data_frame(
1681 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
1682 scoped_ptr<SpdyFrame> finish_data_frame(
1683 framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN));
1684
1685 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
1686
1687 // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k
1688 // bytes.
1689 MockRead reads[] = {
1690 CreateMockRead(*resp1, 1),
1691 CreateMockRead(*partial_data_frame, 2),
1692 CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
1693 CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
1694 CreateMockRead(*finish_data_frame, 5, SYNCHRONOUS),
1695 MockRead(ASYNC, 0, 6) // EOF
1696 };
1697
1698 // Create SpdySession and SpdyStream and send the request.
1699 DeterministicSocketData data(reads, arraysize(reads),
1700 writes, arraysize(writes));
1701 data.set_connect_data(connect_data);
1702 session_deps_.host_resolver->set_synchronous_mode(true);
1703 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1704
1705 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1706 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1707
1708 CreateDeterministicNetworkSession();
1709
1710 scoped_refptr<SpdySession> session = CreateInitializedSession();
1711
1712 GURL url1("http://www.google.com");
1713 scoped_refptr<SpdyStream> spdy_stream1 =
1714 CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
1715 ASSERT_TRUE(spdy_stream1.get() != NULL);
1716 EXPECT_EQ(0u, spdy_stream1->stream_id());
1717
1718 spdy_stream1->set_spdy_headers(ConstructGetHeaderBlock(url1.spec()));
1719 EXPECT_TRUE(spdy_stream1->HasUrl());
1720 spdy_stream1->SendRequest(false);
1721
1722 // Set up the TaskObserver to verify SpdySession::DoRead doesn't post a task.
1723 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead");
1724
1725 // Run until 1st read.
1726 EXPECT_EQ(0u, spdy_stream1->stream_id());
1727 data.RunFor(2);
1728 EXPECT_EQ(1u, spdy_stream1->stream_id());
1729 EXPECT_EQ(0u, observer.executed_count());
1730
1731 // Read all the data and verify SpdySession::DoRead has not posted a task.
1732 data.RunFor(4);
1733
1734 // Verify task observer's executed_count is zero, which indicates DoRead read
1735 // all the available data.
1736 EXPECT_EQ(0u, observer.executed_count());
1737 EXPECT_TRUE(data.at_write_eof());
1738 EXPECT_TRUE(data.at_read_eof());
1739 }
1740
1741 // Test that SpdySession::DoRead yields while reading the data. This test makes
1742 // 32k + 1 bytes of data available on the socket for reading. It then verifies
1743 // that DoRead has yielded even though there is data available for it to read
1744 // (i.e, socket()->Read didn't return ERR_IO_PENDING during socket reads).
1745 TEST_F(SpdySessionSpdy3Test, TestYieldingDuringReadData) {
1746 MockConnect connect_data(SYNCHRONOUS, OK);
1747 BufferedSpdyFramer framer(3, false);
1748
1749 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
1750 MockWrite writes[] = {
1751 CreateMockWrite(*req1, 0),
1752 };
1753
1754 // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size).
1755 ASSERT_EQ(32 * 1024, kMaxReadBytes);
1756 const int kPayloadSize =
1757 kMaxReadBytes / 4 - framer.GetControlFrameHeaderSize();
1758 TestDataStream test_stream;
1759 scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(kPayloadSize));
1760 char* payload_data = payload->data();
1761 test_stream.GetBytes(payload_data, kPayloadSize);
1762
1763 scoped_ptr<SpdyFrame> partial_data_frame(
1764 framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
1765 scoped_ptr<SpdyFrame> finish_data_frame(
1766 framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN));
1767
1768 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
1769
1770 // Write 1 byte more than kMaxReadBytes to check that DoRead yields.
1771 MockRead reads[] = {
1772 CreateMockRead(*resp1, 1),
1773 CreateMockRead(*partial_data_frame, 2),
1774 CreateMockRead(*partial_data_frame, 3, SYNCHRONOUS),
1775 CreateMockRead(*partial_data_frame, 4, SYNCHRONOUS),
1776 CreateMockRead(*partial_data_frame, 5, SYNCHRONOUS),
1777 CreateMockRead(*finish_data_frame, 6, SYNCHRONOUS),
1778 MockRead(ASYNC, 0, 7) // EOF
1779 };
1780
1781 // Create SpdySession and SpdyStream and send the request.
1782 DeterministicSocketData data(reads, arraysize(reads),
1783 writes, arraysize(writes));
1784 data.set_connect_data(connect_data);
1785 session_deps_.host_resolver->set_synchronous_mode(true);
1786 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1787
1788 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1789 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1790
1791 CreateDeterministicNetworkSession();
1792
1793 scoped_refptr<SpdySession> session = CreateInitializedSession();
1794
1795 GURL url1("http://www.google.com");
1796 scoped_refptr<SpdyStream> spdy_stream1 =
1797 CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
1798 ASSERT_TRUE(spdy_stream1.get() != NULL);
1799 EXPECT_EQ(0u, spdy_stream1->stream_id());
1800
1801 spdy_stream1->set_spdy_headers(ConstructGetHeaderBlock(url1.spec()));
1802 EXPECT_TRUE(spdy_stream1->HasUrl());
1803 spdy_stream1->SendRequest(false);
1804
1805 // Set up the TaskObserver to verify SpdySession::DoRead posts a task.
1806 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead");
1807
1808 // Run until 1st read.
1809 EXPECT_EQ(0u, spdy_stream1->stream_id());
1810 data.RunFor(2);
1811 EXPECT_EQ(1u, spdy_stream1->stream_id());
1812 EXPECT_EQ(0u, observer.executed_count());
1813
1814 // Read all the data and verify SpdySession::DoRead has posted a task.
1815 data.RunFor(6);
1816
1817 // Verify task observer's executed_count is 1, which indicates DoRead has
1818 // posted only one task and thus yielded though there is data available for it
1819 // to read.
1820 EXPECT_EQ(1u, observer.executed_count());
1821 EXPECT_TRUE(data.at_write_eof());
1822 EXPECT_TRUE(data.at_read_eof());
1823 }
1824
1825 // Test that SpdySession::DoRead() tests interactions of yielding + async,
1826 // by doing the following MockReads.
1827 //
1828 // MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K
1829 // ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K.
1830 //
1831 // The above reads 26K synchronously. Since that is less that 32K, we will
1832 // attempt to read again. However, that DoRead() will return ERR_IO_PENDING
1833 // (because of async read), so DoRead() will yield. When we come back, DoRead()
1834 // will read the results from the async read, and rest of the data
1835 // synchronously.
1836 TEST_F(SpdySessionSpdy3Test, TestYieldingDuringAsyncReadData) {
1837 MockConnect connect_data(SYNCHRONOUS, OK);
1838 BufferedSpdyFramer framer(3, false);
1839
1840 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
1841 MockWrite writes[] = {
1842 CreateMockWrite(*req1, 0),
1843 };
1844
1845 // Build buffer of size kMaxReadBytes / 4 (-spdy_data_frame_size).
1846 ASSERT_EQ(32 * 1024, kMaxReadBytes);
1847 TestDataStream test_stream;
1848 const int kEightKPayloadSize =
1849 kMaxReadBytes / 4 - framer.GetControlFrameHeaderSize();
1850 scoped_refptr<net::IOBuffer> eightk_payload(
1851 new net::IOBuffer(kEightKPayloadSize));
1852 char* eightk_payload_data = eightk_payload->data();
1853 test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize);
1854
1855 // Build buffer of 2k size.
1856 TestDataStream test_stream2;
1857 const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024;
1858 scoped_refptr<net::IOBuffer> twok_payload(
1859 new net::IOBuffer(kTwoKPayloadSize));
1860 char* twok_payload_data = twok_payload->data();
1861 test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize);
1862
1863 scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame(
1864 1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE));
1865 scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame(
1866 1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE));
1867 scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame(
1868 1, "h", 1, DATA_FLAG_FIN));
1869
1870 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
1871
1872 MockRead reads[] = {
1873 CreateMockRead(*resp1, 1),
1874 CreateMockRead(*eightk_data_frame, 2),
1875 CreateMockRead(*eightk_data_frame, 3, SYNCHRONOUS),
1876 CreateMockRead(*eightk_data_frame, 4, SYNCHRONOUS),
1877 CreateMockRead(*twok_data_frame, 5, SYNCHRONOUS),
1878 CreateMockRead(*eightk_data_frame, 6, ASYNC),
1879 CreateMockRead(*eightk_data_frame, 7, SYNCHRONOUS),
1880 CreateMockRead(*eightk_data_frame, 8, SYNCHRONOUS),
1881 CreateMockRead(*eightk_data_frame, 9, SYNCHRONOUS),
1882 CreateMockRead(*twok_data_frame, 10, SYNCHRONOUS),
1883 CreateMockRead(*finish_data_frame, 11, SYNCHRONOUS),
1884 MockRead(ASYNC, 0, 12) // EOF
1885 };
1886
1887 // Create SpdySession and SpdyStream and send the request.
1888 DeterministicSocketData data(reads, arraysize(reads),
1889 writes, arraysize(writes));
1890 data.set_connect_data(connect_data);
1891 session_deps_.host_resolver->set_synchronous_mode(true);
1892 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1893
1894 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1895 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1896
1897 CreateDeterministicNetworkSession();
1898
1899 scoped_refptr<SpdySession> session = CreateInitializedSession();
1900
1901 GURL url1("http://www.google.com");
1902 scoped_refptr<SpdyStream> spdy_stream1 =
1903 CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
1904 ASSERT_TRUE(spdy_stream1.get() != NULL);
1905 EXPECT_EQ(0u, spdy_stream1->stream_id());
1906
1907 spdy_stream1->set_spdy_headers(ConstructGetHeaderBlock(url1.spec()));
1908 EXPECT_TRUE(spdy_stream1->HasUrl());
1909 spdy_stream1->SendRequest(false);
1910
1911 // Set up the TaskObserver to monitor SpdySession::DoRead posting of tasks.
1912 SpdySessionTestTaskObserver observer("spdy_session.cc", "DoRead");
1913
1914 // Run until 1st read.
1915 EXPECT_EQ(0u, spdy_stream1->stream_id());
1916 data.RunFor(2);
1917 EXPECT_EQ(1u, spdy_stream1->stream_id());
1918 EXPECT_EQ(0u, observer.executed_count());
1919
1920 // Read all the data and verify SpdySession::DoRead has posted a task.
1921 data.RunFor(12);
1922
1923 // Verify task observer's executed_count is 1, which indicates DoRead has
1924 // posted only one task and thus yielded though there is data available for
1925 // it to read.
1926 EXPECT_EQ(1u, observer.executed_count());
1927 EXPECT_TRUE(data.at_write_eof());
1928 EXPECT_TRUE(data.at_read_eof());
1929 }
1930
1931 // Send a GoAway frame when SpdySession is in DoLoop. If scoped_refptr to
1932 // <SpdySession> is deleted from SpdySession::DoLoop(), we get a crash because
1933 // GoAway could delete the SpdySession from the SpdySessionPool and the last
1934 // reference to SpdySession.
1935 TEST_F(SpdySessionSpdy3Test, GoAwayWhileInDoLoop) {
1936 MockConnect connect_data(SYNCHRONOUS, OK);
1937 BufferedSpdyFramer framer(3, false);
1938
1939 scoped_ptr<SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, MEDIUM));
1940 MockWrite writes[] = {
1941 CreateMockWrite(*req1, 0),
1942 };
1943
1944 scoped_ptr<SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
1945 scoped_ptr<SpdyFrame> body1(ConstructSpdyBodyFrame(1, true));
1946 scoped_ptr<SpdyFrame> goaway(ConstructSpdyGoAway());
1947
1948 MockRead reads[] = {
1949 CreateMockRead(*resp1, 1),
1950 CreateMockRead(*body1, 2),
1951 CreateMockRead(*goaway, 3),
1952 MockRead(ASYNC, 0, 4) // EOF
1953 };
1954
1955 // Create SpdySession and SpdyStream and send the request.
1956 DeterministicSocketData data(reads, arraysize(reads),
1957 writes, arraysize(writes));
1958 data.set_connect_data(connect_data);
1959 session_deps_.host_resolver->set_synchronous_mode(true);
1960 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
1961
1962 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
1963 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
1964
1965 CreateDeterministicNetworkSession();
1966
1967 scoped_refptr<SpdySession> session = CreateInitializedSession();
1968
1969 GURL url1("http://www.google.com");
1970 scoped_refptr<SpdyStream> spdy_stream1 =
1971 CreateStreamSynchronously(session, url1, MEDIUM, BoundNetLog());
1972 ASSERT_TRUE(spdy_stream1.get() != NULL);
1973 EXPECT_EQ(0u, spdy_stream1->stream_id());
1974
1975 spdy_stream1->set_spdy_headers(ConstructGetHeaderBlock(url1.spec()));
1976 EXPECT_TRUE(spdy_stream1->HasUrl());
1977 spdy_stream1->SendRequest(false);
1978
1979 // Run until 1st read.
1980 EXPECT_EQ(0u, spdy_stream1->stream_id());
1981 data.RunFor(1);
1982 EXPECT_EQ(1u, spdy_stream1->stream_id());
1983
1984 // Drop the reference to the session.
1985 session = NULL;
1986
1987 // Run until GoAway.
1988 data.RunFor(2);
1989
1990 // Drop the reference to the stream which deletes its reference to the
1991 // SpdySession. Only references to SpdySession are held by DoLoop and
1992 // SpdySessionPool. If DoLoop doesn't hold the reference, we get a crash if
1993 // SpdySession is deleted from the SpdySessionPool.
1994 spdy_stream1 = NULL;
1995
1996 data.RunFor(2);
1997 EXPECT_TRUE(data.at_write_eof());
1998 EXPECT_TRUE(data.at_read_eof());
1999 }
2000
1655 // Within this framework, a SpdySession should be initialized with 2001 // Within this framework, a SpdySession should be initialized with
1656 // flow control enabled only for streams and with protocol version 3 2002 // flow control enabled only for streams and with protocol version 3
1657 // by default. 2003 // by default.
1658 TEST_F(SpdySessionSpdy3Test, ProtocolNegotiation) { 2004 TEST_F(SpdySessionSpdy3Test, ProtocolNegotiation) {
1659 session_deps_.host_resolver->set_synchronous_mode(true); 2005 session_deps_.host_resolver->set_synchronous_mode(true);
1660 2006
1661 MockConnect connect_data(SYNCHRONOUS, OK); 2007 MockConnect connect_data(SYNCHRONOUS, OK);
1662 MockRead reads[] = { 2008 MockRead reads[] = {
1663 MockRead(SYNCHRONOUS, 0, 0) // EOF 2009 MockRead(SYNCHRONOUS, 0, 0) // EOF
1664 }; 2010 };
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 EXPECT_EQ(0, delegate1.body_data_sent()); 2974 EXPECT_EQ(0, delegate1.body_data_sent());
2629 2975
2630 EXPECT_TRUE(delegate2.send_headers_completed()); 2976 EXPECT_TRUE(delegate2.send_headers_completed());
2631 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 2977 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
2632 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); 2978 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
2633 EXPECT_EQ("", delegate2.received_data()); 2979 EXPECT_EQ("", delegate2.received_data());
2634 EXPECT_EQ(0, delegate2.body_data_sent()); 2980 EXPECT_EQ(0, delegate2.body_data_sent());
2635 } 2981 }
2636 2982
2637 } // namespace net 2983 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session_spdy2_unittest.cc ('k') | net/spdy/spdy_session_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698