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