OLD | NEW |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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_job_controller.h" | 5 #include "net/http/http_stream_factory_impl_job_controller.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 return job_controller->main_job_is_blocked_; | 153 return job_controller->main_job_is_blocked_; |
154 } | 154 } |
155 static bool main_job_is_resumed( | 155 static bool main_job_is_resumed( |
156 HttpStreamFactoryImpl::JobController* job_controller) { | 156 HttpStreamFactoryImpl::JobController* job_controller) { |
157 return job_controller->main_job_is_resumed_; | 157 return job_controller->main_job_is_resumed_; |
158 } | 158 } |
159 }; | 159 }; |
160 | 160 |
161 class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { | 161 class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { |
162 public: | 162 public: |
163 HttpStreamFactoryImplJobControllerTest() | 163 HttpStreamFactoryImplJobControllerTest() { session_deps_.enable_quic = true; } |
164 : session_deps_(ProxyService::CreateDirect()), | |
165 random_generator_(0), | |
166 client_maker_(HttpNetworkSession::Params().quic_supported_versions[0], | |
167 0, | |
168 &clock_, | |
169 kServerHostname, | |
170 Perspective::IS_CLIENT), | |
171 use_alternative_proxy_(false), | |
172 is_preconnect_(false), | |
173 enable_ip_based_pooling_(true), | |
174 enable_alternative_services_(true), | |
175 test_proxy_delegate_(nullptr) { | |
176 session_deps_.enable_quic = true; | |
177 } | |
178 | 164 |
179 void UseAlternativeProxy() { | 165 void UseAlternativeProxy() { |
180 ASSERT_FALSE(test_proxy_delegate_); | 166 ASSERT_FALSE(test_proxy_delegate_); |
181 use_alternative_proxy_ = true; | 167 use_alternative_proxy_ = true; |
182 } | 168 } |
183 | 169 |
184 void SetPreconnect() { | 170 void SetPreconnect() { |
185 ASSERT_FALSE(test_proxy_delegate_); | 171 ASSERT_FALSE(test_proxy_delegate_); |
186 is_preconnect_ = true; | 172 is_preconnect_ = true; |
187 } | 173 } |
188 | 174 |
189 void DisableIPBasedPooling() { | 175 void DisableIPBasedPooling() { |
190 ASSERT_FALSE(test_proxy_delegate_); | 176 ASSERT_FALSE(test_proxy_delegate_); |
191 enable_ip_based_pooling_ = false; | 177 enable_ip_based_pooling_ = false; |
192 } | 178 } |
193 | 179 |
194 void DisableAlternativeServices() { | 180 void DisableAlternativeServices() { |
195 ASSERT_FALSE(test_proxy_delegate_); | 181 ASSERT_FALSE(test_proxy_delegate_); |
196 enable_alternative_services_ = false; | 182 enable_alternative_services_ = false; |
197 } | 183 } |
198 | 184 |
| 185 void SkipCreatingJobController() { |
| 186 ASSERT_FALSE(job_controller_); |
| 187 create_job_controller_ = false; |
| 188 } |
| 189 |
199 void Initialize(const HttpRequestInfo& request_info) { | 190 void Initialize(const HttpRequestInfo& request_info) { |
200 ASSERT_FALSE(test_proxy_delegate_); | 191 ASSERT_FALSE(test_proxy_delegate_); |
201 auto test_proxy_delegate = base::MakeUnique<TestProxyDelegate>(); | 192 auto test_proxy_delegate = base::MakeUnique<TestProxyDelegate>(); |
202 test_proxy_delegate_ = test_proxy_delegate.get(); | 193 test_proxy_delegate_ = test_proxy_delegate.get(); |
203 | 194 |
204 test_proxy_delegate->set_alternative_proxy_server( | 195 test_proxy_delegate->set_alternative_proxy_server( |
205 ProxyServer::FromPacString("QUIC myproxy.org:443")); | 196 ProxyServer::FromPacString("QUIC myproxy.org:443")); |
206 EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic()); | 197 EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic()); |
207 session_deps_.proxy_delegate = std::move(test_proxy_delegate); | 198 session_deps_.proxy_delegate = std::move(test_proxy_delegate); |
208 | 199 |
(...skipping 11 matching lines...) Expand all Loading... |
220 SpdySessionDependencies::CreateSessionParams(&session_deps_); | 211 SpdySessionDependencies::CreateSessionParams(&session_deps_); |
221 HttpNetworkSession::Context session_context = | 212 HttpNetworkSession::Context session_context = |
222 SpdySessionDependencies::CreateSessionContext(&session_deps_); | 213 SpdySessionDependencies::CreateSessionContext(&session_deps_); |
223 | 214 |
224 session_context.quic_crypto_client_stream_factory = | 215 session_context.quic_crypto_client_stream_factory = |
225 &crypto_client_stream_factory_; | 216 &crypto_client_stream_factory_; |
226 session_context.quic_random = &random_generator_; | 217 session_context.quic_random = &random_generator_; |
227 session_ = base::MakeUnique<HttpNetworkSession>(params, session_context); | 218 session_ = base::MakeUnique<HttpNetworkSession>(params, session_context); |
228 factory_ = | 219 factory_ = |
229 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); | 220 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); |
230 job_controller_ = new HttpStreamFactoryImpl::JobController( | 221 if (create_job_controller_) { |
231 factory_, &request_delegate_, session_.get(), &job_factory_, | 222 job_controller_ = new HttpStreamFactoryImpl::JobController( |
232 request_info, is_preconnect_, enable_ip_based_pooling_, | 223 factory_, &request_delegate_, session_.get(), &job_factory_, |
233 enable_alternative_services_, SSLConfig(), SSLConfig()); | 224 request_info, is_preconnect_, enable_ip_based_pooling_, |
234 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); | 225 enable_alternative_services_, SSLConfig(), SSLConfig()); |
| 226 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); |
| 227 } |
235 } | 228 } |
236 | 229 |
237 TestProxyDelegate* test_proxy_delegate() const { | 230 TestProxyDelegate* test_proxy_delegate() const { |
238 return test_proxy_delegate_; | 231 return test_proxy_delegate_; |
239 } | 232 } |
240 | 233 |
241 ~HttpStreamFactoryImplJobControllerTest() override { | 234 ~HttpStreamFactoryImplJobControllerTest() override { |
242 if (quic_data_) { | 235 if (quic_data_) { |
243 EXPECT_TRUE(quic_data_->AllReadDataConsumed()); | 236 EXPECT_TRUE(quic_data_->AllReadDataConsumed()); |
244 EXPECT_TRUE(quic_data_->AllWriteDataConsumed()); | 237 EXPECT_TRUE(quic_data_->AllWriteDataConsumed()); |
(...skipping 19 matching lines...) Expand all Loading... |
264 const AlternativeServiceInfoVector alternative_service_info_vector = | 257 const AlternativeServiceInfoVector alternative_service_info_vector = |
265 session_->http_server_properties()->GetAlternativeServiceInfos(server); | 258 session_->http_server_properties()->GetAlternativeServiceInfos(server); |
266 EXPECT_EQ(1u, alternative_service_info_vector.size()); | 259 EXPECT_EQ(1u, alternative_service_info_vector.size()); |
267 EXPECT_EQ(should_mark_broken, | 260 EXPECT_EQ(should_mark_broken, |
268 session_->http_server_properties()->IsAlternativeServiceBroken( | 261 session_->http_server_properties()->IsAlternativeServiceBroken( |
269 alternative_service_info_vector[0].alternative_service())); | 262 alternative_service_info_vector[0].alternative_service())); |
270 } | 263 } |
271 | 264 |
272 TestJobFactory job_factory_; | 265 TestJobFactory job_factory_; |
273 MockHttpStreamRequestDelegate request_delegate_; | 266 MockHttpStreamRequestDelegate request_delegate_; |
274 SpdySessionDependencies session_deps_; | 267 SpdySessionDependencies session_deps_{ProxyService::CreateDirect()}; |
275 std::unique_ptr<HttpNetworkSession> session_; | 268 std::unique_ptr<HttpNetworkSession> session_; |
276 HttpStreamFactoryImpl* factory_; | 269 HttpStreamFactoryImpl* factory_ = nullptr; |
277 HttpStreamFactoryImpl::JobController* job_controller_; | 270 HttpStreamFactoryImpl::JobController* job_controller_ = nullptr; |
278 std::unique_ptr<HttpStreamFactoryImpl::Request> request_; | 271 std::unique_ptr<HttpStreamFactoryImpl::Request> request_; |
279 std::unique_ptr<SequencedSocketData> tcp_data_; | 272 std::unique_ptr<SequencedSocketData> tcp_data_; |
280 std::unique_ptr<test::MockQuicData> quic_data_; | 273 std::unique_ptr<test::MockQuicData> quic_data_; |
281 MockCryptoClientStreamFactory crypto_client_stream_factory_; | 274 MockCryptoClientStreamFactory crypto_client_stream_factory_; |
282 MockClock clock_; | 275 MockClock clock_; |
283 test::MockRandom random_generator_; | 276 test::MockRandom random_generator_{0}; |
284 test::QuicTestPacketMaker client_maker_; | 277 test::QuicTestPacketMaker client_maker_{ |
| 278 HttpNetworkSession::Params().quic_supported_versions[0], 0, &clock_, |
| 279 kServerHostname, Perspective::IS_CLIENT}; |
285 | 280 |
286 protected: | 281 protected: |
287 bool use_alternative_proxy_; | 282 bool use_alternative_proxy_ = false; |
288 bool is_preconnect_; | 283 bool is_preconnect_ = false; |
289 bool enable_ip_based_pooling_; | 284 bool enable_ip_based_pooling_ = true; |
290 bool enable_alternative_services_; | 285 bool enable_alternative_services_ = true; |
291 | 286 |
292 private: | 287 private: |
293 // Not owned by |this|. | 288 // Not owned by |this|. |
294 TestProxyDelegate* test_proxy_delegate_; | 289 TestProxyDelegate* test_proxy_delegate_ = nullptr; |
| 290 bool create_job_controller_ = true; |
295 | 291 |
296 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest); | 292 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest); |
297 }; | 293 }; |
298 | 294 |
299 TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsSync) { | 295 TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsSync) { |
300 ProxyConfig proxy_config; | 296 ProxyConfig proxy_config; |
301 proxy_config.set_pac_url(GURL("http://fooproxyurl")); | 297 proxy_config.set_pac_url(GURL("http://fooproxyurl")); |
302 proxy_config.set_pac_mandatory(true); | 298 proxy_config.set_pac_mandatory(true); |
303 session_deps_.proxy_service.reset(new ProxyService( | 299 session_deps_.proxy_service.reset(new ProxyService( |
304 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | 300 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 PreconnectMultipleStreamsToH2Server) { | 1552 PreconnectMultipleStreamsToH2Server) { |
1557 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | 1553 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
1558 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); | 1554 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
1559 SetPreconnect(); | 1555 SetPreconnect(); |
1560 | 1556 |
1561 HttpRequestInfo request_info; | 1557 HttpRequestInfo request_info; |
1562 request_info.method = "GET"; | 1558 request_info.method = "GET"; |
1563 request_info.url = GURL("http://www.example.com"); | 1559 request_info.url = GURL("http://www.example.com"); |
1564 Initialize(request_info); | 1560 Initialize(request_info); |
1565 | 1561 |
| 1562 // Sets server support HTTP/2. |
1566 url::SchemeHostPort server(request_info.url); | 1563 url::SchemeHostPort server(request_info.url); |
1567 | |
1568 // Sets server support Http/2. | |
1569 session_->http_server_properties()->SetSupportsSpdy(server, true); | 1564 session_->http_server_properties()->SetSupportsSpdy(server, true); |
1570 | 1565 |
1571 job_controller_->Preconnect(/*num_streams=*/5); | 1566 job_controller_->Preconnect(/*num_streams=*/5); |
1572 // Only one job is started. | 1567 // Only one job is started. |
1573 EXPECT_TRUE(job_controller_->main_job()); | 1568 EXPECT_TRUE(job_controller_->main_job()); |
1574 EXPECT_FALSE(job_controller_->alternative_job()); | 1569 EXPECT_FALSE(job_controller_->alternative_job()); |
1575 EXPECT_EQ(HttpStreamFactoryImpl::PRECONNECT, | 1570 EXPECT_EQ(HttpStreamFactoryImpl::PRECONNECT, |
1576 job_controller_->main_job()->job_type()); | 1571 job_controller_->main_job()->job_type()); |
1577 // There is only 1 connect even though multiple streams were requested. | 1572 // There is only 1 connect even though multiple streams were requested. |
1578 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams( | 1573 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams( |
1579 job_controller_->main_job())); | 1574 job_controller_->main_job())); |
1580 | 1575 |
1581 base::RunLoop().RunUntilIdle(); | 1576 base::RunLoop().RunUntilIdle(); |
1582 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1577 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
1583 } | 1578 } |
1584 | 1579 |
| 1580 class JobControllerLimitMultipleH2Requests |
| 1581 : public HttpStreamFactoryImplJobControllerTest { |
| 1582 protected: |
| 1583 const int kNumRequests = 5; |
| 1584 void SetUp() override { SkipCreatingJobController(); } |
| 1585 }; |
| 1586 |
| 1587 TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequests) { |
| 1588 // Make sure there is only one socket connect. |
| 1589 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; |
| 1590 tcp_data_ = base::MakeUnique<SequencedSocketData>(reads, arraysize(reads), |
| 1591 nullptr, 0); |
| 1592 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
| 1593 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
| 1594 ssl_data->next_proto = kProtoHTTP2; |
| 1595 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
| 1596 HttpRequestInfo request_info; |
| 1597 request_info.method = "GET"; |
| 1598 request_info.url = GURL("https://www.example.com"); |
| 1599 Initialize(request_info); |
| 1600 SpdySessionPoolPeer pool_peer(session_->spdy_session_pool()); |
| 1601 pool_peer.SetEnableSendingInitialData(false); |
| 1602 |
| 1603 // Sets server support HTTP/2. |
| 1604 url::SchemeHostPort server(request_info.url); |
| 1605 session_->http_server_properties()->SetSupportsSpdy(server, true); |
| 1606 |
| 1607 std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates; |
| 1608 std::vector<std::unique_ptr<HttpStreamRequest>> requests; |
| 1609 for (int i = 0; i < kNumRequests; ++i) { |
| 1610 request_delegates.emplace_back( |
| 1611 base::MakeUnique<MockHttpStreamRequestDelegate>()); |
| 1612 HttpStreamFactoryImpl::JobController* job_controller = |
| 1613 new HttpStreamFactoryImpl::JobController( |
| 1614 factory_, request_delegates[i].get(), session_.get(), &job_factory_, |
| 1615 request_info, is_preconnect_, enable_ip_based_pooling_, |
| 1616 enable_alternative_services_, SSLConfig(), SSLConfig()); |
| 1617 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller); |
| 1618 auto request = job_controller->Start( |
| 1619 request_delegates[i].get(), nullptr, NetLogWithSource(), |
| 1620 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
| 1621 EXPECT_TRUE(job_controller->main_job()); |
| 1622 EXPECT_FALSE(job_controller->alternative_job()); |
| 1623 requests.push_back(std::move(request)); |
| 1624 } |
| 1625 |
| 1626 for (int i = 0; i < kNumRequests; ++i) { |
| 1627 // When a request is completed, delete it. This is needed because |
| 1628 // otherwise request will be completed twice. See crbug.com/706974. |
| 1629 EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _, _)) |
| 1630 .WillOnce(testing::InvokeWithoutArgs( |
| 1631 [this, &requests, i]() { requests[i].reset(); })); |
| 1632 } |
| 1633 |
| 1634 base::RunLoop().RunUntilIdle(); |
| 1635 requests.clear(); |
| 1636 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1637 } |
| 1638 |
| 1639 TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequestsFirstRequestHang) { |
| 1640 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
| 1641 // First socket connect hang. |
| 1642 auto hangdata = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 1643 hangdata->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
| 1644 session_deps_.socket_factory->AddSocketDataProvider(hangdata.get()); |
| 1645 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; |
| 1646 std::vector<std::unique_ptr<SequencedSocketData>> socket_data; |
| 1647 std::vector<std::unique_ptr<SSLSocketDataProvider>> ssl_socket_data; |
| 1648 // kNumRequests - 1 will resume themselves after a delay. There will be |
| 1649 // kNumRequests - 1 sockets opened. |
| 1650 for (int i = 0; i < kNumRequests - 1; i++) { |
| 1651 // Only the first one needs a MockRead because subsequent sockets are |
| 1652 // not used to establish a SpdySession. |
| 1653 auto tcp_data = |
| 1654 i == 0 ? base::MakeUnique<SequencedSocketData>(reads, arraysize(reads), |
| 1655 nullptr, 0) |
| 1656 : base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 1657 tcp_data->set_connect_data(MockConnect(ASYNC, OK)); |
| 1658 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
| 1659 ssl_data->next_proto = kProtoHTTP2; |
| 1660 session_deps_.socket_factory->AddSocketDataProvider(tcp_data.get()); |
| 1661 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
| 1662 socket_data.push_back(std::move(tcp_data)); |
| 1663 ssl_socket_data.push_back(std::move(ssl_data)); |
| 1664 } |
| 1665 HttpRequestInfo request_info; |
| 1666 request_info.method = "GET"; |
| 1667 request_info.url = GURL("https://www.example.com"); |
| 1668 Initialize(request_info); |
| 1669 SpdySessionPoolPeer pool_peer(session_->spdy_session_pool()); |
| 1670 pool_peer.SetEnableSendingInitialData(false); |
| 1671 |
| 1672 // Sets server support HTTP/2. |
| 1673 url::SchemeHostPort server(request_info.url); |
| 1674 session_->http_server_properties()->SetSupportsSpdy(server, true); |
| 1675 |
| 1676 std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates; |
| 1677 std::vector<std::unique_ptr<HttpStreamRequest>> requests; |
| 1678 for (int i = 0; i < kNumRequests; ++i) { |
| 1679 request_delegates.push_back( |
| 1680 base::MakeUnique<MockHttpStreamRequestDelegate>()); |
| 1681 HttpStreamFactoryImpl::JobController* job_controller = |
| 1682 new HttpStreamFactoryImpl::JobController( |
| 1683 factory_, request_delegates[i].get(), session_.get(), &job_factory_, |
| 1684 request_info, is_preconnect_, enable_ip_based_pooling_, |
| 1685 enable_alternative_services_, SSLConfig(), SSLConfig()); |
| 1686 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller); |
| 1687 auto request = job_controller->Start( |
| 1688 request_delegates[i].get(), nullptr, NetLogWithSource(), |
| 1689 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
| 1690 EXPECT_TRUE(job_controller->main_job()); |
| 1691 EXPECT_FALSE(job_controller->alternative_job()); |
| 1692 requests.push_back(std::move(request)); |
| 1693 } |
| 1694 |
| 1695 for (int i = 0; i < kNumRequests; ++i) { |
| 1696 // When a request is completed, delete it. This is needed because |
| 1697 // otherwise request will be completed twice. See crbug.com/706974. |
| 1698 EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _, _)) |
| 1699 .WillOnce(testing::InvokeWithoutArgs( |
| 1700 [this, &requests, i]() { requests[i].reset(); })); |
| 1701 } |
| 1702 |
| 1703 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 1704 test_task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds( |
| 1705 HttpStreamFactoryImpl::Job::kHTTP2ThrottleMs)); |
| 1706 base::RunLoop().RunUntilIdle(); |
| 1707 |
| 1708 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1709 EXPECT_TRUE(hangdata->AllReadDataConsumed()); |
| 1710 for (const auto& data : socket_data) { |
| 1711 EXPECT_TRUE(data->AllReadDataConsumed()); |
| 1712 EXPECT_TRUE(data->AllWriteDataConsumed()); |
| 1713 } |
| 1714 } |
| 1715 |
| 1716 TEST_F(JobControllerLimitMultipleH2Requests, |
| 1717 MultipleRequestsFirstRequestCanceled) { |
| 1718 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; |
| 1719 auto first_socket = base::MakeUnique<SequencedSocketData>( |
| 1720 reads, arraysize(reads), nullptr, 0); |
| 1721 first_socket->set_connect_data(MockConnect(ASYNC, OK)); |
| 1722 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
| 1723 ssl_data->next_proto = kProtoHTTP2; |
| 1724 session_deps_.socket_factory->AddSocketDataProvider(first_socket.get()); |
| 1725 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
| 1726 std::vector<std::unique_ptr<SequencedSocketData>> socket_data; |
| 1727 std::vector<std::unique_ptr<SSLSocketDataProvider>> ssl_socket_data; |
| 1728 // kNumRequests - 1 will be resumed when the first request is canceled. |
| 1729 for (int i = 0; i < kNumRequests - 1; i++) { |
| 1730 auto tcp_data = |
| 1731 base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 1732 tcp_data->set_connect_data(MockConnect(ASYNC, OK)); |
| 1733 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
| 1734 ssl_data->next_proto = kProtoHTTP2; |
| 1735 session_deps_.socket_factory->AddSocketDataProvider(tcp_data.get()); |
| 1736 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
| 1737 socket_data.push_back(std::move(tcp_data)); |
| 1738 ssl_socket_data.push_back(std::move(ssl_data)); |
| 1739 } |
| 1740 |
| 1741 HttpRequestInfo request_info; |
| 1742 request_info.method = "GET"; |
| 1743 request_info.url = GURL("https://www.example.com"); |
| 1744 Initialize(request_info); |
| 1745 SpdySessionPoolPeer pool_peer(session_->spdy_session_pool()); |
| 1746 pool_peer.SetEnableSendingInitialData(false); |
| 1747 |
| 1748 // Sets server support HTTP/2. |
| 1749 url::SchemeHostPort server(request_info.url); |
| 1750 session_->http_server_properties()->SetSupportsSpdy(server, true); |
| 1751 |
| 1752 std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates; |
| 1753 std::vector<std::unique_ptr<HttpStreamRequest>> requests; |
| 1754 for (int i = 0; i < kNumRequests; ++i) { |
| 1755 request_delegates.emplace_back( |
| 1756 base::MakeUnique<MockHttpStreamRequestDelegate>()); |
| 1757 HttpStreamFactoryImpl::JobController* job_controller = |
| 1758 new HttpStreamFactoryImpl::JobController( |
| 1759 factory_, request_delegates[i].get(), session_.get(), &job_factory_, |
| 1760 request_info, is_preconnect_, enable_ip_based_pooling_, |
| 1761 enable_alternative_services_, SSLConfig(), SSLConfig()); |
| 1762 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller); |
| 1763 auto request = job_controller->Start( |
| 1764 request_delegates[i].get(), nullptr, NetLogWithSource(), |
| 1765 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
| 1766 EXPECT_TRUE(job_controller->main_job()); |
| 1767 EXPECT_FALSE(job_controller->alternative_job()); |
| 1768 requests.push_back(std::move(request)); |
| 1769 } |
| 1770 // Cancel the first one. |
| 1771 requests[0].reset(); |
| 1772 |
| 1773 for (int i = 1; i < kNumRequests; ++i) { |
| 1774 // When a request is completed, delete it. This is needed because |
| 1775 // otherwise request will be completed twice. See crbug.com/706974. |
| 1776 EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _, _)) |
| 1777 .WillOnce(testing::InvokeWithoutArgs( |
| 1778 [this, &requests, i]() { requests[i].reset(); })); |
| 1779 } |
| 1780 base::RunLoop().RunUntilIdle(); |
| 1781 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1782 EXPECT_TRUE(first_socket->AllReadDataConsumed()); |
| 1783 for (const auto& data : socket_data) { |
| 1784 EXPECT_TRUE(data->AllReadDataConsumed()); |
| 1785 EXPECT_TRUE(data->AllWriteDataConsumed()); |
| 1786 } |
| 1787 } |
| 1788 |
| 1789 TEST_F(JobControllerLimitMultipleH2Requests, MultiplePreconnects) { |
| 1790 // Make sure there is only one socket connect. |
| 1791 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 1792 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
| 1793 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
| 1794 ssl_data->next_proto = kProtoHTTP2; |
| 1795 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
| 1796 HttpRequestInfo request_info; |
| 1797 request_info.method = "GET"; |
| 1798 request_info.url = GURL("https://www.example.com"); |
| 1799 SetPreconnect(); |
| 1800 Initialize(request_info); |
| 1801 |
| 1802 // Sets server support HTTP/2. |
| 1803 url::SchemeHostPort server(request_info.url); |
| 1804 session_->http_server_properties()->SetSupportsSpdy(server, true); |
| 1805 |
| 1806 std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates; |
| 1807 for (int i = 0; i < kNumRequests; ++i) { |
| 1808 request_delegates.emplace_back( |
| 1809 base::MakeUnique<MockHttpStreamRequestDelegate>()); |
| 1810 HttpStreamFactoryImpl::JobController* job_controller = |
| 1811 new HttpStreamFactoryImpl::JobController( |
| 1812 factory_, request_delegates[i].get(), session_.get(), &job_factory_, |
| 1813 request_info, is_preconnect_, enable_ip_based_pooling_, |
| 1814 enable_alternative_services_, SSLConfig(), SSLConfig()); |
| 1815 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller); |
| 1816 job_controller->Preconnect(1); |
| 1817 EXPECT_TRUE(job_controller->main_job()); |
| 1818 EXPECT_FALSE(job_controller->alternative_job()); |
| 1819 } |
| 1820 base::RunLoop().RunUntilIdle(); |
| 1821 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1822 } |
| 1823 |
| 1824 TEST_F(JobControllerLimitMultipleH2Requests, H1NegotiatedForFirstRequest) { |
| 1825 // First socket is an HTTP/1.1 socket. |
| 1826 auto first_socket = |
| 1827 base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 1828 first_socket->set_connect_data(MockConnect(ASYNC, OK)); |
| 1829 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
| 1830 session_deps_.socket_factory->AddSocketDataProvider(first_socket.get()); |
| 1831 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
| 1832 // Second socket is an HTTP/2 socket. |
| 1833 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)}; |
| 1834 auto second_socket = base::MakeUnique<SequencedSocketData>( |
| 1835 reads, arraysize(reads), nullptr, 0); |
| 1836 second_socket->set_connect_data(MockConnect(ASYNC, OK)); |
| 1837 auto second_ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
| 1838 second_ssl_data->next_proto = kProtoHTTP2; |
| 1839 session_deps_.socket_factory->AddSocketDataProvider(second_socket.get()); |
| 1840 session_deps_.socket_factory->AddSSLSocketDataProvider(second_ssl_data.get()); |
| 1841 |
| 1842 HttpRequestInfo request_info; |
| 1843 request_info.method = "GET"; |
| 1844 request_info.url = GURL("https://www.example.com"); |
| 1845 Initialize(request_info); |
| 1846 SpdySessionPoolPeer pool_peer(session_->spdy_session_pool()); |
| 1847 pool_peer.SetEnableSendingInitialData(false); |
| 1848 |
| 1849 // Sets server support HTTP/2. |
| 1850 url::SchemeHostPort server(request_info.url); |
| 1851 session_->http_server_properties()->SetSupportsSpdy(server, true); |
| 1852 |
| 1853 std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates; |
| 1854 std::vector<std::unique_ptr<HttpStreamRequest>> requests; |
| 1855 for (int i = 0; i < 2; ++i) { |
| 1856 request_delegates.emplace_back( |
| 1857 base::MakeUnique<MockHttpStreamRequestDelegate>()); |
| 1858 HttpStreamFactoryImpl::JobController* job_controller = |
| 1859 new HttpStreamFactoryImpl::JobController( |
| 1860 factory_, request_delegates[i].get(), session_.get(), &job_factory_, |
| 1861 request_info, is_preconnect_, enable_ip_based_pooling_, |
| 1862 enable_alternative_services_, SSLConfig(), SSLConfig()); |
| 1863 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller); |
| 1864 auto request = job_controller->Start( |
| 1865 request_delegates[i].get(), nullptr, NetLogWithSource(), |
| 1866 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY); |
| 1867 EXPECT_TRUE(job_controller->main_job()); |
| 1868 EXPECT_FALSE(job_controller->alternative_job()); |
| 1869 requests.push_back(std::move(request)); |
| 1870 } |
| 1871 |
| 1872 for (int i = 0; i < 2; ++i) { |
| 1873 // When a request is completed, delete it. This is needed because |
| 1874 // otherwise request will be completed twice. See crbug.com/706974. |
| 1875 EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _, _)) |
| 1876 .WillOnce(testing::InvokeWithoutArgs( |
| 1877 [this, &requests, i]() { requests[i].reset(); })); |
| 1878 } |
| 1879 base::RunLoop().RunUntilIdle(); |
| 1880 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1881 EXPECT_TRUE(first_socket->AllReadDataConsumed()); |
| 1882 EXPECT_FALSE(second_socket->AllReadDataConsumed()); |
| 1883 } |
| 1884 |
1585 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry | 1885 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry |
1586 : public HttpStreamFactoryImplJobControllerTest, | 1886 : public HttpStreamFactoryImplJobControllerTest, |
1587 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; | 1887 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; |
1588 | 1888 |
1589 INSTANTIATE_TEST_CASE_P( | 1889 INSTANTIATE_TEST_CASE_P( |
1590 /* no prefix */, | 1890 /* no prefix */, |
1591 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, | 1891 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
1592 ::testing::Combine(::testing::Bool(), ::testing::Bool())); | 1892 ::testing::Combine(::testing::Bool(), ::testing::Bool())); |
1593 | 1893 |
1594 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, | 1894 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 Preconnect(kNumPreconects); | 2002 Preconnect(kNumPreconects); |
1703 // If experiment is enabled, only 1 stream is requested. | 2003 // If experiment is enabled, only 1 stream is requested. |
1704 EXPECT_EQ( | 2004 EXPECT_EQ( |
1705 (int)actual_num_connects, | 2005 (int)actual_num_connects, |
1706 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); | 2006 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); |
1707 base::RunLoop().RunUntilIdle(); | 2007 base::RunLoop().RunUntilIdle(); |
1708 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 2008 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
1709 } | 2009 } |
1710 | 2010 |
1711 } // namespace net | 2011 } // namespace net |
OLD | NEW |