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 <memory> | 7 #include <memory> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "base/test/histogram_tester.h" | 12 #include "base/test/histogram_tester.h" |
13 #include "base/test/scoped_feature_list.h" | 13 #include "base/test/scoped_feature_list.h" |
14 #include "base/test/scoped_mock_time_message_loop_task_runner.h" | 14 #include "base/test/scoped_mock_time_message_loop_task_runner.h" |
15 #include "base/threading/platform_thread.h" | 15 #include "base/threading/platform_thread.h" |
16 #include "net/base/test_proxy_delegate.h" | 16 #include "net/base/test_proxy_delegate.h" |
17 #include "net/dns/mock_host_resolver.h" | 17 #include "net/dns/mock_host_resolver.h" |
18 #include "net/http/http_basic_stream.h" | 18 #include "net/http/http_basic_stream.h" |
19 #include "net/http/http_stream_factory_impl_job.h" | |
19 #include "net/http/http_stream_factory_impl_request.h" | 20 #include "net/http/http_stream_factory_impl_request.h" |
20 #include "net/http/http_stream_factory_test_util.h" | 21 #include "net/http/http_stream_factory_test_util.h" |
21 #include "net/log/net_log_with_source.h" | 22 #include "net/log/net_log_with_source.h" |
22 #include "net/proxy/mock_proxy_resolver.h" | 23 #include "net/proxy/mock_proxy_resolver.h" |
23 #include "net/proxy/proxy_config_service_fixed.h" | 24 #include "net/proxy/proxy_config_service_fixed.h" |
24 #include "net/proxy/proxy_info.h" | 25 #include "net/proxy/proxy_info.h" |
25 #include "net/proxy/proxy_service.h" | 26 #include "net/proxy/proxy_service.h" |
27 #include "net/quic/chromium/quic_stream_factory.h" | |
26 #include "net/quic/chromium/quic_stream_factory_peer.h" | 28 #include "net/quic/chromium/quic_stream_factory_peer.h" |
27 #include "net/socket/socket_test_util.h" | 29 #include "net/socket/socket_test_util.h" |
28 #include "net/spdy/chromium/spdy_test_util_common.h" | 30 #include "net/spdy/chromium/spdy_test_util_common.h" |
29 #include "testing/gmock/include/gmock/gmock.h" | 31 #include "testing/gmock/include/gmock/gmock.h" |
30 #include "testing/gmock_mutant.h" | 32 #include "testing/gmock_mutant.h" |
31 #include "testing/gtest/include/gtest/gtest.h" | 33 #include "testing/gtest/include/gtest/gtest.h" |
32 | 34 |
33 using ::testing::_; | 35 using ::testing::_; |
34 using ::testing::Invoke; | 36 using ::testing::Invoke; |
35 | 37 |
36 namespace net { | 38 namespace net { |
37 | 39 |
38 namespace { | 40 namespace { |
39 | 41 |
42 // List of errors that are used in the proxy resolution tests. | |
43 const int proxy_test_mock_errors[] = { | |
44 ERR_PROXY_CONNECTION_FAILED, | |
45 ERR_NAME_NOT_RESOLVED, | |
46 ERR_ADDRESS_UNREACHABLE, | |
47 ERR_CONNECTION_CLOSED, | |
48 ERR_CONNECTION_TIMED_OUT, | |
49 ERR_CONNECTION_RESET, | |
50 ERR_CONNECTION_REFUSED, | |
51 ERR_CONNECTION_ABORTED, | |
52 ERR_TIMED_OUT, | |
53 ERR_TUNNEL_CONNECTION_FAILED, | |
54 ERR_SOCKS_CONNECTION_FAILED, | |
55 ERR_PROXY_CERTIFICATE_INVALID, | |
56 ERR_QUIC_PROTOCOL_ERROR, | |
57 ERR_QUIC_HANDSHAKE_FAILED, | |
58 ERR_SSL_PROTOCOL_ERROR, | |
59 ERR_MSG_TOO_BIG, | |
60 }; | |
61 | |
40 void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config, | 62 void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config, |
41 const ProxyInfo& used_proxy_info, | 63 const ProxyInfo& used_proxy_info, |
42 HttpStream* stream) { | 64 HttpStream* stream) { |
43 delete stream; | 65 delete stream; |
44 } | 66 } |
45 | 67 |
46 class FailingProxyResolverFactory : public ProxyResolverFactory { | 68 class FailingProxyResolverFactory : public ProxyResolverFactory { |
47 public: | 69 public: |
48 FailingProxyResolverFactory() : ProxyResolverFactory(false) {} | 70 FailingProxyResolverFactory() : ProxyResolverFactory(false) {} |
49 | 71 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 int Resolve(const RequestInfo& info, | 104 int Resolve(const RequestInfo& info, |
83 RequestPriority priority, | 105 RequestPriority priority, |
84 AddressList* addresses, | 106 AddressList* addresses, |
85 const CompletionCallback& callback, | 107 const CompletionCallback& callback, |
86 std::unique_ptr<Request>* out_req, | 108 std::unique_ptr<Request>* out_req, |
87 const NetLogWithSource& net_log) override { | 109 const NetLogWithSource& net_log) override { |
88 return ERR_IO_PENDING; | 110 return ERR_IO_PENDING; |
89 } | 111 } |
90 }; | 112 }; |
91 | 113 |
114 // A mock QuicStreamRequest that returns |net_error|. | |
115 class MockQuicStreamRequest : public QuicStreamRequest { | |
116 public: | |
117 MockQuicStreamRequest(int net_error) | |
118 : QuicStreamRequest(nullptr, nullptr), net_error_(net_error) {} | |
119 ~MockQuicStreamRequest() {} | |
120 | |
121 int Request(const HostPortPair& destination, | |
122 PrivacyMode privacy_mode, | |
123 int cert_verify_flags, | |
124 const GURL& url, | |
125 QuicStringPiece method, | |
126 const NetLogWithSource& net_log, | |
127 const CompletionCallback& callback) override { | |
128 return net_error_; | |
129 } | |
130 | |
131 std::unique_ptr<HttpStream> CreateStream() override { | |
132 if (net_error_ != OK) { | |
133 NOTREACHED(); | |
134 return nullptr; | |
135 } | |
136 return base::MakeUnique<HttpBasicStream>( | |
137 base::MakeUnique<ClientSocketHandle>(), false, false); | |
138 } | |
139 | |
140 std::unique_ptr<BidirectionalStreamImpl> CreateBidirectionalStreamImpl() | |
141 override { | |
142 NOTREACHED(); | |
143 return nullptr; | |
144 } | |
145 | |
146 private: | |
147 int net_error_; | |
148 }; | |
149 | |
150 // A mock QuicStreamRequest that returns |net_error|. | |
Bence
2017/05/03 14:11:11
I was thinking about "A factory to create a MockQu
xunjieli
2017/05/03 22:18:29
Acknowledged. With Ryan's help, I am able to use M
| |
151 class MockQuicStreamRequestFactory : public QuicStreamRequestFactory { | |
152 public: | |
153 MockQuicStreamRequestFactory(int net_error) | |
154 : QuicStreamRequestFactory(), net_error_(net_error) {} | |
155 ~MockQuicStreamRequestFactory() {} | |
156 | |
157 std::unique_ptr<QuicStreamRequest> CreateRequest( | |
158 QuicStreamFactory* factory, | |
159 HttpServerProperties* http_server_properties) override { | |
160 return base::MakeUnique<MockQuicStreamRequest>(net_error_); | |
161 } | |
162 | |
163 private: | |
164 int net_error_; | |
165 }; | |
166 | |
92 // A mock HttpServerProperties that always returns false for IsInitialized(). | 167 // A mock HttpServerProperties that always returns false for IsInitialized(). |
93 class MockHttpServerProperties : public HttpServerPropertiesImpl { | 168 class MockHttpServerProperties : public HttpServerPropertiesImpl { |
94 public: | 169 public: |
95 MockHttpServerProperties() {} | 170 MockHttpServerProperties() {} |
96 ~MockHttpServerProperties() override {} | 171 ~MockHttpServerProperties() override {} |
97 bool IsInitialized() const override { return false; } | 172 bool IsInitialized() const override { return false; } |
98 }; | 173 }; |
99 | 174 |
100 } // anonymous namespace | 175 } // anonymous namespace |
101 | 176 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 ASSERT_FALSE(test_proxy_delegate_); | 234 ASSERT_FALSE(test_proxy_delegate_); |
160 std::unique_ptr<TestProxyDelegate> test_proxy_delegate( | 235 std::unique_ptr<TestProxyDelegate> test_proxy_delegate( |
161 new TestProxyDelegate()); | 236 new TestProxyDelegate()); |
162 test_proxy_delegate_ = test_proxy_delegate.get(); | 237 test_proxy_delegate_ = test_proxy_delegate.get(); |
163 | 238 |
164 test_proxy_delegate->set_alternative_proxy_server( | 239 test_proxy_delegate->set_alternative_proxy_server( |
165 ProxyServer::FromPacString("QUIC myproxy.org:443")); | 240 ProxyServer::FromPacString("QUIC myproxy.org:443")); |
166 EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic()); | 241 EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic()); |
167 session_deps_.proxy_delegate = std::move(test_proxy_delegate); | 242 session_deps_.proxy_delegate = std::move(test_proxy_delegate); |
168 | 243 |
244 if (tcp_data_) | |
245 session_deps_.socket_factory->AddSocketDataProvider(tcp_data_.get()); | |
246 | |
169 if (use_alternative_proxy_) { | 247 if (use_alternative_proxy_) { |
170 std::unique_ptr<ProxyService> proxy_service = | 248 std::unique_ptr<ProxyService> proxy_service = |
171 ProxyService::CreateFixedFromPacResult("HTTPS myproxy.org:443"); | 249 ProxyService::CreateFixedFromPacResult("HTTPS myproxy.org:443"); |
172 session_deps_.proxy_service = std::move(proxy_service); | 250 session_deps_.proxy_service = std::move(proxy_service); |
173 } | 251 } |
174 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); | 252 HttpNetworkSession::Params params = |
253 SpdySessionDependencies::CreateSessionParams(&session_deps_); | |
254 session_ = base::MakeUnique<HttpNetworkSession>(params); | |
175 factory_ = | 255 factory_ = |
176 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); | 256 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); |
177 job_controller_ = new HttpStreamFactoryImpl::JobController( | 257 job_controller_ = new HttpStreamFactoryImpl::JobController( |
178 factory_, &request_delegate_, session_.get(), &job_factory_, | 258 factory_, &request_delegate_, session_.get(), &job_factory_, |
179 request_info, is_preconnect_, enable_ip_based_pooling_, | 259 request_info, is_preconnect_, enable_ip_based_pooling_, |
180 enable_alternative_services_); | 260 enable_alternative_services_, SSLConfig(), SSLConfig()); |
181 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); | 261 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); |
182 } | 262 } |
183 | 263 |
184 TestProxyDelegate* test_proxy_delegate() const { | 264 TestProxyDelegate* test_proxy_delegate() const { |
185 return test_proxy_delegate_; | 265 return test_proxy_delegate_; |
186 } | 266 } |
187 | 267 |
188 ~HttpStreamFactoryImplJobControllerTest() override {} | 268 ~HttpStreamFactoryImplJobControllerTest() override { |
269 if (tcp_data_) { | |
270 EXPECT_TRUE(tcp_data_->AllReadDataConsumed()); | |
271 EXPECT_TRUE(tcp_data_->AllWriteDataConsumed()); | |
272 } | |
273 } | |
189 | 274 |
190 void SetAlternativeService(const HttpRequestInfo& request_info, | 275 void SetAlternativeService(const HttpRequestInfo& request_info, |
191 AlternativeService alternative_service) { | 276 AlternativeService alternative_service) { |
192 HostPortPair host_port_pair = HostPortPair::FromURL(request_info.url); | 277 HostPortPair host_port_pair = HostPortPair::FromURL(request_info.url); |
193 url::SchemeHostPort server(request_info.url); | 278 url::SchemeHostPort server(request_info.url); |
194 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); | 279 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); |
195 session_->http_server_properties()->SetAlternativeService( | 280 session_->http_server_properties()->SetAlternativeService( |
196 server, alternative_service, expiration); | 281 server, alternative_service, expiration); |
197 } | 282 } |
198 | 283 |
199 void VerifyBrokenAlternateProtocolMapping(const HttpRequestInfo& request_info, | 284 void VerifyBrokenAlternateProtocolMapping(const HttpRequestInfo& request_info, |
200 bool should_mark_broken) { | 285 bool should_mark_broken) { |
201 const url::SchemeHostPort server(request_info.url); | 286 const url::SchemeHostPort server(request_info.url); |
202 const AlternativeServiceVector alternative_service_vector = | 287 const AlternativeServiceVector alternative_service_vector = |
203 session_->http_server_properties()->GetAlternativeServices(server); | 288 session_->http_server_properties()->GetAlternativeServices(server); |
204 EXPECT_EQ(1u, alternative_service_vector.size()); | 289 EXPECT_EQ(1u, alternative_service_vector.size()); |
205 EXPECT_EQ(should_mark_broken, | 290 EXPECT_EQ(should_mark_broken, |
206 session_->http_server_properties()->IsAlternativeServiceBroken( | 291 session_->http_server_properties()->IsAlternativeServiceBroken( |
207 alternative_service_vector[0])); | 292 alternative_service_vector[0])); |
208 } | 293 } |
209 | 294 |
210 TestJobFactory job_factory_; | 295 TestJobFactory job_factory_; |
211 MockHttpStreamRequestDelegate request_delegate_; | 296 MockHttpStreamRequestDelegate request_delegate_; |
212 SpdySessionDependencies session_deps_; | 297 SpdySessionDependencies session_deps_; |
213 std::unique_ptr<HttpNetworkSession> session_; | 298 std::unique_ptr<HttpNetworkSession> session_; |
214 HttpStreamFactoryImpl* factory_; | 299 HttpStreamFactoryImpl* factory_; |
215 HttpStreamFactoryImpl::JobController* job_controller_; | 300 HttpStreamFactoryImpl::JobController* job_controller_; |
216 std::unique_ptr<HttpStreamFactoryImpl::Request> request_; | 301 std::unique_ptr<HttpStreamFactoryImpl::Request> request_; |
217 | 302 std::unique_ptr<SequencedSocketData> tcp_data_; |
218 private: | 303 |
304 protected: | |
219 bool use_alternative_proxy_; | 305 bool use_alternative_proxy_; |
220 bool is_preconnect_; | 306 bool is_preconnect_; |
221 bool enable_ip_based_pooling_; | 307 bool enable_ip_based_pooling_; |
222 bool enable_alternative_services_; | 308 bool enable_alternative_services_; |
223 | 309 |
310 private: | |
224 // Not owned by |this|. | 311 // Not owned by |this|. |
225 TestProxyDelegate* test_proxy_delegate_; | 312 TestProxyDelegate* test_proxy_delegate_; |
226 | 313 |
227 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest); | 314 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest); |
228 }; | 315 }; |
229 | 316 |
230 TEST_F(HttpStreamFactoryImplJobControllerTest, | 317 TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsSync) { |
231 OnStreamFailedWithNoAlternativeJob) { | |
232 ProxyConfig proxy_config; | 318 ProxyConfig proxy_config; |
233 proxy_config.set_auto_detect(true); | 319 proxy_config.set_pac_url(GURL("http://www.example.com")); |
234 // Use asynchronous proxy resolver. | 320 proxy_config.set_pac_mandatory(true); |
321 MockAsyncProxyResolver resolver; | |
322 session_deps_.proxy_service.reset(new ProxyService( | |
323 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
324 base::WrapUnique(new FailingProxyResolverFactory), nullptr)); | |
325 HttpRequestInfo request_info; | |
326 request_info.method = "GET"; | |
327 request_info.url = GURL("http://www.google.com"); | |
328 | |
329 Initialize(request_info); | |
330 | |
331 EXPECT_CALL(request_delegate_, | |
332 OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _)) | |
333 .Times(1); | |
334 request_.reset( | |
335 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), | |
336 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); | |
337 | |
338 EXPECT_FALSE(job_controller_->main_job()); | |
339 EXPECT_FALSE(job_controller_->alternative_job()); | |
340 | |
341 base::RunLoop().RunUntilIdle(); | |
342 request_.reset(); | |
343 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | |
344 } | |
345 | |
346 TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsAsync) { | |
347 ProxyConfig proxy_config; | |
348 proxy_config.set_pac_url(GURL("http://www.example.com")); | |
349 proxy_config.set_pac_mandatory(true); | |
235 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 350 MockAsyncProxyResolverFactory* proxy_resolver_factory = |
236 new MockAsyncProxyResolverFactory(false); | 351 new MockAsyncProxyResolverFactory(false); |
352 MockAsyncProxyResolver resolver; | |
237 session_deps_.proxy_service.reset( | 353 session_deps_.proxy_service.reset( |
238 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | 354 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), |
239 base::WrapUnique(proxy_resolver_factory), nullptr)); | 355 base::WrapUnique(proxy_resolver_factory), nullptr)); |
240 | 356 HttpRequestInfo request_info; |
241 HttpRequestInfo request_info; | 357 request_info.method = "GET"; |
242 request_info.method = "GET"; | 358 request_info.url = GURL("http://www.google.com"); |
359 | |
360 Initialize(request_info); | |
361 | |
362 request_.reset( | |
363 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), | |
364 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); | |
365 | |
366 EXPECT_FALSE(job_controller_->main_job()); | |
367 EXPECT_FALSE(job_controller_->alternative_job()); | |
368 | |
369 EXPECT_CALL(request_delegate_, | |
370 OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _)) | |
371 .Times(1); | |
372 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( | |
373 ERR_FAILED, &resolver); | |
374 base::RunLoop().RunUntilIdle(); | |
375 request_.reset(); | |
376 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | |
377 } | |
378 | |
379 class JobControllerReconsiderProxyAfterError | |
380 : public HttpStreamFactoryImplJobControllerTest, | |
381 public ::testing::WithParamInterface<::testing::tuple<bool, int>> { | |
382 public: | |
383 void Initialize(std::unique_ptr<ProxyService> proxy_service, | |
384 std::unique_ptr<ProxyDelegate> proxy_delegate) { | |
385 session_deps_.proxy_delegate = std::move(proxy_delegate); | |
386 session_deps_.proxy_service = std::move(proxy_service); | |
387 HttpNetworkSession::Params params = | |
388 SpdySessionDependencies::CreateSessionParams(&session_deps_); | |
389 session_ = base::MakeUnique<HttpNetworkSession>(params); | |
390 factory_ = | |
391 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); | |
392 } | |
393 | |
394 std::unique_ptr<HttpStreamRequest> CreateJobController( | |
395 const HttpRequestInfo& request_info) { | |
396 HttpStreamFactoryImpl::JobController* job_controller = | |
397 new HttpStreamFactoryImpl::JobController( | |
398 factory_, &request_delegate_, session_.get(), &default_job_factory_, | |
399 request_info, is_preconnect_, enable_ip_based_pooling_, | |
400 enable_alternative_services_, SSLConfig(), SSLConfig()); | |
401 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller); | |
402 return base::WrapUnique(job_controller->Start( | |
403 &request_delegate_, nullptr, NetLogWithSource(), | |
404 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); | |
405 } | |
406 | |
407 private: | |
408 // Use real Jobs so that Job::Resume() is not mocked out. When main job is | |
409 // resumed it will use mock socket data. | |
410 HttpStreamFactoryImpl::JobFactory default_job_factory_; | |
411 }; | |
412 | |
413 INSTANTIATE_TEST_CASE_P( | |
414 /* no prefix */, | |
415 JobControllerReconsiderProxyAfterError, | |
416 ::testing::Combine(::testing::Bool(), | |
417 testing::ValuesIn(proxy_test_mock_errors))); | |
418 | |
419 TEST_P(JobControllerReconsiderProxyAfterError, ReconsiderProxyAfterError) { | |
420 const bool set_alternative_proxy_server = ::testing::get<0>(GetParam()); | |
421 const int mock_error = ::testing::get<1>(GetParam()); | |
422 std::unique_ptr<ProxyService> proxy_service = | |
423 ProxyService::CreateFixedFromPacResult( | |
424 "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT"); | |
425 std::unique_ptr<TestProxyDelegate> test_proxy_delegate = | |
426 base::MakeUnique<TestProxyDelegate>(); | |
427 TestProxyDelegate* test_proxy_delegate_raw = test_proxy_delegate.get(); | |
428 | |
429 // Before starting the test, verify that there are no proxies marked as bad. | |
430 ASSERT_TRUE(proxy_service->proxy_retry_info().empty()) << mock_error; | |
431 | |
432 StaticSocketDataProvider socket_data_proxy_main_job; | |
433 socket_data_proxy_main_job.set_connect_data(MockConnect(ASYNC, mock_error)); | |
434 session_deps_.socket_factory->AddSocketDataProvider( | |
435 &socket_data_proxy_main_job); | |
436 | |
437 StaticSocketDataProvider socket_data_proxy_alternate_job; | |
438 if (set_alternative_proxy_server) { | |
439 // Mock socket used by the QUIC job. | |
440 socket_data_proxy_alternate_job.set_connect_data( | |
441 MockConnect(ASYNC, mock_error)); | |
442 session_deps_.socket_factory->AddSocketDataProvider( | |
443 &socket_data_proxy_alternate_job); | |
444 test_proxy_delegate->set_alternative_proxy_server( | |
445 ProxyServer::FromPacString("QUIC badproxy:99")); | |
446 } | |
447 | |
448 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
449 | |
450 // When retrying the job using the second proxy (badFallback:98), | |
451 // alternative job must not be created. So, socket data for only the | |
452 // main job is needed. | |
453 StaticSocketDataProvider socket_data_proxy_main_job_2; | |
454 socket_data_proxy_main_job_2.set_connect_data(MockConnect(ASYNC, mock_error)); | |
455 session_deps_.socket_factory->AddSocketDataProvider( | |
456 &socket_data_proxy_main_job_2); | |
457 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
458 | |
459 // First request would use DIRECT, and succeed. | |
460 StaticSocketDataProvider socket_data_direct_first_request; | |
461 socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK)); | |
462 session_deps_.socket_factory->AddSocketDataProvider( | |
463 &socket_data_direct_first_request); | |
464 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
465 | |
466 // Second request would use DIRECT, and succeed. | |
467 StaticSocketDataProvider socket_data_direct_second_request; | |
468 socket_data_direct_second_request.set_connect_data(MockConnect(ASYNC, OK)); | |
469 session_deps_.socket_factory->AddSocketDataProvider( | |
470 &socket_data_direct_second_request); | |
471 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
472 | |
473 // Now request a stream. It should succeed using the DIRECT. | |
474 HttpRequestInfo request_info; | |
475 request_info.method = "GET"; | |
476 request_info.url = GURL("http://www.example.com"); | |
477 | |
478 Initialize(std::move(proxy_service), std::move(test_proxy_delegate)); | |
479 EXPECT_EQ(set_alternative_proxy_server, | |
480 test_proxy_delegate_raw->alternative_proxy_server().is_quic()); | |
481 | |
482 // Start two requests. The first request should consume data from | |
483 // |socket_data_proxy_main_job|, | |
484 // |socket_data_proxy_alternate_job| and | |
485 // |socket_data_direct_first_request|. The second request should consume | |
486 // data from |socket_data_direct_second_request|. | |
487 | |
488 for (size_t i = 0; i < 2; ++i) { | |
489 ProxyInfo used_proxy_info; | |
490 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) | |
491 .Times(1) | |
492 .WillOnce(DoAll(::testing::SaveArg<1>(&used_proxy_info), | |
493 Invoke(DeleteHttpStreamPointer))); | |
494 | |
495 std::unique_ptr<HttpStreamRequest> request = | |
496 CreateJobController(request_info); | |
497 | |
498 base::RunLoop().RunUntilIdle(); | |
499 // The proxy that failed should now be known to the proxy_service as | |
500 // bad. | |
501 const ProxyRetryInfoMap retry_info = | |
502 session_->proxy_service()->proxy_retry_info(); | |
503 EXPECT_EQ(2u, retry_info.size()) << mock_error; | |
504 EXPECT_NE(retry_info.end(), retry_info.find("https://badproxy:99")); | |
505 EXPECT_NE(retry_info.end(), retry_info.find("https://badfallbackproxy:98")); | |
506 | |
507 // Verify that request was fetched without proxy. | |
508 EXPECT_TRUE(used_proxy_info.is_direct()); | |
509 | |
510 // If alternative proxy server was specified, it should have been marked | |
511 // as invalid so that it is not used for subsequent requests. | |
512 EXPECT_FALSE( | |
513 test_proxy_delegate_raw->alternative_proxy_server().is_valid()); | |
514 | |
515 if (set_alternative_proxy_server) { | |
516 // GetAlternativeProxy should be called only once for the first | |
517 // request. | |
518 EXPECT_EQ(1, | |
519 test_proxy_delegate_raw->get_alternative_proxy_invocations()); | |
520 } else { | |
521 // Alternative proxy server job is never started. So, ProxyDelegate is | |
522 // queried once per request. | |
523 EXPECT_EQ(2, | |
524 test_proxy_delegate_raw->get_alternative_proxy_invocations()); | |
525 } | |
526 } | |
527 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | |
528 } | |
529 | |
530 TEST_F(HttpStreamFactoryImplJobControllerTest, | |
531 OnStreamFailedWithNoAlternativeJob) { | |
532 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
533 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); | |
534 | |
535 HttpRequestInfo request_info; | |
536 request_info.method = "GET"; | |
243 request_info.url = GURL("http://www.google.com"); | 537 request_info.url = GURL("http://www.google.com"); |
244 | 538 |
245 Initialize(request_info); | 539 Initialize(request_info); |
246 | 540 |
247 request_.reset( | 541 request_.reset( |
248 job_controller_->Start(request_info, &request_delegate_, nullptr, | 542 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
249 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 543 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
250 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
251 | 544 |
252 EXPECT_TRUE(job_controller_->main_job()); | 545 EXPECT_TRUE(job_controller_->main_job()); |
546 EXPECT_FALSE(job_controller_->alternative_job()); | |
253 | 547 |
254 // There's no other alternative job. Thus when stream failed, it should | 548 // There's no other alternative job. Thus when stream failed, it should |
255 // notify Request of the stream failure. | 549 // notify Request of the stream failure. |
256 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1); | 550 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1); |
257 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, | 551 base::RunLoop().RunUntilIdle(); |
258 SSLConfig()); | |
259 } | 552 } |
260 | 553 |
261 TEST_F(HttpStreamFactoryImplJobControllerTest, | 554 TEST_F(HttpStreamFactoryImplJobControllerTest, |
262 OnStreamReadyWithNoAlternativeJob) { | 555 OnStreamReadyWithNoAlternativeJob) { |
263 ProxyConfig proxy_config; | 556 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
264 proxy_config.set_auto_detect(true); | 557 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
265 // Use asynchronous proxy resolver. | 558 |
266 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
267 new MockAsyncProxyResolverFactory(false); | |
268 session_deps_.proxy_service.reset( | |
269 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
270 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
271 HttpRequestInfo request_info; | 559 HttpRequestInfo request_info; |
272 request_info.method = "GET"; | 560 request_info.method = "GET"; |
273 request_info.url = GURL("http://www.google.com"); | 561 request_info.url = GURL("http://www.google.com"); |
274 | 562 |
275 Initialize(request_info); | 563 Initialize(request_info); |
276 | 564 |
277 request_.reset( | 565 request_.reset( |
278 job_controller_->Start(request_info, &request_delegate_, nullptr, | 566 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
279 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 567 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
280 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
281 | 568 |
282 // There's no other alternative job. Thus when a stream is ready, it should | 569 // There's no other alternative job. Thus when a stream is ready, it should |
283 // notify Request. | 570 // notify Request. |
284 HttpStream* http_stream = | 571 EXPECT_TRUE(job_controller_->main_job()); |
285 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
286 job_factory_.main_job()->SetStream(http_stream); | |
287 | 572 |
288 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | 573 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
289 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 574 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
290 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | 575 base::RunLoop().RunUntilIdle(); |
291 } | 576 } |
292 | 577 |
293 // Test we cancel Jobs correctly when the Request is explicitly canceled | 578 // Test we cancel Jobs correctly when the Request is explicitly canceled |
294 // before any Job is bound to Request. | 579 // before any Job is bound to Request. |
295 TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { | 580 TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { |
296 ProxyConfig proxy_config; | 581 // One TCP connect. |
297 proxy_config.set_auto_detect(true); | 582 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
298 // Use asynchronous proxy resolver. | 583 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
299 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
300 new MockAsyncProxyResolverFactory(false); | |
301 session_deps_.proxy_service.reset(new ProxyService( | |
302 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), | |
303 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
304 | |
305 HttpRequestInfo request_info; | 584 HttpRequestInfo request_info; |
306 request_info.method = "GET"; | 585 request_info.method = "GET"; |
307 request_info.url = GURL("https://www.google.com"); | 586 request_info.url = GURL("https://www.google.com"); |
308 | 587 |
309 Initialize(request_info); | 588 Initialize(request_info); |
310 url::SchemeHostPort server(request_info.url); | 589 url::SchemeHostPort server(request_info.url); |
311 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 590 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
312 SetAlternativeService(request_info, alternative_service); | 591 SetAlternativeService(request_info, alternative_service); |
313 | 592 |
593 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
594 session_->quic_stream_factory(), | |
595 base::MakeUnique<MockQuicStreamRequestFactory>(OK)); | |
596 | |
314 request_.reset( | 597 request_.reset( |
315 job_controller_->Start(request_info, &request_delegate_, nullptr, | 598 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
316 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 599 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
317 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
318 EXPECT_TRUE(job_controller_->main_job()); | 600 EXPECT_TRUE(job_controller_->main_job()); |
319 EXPECT_TRUE(job_controller_->alternative_job()); | 601 EXPECT_TRUE(job_controller_->alternative_job()); |
320 | 602 |
321 // Reset the Request will cancel all the Jobs since there's no Job determined | 603 // Reset the Request will cancel all the Jobs since there's no Job determined |
322 // to serve Request yet and JobController will notify the factory to delete | 604 // to serve Request yet and JobController will notify the factory to delete |
323 // itself upon completion. | 605 // itself upon completion. |
324 request_.reset(); | 606 request_.reset(); |
325 VerifyBrokenAlternateProtocolMapping(request_info, false); | 607 VerifyBrokenAlternateProtocolMapping(request_info, false); |
326 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 608 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
327 } | 609 } |
328 | 610 |
329 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { | 611 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { |
330 ProxyConfig proxy_config; | 612 // One TCP connect and one UDP connect. |
331 proxy_config.set_auto_detect(true); | 613 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
332 // Use asynchronous proxy resolver. | 614 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); |
333 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
334 new MockAsyncProxyResolverFactory(false); | |
335 session_deps_.proxy_service.reset( | |
336 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
337 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
338 | 615 |
339 HttpRequestInfo request_info; | 616 HttpRequestInfo request_info; |
340 request_info.method = "GET"; | 617 request_info.method = "GET"; |
341 request_info.url = GURL("https://www.google.com"); | 618 request_info.url = GURL("https://www.google.com"); |
342 | 619 |
343 Initialize(request_info); | 620 Initialize(request_info); |
344 url::SchemeHostPort server(request_info.url); | 621 url::SchemeHostPort server(request_info.url); |
345 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 622 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
346 SetAlternativeService(request_info, alternative_service); | 623 SetAlternativeService(request_info, alternative_service); |
347 | 624 |
625 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
626 session_->quic_stream_factory(), | |
627 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED)); | |
628 | |
348 request_.reset( | 629 request_.reset( |
349 job_controller_->Start(request_info, &request_delegate_, nullptr, | 630 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
350 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 631 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
351 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
352 EXPECT_TRUE(job_controller_->main_job()); | 632 EXPECT_TRUE(job_controller_->main_job()); |
353 EXPECT_TRUE(job_controller_->alternative_job()); | 633 EXPECT_TRUE(job_controller_->alternative_job()); |
354 | 634 |
355 // We have the main job with unknown status when the alternative job is failed | |
356 // thus should not notify Request of the alternative job's failure. But should | |
357 // notify the main job to mark the alternative job failed. | |
358 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | |
359 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, | |
360 SSLConfig()); | |
361 EXPECT_TRUE(!job_controller_->alternative_job()); | |
362 EXPECT_TRUE(job_controller_->main_job()); | |
363 | |
364 // The failure of second Job should be reported to Request as there's no more | 635 // The failure of second Job should be reported to Request as there's no more |
365 // pending Job to serve the Request. | 636 // pending Job to serve the Request. |
366 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); | 637 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); |
367 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, | 638 base::RunLoop().RunUntilIdle(); |
368 SSLConfig()); | |
369 VerifyBrokenAlternateProtocolMapping(request_info, false); | 639 VerifyBrokenAlternateProtocolMapping(request_info, false); |
640 request_.reset(); | |
641 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | |
370 } | 642 } |
371 | 643 |
372 TEST_F(HttpStreamFactoryImplJobControllerTest, | 644 TEST_F(HttpStreamFactoryImplJobControllerTest, |
373 AltJobFailsAfterMainJobSucceeds) { | 645 AltJobFailsAfterMainJobSucceeds) { |
374 ProxyConfig proxy_config; | 646 // One TCP connect. |
375 proxy_config.set_auto_detect(true); | 647 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
376 // Use asynchronous proxy resolver. | 648 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
377 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 649 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
378 new MockAsyncProxyResolverFactory(false); | 650 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
379 session_deps_.proxy_service.reset( | |
380 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
381 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
382 | 651 |
383 HttpRequestInfo request_info; | 652 HttpRequestInfo request_info; |
384 request_info.method = "GET"; | 653 request_info.method = "GET"; |
385 request_info.url = GURL("https://www.google.com"); | 654 request_info.url = GURL("https://www.google.com"); |
386 | 655 |
387 Initialize(request_info); | 656 Initialize(request_info); |
388 url::SchemeHostPort server(request_info.url); | 657 url::SchemeHostPort server(request_info.url); |
389 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 658 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
390 SetAlternativeService(request_info, alternative_service); | 659 SetAlternativeService(request_info, alternative_service); |
660 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
661 session_->quic_stream_factory(), | |
662 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED)); | |
391 | 663 |
392 request_.reset( | 664 request_.reset( |
393 job_controller_->Start(request_info, &request_delegate_, nullptr, | 665 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
394 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 666 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
395 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
396 EXPECT_TRUE(job_controller_->main_job()); | 667 EXPECT_TRUE(job_controller_->main_job()); |
397 EXPECT_TRUE(job_controller_->alternative_job()); | 668 EXPECT_TRUE(job_controller_->alternative_job()); |
398 | 669 |
399 // Main job succeeds, starts serving Request and it should report status | 670 // Main job succeeds, starts serving Request and it should report status |
400 // to Request. The alternative job will mark the main job complete and gets | 671 // to Request. The alternative job will mark the main job complete and gets |
401 // orphaned. | 672 // orphaned. |
402 HttpStream* http_stream = | 673 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
403 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
404 job_factory_.main_job()->SetStream(http_stream); | |
405 | |
406 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | |
407 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 674 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
408 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | |
409 | |
410 // JobController shouldn't report the status of second job as request | 675 // JobController shouldn't report the status of second job as request |
411 // is already successfully served. | 676 // is already successfully served. |
412 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 677 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
413 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, | 678 |
414 SSLConfig()); | 679 base::RunLoop().RunUntilIdle(); |
415 | 680 |
416 VerifyBrokenAlternateProtocolMapping(request_info, true); | 681 VerifyBrokenAlternateProtocolMapping(request_info, true); |
417 // Reset the request as it's been successfully served. | 682 // Reset the request as it's been successfully served. |
418 request_.reset(); | 683 request_.reset(); |
419 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 684 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
420 } | 685 } |
421 | 686 |
422 // Tests that if alt job succeeds and main job is blocked, main job should be | 687 // Tests that if alt job succeeds and main job is blocked, main job should be |
423 // cancelled immediately. |request_| completion will clean up the JobController. | 688 // cancelled immediately. |request_| completion will clean up the JobController. |
424 // Regression test for crbug.com/678768. | 689 // Regression test for crbug.com/678768. |
425 TEST_F(HttpStreamFactoryImplJobControllerTest, | 690 TEST_F(HttpStreamFactoryImplJobControllerTest, |
426 AltJobSucceedsMainJobBlockedControllerDestroyed) { | 691 AltJobSucceedsMainJobBlockedControllerDestroyed) { |
427 ProxyConfig proxy_config; | |
428 proxy_config.set_auto_detect(true); | |
429 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
430 new MockAsyncProxyResolverFactory(false); | |
431 session_deps_.proxy_service.reset( | |
432 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
433 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
434 HttpRequestInfo request_info; | 692 HttpRequestInfo request_info; |
435 request_info.method = "GET"; | 693 request_info.method = "GET"; |
436 request_info.url = GURL("https://www.google.com"); | 694 request_info.url = GURL("https://www.google.com"); |
437 | 695 |
438 Initialize(request_info); | 696 Initialize(request_info); |
439 | 697 |
698 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
699 session_->quic_stream_factory(), | |
700 base::MakeUnique<MockQuicStreamRequestFactory>(OK)); | |
701 | |
440 url::SchemeHostPort server(request_info.url); | 702 url::SchemeHostPort server(request_info.url); |
441 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 703 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
442 SetAlternativeService(request_info, alternative_service); | 704 SetAlternativeService(request_info, alternative_service); |
443 request_.reset( | 705 request_.reset( |
444 job_controller_->Start(request_info, &request_delegate_, nullptr, | 706 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
445 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 707 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
446 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
447 EXPECT_TRUE(job_controller_->main_job()); | 708 EXPECT_TRUE(job_controller_->main_job()); |
448 EXPECT_TRUE(job_controller_->alternative_job()); | 709 EXPECT_TRUE(job_controller_->alternative_job()); |
449 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 710 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
450 | 711 |
451 // |alternative_job| succeeds and should report status to Request. | 712 // |alternative_job| succeeds and should report status to |request_delegate_|. |
452 HttpStream* http_stream = | 713 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
453 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
454 job_factory_.alternative_job()->SetStream(http_stream); | |
455 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | |
456 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 714 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
457 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); | 715 |
716 base::RunLoop().RunUntilIdle(); | |
458 | 717 |
459 EXPECT_FALSE(job_controller_->main_job()); | 718 EXPECT_FALSE(job_controller_->main_job()); |
460 EXPECT_TRUE(job_controller_->alternative_job()); | 719 EXPECT_TRUE(job_controller_->alternative_job()); |
461 | 720 |
462 // Invoke OnRequestComplete() which should delete |job_controller_| from | 721 // Invoke OnRequestComplete() which should delete |job_controller_| from |
463 // |factory_|. | 722 // |factory_|. |
464 request_.reset(); | 723 request_.reset(); |
465 VerifyBrokenAlternateProtocolMapping(request_info, false); | 724 VerifyBrokenAlternateProtocolMapping(request_info, false); |
466 // This fails without the fix for crbug.com/678768. | 725 // This fails without the fix for crbug.com/678768. |
467 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 726 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
468 } | 727 } |
469 | 728 |
470 // Tests that if an orphaned job completes after |request_| is gone, | 729 // Tests that if an orphaned job completes after |request_| is gone, |
471 // JobController will be cleaned up. | 730 // JobController will be cleaned up. |
472 TEST_F(HttpStreamFactoryImplJobControllerTest, | 731 TEST_F(HttpStreamFactoryImplJobControllerTest, |
473 OrphanedJobCompletesControllerDestroyed) { | 732 OrphanedJobCompletesControllerDestroyed) { |
474 ProxyConfig proxy_config; | 733 // One TCP connect. |
475 proxy_config.set_auto_detect(true); | 734 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
476 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 735 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
477 new MockAsyncProxyResolverFactory(false); | 736 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
478 session_deps_.proxy_service.reset( | 737 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
479 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | 738 |
480 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
481 HttpRequestInfo request_info; | 739 HttpRequestInfo request_info; |
482 request_info.method = "GET"; | 740 request_info.method = "GET"; |
483 request_info.url = GURL("https://www.google.com"); | 741 request_info.url = GURL("https://www.google.com"); |
484 | 742 |
485 Initialize(request_info); | 743 Initialize(request_info); |
486 | 744 |
745 // Make QuicStreamRequest complete asynchonously. | |
746 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
747 session_->quic_stream_factory(), | |
748 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); | |
749 | |
487 url::SchemeHostPort server(request_info.url); | 750 url::SchemeHostPort server(request_info.url); |
488 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 751 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
489 SetAlternativeService(request_info, alternative_service); | 752 SetAlternativeService(request_info, alternative_service); |
490 // Hack to use different URL for the main job to help differentiate the proxy | 753 |
491 // requests. | |
492 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); | |
493 request_.reset( | 754 request_.reset( |
494 job_controller_->Start(request_info, &request_delegate_, nullptr, | 755 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
495 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 756 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
496 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
497 EXPECT_TRUE(job_controller_->main_job()); | 757 EXPECT_TRUE(job_controller_->main_job()); |
498 EXPECT_TRUE(job_controller_->alternative_job()); | 758 EXPECT_TRUE(job_controller_->alternative_job()); |
499 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 759 // main job should not be blocked because alt job returned ERR_IO_PENDING. |
760 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); | |
761 | |
762 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) | |
763 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
500 | 764 |
501 // Complete main job now. | 765 // Complete main job now. |
502 MockAsyncProxyResolver resolver; | 766 base::RunLoop().RunUntilIdle(); |
503 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( | |
504 net::OK, &resolver); | |
505 int main_job_request_id = | |
506 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; | |
507 | 767 |
508 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( | |
509 "result1:80"); | |
510 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); | |
511 | |
512 HttpStream* http_stream = | |
513 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
514 job_factory_.main_job()->SetStream(http_stream); | |
515 | |
516 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | |
517 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
518 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | |
519 // Invoke OnRequestComplete() which should not delete |job_controller_| from | 768 // Invoke OnRequestComplete() which should not delete |job_controller_| from |
520 // |factory_| because alt job is yet to finish. | 769 // |factory_| because alt job is yet to finish. |
521 request_.reset(); | 770 request_.reset(); |
522 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 771 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
523 EXPECT_FALSE(job_controller_->main_job()); | 772 EXPECT_FALSE(job_controller_->main_job()); |
524 EXPECT_TRUE(job_controller_->alternative_job()); | 773 EXPECT_TRUE(job_controller_->alternative_job()); |
525 | 774 |
526 // Make |alternative_job| succeed. | 775 // Make |alternative_job| succeed. |
527 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); | 776 HttpStream* http_stream = |
528 resolver.pending_jobs()[0]->CompleteNow(net::OK); | |
529 HttpStream* http_stream2 = | |
530 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | 777 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
531 job_factory_.alternative_job()->SetStream(http_stream2); | 778 job_factory_.alternative_job()->SetStream(http_stream); |
532 // This should not call request_delegate_::OnStreamReady. | 779 // This should not call request_delegate_::OnStreamReady. |
533 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); | 780 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
534 // Make sure that controller does not leak. | 781 // Make sure that controller does not leak. |
535 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 782 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
536 } | 783 } |
537 | 784 |
538 TEST_F(HttpStreamFactoryImplJobControllerTest, | 785 TEST_F(HttpStreamFactoryImplJobControllerTest, |
539 AltJobSucceedsAfterMainJobFailed) { | 786 AltJobSucceedsAfterMainJobFailed) { |
540 ProxyConfig proxy_config; | 787 // One failed TCP connect. |
541 proxy_config.set_auto_detect(true); | 788 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
542 // Use asynchronous proxy resolver. | 789 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED)); |
543 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 790 |
544 new MockAsyncProxyResolverFactory(false); | |
545 session_deps_.proxy_service.reset( | |
546 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
547 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
548 HttpRequestInfo request_info; | 791 HttpRequestInfo request_info; |
549 request_info.method = "GET"; | 792 request_info.method = "GET"; |
550 request_info.url = GURL("https://www.google.com"); | 793 request_info.url = GURL("https://www.google.com"); |
551 | 794 |
552 Initialize(request_info); | 795 Initialize(request_info); |
553 | 796 |
554 url::SchemeHostPort server(request_info.url); | 797 url::SchemeHostPort server(request_info.url); |
555 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 798 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
556 SetAlternativeService(request_info, alternative_service); | 799 SetAlternativeService(request_info, alternative_service); |
557 | 800 |
558 request_.reset( | 801 test::QuicStreamFactoryPeer::SetStreamRequestFactory( |
559 job_controller_->Start(request_info, &request_delegate_, nullptr, | 802 session_->quic_stream_factory(), |
560 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 803 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); |
561 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
562 EXPECT_TRUE(job_controller_->main_job()); | |
563 EXPECT_TRUE(job_controller_->alternative_job()); | |
564 | 804 |
565 // |main_job| fails but should not report status to Request. | 805 // |main_job| fails but should not report status to Request. |
566 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 806 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
567 | 807 |
568 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, | 808 request_.reset( |
569 SSLConfig()); | 809 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
810 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); | |
811 EXPECT_TRUE(job_controller_->main_job()); | |
812 EXPECT_TRUE(job_controller_->alternative_job()); | |
570 | 813 |
571 // |alternative_job| succeeds and should report status to Request. | 814 base::RunLoop().RunUntilIdle(); |
815 | |
816 // Make |alternative_job| succeed. | |
572 HttpStream* http_stream = | 817 HttpStream* http_stream = |
573 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | 818 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
574 job_factory_.alternative_job()->SetStream(http_stream); | |
575 | 819 |
576 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | 820 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
577 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 821 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
822 | |
823 job_factory_.alternative_job()->SetStream(http_stream); | |
578 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); | 824 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
825 | |
826 // |alternative_job| succeeds and should report status to Request. | |
579 VerifyBrokenAlternateProtocolMapping(request_info, false); | 827 VerifyBrokenAlternateProtocolMapping(request_info, false); |
580 } | 828 } |
581 | 829 |
582 TEST_F(HttpStreamFactoryImplJobControllerTest, | 830 TEST_F(HttpStreamFactoryImplJobControllerTest, |
583 MainJobSucceedsAfterAltJobFailed) { | 831 MainJobSucceedsAfterAltJobFailed) { |
832 // One TCP connect. | |
833 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
834 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
835 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
836 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
837 | |
584 base::HistogramTester histogram_tester; | 838 base::HistogramTester histogram_tester; |
585 ProxyConfig proxy_config; | |
586 proxy_config.set_auto_detect(true); | |
587 // Use asynchronous proxy resolver. | |
588 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
589 new MockAsyncProxyResolverFactory(false); | |
590 session_deps_.proxy_service.reset( | |
591 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
592 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
593 HttpRequestInfo request_info; | 839 HttpRequestInfo request_info; |
594 request_info.method = "GET"; | 840 request_info.method = "GET"; |
595 request_info.url = GURL("https://www.google.com"); | 841 request_info.url = GURL("https://www.google.com"); |
596 | 842 |
597 Initialize(request_info); | 843 Initialize(request_info); |
598 | 844 |
599 url::SchemeHostPort server(request_info.url); | 845 url::SchemeHostPort server(request_info.url); |
600 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 846 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
601 SetAlternativeService(request_info, alternative_service); | 847 SetAlternativeService(request_info, alternative_service); |
848 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
849 session_->quic_stream_factory(), | |
850 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED)); | |
602 | 851 |
603 request_.reset( | 852 request_.reset( |
604 job_controller_->Start(request_info, &request_delegate_, nullptr, | 853 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
605 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 854 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
606 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
607 EXPECT_TRUE(job_controller_->main_job()); | 855 EXPECT_TRUE(job_controller_->main_job()); |
608 EXPECT_TRUE(job_controller_->alternative_job()); | 856 EXPECT_TRUE(job_controller_->alternative_job()); |
609 | 857 |
610 // |alternative_job| fails but should not report status to Request. | 858 // |alternative_job| fails but should not report status to Request. |
611 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 859 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
860 // |main_job| succeeds and should report status to Request. | |
861 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) | |
862 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
612 | 863 |
613 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, | 864 base::RunLoop().RunUntilIdle(); |
614 SSLConfig()); | |
615 | |
616 // |main_job| succeeds and should report status to Request. | |
617 HttpStream* http_stream = | |
618 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
619 job_factory_.main_job()->SetStream(http_stream); | |
620 | |
621 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | |
622 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
623 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | |
624 | 865 |
625 // Verify that the alternate protocol is marked as broken. | 866 // Verify that the alternate protocol is marked as broken. |
626 VerifyBrokenAlternateProtocolMapping(request_info, true); | 867 VerifyBrokenAlternateProtocolMapping(request_info, true); |
627 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED, | 868 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED, |
628 1); | 869 1); |
629 } | 870 } |
630 | 871 |
631 // Verifies that if the alternative job fails due to a connection change event, | 872 // Verifies that if the alternative job fails due to a connection change event, |
632 // then the alternative service is not marked as broken. | 873 // then the alternative service is not marked as broken. |
633 TEST_F(HttpStreamFactoryImplJobControllerTest, | 874 TEST_F(HttpStreamFactoryImplJobControllerTest, |
634 MainJobSucceedsAfterConnectionChanged) { | 875 MainJobSucceedsAfterConnectionChanged) { |
876 // One TCP connect. | |
877 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
878 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
879 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
880 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
881 | |
635 base::HistogramTester histogram_tester; | 882 base::HistogramTester histogram_tester; |
636 ProxyConfig proxy_config; | |
637 proxy_config.set_auto_detect(true); | |
638 // Use asynchronous proxy resolver. | |
639 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
640 new MockAsyncProxyResolverFactory(false); | |
641 session_deps_.proxy_service.reset( | |
642 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
643 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
644 session_deps_.quic_do_not_mark_as_broken_on_network_change = true; | 883 session_deps_.quic_do_not_mark_as_broken_on_network_change = true; |
645 | 884 |
646 HttpRequestInfo request_info; | 885 HttpRequestInfo request_info; |
647 request_info.method = "GET"; | 886 request_info.method = "GET"; |
648 request_info.url = GURL("https://www.google.com"); | 887 request_info.url = GURL("https://www.google.com"); |
649 Initialize(request_info); | 888 Initialize(request_info); |
650 | 889 |
651 url::SchemeHostPort server(request_info.url); | 890 url::SchemeHostPort server(request_info.url); |
652 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 891 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
653 SetAlternativeService(request_info, alternative_service); | 892 SetAlternativeService(request_info, alternative_service); |
654 | 893 |
894 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
895 session_->quic_stream_factory(), | |
896 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_NETWORK_CHANGED)); | |
897 | |
655 request_.reset( | 898 request_.reset( |
656 job_controller_->Start(request_info, &request_delegate_, nullptr, | 899 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
657 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 900 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
658 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
659 EXPECT_TRUE(job_controller_->main_job()); | 901 EXPECT_TRUE(job_controller_->main_job()); |
660 EXPECT_TRUE(job_controller_->alternative_job()); | 902 EXPECT_TRUE(job_controller_->alternative_job()); |
661 | 903 |
662 // |alternative_job| fails but should not report status to Request. | 904 // |alternative_job| fails but should not report status to Request. |
663 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 905 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
664 | |
665 job_controller_->OnStreamFailed(job_factory_.alternative_job(), | |
666 ERR_NETWORK_CHANGED, SSLConfig()); | |
667 | |
668 // |main_job| succeeds and should report status to Request. | 906 // |main_job| succeeds and should report status to Request. |
669 HttpStream* http_stream = | 907 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
670 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
671 job_factory_.main_job()->SetStream(http_stream); | |
672 | |
673 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | |
674 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 908 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
675 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | 909 base::RunLoop().RunUntilIdle(); |
676 | 910 |
677 // Verify that the alternate protocol is not marked as broken. | 911 // Verify that the alternate protocol is not marked as broken. |
678 VerifyBrokenAlternateProtocolMapping(request_info, false); | 912 VerifyBrokenAlternateProtocolMapping(request_info, false); |
679 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", | 913 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", |
680 -ERR_NETWORK_CHANGED, 1); | 914 -ERR_NETWORK_CHANGED, 1); |
681 } | 915 } |
682 | 916 |
683 // Regression test for crbug/621069. | 917 // Regression test for crbug/621069. |
684 // Get load state after main job fails and before alternative job succeeds. | 918 // Get load state after main job fails and before alternative job succeeds. |
685 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { | 919 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
686 ProxyConfig proxy_config; | 920 // One failed TCP connect. |
687 proxy_config.set_auto_detect(true); | 921 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
688 // Use asynchronous proxy resolver. | 922 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); |
689 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
690 new MockAsyncProxyResolverFactory(false); | |
691 session_deps_.proxy_service.reset(new ProxyService( | |
692 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), | |
693 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
694 | 923 |
695 HttpRequestInfo request_info; | 924 HttpRequestInfo request_info; |
696 request_info.method = "GET"; | 925 request_info.method = "GET"; |
697 request_info.url = GURL("https://www.google.com"); | 926 request_info.url = GURL("https://www.google.com"); |
698 | 927 |
699 Initialize(request_info); | 928 Initialize(request_info); |
700 url::SchemeHostPort server(request_info.url); | 929 url::SchemeHostPort server(request_info.url); |
701 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 930 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
702 SetAlternativeService(request_info, alternative_service); | 931 SetAlternativeService(request_info, alternative_service); |
703 | 932 |
933 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
934 session_->quic_stream_factory(), | |
935 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); | |
936 | |
704 request_.reset( | 937 request_.reset( |
705 job_controller_->Start(request_info, &request_delegate_, nullptr, | 938 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
706 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 939 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
707 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
708 EXPECT_TRUE(job_controller_->main_job()); | 940 EXPECT_TRUE(job_controller_->main_job()); |
709 EXPECT_TRUE(job_controller_->alternative_job()); | 941 EXPECT_TRUE(job_controller_->alternative_job()); |
710 | 942 |
711 // |main_job| fails but should not report status to Request. | 943 // |main_job| fails but should not report status to Request. |
712 // The alternative job will mark the main job complete. | 944 // The alternative job will mark the main job complete. |
713 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 945 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
714 | 946 |
715 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, | 947 base::RunLoop().RunUntilIdle(); |
716 SSLConfig()); | |
717 | 948 |
718 // Controller should use alternative job to get load state. | 949 // Controller should use alternative job to get load state. |
719 job_controller_->GetLoadState(); | 950 job_controller_->GetLoadState(); |
720 | 951 |
721 // |alternative_job| succeeds and should report status to Request. | 952 // |alternative_job| succeeds and should report status to Request. |
722 HttpStream* http_stream = | 953 HttpStream* http_stream = |
723 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | 954 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
724 job_factory_.alternative_job()->SetStream(http_stream); | 955 job_factory_.alternative_job()->SetStream(http_stream); |
725 | 956 |
726 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | 957 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
727 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 958 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
728 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); | 959 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
729 } | 960 } |
730 | 961 |
731 TEST_F(HttpStreamFactoryImplJobControllerTest, DoNotResumeMainJobBeforeWait) { | 962 TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobWhenAltJobStalls) { |
732 // Use failing ProxyResolverFactory which is unable to create ProxyResolver | 963 // One TCP connect. |
733 // to stall the alternative job and report to controller to maybe resume the | 964 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
734 // main job. | 965 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
735 ProxyConfig proxy_config; | 966 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
736 proxy_config.set_auto_detect(true); | 967 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); |
737 proxy_config.set_pac_mandatory(true); | |
738 session_deps_.proxy_service.reset(new ProxyService( | |
739 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
740 base::WrapUnique(new FailingProxyResolverFactory), nullptr)); | |
741 | 968 |
742 HttpRequestInfo request_info; | 969 HttpRequestInfo request_info; |
743 request_info.method = "GET"; | 970 request_info.method = "GET"; |
744 request_info.url = GURL("https://www.google.com"); | 971 request_info.url = GURL("https://www.google.com"); |
745 | 972 |
746 Initialize(request_info); | 973 Initialize(request_info); |
747 url::SchemeHostPort server(request_info.url); | 974 url::SchemeHostPort server(request_info.url); |
748 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 975 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
749 SetAlternativeService(request_info, alternative_service); | 976 SetAlternativeService(request_info, alternative_service); |
977 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
978 session_->quic_stream_factory(), | |
979 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); | |
750 | 980 |
751 request_.reset( | 981 request_.reset( |
752 job_controller_->Start(request_info, &request_delegate_, nullptr, | 982 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
753 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 983 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
754 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
755 EXPECT_TRUE(job_controller_->main_job()); | 984 EXPECT_TRUE(job_controller_->main_job()); |
756 EXPECT_TRUE(job_controller_->alternative_job()); | 985 EXPECT_TRUE(job_controller_->alternative_job()); |
757 | 986 |
758 // Wait until OnStreamFailedCallback is executed on the alternative job. | 987 // Alt job is stalled and main job should complete successfully. |
759 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); | 988 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
989 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
990 | |
760 base::RunLoop().RunUntilIdle(); | 991 base::RunLoop().RunUntilIdle(); |
761 } | 992 } |
762 | 993 |
763 TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { | 994 TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { |
764 HttpRequestInfo request_info; | 995 HttpRequestInfo request_info; |
765 request_info.method = "GET"; | 996 request_info.method = "GET"; |
766 request_info.url = GURL("https://www.google.com"); | 997 request_info.url = GURL("https://www.google.com"); |
767 | 998 |
768 // Using a restricted port 101 for QUIC should fail and the alternative job | 999 // Using a restricted port 101 for QUIC should fail and the alternative job |
769 // should post OnStreamFailedCall on the controller to resume the main job. | 1000 // should post OnStreamFailedCall on the controller to resume the main job. |
770 Initialize(request_info); | 1001 Initialize(request_info); |
771 | 1002 |
772 url::SchemeHostPort server(request_info.url); | 1003 url::SchemeHostPort server(request_info.url); |
773 AlternativeService alternative_service(kProtoQUIC, server.host(), 101); | 1004 AlternativeService alternative_service(kProtoQUIC, server.host(), 101); |
774 SetAlternativeService(request_info, alternative_service); | 1005 SetAlternativeService(request_info, alternative_service); |
775 | 1006 |
776 request_.reset( | 1007 request_.reset( |
777 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1008 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
778 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1009 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
779 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
780 | 1010 |
781 EXPECT_TRUE(job_factory_.main_job()->is_waiting()); | 1011 EXPECT_TRUE(job_factory_.main_job()->is_waiting()); |
782 | 1012 |
783 // Wait until OnStreamFailedCallback is executed on the alternative job. | 1013 // Wait until OnStreamFailedCallback is executed on the alternative job. |
784 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 1014 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
785 base::RunLoop().RunUntilIdle(); | 1015 base::RunLoop().RunUntilIdle(); |
786 } | 1016 } |
787 | 1017 |
788 TEST_F(HttpStreamFactoryImplJobControllerTest, | |
789 NoAvailableSpdySessionToResumeMainJob) { | |
790 // Test the alternative job is not resumed when the alternative job is | |
791 // IO_PENDING for proxy resolution. Once all the proxy resolution succeeds, | |
792 // the latter part of this test tests controller resumes the main job | |
793 // when there's no SPDY session for the alternative job. | |
794 ProxyConfig proxy_config; | |
795 proxy_config.set_auto_detect(true); | |
796 // Use asynchronous proxy resolver. | |
797 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
798 new MockAsyncProxyResolverFactory(false); | |
799 session_deps_.proxy_service.reset( | |
800 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
801 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
802 | |
803 HangingResolver* host_resolver = new HangingResolver(); | |
804 session_deps_.host_resolver.reset(host_resolver); | |
805 session_deps_.host_resolver->set_synchronous_mode(false); | |
806 | |
807 HttpRequestInfo request_info; | |
808 request_info.method = "GET"; | |
809 request_info.url = GURL("https://www.google.com"); | |
810 | |
811 Initialize(request_info); | |
812 | |
813 // Set a SPDY alternative service for the server. | |
814 url::SchemeHostPort server(request_info.url); | |
815 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | |
816 SetAlternativeService(request_info, alternative_service); | |
817 // Hack to use different URL for the main job to help differentiate the proxy | |
818 // requests. | |
819 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); | |
820 | |
821 request_.reset( | |
822 job_controller_->Start(request_info, &request_delegate_, nullptr, | |
823 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | |
824 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
825 // Both jobs should be created but stalled as proxy resolution not completed. | |
826 EXPECT_TRUE(job_controller_->main_job()); | |
827 EXPECT_TRUE(job_controller_->alternative_job()); | |
828 | |
829 MockAsyncProxyResolver resolver; | |
830 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( | |
831 net::OK, &resolver); | |
832 | |
833 // Resolve proxy for the main job which then proceed to wait for the | |
834 // alternative job which is IO_PENDING. | |
835 int main_job_request_id = | |
836 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; | |
837 | |
838 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( | |
839 "result1:80"); | |
840 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); | |
841 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | |
842 | |
843 // Resolve proxy for the alternative job to proceed to create a connection. | |
844 // Use hanging HostResolver to fail creation of a SPDY session for the | |
845 // alternative job. The alternative job will be IO_PENDING thus should resume | |
846 // the main job. | |
847 resolver.pending_jobs()[0]->CompleteNow(net::OK); | |
848 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | |
849 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | |
850 | |
851 base::RunLoop().RunUntilIdle(); | |
852 } | |
853 | |
854 TEST_F(HttpStreamFactoryImplJobControllerTest, | |
855 NoAvailableQuicSessionToResumeMainJob) { | |
856 // Use failing HostResolver which is unable to resolve the host name for QUIC. | |
857 // No QUIC session is created and thus should resume the main job. | |
858 FailingHostResolver* host_resolver = new FailingHostResolver(); | |
859 session_deps_.host_resolver.reset(host_resolver); | |
860 | |
861 ProxyConfig proxy_config; | |
862 proxy_config.set_auto_detect(true); | |
863 // Use asynchronous proxy resolver. | |
864 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
865 new MockAsyncProxyResolverFactory(false); | |
866 session_deps_.proxy_service.reset( | |
867 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
868 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
869 | |
870 HttpRequestInfo request_info; | |
871 request_info.method = "GET"; | |
872 request_info.url = GURL("https://www.google.com"); | |
873 | |
874 Initialize(request_info); | |
875 url::SchemeHostPort server(request_info.url); | |
876 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | |
877 SetAlternativeService(request_info, alternative_service); | |
878 // Hack to use different URL for the main job to help differentiate the proxy | |
879 // requests. | |
880 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); | |
881 | |
882 request_.reset( | |
883 job_controller_->Start(request_info, &request_delegate_, nullptr, | |
884 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | |
885 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
886 EXPECT_TRUE(job_controller_->main_job()); | |
887 EXPECT_TRUE(job_controller_->alternative_job()); | |
888 | |
889 MockAsyncProxyResolver resolver; | |
890 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( | |
891 net::OK, &resolver); | |
892 | |
893 // Resolve proxy for the main job which then proceed to wait for the | |
894 // alternative job which is IO_PENDING. | |
895 int main_job_request_id = | |
896 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; | |
897 | |
898 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( | |
899 "result1:80"); | |
900 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); | |
901 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | |
902 | |
903 // Resolve proxy for the alternative job to proceed to create a connection. | |
904 // Use failing HostResolver to fail creation of a QUIC session for the | |
905 // alternative job. The alternative job will thus resume the main job. | |
906 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); | |
907 resolver.pending_jobs()[0]->CompleteNow(net::OK); | |
908 | |
909 // Wait until OnStreamFailedCallback is executed on the alternative job. | |
910 // Request shouldn't be notified as the main job is still pending status. | |
911 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | |
912 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | |
913 | |
914 base::RunLoop().RunUntilIdle(); | |
915 } | |
916 | |
917 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { | 1018 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { |
918 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; | 1019 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
919 auto failing_resolver = base::MakeUnique<MockHostResolver>(); | 1020 auto failing_resolver = base::MakeUnique<MockHostResolver>(); |
920 failing_resolver->set_ondemand_mode(true); | 1021 failing_resolver->set_ondemand_mode(true); |
921 failing_resolver->rules()->AddSimulatedFailure("*google.com"); | 1022 failing_resolver->rules()->AddSimulatedFailure("*google.com"); |
922 session_deps_.host_resolver = std::move(failing_resolver); | 1023 session_deps_.host_resolver = std::move(failing_resolver); |
923 | 1024 |
924 HttpRequestInfo request_info; | 1025 HttpRequestInfo request_info; |
925 request_info.method = "GET"; | 1026 request_info.method = "GET"; |
926 request_info.url = GURL("https://www.google.com"); | 1027 request_info.url = GURL("https://www.google.com"); |
927 | 1028 |
928 Initialize(request_info); | 1029 Initialize(request_info); |
929 | 1030 |
930 // Enable delayed TCP and set time delay for waiting job. | 1031 // Enable delayed TCP and set time delay for waiting job. |
931 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 1032 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
932 quic_stream_factory->set_require_confirmation(false); | 1033 quic_stream_factory->set_require_confirmation(false); |
933 ServerNetworkStats stats1; | 1034 ServerNetworkStats stats1; |
934 stats1.srtt = base::TimeDelta::FromMicroseconds(10); | 1035 stats1.srtt = base::TimeDelta::FromMicroseconds(10); |
935 session_->http_server_properties()->SetServerNetworkStats( | 1036 session_->http_server_properties()->SetServerNetworkStats( |
936 url::SchemeHostPort(GURL("https://www.google.com")), stats1); | 1037 url::SchemeHostPort(GURL("https://www.google.com")), stats1); |
937 | 1038 |
938 // Set a SPDY alternative service for the server. | |
939 url::SchemeHostPort server(request_info.url); | 1039 url::SchemeHostPort server(request_info.url); |
940 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1040 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
941 SetAlternativeService(request_info, alternative_service); | 1041 SetAlternativeService(request_info, alternative_service); |
942 | 1042 |
943 request_.reset( | 1043 request_.reset( |
944 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1044 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
945 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1045 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
946 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
947 EXPECT_TRUE(job_controller_->main_job()); | 1046 EXPECT_TRUE(job_controller_->main_job()); |
948 EXPECT_TRUE(job_controller_->alternative_job()); | 1047 EXPECT_TRUE(job_controller_->alternative_job()); |
949 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1048 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
950 | 1049 |
951 // The alternative job stalls as host resolution hangs when creating the QUIC | 1050 // The alternative job stalls as host resolution hangs when creating the QUIC |
952 // request and controller should resume the main job after delay. | 1051 // request and controller should resume the main job after delay. |
953 EXPECT_TRUE(test_task_runner->HasPendingTask()); | 1052 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
954 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1053 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
955 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 1054 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
956 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); | 1055 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1002 stats1.srtt = base::TimeDelta::FromSeconds(100); | 1101 stats1.srtt = base::TimeDelta::FromSeconds(100); |
1003 session_->http_server_properties()->SetServerNetworkStats( | 1102 session_->http_server_properties()->SetServerNetworkStats( |
1004 url::SchemeHostPort(GURL("https://www.google.com")), stats1); | 1103 url::SchemeHostPort(GURL("https://www.google.com")), stats1); |
1005 | 1104 |
1006 // Set a SPDY alternative service for the server. | 1105 // Set a SPDY alternative service for the server. |
1007 url::SchemeHostPort server(request_info.url); | 1106 url::SchemeHostPort server(request_info.url); |
1008 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1107 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
1009 SetAlternativeService(request_info, alternative_service); | 1108 SetAlternativeService(request_info, alternative_service); |
1010 | 1109 |
1011 request_.reset( | 1110 request_.reset( |
1012 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1111 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
1013 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1112 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
1014 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
1015 EXPECT_TRUE(job_controller_->main_job()); | 1113 EXPECT_TRUE(job_controller_->main_job()); |
1016 EXPECT_TRUE(job_controller_->alternative_job()); | 1114 EXPECT_TRUE(job_controller_->alternative_job()); |
1017 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1115 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
1018 | 1116 |
1019 // The alternative job stalls as host resolution hangs when creating the QUIC | 1117 // The alternative job stalls as host resolution hangs when creating the QUIC |
1020 // request and controller should resume the main job after delay. | 1118 // request and controller should resume the main job after delay. |
1021 EXPECT_TRUE(test_task_runner->HasPendingTask()); | 1119 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
1022 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1120 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
1023 | 1121 |
1024 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 1122 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1062 | 1160 |
1063 // Set a SPDY alternative service for the server. | 1161 // Set a SPDY alternative service for the server. |
1064 url::SchemeHostPort server(request_info.url); | 1162 url::SchemeHostPort server(request_info.url); |
1065 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1163 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
1066 SetAlternativeService(request_info, alternative_service); | 1164 SetAlternativeService(request_info, alternative_service); |
1067 | 1165 |
1068 // The alternative job stalls as host resolution hangs when creating the QUIC | 1166 // The alternative job stalls as host resolution hangs when creating the QUIC |
1069 // request and controller should resume the main job with delay. | 1167 // request and controller should resume the main job with delay. |
1070 // OnStreamFailed should resume the main job immediately. | 1168 // OnStreamFailed should resume the main job immediately. |
1071 request_.reset( | 1169 request_.reset( |
1072 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1170 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
1073 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1171 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
1074 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
1075 EXPECT_TRUE(job_controller_->main_job()); | 1172 EXPECT_TRUE(job_controller_->main_job()); |
1076 EXPECT_TRUE(job_controller_->alternative_job()); | 1173 EXPECT_TRUE(job_controller_->alternative_job()); |
1077 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1174 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
1078 | 1175 |
1079 EXPECT_TRUE(test_task_runner->HasPendingTask()); | 1176 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
1080 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1177 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
1081 | 1178 |
1082 // |alternative_job| fails but should not report status to Request. | 1179 // |alternative_job| fails but should not report status to Request. |
1083 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 1180 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
1084 // Now unblock Resolver to fail the alternate job. | 1181 // Now unblock Resolver to fail the alternate job. |
(...skipping 23 matching lines...) Expand all Loading... | |
1108 HangingResolver* resolver = new HangingResolver(); | 1205 HangingResolver* resolver = new HangingResolver(); |
1109 session_deps_.host_resolver.reset(resolver); | 1206 session_deps_.host_resolver.reset(resolver); |
1110 | 1207 |
1111 HttpRequestInfo request_info; | 1208 HttpRequestInfo request_info; |
1112 request_info.method = "GET"; | 1209 request_info.method = "GET"; |
1113 request_info.url = GURL("https://mail.example.org/"); | 1210 request_info.url = GURL("https://mail.example.org/"); |
1114 Initialize(request_info); | 1211 Initialize(request_info); |
1115 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); | 1212 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
1116 | 1213 |
1117 request_.reset( | 1214 request_.reset( |
1118 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1215 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
1119 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1216 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
1120 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
1121 EXPECT_TRUE(job_controller_->main_job()); | 1217 EXPECT_TRUE(job_controller_->main_job()); |
1122 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); | 1218 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); |
1123 EXPECT_FALSE(job_controller_->alternative_job()); | 1219 EXPECT_FALSE(job_controller_->alternative_job()); |
1124 | 1220 |
1125 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | 1221 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); |
1126 base::RunLoop().RunUntilIdle(); | 1222 base::RunLoop().RunUntilIdle(); |
1127 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); | 1223 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); |
1128 } | 1224 } |
1129 | 1225 |
1130 // Verifies that the alternative proxy server job is not created if the main job | 1226 // Verifies that the alternative proxy server job is not created if the main job |
1131 // does not fetch the resource through a proxy. | 1227 // does not fetch the resource through a proxy. |
1132 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) { | 1228 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) { |
1133 // Using hanging resolver will cause the alternative job to hang indefinitely. | 1229 // Using hanging resolver will cause the alternative job to hang indefinitely. |
1134 HangingResolver* resolver = new HangingResolver(); | 1230 HangingResolver* resolver = new HangingResolver(); |
1135 session_deps_.host_resolver.reset(resolver); | 1231 session_deps_.host_resolver.reset(resolver); |
1136 | 1232 |
1137 HttpRequestInfo request_info; | 1233 HttpRequestInfo request_info; |
1138 request_info.method = "GET"; | 1234 request_info.method = "GET"; |
1139 request_info.url = GURL("http://mail.example.org/"); | 1235 request_info.url = GURL("http://mail.example.org/"); |
1140 | 1236 |
1141 Initialize(request_info); | 1237 Initialize(request_info); |
1142 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); | 1238 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
1143 | 1239 |
1144 request_.reset( | 1240 request_.reset( |
1145 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1241 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
1146 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1242 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
1147 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
1148 EXPECT_TRUE(job_controller_->main_job()); | 1243 EXPECT_TRUE(job_controller_->main_job()); |
1149 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); | 1244 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); |
1150 EXPECT_FALSE(job_controller_->alternative_job()); | 1245 EXPECT_FALSE(job_controller_->alternative_job()); |
1151 | 1246 |
1152 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | 1247 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); |
1153 base::RunLoop().RunUntilIdle(); | 1248 base::RunLoop().RunUntilIdle(); |
1154 | 1249 |
1155 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); | 1250 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); |
1156 } | 1251 } |
1157 | 1252 |
1158 // Verifies that the main job is resumed properly after a delay when the | 1253 // Verifies that the main job is resumed properly after a delay when the |
1159 // alternative proxy server job hangs. | 1254 // alternative proxy server job hangs. |
1160 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { | 1255 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { |
1161 // Overrides the main thread's message loop with a mock tick clock so that we | 1256 // Overrides the main thread's message loop with a mock tick clock so that we |
1162 // could verify the main job is resumed with appropriate delay. | 1257 // could verify the main job is resumed with appropriate delay. |
1163 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; | 1258 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
1164 | |
1165 auto failing_resolver = base::MakeUnique<MockHostResolver>(); | |
1166 failing_resolver->set_ondemand_mode(true); | |
1167 failing_resolver->rules()->AddSimulatedFailure("*myproxy.org"); | |
1168 session_deps_.host_resolver = std::move(failing_resolver); | |
1169 | |
1170 UseAlternativeProxy(); | 1259 UseAlternativeProxy(); |
1171 | 1260 |
1172 HttpRequestInfo request_info; | 1261 HttpRequestInfo request_info; |
1173 request_info.method = "GET"; | 1262 request_info.method = "GET"; |
1174 request_info.url = GURL("http://mail.example.org/"); | 1263 request_info.url = GURL("http://mail.example.org/"); |
1175 Initialize(request_info); | 1264 Initialize(request_info); |
1176 | 1265 |
1266 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
1267 session_->quic_stream_factory(), | |
1268 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING)); | |
1269 | |
1177 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); | 1270 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
1178 | 1271 |
1179 // Enable delayed TCP and set time delay for waiting job. | 1272 // Enable delayed TCP and set time delay for waiting job. |
1180 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 1273 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
1181 quic_stream_factory->set_require_confirmation(false); | 1274 quic_stream_factory->set_require_confirmation(false); |
1182 ServerNetworkStats stats1; | 1275 ServerNetworkStats stats1; |
1183 stats1.srtt = base::TimeDelta::FromMicroseconds(10); | 1276 stats1.srtt = base::TimeDelta::FromMicroseconds(10); |
1184 session_->http_server_properties()->SetServerNetworkStats( | 1277 session_->http_server_properties()->SetServerNetworkStats( |
1185 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); | 1278 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); |
1186 | 1279 |
1187 request_.reset( | 1280 request_.reset( |
1188 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1281 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
1189 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1282 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
1190 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
1191 EXPECT_TRUE(job_controller_->main_job()); | 1283 EXPECT_TRUE(job_controller_->main_job()); |
1192 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1284 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
1193 EXPECT_TRUE(job_controller_->alternative_job()); | 1285 EXPECT_TRUE(job_controller_->alternative_job()); |
1194 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 1286 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
1195 | 1287 |
1196 // Alternative proxy server job will start in the next message loop. | 1288 // Move forward the delay and verify the main job is resumed. |
1197 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1289 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
1198 | |
1199 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | |
1200 // Run tasks with no remaining delay, this will start the alternative proxy | 1290 // Run tasks with no remaining delay, this will start the alternative proxy |
1201 // server job. The alternative proxy server job stalls when connecting to the | 1291 // server job. The alternative proxy server job stalls when connecting to the |
1202 // alternative proxy server, and should schedule a task to resume the main job | 1292 // alternative proxy server, and should schedule a task to resume the main job |
1203 // after delay. That task will be queued. | 1293 // after delay. That task will be queued. |
1204 test_task_runner->RunUntilIdle(); | |
1205 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1294 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
1206 | |
1207 // Move forward the delay and verify the main job is resumed. | |
1208 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | |
1209 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); | 1295 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); |
1210 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 1296 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
1211 | 1297 |
1212 test_task_runner->RunUntilIdle(); | 1298 test_task_runner->RunUntilIdle(); |
1213 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); | 1299 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); |
1214 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); | 1300 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); |
1215 EXPECT_FALSE(test_task_runner->HasPendingTask()); | 1301 EXPECT_FALSE(test_task_runner->HasPendingTask()); |
1216 | 1302 |
1217 // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can | 1303 // Resume() function is mocked, so we will still have main job around. |
1218 // be cleaned up. | 1304 EXPECT_TRUE(job_controller_->main_job()); |
1219 session_deps_.host_resolver->ResolveAllPending(); | 1305 EXPECT_TRUE(job_controller_->alternative_job()); |
1220 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | |
1221 test_task_runner->FastForwardUntilNoTasksRemain(); | |
1222 EXPECT_FALSE(job_controller_->alternative_job()); | |
1223 } | 1306 } |
1224 | 1307 |
1225 // Verifies that the alternative proxy server job fails immediately, and the | 1308 // Verifies that if the alternative proxy server job fails immediately, the |
1226 // main job is not blocked. | 1309 // main job is not blocked. |
1227 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { | 1310 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { |
1228 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; | 1311 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
1229 // Using failing resolver will cause the alternative job to fail. | |
1230 FailingHostResolver* resolver = new FailingHostResolver(); | |
1231 session_deps_.host_resolver.reset(resolver); | |
1232 | |
1233 UseAlternativeProxy(); | 1312 UseAlternativeProxy(); |
1234 | 1313 |
1235 HttpRequestInfo request_info; | 1314 HttpRequestInfo request_info; |
1236 request_info.method = "GET"; | 1315 request_info.method = "GET"; |
1237 request_info.url = GURL("http://mail.example.org/"); | 1316 request_info.url = GURL("http://mail.example.org/"); |
1238 Initialize(request_info); | 1317 Initialize(request_info); |
1239 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); | 1318 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
1240 | 1319 |
1241 // Enable delayed TCP and set time delay for waiting job. | 1320 // Enable delayed TCP and set time delay for waiting job. |
1242 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 1321 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
1243 quic_stream_factory->set_require_confirmation(false); | 1322 quic_stream_factory->set_require_confirmation(false); |
1244 ServerNetworkStats stats1; | 1323 ServerNetworkStats stats1; |
1245 stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000); | 1324 stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000); |
1246 session_->http_server_properties()->SetServerNetworkStats( | 1325 session_->http_server_properties()->SetServerNetworkStats( |
1247 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); | 1326 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); |
1327 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
1328 session_->quic_stream_factory(), | |
1329 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED)); | |
1248 | 1330 |
1249 request_.reset( | 1331 request_.reset( |
1250 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1332 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
1251 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1333 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
1252 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
1253 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1334 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
1254 EXPECT_TRUE(job_controller_->alternative_job()); | 1335 EXPECT_TRUE(job_controller_->alternative_job()); |
1255 | 1336 |
1256 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1337 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
1257 | 1338 |
1258 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)).Times(0); | 1339 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)).Times(0); |
1259 | 1340 |
1260 // Since the alternative proxy server job is started in the next message loop, | 1341 // Since the alternative proxy server job is started in the next message loop, |
1261 // the main job would remain blocked until the alternative proxy starts, and | 1342 // the main job would remain blocked until the alternative proxy starts, and |
1262 // fails. | 1343 // fails. |
1263 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 1344 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
1264 | 1345 |
1265 // Run tasks with no remaining delay. | 1346 // Run tasks with no remaining delay. |
1266 test_task_runner->RunUntilIdle(); | 1347 test_task_runner->RunUntilIdle(); |
1267 | 1348 |
1268 EXPECT_FALSE(job_controller_->alternative_job()); | 1349 EXPECT_FALSE(job_controller_->alternative_job()); |
1269 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1350 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
1270 // Since the main job did not complete successfully, the alternative proxy | 1351 // The alternative proxy server should be marked as bad. |
1271 // server should not be marked as bad. | 1352 EXPECT_FALSE(test_proxy_delegate()->alternative_proxy_server().is_valid()); |
1272 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); | |
1273 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); | 1353 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); |
1274 EXPECT_FALSE(test_task_runner->HasPendingTask()); | 1354 EXPECT_FALSE(test_task_runner->HasPendingTask()); |
1275 } | 1355 } |
1276 | 1356 |
1277 TEST_F(HttpStreamFactoryImplJobControllerTest, | 1357 TEST_F(HttpStreamFactoryImplJobControllerTest, |
1278 AlternativeProxyServerJobFailsAfterMainJobSucceeds) { | 1358 AlternativeProxyServerJobFailsAfterMainJobSucceeds) { |
1279 base::HistogramTester histogram_tester; | 1359 base::HistogramTester histogram_tester; |
1280 | 1360 |
1281 UseAlternativeProxy(); | 1361 UseAlternativeProxy(); |
1282 | 1362 |
1283 HttpRequestInfo request_info; | 1363 HttpRequestInfo request_info; |
1284 request_info.method = "GET"; | 1364 request_info.method = "GET"; |
1285 request_info.url = GURL("http://www.google.com"); | 1365 request_info.url = GURL("http://www.google.com"); |
1286 Initialize(request_info); | 1366 Initialize(request_info); |
1287 | 1367 |
1288 url::SchemeHostPort server(request_info.url); | 1368 url::SchemeHostPort server(request_info.url); |
1289 | 1369 |
1290 request_.reset( | 1370 request_.reset( |
1291 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1371 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
1292 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1372 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
1293 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
1294 EXPECT_TRUE(job_controller_->main_job()); | 1373 EXPECT_TRUE(job_controller_->main_job()); |
1295 EXPECT_TRUE(job_controller_->alternative_job()); | 1374 EXPECT_TRUE(job_controller_->alternative_job()); |
1296 | 1375 |
1297 // Main job succeeds, starts serving Request and it should report status | 1376 // Main job succeeds, starts serving Request and it should report status |
1298 // to Request. The alternative job will mark the main job complete and gets | 1377 // to Request. The alternative job will mark the main job complete and gets |
1299 // orphaned. | 1378 // orphaned. |
1300 HttpStream* http_stream = | 1379 HttpStream* http_stream = |
1301 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | 1380 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
1302 job_factory_.main_job()->SetStream(http_stream); | 1381 job_factory_.main_job()->SetStream(http_stream); |
1303 | 1382 |
(...skipping 12 matching lines...) Expand all Loading... | |
1316 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1395 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
1317 | 1396 |
1318 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", | 1397 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", |
1319 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, | 1398 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, |
1320 1); | 1399 1); |
1321 } | 1400 } |
1322 | 1401 |
1323 // When preconnect to a H2 supported server, only 1 connection is opened. | 1402 // When preconnect to a H2 supported server, only 1 connection is opened. |
1324 TEST_F(HttpStreamFactoryImplJobControllerTest, | 1403 TEST_F(HttpStreamFactoryImplJobControllerTest, |
1325 PreconnectMultipleStreamsToH2Server) { | 1404 PreconnectMultipleStreamsToH2Server) { |
1326 MockRead reads[] = {MockRead(ASYNC, OK)}; | 1405 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
1327 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); | 1406 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
1328 session_deps_.socket_factory->AddSocketDataProvider(&data); | |
1329 | |
1330 SetPreconnect(); | 1407 SetPreconnect(); |
1331 | 1408 |
1332 HttpRequestInfo request_info; | 1409 HttpRequestInfo request_info; |
1333 request_info.method = "GET"; | 1410 request_info.method = "GET"; |
1334 request_info.url = GURL("http://www.example.com"); | 1411 request_info.url = GURL("http://www.example.com"); |
1335 Initialize(request_info); | 1412 Initialize(request_info); |
1336 | 1413 |
1337 url::SchemeHostPort server(request_info.url); | 1414 url::SchemeHostPort server(request_info.url); |
1338 | 1415 |
1339 // Sets server support Http/2. | 1416 // Sets server support Http/2. |
1340 session_->http_server_properties()->SetSupportsSpdy(server, true); | 1417 session_->http_server_properties()->SetSupportsSpdy(server, true); |
1341 | 1418 |
1342 job_controller_->Preconnect(/*num_streams=*/5, request_info, SSLConfig(), | 1419 job_controller_->Preconnect(/*num_streams=*/5); |
1343 SSLConfig()); | |
1344 // Only one job is started. | 1420 // Only one job is started. |
1345 EXPECT_TRUE(job_controller_->main_job()); | 1421 EXPECT_TRUE(job_controller_->main_job()); |
1346 EXPECT_FALSE(job_controller_->alternative_job()); | 1422 EXPECT_FALSE(job_controller_->alternative_job()); |
1347 // There is only 1 connect even though multiple streams were requested. | 1423 // There is only 1 connect even though multiple streams were requested. |
1348 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams( | 1424 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams( |
1349 job_controller_->main_job())); | 1425 job_controller_->main_job())); |
1350 | 1426 |
1351 base::RunLoop().RunUntilIdle(); | 1427 base::RunLoop().RunUntilIdle(); |
1352 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1428 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
1353 } | 1429 } |
1354 | 1430 |
1355 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry | 1431 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry |
1356 : public HttpStreamFactoryImplJobControllerTest, | 1432 : public HttpStreamFactoryImplJobControllerTest, |
1357 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; | 1433 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; |
1358 | 1434 |
1359 INSTANTIATE_TEST_CASE_P( | 1435 INSTANTIATE_TEST_CASE_P( |
1360 /* no prefix */, | 1436 /* no prefix */, |
1361 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, | 1437 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
1362 ::testing::Combine(::testing::Bool(), ::testing::Bool())); | 1438 ::testing::Combine(::testing::Bool(), ::testing::Bool())); |
1363 | 1439 |
1364 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, | 1440 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
1365 DisableIPBasedPoolingAndAlternativeServices) { | 1441 DisableIPBasedPoolingAndAlternativeServices) { |
1442 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
1443 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
1444 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
1445 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
1446 | |
1366 const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); | 1447 const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); |
1367 const bool enable_alternative_services = ::testing::get<1>(GetParam()); | 1448 const bool enable_alternative_services = ::testing::get<1>(GetParam()); |
1368 | 1449 |
1369 ProxyConfig proxy_config; | |
1370 proxy_config.set_auto_detect(true); | |
1371 // Use asynchronous proxy resolver. | |
1372 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
1373 new MockAsyncProxyResolverFactory(false); | |
1374 session_deps_.proxy_service.reset( | |
1375 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
1376 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
1377 HttpRequestInfo request_info; | 1450 HttpRequestInfo request_info; |
1378 request_info.method = "GET"; | 1451 request_info.method = "GET"; |
1379 request_info.url = GURL("https://www.google.com"); | 1452 request_info.url = GURL("https://www.google.com"); |
1380 | 1453 |
1381 if (!enable_ip_based_pooling) | 1454 if (!enable_ip_based_pooling) |
1382 DisableIPBasedPooling(); | 1455 DisableIPBasedPooling(); |
1383 if (!enable_alternative_services) | 1456 if (!enable_alternative_services) |
1384 DisableAlternativeServices(); | 1457 DisableAlternativeServices(); |
1385 | 1458 |
1386 Initialize(request_info); | 1459 Initialize(request_info); |
1387 | 1460 |
1388 url::SchemeHostPort server(request_info.url); | 1461 url::SchemeHostPort server(request_info.url); |
1389 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1462 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
1390 SetAlternativeService(request_info, alternative_service); | 1463 SetAlternativeService(request_info, alternative_service); |
1464 if (enable_alternative_services) { | |
1465 // Mock out Quic request | |
1466 test::QuicStreamFactoryPeer::SetStreamRequestFactory( | |
1467 session_->quic_stream_factory(), | |
1468 base::MakeUnique<MockQuicStreamRequestFactory>(OK)); | |
1469 } | |
1391 | 1470 |
1392 request_.reset( | 1471 request_.reset( |
1393 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1472 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
1394 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1473 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
1395 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
1396 EXPECT_TRUE(job_controller_->main_job()); | 1474 EXPECT_TRUE(job_controller_->main_job()); |
1397 if (enable_alternative_services) { | 1475 if (enable_alternative_services) { |
1398 EXPECT_TRUE(job_controller_->alternative_job()); | 1476 EXPECT_TRUE(job_controller_->alternative_job()); |
1399 } else { | 1477 } else { |
1400 EXPECT_FALSE(job_controller_->alternative_job()); | 1478 EXPECT_FALSE(job_controller_->alternative_job()); |
1401 } | 1479 } |
1402 | 1480 |
1403 // |main_job| succeeds and should report status to Request. | 1481 // |main_job| succeeds and should report status to Request. |
1404 HttpStream* http_stream = | 1482 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
1405 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
1406 job_factory_.main_job()->SetStream(http_stream); | |
1407 | |
1408 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | |
1409 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 1483 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
1410 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | 1484 base::RunLoop().RunUntilIdle(); |
1411 } | 1485 } |
1412 | 1486 |
1413 class HttpStreamFactoryImplJobControllerPreconnectTest | 1487 class HttpStreamFactoryImplJobControllerPreconnectTest |
1414 : public HttpStreamFactoryImplJobControllerTest, | 1488 : public HttpStreamFactoryImplJobControllerTest, |
1415 public ::testing::WithParamInterface<bool> { | 1489 public ::testing::WithParamInterface<bool> { |
1416 protected: | 1490 protected: |
1417 void SetUp() override { | 1491 void SetUp() override { |
1418 if (GetParam()) { | 1492 if (GetParam()) { |
1419 scoped_feature_list_.InitFromCommandLine("LimitEarlyPreconnects", | 1493 scoped_feature_list_.InitFromCommandLine("LimitEarlyPreconnects", |
1420 std::string()); | 1494 std::string()); |
1421 } | 1495 } |
1422 } | 1496 } |
1423 | 1497 |
1424 void Initialize() { | 1498 void Initialize() { |
1425 session_deps_.http_server_properties = | 1499 session_deps_.http_server_properties = |
1426 base::MakeUnique<MockHttpServerProperties>(); | 1500 base::MakeUnique<MockHttpServerProperties>(); |
1427 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); | 1501 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); |
1428 factory_ = | 1502 factory_ = |
1429 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); | 1503 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); |
1430 request_info_.method = "GET"; | 1504 request_info_.method = "GET"; |
1431 request_info_.url = GURL("https://www.example.com"); | 1505 request_info_.url = GURL("https://www.example.com"); |
1432 job_controller_ = new HttpStreamFactoryImpl::JobController( | 1506 job_controller_ = new HttpStreamFactoryImpl::JobController( |
1433 factory_, &request_delegate_, session_.get(), &job_factory_, | 1507 factory_, &request_delegate_, session_.get(), &job_factory_, |
1434 request_info_, /* is_preconnect = */ true, | 1508 request_info_, /* is_preconnect = */ true, |
1435 /* enable_ip_based_pooling = */ true, | 1509 /* enable_ip_based_pooling = */ true, |
1436 /* enable_alternative_services = */ true); | 1510 /* enable_alternative_services = */ true, SSLConfig(), SSLConfig()); |
1437 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); | 1511 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); |
1438 } | 1512 } |
1439 | 1513 |
1440 protected: | 1514 protected: |
1441 void Preconnect(int num_streams) { | 1515 void Preconnect(int num_streams) { |
1442 job_controller_->Preconnect(num_streams, request_info_, SSLConfig(), | 1516 job_controller_->Preconnect(num_streams); |
1443 SSLConfig()); | |
1444 // Only one job is started. | 1517 // Only one job is started. |
1445 EXPECT_TRUE(job_controller_->main_job()); | 1518 EXPECT_TRUE(job_controller_->main_job()); |
1446 EXPECT_FALSE(job_controller_->alternative_job()); | 1519 EXPECT_FALSE(job_controller_->alternative_job()); |
1447 } | 1520 } |
1448 | 1521 |
1449 private: | 1522 private: |
1450 base::test::ScopedFeatureList scoped_feature_list_; | 1523 base::test::ScopedFeatureList scoped_feature_list_; |
1451 HttpRequestInfo request_info_; | 1524 HttpRequestInfo request_info_; |
1452 }; | 1525 }; |
1453 | 1526 |
(...skipping 23 matching lines...) Expand all Loading... | |
1477 Preconnect(kNumPreconects); | 1550 Preconnect(kNumPreconects); |
1478 // If experiment is enabled, only 1 stream is requested. | 1551 // If experiment is enabled, only 1 stream is requested. |
1479 EXPECT_EQ( | 1552 EXPECT_EQ( |
1480 (int)actual_num_connects, | 1553 (int)actual_num_connects, |
1481 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); | 1554 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); |
1482 base::RunLoop().RunUntilIdle(); | 1555 base::RunLoop().RunUntilIdle(); |
1483 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1556 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
1484 } | 1557 } |
1485 | 1558 |
1486 } // namespace net | 1559 } // namespace net |
OLD | NEW |