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

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: Fix compile due to merge 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
« no previous file with comments | « net/http/http_stream_factory_impl_request.cc ('k') | net/net.gyp » ('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/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 // BidirectionalStreamJob::Delegate to wait until response headers are
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 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool( 1512 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetTransportSocketPool(
1436 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1513 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1437 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( 1514 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
1438 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1515 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1439 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1516 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1440 ASSERT_EQ(0u, 1517 ASSERT_EQ(0u,
1441 static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory()) 1518 static_cast<HttpStreamFactoryImpl*>(session->http_stream_factory())
1442 ->num_orphaned_jobs()); 1519 ->num_orphaned_jobs());
1443 } 1520 }
1444 1521
1522 class HttpStreamFactoryBidirectionalQuicTest
1523 : public ::testing::Test,
1524 public ::testing::WithParamInterface<QuicVersion> {
1525 protected:
1526 HttpStreamFactoryBidirectionalQuicTest()
1527 : clock_(new MockClock),
1528 packet_maker_(GetParam(), 0, clock_, "www.example.org"),
1529 random_generator_(0),
1530 proxy_service_(ProxyService::CreateDirect()),
1531 ssl_config_service_(new SSLConfigServiceDefaults) {
1532 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
1533 }
1534
1535 void Initialize() {
1536 params_.enable_quic = true;
1537 params_.http_server_properties = http_server_properties_.GetWeakPtr();
1538 params_.quic_host_whitelist.insert("www.example.org");
1539 params_.quic_random = &random_generator_;
1540 params_.quic_clock = clock_;
1541
1542 // Load a certificate that is valid for *.example.org
1543 scoped_refptr<X509Certificate> test_cert(
1544 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1545 EXPECT_TRUE(test_cert.get());
1546 verify_details_.cert_verify_result.verified_cert = test_cert;
1547 verify_details_.cert_verify_result.is_issued_by_known_root = true;
1548 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
1549 crypto_client_stream_factory_.set_handshake_mode(
1550 MockCryptoClientStream::CONFIRM_HANDSHAKE);
1551 params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
1552 params_.quic_supported_versions = test::SupportedVersions(GetParam());
1553 params_.transport_security_state = &transport_security_state_;
1554 params_.host_resolver = &host_resolver_;
1555 params_.proxy_service = proxy_service_.get();
1556 params_.ssl_config_service = ssl_config_service_.get();
1557 params_.client_socket_factory = &socket_factory_;
1558 session_.reset(new HttpNetworkSession(params_));
1559 session_->quic_stream_factory()->set_require_confirmation(false);
1560 }
1561
1562 void AddQuicAlternativeService() {
1563 const AlternativeService alternative_service(QUIC, "www.example.org", 443);
1564 AlternativeServiceInfoVector alternative_service_info_vector;
1565 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1566 alternative_service_info_vector.push_back(
1567 AlternativeServiceInfo(alternative_service, 1.0, expiration));
1568 HostPortPair host_port_pair(alternative_service.host_port_pair());
1569 http_server_properties_.SetAlternativeServices(
1570 host_port_pair, alternative_service_info_vector);
1571 };
1572
1573 test::QuicTestPacketMaker& packet_maker() { return packet_maker_; }
1574
1575 MockClientSocketFactory& socket_factory() { return socket_factory_; }
1576
1577 HttpNetworkSession* session() { return session_.get(); }
1578
1579 private:
1580 MockClock* clock_; // Owned by QuicStreamFactory
1581 test::QuicTestPacketMaker packet_maker_;
1582 MockClientSocketFactory socket_factory_;
1583 scoped_ptr<HttpNetworkSession> session_;
1584 test::MockRandom random_generator_;
1585 ProofVerifyDetailsChromium verify_details_;
1586 MockCryptoClientStreamFactory crypto_client_stream_factory_;
1587 HttpServerPropertiesImpl http_server_properties_;
1588 TransportSecurityState transport_security_state_;
1589 MockHostResolver host_resolver_;
1590 scoped_ptr<ProxyService> proxy_service_;
1591 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
1592 HttpNetworkSession::Params params_;
1593 };
1594
1595 INSTANTIATE_TEST_CASE_P(Version,
1596 HttpStreamFactoryBidirectionalQuicTest,
1597 ::testing::ValuesIn(QuicSupportedVersions()));
1598
1599 TEST_P(HttpStreamFactoryBidirectionalQuicTest,
1600 RequestBidirectionalStreamJobQuicAlternative) {
1601 GURL url = GURL("https://www.example.org");
1602
1603 MockQuicData mock_quic_data;
1604 SpdyPriority priority =
1605 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
1606 size_t spdy_headers_frame_length;
1607 mock_quic_data.AddWrite(packet_maker().MakeRequestHeadersPacket(
1608 1, test::kClientDataStreamId1, /*should_include_version=*/true,
1609 /*fin=*/true, priority,
1610 packet_maker().GetRequestHeaders("GET", "https", "/"),
1611 &spdy_headers_frame_length));
1612 size_t spdy_response_headers_frame_length;
1613 mock_quic_data.AddRead(packet_maker().MakeResponseHeadersPacket(
1614 1, test::kClientDataStreamId1, /*should_include_version=*/false,
1615 /*fin=*/true, packet_maker().GetResponseHeaders("200"),
1616 &spdy_response_headers_frame_length));
1617 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
1618 mock_quic_data.AddSocketDataToFactory(&socket_factory());
1619
1620 // Add hanging data for http job.
1621 scoped_ptr<StaticSocketDataProvider> hanging_data;
1622 hanging_data.reset(new StaticSocketDataProvider());
1623 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
1624 hanging_data->set_connect_data(hanging_connect);
1625 socket_factory().AddSocketDataProvider(hanging_data.get());
1626 SSLSocketDataProvider ssl_data(ASYNC, OK);
1627 socket_factory().AddSSLSocketDataProvider(&ssl_data);
1628
1629 // Set up QUIC as alternative_service.
1630 AddQuicAlternativeService();
1631 Initialize();
1632
1633 // Now request a stream.
1634 SSLConfig ssl_config;
1635 HttpRequestInfo request_info;
1636 request_info.method = "GET";
1637 request_info.url = GURL("https://www.example.org");
1638 request_info.load_flags = 0;
1639
1640 StreamRequestWaiter waiter;
1641 scoped_ptr<HttpStreamRequest> request(
1642 session()->http_stream_factory()->RequestBidirectionalStreamJob(
1643 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter,
1644 BoundNetLog()));
1645
1646 waiter.WaitForStream();
1647 EXPECT_TRUE(waiter.stream_done());
1648 EXPECT_FALSE(waiter.websocket_stream());
1649 ASSERT_FALSE(waiter.stream());
1650 ASSERT_TRUE(waiter.bidirectional_stream_job());
1651 BidirectionalStreamJob* job = waiter.bidirectional_stream_job();
1652
1653 BidirectionalStreamRequestInfo bidi_request_info;
1654 bidi_request_info.method = "GET";
1655 bidi_request_info.url = GURL("https://www.example.org/");
1656 bidi_request_info.end_stream_on_headers = true;
1657 bidi_request_info.priority = LOWEST;
1658
1659 TestBidirectionalDelegate delegate;
1660 job->Start(&bidi_request_info, BoundNetLog(), &delegate, nullptr);
1661 delegate.WaitUntilDone();
1662
1663 scoped_refptr<IOBuffer> buffer = new net::IOBuffer(1);
1664 EXPECT_EQ(OK, job->ReadData(buffer.get(), 1));
1665 EXPECT_EQ("200", delegate.response_headers().find(":status")->second);
1666 EXPECT_EQ(1, GetSocketPoolGroupCount(session()->GetTransportSocketPool(
1667 HttpNetworkSession::NORMAL_SOCKET_POOL)));
1668 EXPECT_EQ(1, GetSocketPoolGroupCount(session()->GetSSLSocketPool(
1669 HttpNetworkSession::NORMAL_SOCKET_POOL)));
1670 EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetTransportSocketPool(
1671 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1672 EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetSSLSocketPool(
1673 HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
1674 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1675 }
1676
1445 TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJobFailure) { 1677 TEST_P(HttpStreamFactoryTest, RequestBidirectionalStreamJobFailure) {
1446 SpdySessionDependencies session_deps(GetParam(), 1678 SpdySessionDependencies session_deps(GetParam(),
1447 ProxyService::CreateDirect()); 1679 ProxyService::CreateDirect());
1448 1680
1449 MockRead mock_read(ASYNC, OK); 1681 MockRead mock_read(ASYNC, OK);
1450 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0); 1682 SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
1451 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1683 socket_data.set_connect_data(MockConnect(ASYNC, OK));
1452 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 1684 session_deps.socket_factory->AddSocketDataProvider(&socket_data);
1453 1685
1454 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1686 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1923 EXPECT_TRUE(waiter.used_proxy_info().is_direct());
1692 1924
1693 // Make sure there is no orphaned job. it is already canceled. 1925 // Make sure there is no orphaned job. it is already canceled.
1694 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( 1926 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
1695 session->http_stream_factory_for_websocket())->num_orphaned_jobs()); 1927 session->http_stream_factory_for_websocket())->num_orphaned_jobs());
1696 } 1928 }
1697 1929
1698 } // namespace 1930 } // namespace
1699 1931
1700 } // namespace net 1932 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_stream_factory_impl_request.cc ('k') | net/net.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698