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