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

Side by Side Diff: net/http/http_stream_factory_impl_unittest.cc

Issue 1744693002: Implement QUIC-based net::BidirectionalStream (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@basecl
Patch Set: Address Ryan's comments Created 4 years, 9 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
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/http/http_stream_factory_impl.h" 5 #include "net/http/http_stream_factory_impl.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/run_loop.h"
14 #include "net/base/port_util.h" 15 #include "net/base/port_util.h"
15 #include "net/base/test_completion_callback.h" 16 #include "net/base/test_completion_callback.h"
17 #include "net/base/test_data_directory.h"
16 #include "net/cert/mock_cert_verifier.h" 18 #include "net/cert/mock_cert_verifier.h"
17 #include "net/dns/mock_host_resolver.h" 19 #include "net/dns/mock_host_resolver.h"
18 #include "net/http/http_auth_handler_factory.h" 20 #include "net/http/http_auth_handler_factory.h"
19 #include "net/http/http_network_session.h" 21 #include "net/http/http_network_session.h"
20 #include "net/http/http_network_session_peer.h" 22 #include "net/http/http_network_session_peer.h"
21 #include "net/http/http_network_transaction.h" 23 #include "net/http/http_network_transaction.h"
22 #include "net/http/http_request_info.h" 24 #include "net/http/http_request_info.h"
23 #include "net/http/http_server_properties.h" 25 #include "net/http/http_server_properties.h"
24 #include "net/http/http_server_properties_impl.h" 26 #include "net/http/http_server_properties_impl.h"
25 #include "net/http/http_stream.h" 27 #include "net/http/http_stream.h"
26 #include "net/http/transport_security_state.h" 28 #include "net/http/transport_security_state.h"
27 #include "net/log/net_log.h" 29 #include "net/log/net_log.h"
28 #include "net/net_features.h" 30 #include "net/net_features.h"
29 #include "net/proxy/proxy_info.h" 31 #include "net/proxy/proxy_info.h"
30 #include "net/proxy/proxy_service.h" 32 #include "net/proxy/proxy_service.h"
33 #include "net/quic/quic_http_utils.h"
31 #include "net/quic/quic_server_id.h" 34 #include "net/quic/quic_server_id.h"
35 #include "net/quic/test_tools/crypto_test_utils.h"
36 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
37 #include "net/quic/test_tools/mock_random.h"
32 #include "net/quic/test_tools/quic_stream_factory_peer.h" 38 #include "net/quic/test_tools/quic_stream_factory_peer.h"
39 #include "net/quic/test_tools/quic_test_packet_maker.h"
40 #include "net/quic/test_tools/quic_test_utils.h"
33 #include "net/socket/client_socket_handle.h" 41 #include "net/socket/client_socket_handle.h"
34 #include "net/socket/mock_client_socket_pool_manager.h" 42 #include "net/socket/mock_client_socket_pool_manager.h"
35 #include "net/socket/next_proto.h" 43 #include "net/socket/next_proto.h"
36 #include "net/socket/socket_test_util.h" 44 #include "net/socket/socket_test_util.h"
37 #include "net/spdy/spdy_session.h" 45 #include "net/spdy/spdy_session.h"
38 #include "net/spdy/spdy_session_pool.h" 46 #include "net/spdy/spdy_session_pool.h"
39 #include "net/spdy/spdy_test_util_common.h" 47 #include "net/spdy/spdy_test_util_common.h"
40 #include "net/ssl/ssl_config_service.h" 48 #include "net/ssl/ssl_config_service.h"
41 #include "net/ssl/ssl_config_service_defaults.h" 49 #include "net/ssl/ssl_config_service_defaults.h"
50 #include "net/test/cert_test_util.h"
51
42 // This file can be included from net/http even though 52 // This file can be included from net/http even though
43 // it is in net/websockets because it doesn't 53 // it is in net/websockets because it doesn't
44 // introduce any link dependency to net/websockets. 54 // introduce any link dependency to net/websockets.
45 #include "net/websockets/websocket_handshake_stream_base.h" 55 #include "net/websockets/websocket_handshake_stream_base.h"
46 #include "testing/gtest/include/gtest/gtest.h" 56 #include "testing/gtest/include/gtest/gtest.h"
47 57
48 #if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM) 58 #if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
49 #include "net/http/bidirectional_stream_job.h" 59 #include "net/http/bidirectional_stream_job.h"
60 #include "net/http/bidirectional_stream_request_info.h"
50 #endif 61 #endif
51 62
52 namespace net { 63 namespace net {
53 64
54 class BidirectionalStreamJob; 65 class BidirectionalStreamJob;
55 66
56 namespace { 67 namespace {
57 68
58 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase { 69 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
59 public: 70 public:
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 const ProxyRetryInfoMap& retry_info = 742 const ProxyRetryInfoMap& retry_info =
732 session->proxy_service()->proxy_retry_info(); 743 session->proxy_service()->proxy_retry_info();
733 EXPECT_EQ(1u, retry_info.size()) << mock_error[i]; 744 EXPECT_EQ(1u, retry_info.size()) << mock_error[i];
734 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 745 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
735 746
736 ProxyRetryInfoMap::const_iterator iter = retry_info.find("quic://bad:99"); 747 ProxyRetryInfoMap::const_iterator iter = retry_info.find("quic://bad:99");
737 EXPECT_TRUE(iter != retry_info.end()) << mock_error[i]; 748 EXPECT_TRUE(iter != retry_info.end()) << mock_error[i];
738 } 749 }
739 } 750 }
740 751
752 #if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM)
753 // a BidirectionalStreamJob::Delegate to wait until response headers are
mef 2016/02/29 16:26:52 nit: loose 'a'?
xunjieli 2016/02/29 16:34:09 Done.
754 // received.
755 class TestBidirectionalDelegate : public BidirectionalStreamJob::Delegate {
756 public:
757 void WaitUntilDone() { loop_.Run(); }
758
759 const SpdyHeaderBlock& response_headers() const { return response_headers_; }
760
761 private:
762 void OnHeadersSent() override {}
763 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
764 response_headers_ = response_headers;
765 loop_.Quit();
766 }
767 void OnDataRead(int bytes_read) override { NOTREACHED(); }
768 void OnDataSent() override { NOTREACHED(); }
769 void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
770 NOTREACHED();
771 }
772 void OnFailed(int error) override { NOTREACHED(); }
773 base::RunLoop loop_;
774 SpdyHeaderBlock response_headers_;
775 };
776
777 // Helper class to encapsulate MockReads and MockWrites for QUIC.
778 // Simplify ownership issues and the interaction with the MockSocketFactory.
779 class MockQuicData {
780 public:
781 MockQuicData() : packet_number_(0) {}
782
783 ~MockQuicData() { STLDeleteElements(&packets_); }
784
785 void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
786 reads_.push_back(
787 MockRead(ASYNC, packet->data(), packet->length(), packet_number_++));
788 packets_.push_back(packet.release());
789 }
790
791 void AddRead(IoMode mode, int rv) {
792 reads_.push_back(MockRead(mode, rv, packet_number_++));
793 }
794
795 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
796 writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(),
797 packet_number_++));
798 packets_.push_back(packet.release());
799 }
800
801 void AddSocketDataToFactory(MockClientSocketFactory* factory) {
802 MockRead* reads = reads_.empty() ? nullptr : &reads_[0];
803 MockWrite* writes = writes_.empty() ? nullptr : &writes_[0];
804 socket_data_.reset(
805 new SequencedSocketData(reads, reads_.size(), writes, writes_.size()));
806 factory->AddSocketDataProvider(socket_data_.get());
807 }
808
809 private:
810 std::vector<QuicEncryptedPacket*> packets_;
811 std::vector<MockWrite> writes_;
812 std::vector<MockRead> reads_;
813 size_t packet_number_;
814 scoped_ptr<SequencedSocketData> socket_data_;
815 };
816 #endif
817
741 } // namespace 818 } // namespace
742 819
743 TEST_P(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad) { 820 TEST_P(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad) {
744 // Checks if a 821 // Checks if a
745 scoped_ptr<ProxyService> proxy_service; 822 scoped_ptr<ProxyService> proxy_service;
746 proxy_service = ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"); 823 proxy_service = ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT");
747 824
748 HttpNetworkSession::Params params; 825 HttpNetworkSession::Params params;
749 params.enable_quic = true; 826 params.enable_quic = true;
750 params.enable_quic_for_proxies = true; 827 params.enable_quic_for_proxies = true;
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( 1510 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool(
1434 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1511 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1435 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( 1512 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
1436 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1513 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1437 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1514 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1438 ASSERT_EQ(0u, 1515 ASSERT_EQ(0u,
1439 static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory()) 1516 static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory())
1440 ->num_orphaned_jobs()); 1517 ->num_orphaned_jobs());
1441 } 1518 }
1442 1519
1520 class HttpStreamFactoryBidirectionalQuicTest
1521 : public ::testing::Test,
1522 public ::testing::WithParamInterface<QuicVersion> {
1523 protected:
1524 HttpStreamFactoryBidirectionalQuicTest()
1525 : clock_(new MockClock),
1526 maker_(GetParam(), 0, clock_, "www.example.org"),
mef 2016/02/29 16:26:52 nit: maker seems a bit too generic, maybe call it
xunjieli 2016/02/29 16:34:09 Done.
1527 random_generator_(0),
1528 proxy_service_(ProxyService::CreateDirect()),
1529 ssl_config_service_(new SSLConfigServiceDefaults) {
1530 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
1531 }
1532
1533 void Initialize() {
1534 params_.enable_quic = true;
1535 params_.http_server_properties = http_server_properties_.GetWeakPtr();
1536 params_.quic_host_whitelist.insert("www.example.org");
1537 params_.quic_random = &random_generator_;
1538 params_.quic_clock = clock_;
1539
1540 // Load a certificate that is valid for *.example.org
1541 scoped_refptr<X509Certificate> test_cert(
1542 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1543 EXPECT_TRUE(test_cert.get());
1544 verify_details_.cert_verify_result.verified_cert = test_cert;
1545 verify_details_.cert_verify_result.is_issued_by_known_root = true;
1546 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
1547 crypto_client_stream_factory_.set_handshake_mode(
1548 MockCryptoClientStream::CONFIRM_HANDSHAKE);
1549 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
1550 params_.quic_supported_versions = test::SupportedVersions(GetParam());
1551 params_.transport_security_state = &transport_security_state_;
1552 params_.host_resolver = &host_resolver_;
1553 params_.proxy_service = proxy_service_.get();
1554 params_.ssl_config_service = ssl_config_service_.get();
1555 params_.client_socket_factory = &socket_factory_;
1556 session_.reset(new HttpNetworkSession(params_));
1557 session_->quic_stream_factory()->set_require_confirmation(false);
1558 }
1559
1560 void AddQuicAlternativeService() {
1561 const AlternativeService alternative_service(QUIC, "www.example.org", 443);
1562 AlternativeServiceInfoVector alternative_service_info_vector;
1563 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1564 alternative_service_info_vector.push_back(
1565 AlternativeServiceInfo(alternative_service, 1.0, expiration));
1566 HostPortPair host_port_pair(alternative_service.host_port_pair());
1567 http_server_properties_.SetAlternativeServices(
1568 host_port_pair, alternative_service_info_vector);
1569 };
1570
1571 test::QuicTestPacketMaker& maker() { return maker_; }
1572
1573 MockClientSocketFactory& socket_factory() { return socket_factory_; }
1574
1575 HttpNetworkSession* session() { return session_.get(); }
1576
1577 private:
1578 MockClock* clock_; // Owned by QuicStreamFactory
1579 test::QuicTestPacketMaker maker_;
1580 MockClientSocketFactory socket_factory_;
1581 scoped_ptr<HttpNetworkSession> session_;
1582 test::MockRandom random_generator_;
1583 ProofVerifyDetailsChromium verify_details_;
1584 MockCryptoClientStreamFactory crypto_client_stream_factory_;
1585 HttpServerPropertiesImpl http_server_properties_;
1586 TransportSecurityState transport_security_state_;
1587 MockHostResolver host_resolver_;
1588 scoped_ptr<ProxyService> proxy_service_;
1589 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
1590 HttpNetworkSession::Params params_;
1591 };
1592
1593 INSTANTIATE_TEST_CASE_P(Version,
1594 HttpStreamFactoryBidirectionalQuicTest,
1595 ::testing::ValuesIn(QuicSupportedVersions()));
1596
1597 TEST_P(HttpStreamFactoryBidirectionalQuicTest,
1598 RequestBidirectionalStreamJobQuicAlternative) {
1599 GURL url = GURL("https://www.example.org");
1600
1601 MockQuicData mock_quic_data;
1602 SpdyPriority priority =
1603 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
1604 size_t spdy_headers_frame_length;
1605 mock_quic_data.AddWrite(maker().MakeRequestHeadersPacket(
1606 1, test::kClientDataStreamId1, /*should_include_version=*/true,
1607 /*fin=*/true, priority, maker().GetRequestHeaders("GET", "https", "/"),
1608 &spdy_headers_frame_length));
1609 size_t spdy_response_headers_frame_length;
1610 mock_quic_data.AddRead(maker().MakeResponseHeadersPacket(
1611 1, test::kClientDataStreamId1, /*should_include_version=*/false,
1612 /*fin=*/true, maker().GetResponseHeaders("200"),
1613 &spdy_response_headers_frame_length));
1614 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
1615 mock_quic_data.AddSocketDataToFactory(&socket_factory());
1616
1617 // Add hanging data for http job.
1618 scoped_ptr<StaticSocketDataProvider> hanging_data;
1619 hanging_data.reset(new StaticSocketDataProvider());
1620 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
1621 hanging_data->set_connect_data(hanging_connect);
1622 socket_factory().AddSocketDataProvider(hanging_data.get());
1623 SSLSocketDataProvider ssl_data(ASYNC, OK);
1624 socket_factory().AddSSLSocketDataProvider(&ssl_data);
1625
1626 // Set up QUIC as alternative_service.
1627 AddQuicAlternativeService();
1628 Initialize();
1629
1630 // Now request a stream.
1631 SSLConfig ssl_config;
1632 HttpRequestInfo request_info;
1633 request_info.method = "GET";
1634 request_info.url = GURL("https://www.example.org");
1635 request_info.load_flags = 0;
1636
1637 StreamRequestWaiter waiter;
1638 scoped_ptr<HttpStreamRequest> request(
1639 session()->http_stream_factory()->RequestBidirectionalStreamJob(
1640 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1641 BoundNetLog()));
1642
1643 waiter.WaitForStream();
1644 EXPECT_TRUE(waiter.stream_done());
1645 EXPECT_FALSE(waiter.websocket_stream());
1646 ASSERT_FALSE(waiter.stream());
1647 ASSERT_TRUE(waiter.bidirectional_stream_job());
1648 BidirectionalStreamJob* job = waiter.bidirectional_stream_job();
1649
1650 BidirectionalStreamRequestInfo bidi_request_info;
1651 bidi_request_info.method = "GET";
1652 bidi_request_info.url = GURL("https://www.example.org/");
1653 bidi_request_info.end_stream_on_headers = true;
1654 bidi_request_info.priority = LOWEST;
1655
1656 TestBidirectionalDelegate delegate;
1657 job->Start(&bidi_request_info, BoundNetLog(), &delegate, nullptr);
1658 delegate.WaitUntilDone();
1659
1660 scoped_refptr<IOBuffer> buffer = new net::IOBuffer(1);
1661 EXPECT_EQ(OK, job->ReadData(buffer.get(), 1));
1662 EXPECT_EQ("200", delegate.response_headers().find(":status")->second);
1663 EXPECT_EQ(1, GetSocketPoolGroupCount(session()->GetTransportSocketPool(
1664 HttpNetworkSession::NORMAL_SOCKET_POOL)));
1665 EXPECT_EQ(1, GetSocketPoolGroupCount(session()->GetSSLSocketPool(
1666 HttpNetworkSession::NORMAL_SOCKET_POOL)));
1667 EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetTransportSocketPool(
1668 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1669 EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetSSLSocketPool(
1670 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1671 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1672 }
1673
1443 TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJobFailure) { 1674 TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJobFailure) {
1444 SpdySessionDependencies session_deps(GetParam(), 1675 SpdySessionDependencies session_deps(GetParam(),
1445 ProxyService::CreateDirect()); 1676 ProxyService::CreateDirect());
1446 1677
1447 MockRead mock_read(ASYNC, OK); 1678 MockRead mock_read(ASYNC, OK);
1448 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0); 1679 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
1449 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1680 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1450 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 1681 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1451 1682
1452 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1683 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1920 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1690 1921
1691 // Make sure there is no orphaned job. it is already canceled. 1922 // Make sure there is no orphaned job. it is already canceled.
1692 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( 1923 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
1693 session->http_stream_factory_for_websocket())->num_orphaned_jobs()); 1924 session->http_stream_factory_for_websocket())->num_orphaned_jobs());
1694 } 1925 }
1695 1926
1696 } // namespace 1927 } // namespace
1697 1928
1698 } // namespace net 1929 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698