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