Chromium Code Reviews| 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://www.example.com")); |
| 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); | |
|
Zhongyi Shi
2017/05/10 20:28:16
Woohoo! Nice!
| |
| 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://www.example.com")); | |
| 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 } | |
|
Zhongyi Shi
2017/05/10 20:28:16
These two tests all looks good to me. How about on
xunjieli
2017/05/10 23:24:42
Done. Good idea! The code path isn't tested.
| |
| 354 | |
| 355 class JobControllerReconsiderProxyAfterErrorTest | |
| 356 : public HttpStreamFactoryImplJobControllerTest, | |
| 357 public ::testing::WithParamInterface<::testing::tuple<bool, int>> { | |
| 358 public: | |
| 359 void Initialize(std::unique_ptr<ProxyService> proxy_service, | |
| 360 std::unique_ptr<ProxyDelegate> proxy_delegate) { | |
| 361 session_deps_.proxy_delegate = std::move(proxy_delegate); | |
| 362 session_deps_.proxy_service = std::move(proxy_service); | |
| 363 HttpNetworkSession::Params params = | |
| 364 SpdySessionDependencies::CreateSessionParams(&session_deps_); | |
| 365 session_ = base::MakeUnique<HttpNetworkSession>(params); | |
| 366 factory_ = | |
| 367 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); | |
| 368 } | |
| 369 | |
| 370 std::unique_ptr<HttpStreamRequest> CreateJobController( | |
| 371 const HttpRequestInfo& request_info) { | |
| 372 HttpStreamFactoryImpl::JobController* job_controller = | |
| 373 new HttpStreamFactoryImpl::JobController( | |
| 374 factory_, &request_delegate_, session_.get(), &default_job_factory_, | |
| 375 request_info, is_preconnect_, enable_ip_based_pooling_, | |
| 376 enable_alternative_services_, SSLConfig(), SSLConfig()); | |
| 377 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller); | |
| 378 return base::WrapUnique(job_controller->Start( | |
| 379 &request_delegate_, nullptr, NetLogWithSource(), | |
| 380 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); | |
| 381 } | |
| 382 | |
| 383 private: | |
| 384 // Use real Jobs so that Job::Resume() is not mocked out. When main job is | |
| 385 // resumed it will use mock socket data. | |
| 386 HttpStreamFactoryImpl::JobFactory default_job_factory_; | |
| 387 }; | |
| 388 | |
| 389 INSTANTIATE_TEST_CASE_P( | |
| 390 /* no prefix */, | |
| 391 JobControllerReconsiderProxyAfterErrorTest, | |
| 392 ::testing::Combine(::testing::Bool(), | |
| 393 testing::ValuesIn(proxy_test_mock_errors))); | |
| 394 | |
| 395 TEST_P(JobControllerReconsiderProxyAfterErrorTest, ReconsiderProxyAfterError) { | |
| 396 const bool set_alternative_proxy_server = ::testing::get<0>(GetParam()); | |
| 397 const int mock_error = ::testing::get<1>(GetParam()); | |
| 398 std::unique_ptr<ProxyService> proxy_service = | |
| 399 ProxyService::CreateFixedFromPacResult( | |
| 400 "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT"); | |
| 401 std::unique_ptr<TestProxyDelegate> test_proxy_delegate = | |
| 402 base::MakeUnique<TestProxyDelegate>(); | |
| 403 TestProxyDelegate* test_proxy_delegate_raw = test_proxy_delegate.get(); | |
| 404 | |
| 405 // Before starting the test, verify that there are no proxies marked as bad. | |
| 406 ASSERT_TRUE(proxy_service->proxy_retry_info().empty()) << mock_error; | |
| 407 | |
| 408 StaticSocketDataProvider socket_data_proxy_main_job; | |
| 409 socket_data_proxy_main_job.set_connect_data(MockConnect(ASYNC, mock_error)); | |
| 410 session_deps_.socket_factory->AddSocketDataProvider( | |
| 411 &socket_data_proxy_main_job); | |
| 412 | |
| 413 StaticSocketDataProvider socket_data_proxy_alternate_job; | |
| 414 if (set_alternative_proxy_server) { | |
| 415 // Mock socket used by the QUIC job. | |
| 416 socket_data_proxy_alternate_job.set_connect_data( | |
| 417 MockConnect(ASYNC, mock_error)); | |
| 418 session_deps_.socket_factory->AddSocketDataProvider( | |
| 419 &socket_data_proxy_alternate_job); | |
| 420 test_proxy_delegate->set_alternative_proxy_server( | |
| 421 ProxyServer::FromPacString("QUIC badproxy:99")); | |
| 422 } | |
| 423 | |
| 424 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
| 425 | |
| 426 // When retrying the job using the second proxy (badFallback:98), | |
| 427 // alternative job must not be created. So, socket data for only the | |
| 428 // main job is needed. | |
| 429 StaticSocketDataProvider socket_data_proxy_main_job_2; | |
| 430 socket_data_proxy_main_job_2.set_connect_data(MockConnect(ASYNC, mock_error)); | |
| 431 session_deps_.socket_factory->AddSocketDataProvider( | |
| 432 &socket_data_proxy_main_job_2); | |
| 433 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 434 | |
| 435 // First request would use DIRECT, and succeed. | |
| 436 StaticSocketDataProvider socket_data_direct_first_request; | |
| 437 socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK)); | |
| 438 session_deps_.socket_factory->AddSocketDataProvider( | |
| 439 &socket_data_direct_first_request); | |
| 440 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 441 | |
| 442 // Second request would use DIRECT, and succeed. | |
| 443 StaticSocketDataProvider socket_data_direct_second_request; | |
| 444 socket_data_direct_second_request.set_connect_data(MockConnect(ASYNC, OK)); | |
| 445 session_deps_.socket_factory->AddSocketDataProvider( | |
| 446 &socket_data_direct_second_request); | |
| 447 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 448 | |
| 449 // Now request a stream. It should succeed using the DIRECT. | |
| 450 HttpRequestInfo request_info; | |
| 451 request_info.method = "GET"; | |
| 452 request_info.url = GURL("http://www.example.com"); | |
| 453 | |
| 454 Initialize(std::move(proxy_service), std::move(test_proxy_delegate)); | |
| 455 EXPECT_EQ(set_alternative_proxy_server, | |
| 456 test_proxy_delegate_raw->alternative_proxy_server().is_quic()); | |
| 457 | |
| 458 // Start two requests. The first request should consume data from | |
| 459 // |socket_data_proxy_main_job|, | |
| 460 // |socket_data_proxy_alternate_job| and | |
| 461 // |socket_data_direct_first_request|. The second request should consume | |
| 462 // data from |socket_data_direct_second_request|. | |
| 463 | |
| 464 for (size_t i = 0; i < 2; ++i) { | |
| 465 ProxyInfo used_proxy_info; | |
| 466 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) | |
| 467 .Times(1) | |
| 468 .WillOnce(DoAll(::testing::SaveArg<1>(&used_proxy_info), | |
| 469 Invoke(DeleteHttpStreamPointer))); | |
| 470 | |
| 471 std::unique_ptr<HttpStreamRequest> request = | |
| 472 CreateJobController(request_info); | |
| 473 | |
| 474 base::RunLoop().RunUntilIdle(); | |
| 475 // The proxy that failed should now be known to the proxy_service as | |
| 476 // bad. | |
| 477 const ProxyRetryInfoMap retry_info = | |
| 478 session_->proxy_service()->proxy_retry_info(); | |
| 479 EXPECT_EQ(2u, retry_info.size()) << mock_error; | |
| 480 EXPECT_NE(retry_info.end(), retry_info.find("https://badproxy:99")); | |
| 481 EXPECT_NE(retry_info.end(), retry_info.find("https://badfallbackproxy:98")); | |
| 482 | |
| 483 // Verify that request was fetched without proxy. | |
| 484 EXPECT_TRUE(used_proxy_info.is_direct()); | |
| 485 | |
| 486 // If alternative proxy server was specified, it should have been marked | |
| 487 // as invalid so that it is not used for subsequent requests. | |
| 488 EXPECT_FALSE( | |
| 489 test_proxy_delegate_raw->alternative_proxy_server().is_valid()); | |
| 490 | |
| 491 if (set_alternative_proxy_server) { | |
| 492 // GetAlternativeProxy should be called only once for the first | |
| 493 // request. | |
| 494 EXPECT_EQ(1, | |
| 495 test_proxy_delegate_raw->get_alternative_proxy_invocations()); | |
| 496 } else { | |
| 497 // Alternative proxy server job is never started. So, ProxyDelegate is | |
| 498 // queried once per request. | |
| 499 EXPECT_EQ(2, | |
| 500 test_proxy_delegate_raw->get_alternative_proxy_invocations()); | |
| 501 } | |
| 502 } | |
| 503 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | |
| 504 } | |
| 505 | |
| 506 TEST_F(HttpStreamFactoryImplJobControllerTest, | |
| 507 OnStreamFailedWithNoAlternativeJob) { | |
| 508 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
| 509 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); | |
| 510 | |
| 511 HttpRequestInfo request_info; | |
| 512 request_info.method = "GET"; | |
| 243 request_info.url = GURL("http://www.google.com"); | 513 request_info.url = GURL("http://www.google.com"); |
| 244 | 514 |
| 245 Initialize(request_info); | 515 Initialize(request_info); |
| 246 | 516 |
| 247 request_.reset( | 517 request_.reset( |
| 248 job_controller_->Start(request_info, &request_delegate_, nullptr, | 518 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 249 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 519 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 250 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 251 | 520 |
| 252 EXPECT_TRUE(job_controller_->main_job()); | 521 EXPECT_TRUE(job_controller_->main_job()); |
| 522 EXPECT_FALSE(job_controller_->alternative_job()); | |
| 253 | 523 |
| 254 // There's no other alternative job. Thus when stream failed, it should | 524 // There's no other alternative job. Thus when stream failed, it should |
| 255 // notify Request of the stream failure. | 525 // notify Request of the stream failure. |
| 256 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1); | 526 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1); |
| 257 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, | 527 base::RunLoop().RunUntilIdle(); |
| 258 SSLConfig()); | |
| 259 } | 528 } |
| 260 | 529 |
| 261 TEST_F(HttpStreamFactoryImplJobControllerTest, | 530 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 262 OnStreamReadyWithNoAlternativeJob) { | 531 OnStreamReadyWithNoAlternativeJob) { |
| 263 ProxyConfig proxy_config; | 532 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 264 proxy_config.set_auto_detect(true); | 533 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
| 265 // Use asynchronous proxy resolver. | 534 |
| 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; | 535 HttpRequestInfo request_info; |
| 272 request_info.method = "GET"; | 536 request_info.method = "GET"; |
| 273 request_info.url = GURL("http://www.google.com"); | 537 request_info.url = GURL("http://www.google.com"); |
| 274 | 538 |
| 275 Initialize(request_info); | 539 Initialize(request_info); |
| 276 | 540 |
| 277 request_.reset( | 541 request_.reset( |
| 278 job_controller_->Start(request_info, &request_delegate_, nullptr, | 542 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 279 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 543 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 280 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 281 | 544 |
| 282 // There's no other alternative job. Thus when a stream is ready, it should | 545 // There's no other alternative job. Thus when a stream is ready, it should |
| 283 // notify Request. | 546 // notify Request. |
| 284 HttpStream* http_stream = | 547 EXPECT_TRUE(job_controller_->main_job()); |
| 285 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
| 286 job_factory_.main_job()->SetStream(http_stream); | |
| 287 | 548 |
| 288 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | 549 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| 289 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 550 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 290 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | 551 base::RunLoop().RunUntilIdle(); |
| 291 } | 552 } |
| 292 | 553 |
| 293 // Test we cancel Jobs correctly when the Request is explicitly canceled | 554 // Test we cancel Jobs correctly when the Request is explicitly canceled |
| 294 // before any Job is bound to Request. | 555 // before any Job is bound to Request. |
| 295 TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { | 556 TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { |
| 296 ProxyConfig proxy_config; | 557 // Use COLD_START to make the alt job pending. |
| 297 proxy_config.set_auto_detect(true); | 558 crypto_client_stream_factory_.set_handshake_mode( |
| 298 // Use asynchronous proxy resolver. | 559 MockCryptoClientStream::COLD_START); |
| 299 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 560 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 300 new MockAsyncProxyResolverFactory(false); | 561 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 | 562 |
| 563 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
| 564 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); | |
| 305 HttpRequestInfo request_info; | 565 HttpRequestInfo request_info; |
| 306 request_info.method = "GET"; | 566 request_info.method = "GET"; |
| 307 request_info.url = GURL("https://www.google.com"); | 567 request_info.url = GURL("https://www.google.com"); |
| 308 | 568 |
| 309 Initialize(request_info); | 569 Initialize(request_info); |
| 310 url::SchemeHostPort server(request_info.url); | 570 url::SchemeHostPort server(request_info.url); |
| 311 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 571 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 312 SetAlternativeService(request_info, alternative_service); | 572 SetAlternativeService(request_info, alternative_service); |
| 313 | 573 |
| 314 request_.reset( | 574 request_.reset( |
| 315 job_controller_->Start(request_info, &request_delegate_, nullptr, | 575 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 316 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 576 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 317 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 318 EXPECT_TRUE(job_controller_->main_job()); | 577 EXPECT_TRUE(job_controller_->main_job()); |
| 319 EXPECT_TRUE(job_controller_->alternative_job()); | 578 EXPECT_TRUE(job_controller_->alternative_job()); |
| 320 | 579 |
| 321 // Reset the Request will cancel all the Jobs since there's no Job determined | 580 // 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 | 581 // to serve Request yet and JobController will notify the factory to delete |
| 323 // itself upon completion. | 582 // itself upon completion. |
| 324 request_.reset(); | 583 request_.reset(); |
| 325 VerifyBrokenAlternateProtocolMapping(request_info, false); | 584 VerifyBrokenAlternateProtocolMapping(request_info, false); |
| 326 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 585 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 327 } | 586 } |
| 328 | 587 |
| 329 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { | 588 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { |
| 330 ProxyConfig proxy_config; | 589 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 331 proxy_config.set_auto_detect(true); | 590 quic_data_->AddConnect(ASYNC, ERR_FAILED); |
| 332 // Use asynchronous proxy resolver. | 591 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 333 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 592 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 | 593 |
| 339 HttpRequestInfo request_info; | 594 HttpRequestInfo request_info; |
| 340 request_info.method = "GET"; | 595 request_info.method = "GET"; |
| 341 request_info.url = GURL("https://www.google.com"); | 596 request_info.url = GURL("https://www.google.com"); |
| 342 | 597 |
| 343 Initialize(request_info); | 598 Initialize(request_info); |
| 344 url::SchemeHostPort server(request_info.url); | 599 url::SchemeHostPort server(request_info.url); |
| 345 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 600 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 346 SetAlternativeService(request_info, alternative_service); | 601 SetAlternativeService(request_info, alternative_service); |
| 347 | 602 |
| 348 request_.reset( | 603 request_.reset( |
| 349 job_controller_->Start(request_info, &request_delegate_, nullptr, | 604 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 350 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 605 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 351 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 352 EXPECT_TRUE(job_controller_->main_job()); | 606 EXPECT_TRUE(job_controller_->main_job()); |
| 353 EXPECT_TRUE(job_controller_->alternative_job()); | 607 EXPECT_TRUE(job_controller_->alternative_job()); |
| 354 | 608 |
| 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 | 609 // The failure of second Job should be reported to Request as there's no more |
| 365 // pending Job to serve the Request. | 610 // pending Job to serve the Request. |
| 366 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); | 611 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); |
| 367 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, | 612 base::RunLoop().RunUntilIdle(); |
| 368 SSLConfig()); | |
| 369 VerifyBrokenAlternateProtocolMapping(request_info, false); | 613 VerifyBrokenAlternateProtocolMapping(request_info, false); |
| 614 request_.reset(); | |
| 615 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | |
| 370 } | 616 } |
| 371 | 617 |
| 372 TEST_F(HttpStreamFactoryImplJobControllerTest, | 618 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 373 AltJobFailsAfterMainJobSucceeds) { | 619 AltJobFailsAfterMainJobSucceeds) { |
| 374 ProxyConfig proxy_config; | 620 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 375 proxy_config.set_auto_detect(true); | 621 quic_data_->AddRead(ASYNC, ERR_FAILED); |
| 376 // Use asynchronous proxy resolver. | 622 crypto_client_stream_factory_.set_handshake_mode( |
| 377 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 623 MockCryptoClientStream::COLD_START); |
| 378 new MockAsyncProxyResolverFactory(false); | 624 |
| 379 session_deps_.proxy_service.reset( | 625 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 380 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | 626 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
| 381 base::WrapUnique(proxy_resolver_factory), nullptr)); | 627 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(SYNCHRONOUS, OK); |
| 628 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 382 | 629 |
| 383 HttpRequestInfo request_info; | 630 HttpRequestInfo request_info; |
| 384 request_info.method = "GET"; | 631 request_info.method = "GET"; |
| 385 request_info.url = GURL("https://www.google.com"); | 632 request_info.url = GURL("https://www.google.com"); |
| 386 | 633 |
| 387 Initialize(request_info); | 634 Initialize(request_info); |
| 388 url::SchemeHostPort server(request_info.url); | 635 url::SchemeHostPort server(request_info.url); |
| 389 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 636 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 390 SetAlternativeService(request_info, alternative_service); | 637 SetAlternativeService(request_info, alternative_service); |
| 391 | 638 |
| 392 request_.reset( | 639 request_.reset( |
| 393 job_controller_->Start(request_info, &request_delegate_, nullptr, | 640 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 394 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 641 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 395 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 396 EXPECT_TRUE(job_controller_->main_job()); | 642 EXPECT_TRUE(job_controller_->main_job()); |
| 397 EXPECT_TRUE(job_controller_->alternative_job()); | 643 EXPECT_TRUE(job_controller_->alternative_job()); |
| 398 | 644 |
| 399 // Main job succeeds, starts serving Request and it should report status | 645 // 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 | 646 // to Request. The alternative job will mark the main job complete and gets |
| 401 // orphaned. | 647 // orphaned. |
| 402 HttpStream* http_stream = | 648 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)); | 649 .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 | 650 // JobController shouldn't report the status of second job as request |
| 411 // is already successfully served. | 651 // is already successfully served. |
| 412 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 652 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 413 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, | 653 |
| 414 SSLConfig()); | 654 base::RunLoop().RunUntilIdle(); |
| 415 | 655 |
| 416 VerifyBrokenAlternateProtocolMapping(request_info, true); | 656 VerifyBrokenAlternateProtocolMapping(request_info, true); |
| 417 // Reset the request as it's been successfully served. | 657 // Reset the request as it's been successfully served. |
| 418 request_.reset(); | 658 request_.reset(); |
| 419 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 659 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 420 } | 660 } |
| 421 | 661 |
| 422 // Tests that if alt job succeeds and main job is blocked, main job should be | 662 // 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. | 663 // cancelled immediately. |request_| completion will clean up the JobController. |
| 424 // Regression test for crbug.com/678768. | 664 // Regression test for crbug.com/678768. |
| 425 TEST_F(HttpStreamFactoryImplJobControllerTest, | 665 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 426 AltJobSucceedsMainJobBlockedControllerDestroyed) { | 666 AltJobSucceedsMainJobBlockedControllerDestroyed) { |
| 427 ProxyConfig proxy_config; | 667 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 428 proxy_config.set_auto_detect(true); | 668 quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr)); |
| 429 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 669 quic_data_->AddRead(ASYNC, OK); |
| 430 new MockAsyncProxyResolverFactory(false); | 670 |
| 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; | 671 HttpRequestInfo request_info; |
| 435 request_info.method = "GET"; | 672 request_info.method = "GET"; |
| 436 request_info.url = GURL("https://www.google.com"); | 673 request_info.url = GURL("https://www.google.com"); |
| 437 | 674 |
| 438 Initialize(request_info); | 675 Initialize(request_info); |
| 439 | 676 |
| 440 url::SchemeHostPort server(request_info.url); | 677 url::SchemeHostPort server(request_info.url); |
| 441 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 678 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 442 SetAlternativeService(request_info, alternative_service); | 679 SetAlternativeService(request_info, alternative_service); |
| 443 request_.reset( | 680 request_.reset( |
| 444 job_controller_->Start(request_info, &request_delegate_, nullptr, | 681 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 445 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 682 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 446 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 447 EXPECT_TRUE(job_controller_->main_job()); | 683 EXPECT_TRUE(job_controller_->main_job()); |
| 448 EXPECT_TRUE(job_controller_->alternative_job()); | 684 EXPECT_TRUE(job_controller_->alternative_job()); |
| 449 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 685 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| 450 | 686 |
| 451 // |alternative_job| succeeds and should report status to Request. | 687 // |alternative_job| succeeds and should report status to |request_delegate_|. |
| 452 HttpStream* http_stream = | 688 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)); | 689 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 457 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); | 690 |
| 691 base::RunLoop().RunUntilIdle(); | |
| 458 | 692 |
| 459 EXPECT_FALSE(job_controller_->main_job()); | 693 EXPECT_FALSE(job_controller_->main_job()); |
| 460 EXPECT_TRUE(job_controller_->alternative_job()); | 694 EXPECT_TRUE(job_controller_->alternative_job()); |
| 461 | 695 |
| 462 // Invoke OnRequestComplete() which should delete |job_controller_| from | 696 // Invoke OnRequestComplete() which should delete |job_controller_| from |
| 463 // |factory_|. | 697 // |factory_|. |
| 464 request_.reset(); | 698 request_.reset(); |
| 465 VerifyBrokenAlternateProtocolMapping(request_info, false); | 699 VerifyBrokenAlternateProtocolMapping(request_info, false); |
| 466 // This fails without the fix for crbug.com/678768. | 700 // This fails without the fix for crbug.com/678768. |
| 467 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 701 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 468 } | 702 } |
| 469 | 703 |
| 470 // Tests that if an orphaned job completes after |request_| is gone, | 704 // Tests that if an orphaned job completes after |request_| is gone, |
| 471 // JobController will be cleaned up. | 705 // JobController will be cleaned up. |
| 472 TEST_F(HttpStreamFactoryImplJobControllerTest, | 706 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 473 OrphanedJobCompletesControllerDestroyed) { | 707 OrphanedJobCompletesControllerDestroyed) { |
| 474 ProxyConfig proxy_config; | 708 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 475 proxy_config.set_auto_detect(true); | 709 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
| 476 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 710 // Use cold start and complete alt job manually. |
| 477 new MockAsyncProxyResolverFactory(false); | 711 crypto_client_stream_factory_.set_handshake_mode( |
| 478 session_deps_.proxy_service.reset( | 712 MockCryptoClientStream::COLD_START); |
| 479 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | 713 |
| 480 base::WrapUnique(proxy_resolver_factory), nullptr)); | 714 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 715 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
| 716 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
| 717 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 718 | |
| 481 HttpRequestInfo request_info; | 719 HttpRequestInfo request_info; |
| 482 request_info.method = "GET"; | 720 request_info.method = "GET"; |
| 483 request_info.url = GURL("https://www.google.com"); | 721 request_info.url = GURL("https://www.google.com"); |
| 484 | 722 |
| 485 Initialize(request_info); | 723 Initialize(request_info); |
| 486 | 724 |
| 487 url::SchemeHostPort server(request_info.url); | 725 url::SchemeHostPort server(request_info.url); |
| 488 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 726 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 489 SetAlternativeService(request_info, alternative_service); | 727 SetAlternativeService(request_info, alternative_service); |
| 490 // Hack to use different URL for the main job to help differentiate the proxy | 728 |
| 491 // requests. | |
| 492 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); | |
| 493 request_.reset( | 729 request_.reset( |
| 494 job_controller_->Start(request_info, &request_delegate_, nullptr, | 730 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 495 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 731 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 496 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 497 EXPECT_TRUE(job_controller_->main_job()); | 732 EXPECT_TRUE(job_controller_->main_job()); |
| 498 EXPECT_TRUE(job_controller_->alternative_job()); | 733 EXPECT_TRUE(job_controller_->alternative_job()); |
| 499 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 734 // main job should not be blocked because alt job returned ERR_IO_PENDING. |
| 735 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); | |
| 736 | |
| 737 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) | |
| 738 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
| 500 | 739 |
| 501 // Complete main job now. | 740 // Complete main job now. |
| 502 MockAsyncProxyResolver resolver; | 741 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 | 742 |
| 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 | 743 // Invoke OnRequestComplete() which should not delete |job_controller_| from |
| 520 // |factory_| because alt job is yet to finish. | 744 // |factory_| because alt job is yet to finish. |
| 521 request_.reset(); | 745 request_.reset(); |
| 522 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 746 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 523 EXPECT_FALSE(job_controller_->main_job()); | 747 EXPECT_FALSE(job_controller_->main_job()); |
| 524 EXPECT_TRUE(job_controller_->alternative_job()); | 748 EXPECT_TRUE(job_controller_->alternative_job()); |
| 525 | 749 |
| 526 // Make |alternative_job| succeed. | 750 // Make |alternative_job| succeed. |
| 527 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); | 751 HttpStream* http_stream = |
| 528 resolver.pending_jobs()[0]->CompleteNow(net::OK); | |
| 529 HttpStream* http_stream2 = | |
| 530 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | 752 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| 531 job_factory_.alternative_job()->SetStream(http_stream2); | 753 job_factory_.alternative_job()->SetStream(http_stream); |
| 532 // This should not call request_delegate_::OnStreamReady. | 754 // This should not call request_delegate_::OnStreamReady. |
| 533 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); | 755 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
| 534 // Make sure that controller does not leak. | 756 // Make sure that controller does not leak. |
| 535 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 757 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 536 } | 758 } |
| 537 | 759 |
| 538 TEST_F(HttpStreamFactoryImplJobControllerTest, | 760 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 539 AltJobSucceedsAfterMainJobFailed) { | 761 AltJobSucceedsAfterMainJobFailed) { |
| 540 ProxyConfig proxy_config; | 762 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 541 proxy_config.set_auto_detect(true); | 763 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
| 542 // Use asynchronous proxy resolver. | 764 // Use cold start and complete alt job manually. |
| 543 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 765 crypto_client_stream_factory_.set_handshake_mode( |
| 544 new MockAsyncProxyResolverFactory(false); | 766 MockCryptoClientStream::COLD_START); |
| 545 session_deps_.proxy_service.reset( | 767 |
| 546 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | 768 // One failed TCP connect. |
| 547 base::WrapUnique(proxy_resolver_factory), nullptr)); | 769 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 770 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED)); | |
| 771 | |
| 548 HttpRequestInfo request_info; | 772 HttpRequestInfo request_info; |
| 549 request_info.method = "GET"; | 773 request_info.method = "GET"; |
| 550 request_info.url = GURL("https://www.google.com"); | 774 request_info.url = GURL("https://www.google.com"); |
| 551 | 775 |
| 552 Initialize(request_info); | 776 Initialize(request_info); |
| 553 | 777 |
| 554 url::SchemeHostPort server(request_info.url); | 778 url::SchemeHostPort server(request_info.url); |
| 555 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 779 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 556 SetAlternativeService(request_info, alternative_service); | 780 SetAlternativeService(request_info, alternative_service); |
| 557 | 781 |
| 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. | 782 // |main_job| fails but should not report status to Request. |
| 566 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 783 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 567 | 784 |
| 568 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, | 785 request_.reset( |
| 569 SSLConfig()); | 786 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 787 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); | |
| 788 EXPECT_TRUE(job_controller_->main_job()); | |
| 789 EXPECT_TRUE(job_controller_->alternative_job()); | |
| 570 | 790 |
| 571 // |alternative_job| succeeds and should report status to Request. | 791 base::RunLoop().RunUntilIdle(); |
| 792 | |
| 793 // Make |alternative_job| succeed. | |
| 572 HttpStream* http_stream = | 794 HttpStream* http_stream = |
| 573 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | 795 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| 574 job_factory_.alternative_job()->SetStream(http_stream); | |
| 575 | 796 |
| 576 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | 797 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| 577 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 798 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 799 | |
| 800 job_factory_.alternative_job()->SetStream(http_stream); | |
| 578 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); | 801 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
| 802 | |
| 803 // |alternative_job| succeeds and should report status to Request. | |
| 579 VerifyBrokenAlternateProtocolMapping(request_info, false); | 804 VerifyBrokenAlternateProtocolMapping(request_info, false); |
| 580 } | 805 } |
| 581 | 806 |
| 582 TEST_F(HttpStreamFactoryImplJobControllerTest, | 807 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 583 MainJobSucceedsAfterAltJobFailed) { | 808 MainJobSucceedsAfterAltJobFailed) { |
| 809 quic_data_ = base::MakeUnique<test::MockQuicData>(); | |
| 810 quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED); | |
| 811 | |
| 812 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
| 813 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
| 814 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
| 815 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 816 | |
| 584 base::HistogramTester histogram_tester; | 817 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; | 818 HttpRequestInfo request_info; |
| 594 request_info.method = "GET"; | 819 request_info.method = "GET"; |
| 595 request_info.url = GURL("https://www.google.com"); | 820 request_info.url = GURL("https://www.google.com"); |
| 596 | 821 |
| 597 Initialize(request_info); | 822 Initialize(request_info); |
| 598 | 823 |
| 599 url::SchemeHostPort server(request_info.url); | 824 url::SchemeHostPort server(request_info.url); |
| 600 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 825 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 601 SetAlternativeService(request_info, alternative_service); | 826 SetAlternativeService(request_info, alternative_service); |
| 602 | 827 |
| 603 request_.reset( | 828 request_.reset( |
| 604 job_controller_->Start(request_info, &request_delegate_, nullptr, | 829 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 605 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 830 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 606 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 607 EXPECT_TRUE(job_controller_->main_job()); | 831 EXPECT_TRUE(job_controller_->main_job()); |
| 608 EXPECT_TRUE(job_controller_->alternative_job()); | 832 EXPECT_TRUE(job_controller_->alternative_job()); |
| 609 | 833 |
| 610 // |alternative_job| fails but should not report status to Request. | 834 // |alternative_job| fails but should not report status to Request. |
| 611 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 835 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 836 // |main_job| succeeds and should report status to Request. | |
| 837 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) | |
| 838 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
| 612 | 839 |
| 613 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, | 840 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 | 841 |
| 625 // Verify that the alternate protocol is marked as broken. | 842 // Verify that the alternate protocol is marked as broken. |
| 626 VerifyBrokenAlternateProtocolMapping(request_info, true); | 843 VerifyBrokenAlternateProtocolMapping(request_info, true); |
| 627 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED, | 844 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED, |
| 628 1); | 845 1); |
| 629 } | 846 } |
| 630 | 847 |
| 631 // Verifies that if the alternative job fails due to a connection change event, | 848 // Verifies that if the alternative job fails due to a connection change event, |
| 632 // then the alternative service is not marked as broken. | 849 // then the alternative service is not marked as broken. |
| 633 TEST_F(HttpStreamFactoryImplJobControllerTest, | 850 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 634 MainJobSucceedsAfterConnectionChanged) { | 851 MainJobSucceedsAfterConnectionChanged) { |
| 852 quic_data_ = base::MakeUnique<test::MockQuicData>(); | |
| 853 quic_data_->AddConnect(SYNCHRONOUS, ERR_NETWORK_CHANGED); | |
| 854 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
| 855 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
| 856 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
| 857 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 858 | |
| 635 base::HistogramTester histogram_tester; | 859 base::HistogramTester histogram_tester; |
| 636 ProxyConfig proxy_config; | |
| 637 proxy_config.set_auto_detect(true); | |
| 638 // Use asynchronous proxy resolver. | |
| 639 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
| 640 new MockAsyncProxyResolverFactory(false); | |
| 641 session_deps_.proxy_service.reset( | |
| 642 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
| 643 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
| 644 session_deps_.quic_do_not_mark_as_broken_on_network_change = true; | 860 session_deps_.quic_do_not_mark_as_broken_on_network_change = true; |
| 645 | 861 |
| 646 HttpRequestInfo request_info; | 862 HttpRequestInfo request_info; |
| 647 request_info.method = "GET"; | 863 request_info.method = "GET"; |
| 648 request_info.url = GURL("https://www.google.com"); | 864 request_info.url = GURL("https://www.google.com"); |
| 649 Initialize(request_info); | 865 Initialize(request_info); |
| 650 | 866 |
| 651 url::SchemeHostPort server(request_info.url); | 867 url::SchemeHostPort server(request_info.url); |
| 652 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 868 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 653 SetAlternativeService(request_info, alternative_service); | 869 SetAlternativeService(request_info, alternative_service); |
| 654 | 870 |
| 655 request_.reset( | 871 request_.reset( |
| 656 job_controller_->Start(request_info, &request_delegate_, nullptr, | 872 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 657 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 873 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 658 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 659 EXPECT_TRUE(job_controller_->main_job()); | 874 EXPECT_TRUE(job_controller_->main_job()); |
| 660 EXPECT_TRUE(job_controller_->alternative_job()); | 875 EXPECT_TRUE(job_controller_->alternative_job()); |
| 661 | 876 |
| 662 // |alternative_job| fails but should not report status to Request. | 877 // |alternative_job| fails but should not report status to Request. |
| 663 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 878 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 664 | |
| 665 job_controller_->OnStreamFailed(job_factory_.alternative_job(), | |
| 666 ERR_NETWORK_CHANGED, SSLConfig()); | |
| 667 | |
| 668 // |main_job| succeeds and should report status to Request. | 879 // |main_job| succeeds and should report status to Request. |
| 669 HttpStream* http_stream = | 880 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| 670 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
| 671 job_factory_.main_job()->SetStream(http_stream); | |
| 672 | |
| 673 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | |
| 674 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 881 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 675 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | 882 base::RunLoop().RunUntilIdle(); |
| 676 | 883 |
| 677 // Verify that the alternate protocol is not marked as broken. | 884 // Verify that the alternate protocol is not marked as broken. |
| 678 VerifyBrokenAlternateProtocolMapping(request_info, false); | 885 VerifyBrokenAlternateProtocolMapping(request_info, false); |
| 679 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", | 886 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", |
| 680 -ERR_NETWORK_CHANGED, 1); | 887 -ERR_NETWORK_CHANGED, 1); |
| 681 } | 888 } |
| 682 | 889 |
| 683 // Regression test for crbug/621069. | 890 // Regression test for crbug/621069. |
| 684 // Get load state after main job fails and before alternative job succeeds. | 891 // Get load state after main job fails and before alternative job succeeds. |
| 685 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { | 892 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { |
| 686 ProxyConfig proxy_config; | 893 // Use COLD_START to complete alt job manually. |
| 687 proxy_config.set_auto_detect(true); | 894 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 688 // Use asynchronous proxy resolver. | 895 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
| 689 MockAsyncProxyResolverFactory* proxy_resolver_factory = | 896 crypto_client_stream_factory_.set_handshake_mode( |
| 690 new MockAsyncProxyResolverFactory(false); | 897 MockCryptoClientStream::COLD_START); |
| 691 session_deps_.proxy_service.reset(new ProxyService( | 898 |
| 692 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), | 899 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 693 base::WrapUnique(proxy_resolver_factory), nullptr)); | 900 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED)); |
| 694 | 901 |
| 695 HttpRequestInfo request_info; | 902 HttpRequestInfo request_info; |
| 696 request_info.method = "GET"; | 903 request_info.method = "GET"; |
| 697 request_info.url = GURL("https://www.google.com"); | 904 request_info.url = GURL("https://www.google.com"); |
| 698 | 905 |
| 699 Initialize(request_info); | 906 Initialize(request_info); |
| 700 url::SchemeHostPort server(request_info.url); | 907 url::SchemeHostPort server(request_info.url); |
| 701 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 908 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 702 SetAlternativeService(request_info, alternative_service); | 909 SetAlternativeService(request_info, alternative_service); |
| 703 | 910 |
| 704 request_.reset( | 911 request_.reset( |
| 705 job_controller_->Start(request_info, &request_delegate_, nullptr, | 912 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 706 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 913 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 707 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 708 EXPECT_TRUE(job_controller_->main_job()); | 914 EXPECT_TRUE(job_controller_->main_job()); |
| 709 EXPECT_TRUE(job_controller_->alternative_job()); | 915 EXPECT_TRUE(job_controller_->alternative_job()); |
| 710 | 916 |
| 711 // |main_job| fails but should not report status to Request. | 917 // |main_job| fails but should not report status to Request. |
| 712 // The alternative job will mark the main job complete. | 918 // The alternative job will mark the main job complete. |
| 713 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 919 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 714 | 920 |
| 715 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, | 921 base::RunLoop().RunUntilIdle(); |
| 716 SSLConfig()); | |
| 717 | 922 |
| 718 // Controller should use alternative job to get load state. | 923 // Controller should use alternative job to get load state. |
| 719 job_controller_->GetLoadState(); | 924 job_controller_->GetLoadState(); |
| 720 | 925 |
| 721 // |alternative_job| succeeds and should report status to Request. | 926 // |alternative_job| succeeds and should report status to Request. |
| 722 HttpStream* http_stream = | 927 HttpStream* http_stream = |
| 723 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | 928 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); |
| 724 job_factory_.alternative_job()->SetStream(http_stream); | 929 job_factory_.alternative_job()->SetStream(http_stream); |
| 725 | 930 |
| 726 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | 931 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) |
| 727 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 932 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 728 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); | 933 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); |
| 729 } | 934 } |
| 730 | 935 |
| 731 TEST_F(HttpStreamFactoryImplJobControllerTest, DoNotResumeMainJobBeforeWait) { | 936 TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobWhenAltJobStalls) { |
| 732 // Use failing ProxyResolverFactory which is unable to create ProxyResolver | 937 // Use COLD_START to stall alt job. |
| 733 // to stall the alternative job and report to controller to maybe resume the | 938 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 734 // main job. | 939 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); |
| 735 ProxyConfig proxy_config; | 940 crypto_client_stream_factory_.set_handshake_mode( |
| 736 proxy_config.set_auto_detect(true); | 941 MockCryptoClientStream::COLD_START); |
| 737 proxy_config.set_pac_mandatory(true); | 942 |
| 738 session_deps_.proxy_service.reset(new ProxyService( | 943 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 739 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | 944 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
| 740 base::WrapUnique(new FailingProxyResolverFactory), nullptr)); | 945 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); |
| 946 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 741 | 947 |
| 742 HttpRequestInfo request_info; | 948 HttpRequestInfo request_info; |
| 743 request_info.method = "GET"; | 949 request_info.method = "GET"; |
| 744 request_info.url = GURL("https://www.google.com"); | 950 request_info.url = GURL("https://www.google.com"); |
| 745 | 951 |
| 746 Initialize(request_info); | 952 Initialize(request_info); |
| 747 url::SchemeHostPort server(request_info.url); | 953 url::SchemeHostPort server(request_info.url); |
| 748 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 954 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 749 SetAlternativeService(request_info, alternative_service); | 955 SetAlternativeService(request_info, alternative_service); |
| 750 | 956 |
| 751 request_.reset( | 957 request_.reset( |
| 752 job_controller_->Start(request_info, &request_delegate_, nullptr, | 958 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 753 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 959 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 754 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 755 EXPECT_TRUE(job_controller_->main_job()); | 960 EXPECT_TRUE(job_controller_->main_job()); |
| 756 EXPECT_TRUE(job_controller_->alternative_job()); | 961 EXPECT_TRUE(job_controller_->alternative_job()); |
| 757 | 962 |
| 758 // Wait until OnStreamFailedCallback is executed on the alternative job. | 963 // Alt job is stalled and main job should complete successfully. |
| 759 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); | 964 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| 965 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
| 966 | |
| 760 base::RunLoop().RunUntilIdle(); | 967 base::RunLoop().RunUntilIdle(); |
| 761 } | 968 } |
| 762 | 969 |
| 763 TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { | 970 TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { |
| 764 HttpRequestInfo request_info; | 971 HttpRequestInfo request_info; |
| 765 request_info.method = "GET"; | 972 request_info.method = "GET"; |
| 766 request_info.url = GURL("https://www.google.com"); | 973 request_info.url = GURL("https://www.google.com"); |
| 767 | 974 |
| 768 // Using a restricted port 101 for QUIC should fail and the alternative job | 975 // Using a restricted port 101 for QUIC should fail and the alternative job |
| 769 // should post OnStreamFailedCall on the controller to resume the main job. | 976 // should post OnStreamFailedCall on the controller to resume the main job. |
| 770 Initialize(request_info); | 977 Initialize(request_info); |
| 771 | 978 |
| 772 url::SchemeHostPort server(request_info.url); | 979 url::SchemeHostPort server(request_info.url); |
| 773 AlternativeService alternative_service(kProtoQUIC, server.host(), 101); | 980 AlternativeService alternative_service(kProtoQUIC, server.host(), 101); |
| 774 SetAlternativeService(request_info, alternative_service); | 981 SetAlternativeService(request_info, alternative_service); |
| 775 | 982 |
| 776 request_.reset( | 983 request_.reset( |
| 777 job_controller_->Start(request_info, &request_delegate_, nullptr, | 984 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 778 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 985 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 779 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 780 | 986 |
| 781 EXPECT_TRUE(job_factory_.main_job()->is_waiting()); | 987 EXPECT_TRUE(job_factory_.main_job()->is_waiting()); |
| 782 | 988 |
| 783 // Wait until OnStreamFailedCallback is executed on the alternative job. | 989 // Wait until OnStreamFailedCallback is executed on the alternative job. |
| 784 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 990 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| 785 base::RunLoop().RunUntilIdle(); | 991 base::RunLoop().RunUntilIdle(); |
| 786 } | 992 } |
| 787 | 993 |
| 788 TEST_F(HttpStreamFactoryImplJobControllerTest, | |
| 789 NoAvailableSpdySessionToResumeMainJob) { | |
| 790 // Test the alternative job is not resumed when the alternative job is | |
| 791 // IO_PENDING for proxy resolution. Once all the proxy resolution succeeds, | |
| 792 // the latter part of this test tests controller resumes the main job | |
| 793 // when there's no SPDY session for the alternative job. | |
| 794 ProxyConfig proxy_config; | |
| 795 proxy_config.set_auto_detect(true); | |
| 796 // Use asynchronous proxy resolver. | |
| 797 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
| 798 new MockAsyncProxyResolverFactory(false); | |
| 799 session_deps_.proxy_service.reset( | |
| 800 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
| 801 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
| 802 | |
| 803 HangingResolver* host_resolver = new HangingResolver(); | |
| 804 session_deps_.host_resolver.reset(host_resolver); | |
| 805 session_deps_.host_resolver->set_synchronous_mode(false); | |
| 806 | |
| 807 HttpRequestInfo request_info; | |
| 808 request_info.method = "GET"; | |
| 809 request_info.url = GURL("https://www.google.com"); | |
| 810 | |
| 811 Initialize(request_info); | |
| 812 | |
| 813 // Set a SPDY alternative service for the server. | |
| 814 url::SchemeHostPort server(request_info.url); | |
| 815 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | |
| 816 SetAlternativeService(request_info, alternative_service); | |
| 817 // Hack to use different URL for the main job to help differentiate the proxy | |
| 818 // requests. | |
| 819 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); | |
| 820 | |
| 821 request_.reset( | |
| 822 job_controller_->Start(request_info, &request_delegate_, nullptr, | |
| 823 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | |
| 824 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 825 // Both jobs should be created but stalled as proxy resolution not completed. | |
| 826 EXPECT_TRUE(job_controller_->main_job()); | |
| 827 EXPECT_TRUE(job_controller_->alternative_job()); | |
| 828 | |
| 829 MockAsyncProxyResolver resolver; | |
| 830 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( | |
| 831 net::OK, &resolver); | |
| 832 | |
| 833 // Resolve proxy for the main job which then proceed to wait for the | |
| 834 // alternative job which is IO_PENDING. | |
| 835 int main_job_request_id = | |
| 836 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; | |
| 837 | |
| 838 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( | |
| 839 "result1:80"); | |
| 840 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); | |
| 841 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | |
| 842 | |
| 843 // Resolve proxy for the alternative job to proceed to create a connection. | |
| 844 // Use hanging HostResolver to fail creation of a SPDY session for the | |
| 845 // alternative job. The alternative job will be IO_PENDING thus should resume | |
| 846 // the main job. | |
| 847 resolver.pending_jobs()[0]->CompleteNow(net::OK); | |
| 848 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | |
| 849 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | |
| 850 | |
| 851 base::RunLoop().RunUntilIdle(); | |
| 852 } | |
| 853 | |
| 854 TEST_F(HttpStreamFactoryImplJobControllerTest, | |
| 855 NoAvailableQuicSessionToResumeMainJob) { | |
| 856 // Use failing HostResolver which is unable to resolve the host name for QUIC. | |
| 857 // No QUIC session is created and thus should resume the main job. | |
| 858 FailingHostResolver* host_resolver = new FailingHostResolver(); | |
| 859 session_deps_.host_resolver.reset(host_resolver); | |
| 860 | |
| 861 ProxyConfig proxy_config; | |
| 862 proxy_config.set_auto_detect(true); | |
| 863 // Use asynchronous proxy resolver. | |
| 864 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
| 865 new MockAsyncProxyResolverFactory(false); | |
| 866 session_deps_.proxy_service.reset( | |
| 867 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
| 868 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
| 869 | |
| 870 HttpRequestInfo request_info; | |
| 871 request_info.method = "GET"; | |
| 872 request_info.url = GURL("https://www.google.com"); | |
| 873 | |
| 874 Initialize(request_info); | |
| 875 url::SchemeHostPort server(request_info.url); | |
| 876 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | |
| 877 SetAlternativeService(request_info, alternative_service); | |
| 878 // Hack to use different URL for the main job to help differentiate the proxy | |
| 879 // requests. | |
| 880 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); | |
| 881 | |
| 882 request_.reset( | |
| 883 job_controller_->Start(request_info, &request_delegate_, nullptr, | |
| 884 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | |
| 885 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 886 EXPECT_TRUE(job_controller_->main_job()); | |
| 887 EXPECT_TRUE(job_controller_->alternative_job()); | |
| 888 | |
| 889 MockAsyncProxyResolver resolver; | |
| 890 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder( | |
| 891 net::OK, &resolver); | |
| 892 | |
| 893 // Resolve proxy for the main job which then proceed to wait for the | |
| 894 // alternative job which is IO_PENDING. | |
| 895 int main_job_request_id = | |
| 896 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1; | |
| 897 | |
| 898 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy( | |
| 899 "result1:80"); | |
| 900 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK); | |
| 901 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | |
| 902 | |
| 903 // Resolve proxy for the alternative job to proceed to create a connection. | |
| 904 // Use failing HostResolver to fail creation of a QUIC session for the | |
| 905 // alternative job. The alternative job will thus resume the main job. | |
| 906 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); | |
| 907 resolver.pending_jobs()[0]->CompleteNow(net::OK); | |
| 908 | |
| 909 // Wait until OnStreamFailedCallback is executed on the alternative job. | |
| 910 // Request shouldn't be notified as the main job is still pending status. | |
| 911 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | |
| 912 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | |
| 913 | |
| 914 base::RunLoop().RunUntilIdle(); | |
| 915 } | |
| 916 | |
| 917 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { | 994 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { |
| 918 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; | 995 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
| 919 auto failing_resolver = base::MakeUnique<MockHostResolver>(); | 996 auto failing_resolver = base::MakeUnique<MockHostResolver>(); |
| 920 failing_resolver->set_ondemand_mode(true); | 997 failing_resolver->set_ondemand_mode(true); |
| 921 failing_resolver->rules()->AddSimulatedFailure("*google.com"); | 998 failing_resolver->rules()->AddSimulatedFailure("*google.com"); |
| 922 session_deps_.host_resolver = std::move(failing_resolver); | 999 session_deps_.host_resolver = std::move(failing_resolver); |
| 923 | 1000 |
| 924 HttpRequestInfo request_info; | 1001 HttpRequestInfo request_info; |
| 925 request_info.method = "GET"; | 1002 request_info.method = "GET"; |
| 926 request_info.url = GURL("https://www.google.com"); | 1003 request_info.url = GURL("https://www.google.com"); |
| 927 | 1004 |
| 928 Initialize(request_info); | 1005 Initialize(request_info); |
| 929 | 1006 |
| 930 // Enable delayed TCP and set time delay for waiting job. | 1007 // Enable delayed TCP and set time delay for waiting job. |
| 931 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 1008 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
| 932 quic_stream_factory->set_require_confirmation(false); | 1009 quic_stream_factory->set_require_confirmation(false); |
| 933 ServerNetworkStats stats1; | 1010 ServerNetworkStats stats1; |
| 934 stats1.srtt = base::TimeDelta::FromMicroseconds(10); | 1011 stats1.srtt = base::TimeDelta::FromMicroseconds(10); |
| 935 session_->http_server_properties()->SetServerNetworkStats( | 1012 session_->http_server_properties()->SetServerNetworkStats( |
| 936 url::SchemeHostPort(GURL("https://www.google.com")), stats1); | 1013 url::SchemeHostPort(GURL("https://www.google.com")), stats1); |
| 937 | 1014 |
| 938 // Set a SPDY alternative service for the server. | |
| 939 url::SchemeHostPort server(request_info.url); | 1015 url::SchemeHostPort server(request_info.url); |
| 940 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1016 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 941 SetAlternativeService(request_info, alternative_service); | 1017 SetAlternativeService(request_info, alternative_service); |
| 942 | 1018 |
| 943 request_.reset( | 1019 request_.reset( |
| 944 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1020 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 945 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1021 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 946 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 947 EXPECT_TRUE(job_controller_->main_job()); | 1022 EXPECT_TRUE(job_controller_->main_job()); |
| 948 EXPECT_TRUE(job_controller_->alternative_job()); | 1023 EXPECT_TRUE(job_controller_->alternative_job()); |
| 949 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1024 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 950 | 1025 |
| 951 // The alternative job stalls as host resolution hangs when creating the QUIC | 1026 // The alternative job stalls as host resolution hangs when creating the QUIC |
| 952 // request and controller should resume the main job after delay. | 1027 // request and controller should resume the main job after delay. |
| 953 EXPECT_TRUE(test_task_runner->HasPendingTask()); | 1028 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 954 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1029 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 955 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 1030 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| 956 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); | 1031 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1002 stats1.srtt = base::TimeDelta::FromSeconds(100); | 1077 stats1.srtt = base::TimeDelta::FromSeconds(100); |
| 1003 session_->http_server_properties()->SetServerNetworkStats( | 1078 session_->http_server_properties()->SetServerNetworkStats( |
| 1004 url::SchemeHostPort(GURL("https://www.google.com")), stats1); | 1079 url::SchemeHostPort(GURL("https://www.google.com")), stats1); |
| 1005 | 1080 |
| 1006 // Set a SPDY alternative service for the server. | 1081 // Set a SPDY alternative service for the server. |
| 1007 url::SchemeHostPort server(request_info.url); | 1082 url::SchemeHostPort server(request_info.url); |
| 1008 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1083 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 1009 SetAlternativeService(request_info, alternative_service); | 1084 SetAlternativeService(request_info, alternative_service); |
| 1010 | 1085 |
| 1011 request_.reset( | 1086 request_.reset( |
| 1012 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1087 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 1013 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1088 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 1014 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 1015 EXPECT_TRUE(job_controller_->main_job()); | 1089 EXPECT_TRUE(job_controller_->main_job()); |
| 1016 EXPECT_TRUE(job_controller_->alternative_job()); | 1090 EXPECT_TRUE(job_controller_->alternative_job()); |
| 1017 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1091 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 1018 | 1092 |
| 1019 // The alternative job stalls as host resolution hangs when creating the QUIC | 1093 // The alternative job stalls as host resolution hangs when creating the QUIC |
| 1020 // request and controller should resume the main job after delay. | 1094 // request and controller should resume the main job after delay. |
| 1021 EXPECT_TRUE(test_task_runner->HasPendingTask()); | 1095 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 1022 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1096 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 1023 | 1097 |
| 1024 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 1098 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1062 | 1136 |
| 1063 // Set a SPDY alternative service for the server. | 1137 // Set a SPDY alternative service for the server. |
| 1064 url::SchemeHostPort server(request_info.url); | 1138 url::SchemeHostPort server(request_info.url); |
| 1065 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1139 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 1066 SetAlternativeService(request_info, alternative_service); | 1140 SetAlternativeService(request_info, alternative_service); |
| 1067 | 1141 |
| 1068 // The alternative job stalls as host resolution hangs when creating the QUIC | 1142 // The alternative job stalls as host resolution hangs when creating the QUIC |
| 1069 // request and controller should resume the main job with delay. | 1143 // request and controller should resume the main job with delay. |
| 1070 // OnStreamFailed should resume the main job immediately. | 1144 // OnStreamFailed should resume the main job immediately. |
| 1071 request_.reset( | 1145 request_.reset( |
| 1072 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1146 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 1073 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1147 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 1074 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 1075 EXPECT_TRUE(job_controller_->main_job()); | 1148 EXPECT_TRUE(job_controller_->main_job()); |
| 1076 EXPECT_TRUE(job_controller_->alternative_job()); | 1149 EXPECT_TRUE(job_controller_->alternative_job()); |
| 1077 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1150 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 1078 | 1151 |
| 1079 EXPECT_TRUE(test_task_runner->HasPendingTask()); | 1152 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 1080 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1153 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 1081 | 1154 |
| 1082 // |alternative_job| fails but should not report status to Request. | 1155 // |alternative_job| fails but should not report status to Request. |
| 1083 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 1156 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 1084 // Now unblock Resolver to fail the alternate job. | 1157 // Now unblock Resolver to fail the alternate job. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1108 HangingResolver* resolver = new HangingResolver(); | 1181 HangingResolver* resolver = new HangingResolver(); |
| 1109 session_deps_.host_resolver.reset(resolver); | 1182 session_deps_.host_resolver.reset(resolver); |
| 1110 | 1183 |
| 1111 HttpRequestInfo request_info; | 1184 HttpRequestInfo request_info; |
| 1112 request_info.method = "GET"; | 1185 request_info.method = "GET"; |
| 1113 request_info.url = GURL("https://mail.example.org/"); | 1186 request_info.url = GURL("https://mail.example.org/"); |
| 1114 Initialize(request_info); | 1187 Initialize(request_info); |
| 1115 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); | 1188 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
| 1116 | 1189 |
| 1117 request_.reset( | 1190 request_.reset( |
| 1118 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1191 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 1119 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1192 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 1120 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 1121 EXPECT_TRUE(job_controller_->main_job()); | 1193 EXPECT_TRUE(job_controller_->main_job()); |
| 1122 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); | 1194 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); |
| 1123 EXPECT_FALSE(job_controller_->alternative_job()); | 1195 EXPECT_FALSE(job_controller_->alternative_job()); |
| 1124 | 1196 |
| 1125 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | 1197 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); |
| 1126 base::RunLoop().RunUntilIdle(); | 1198 base::RunLoop().RunUntilIdle(); |
| 1127 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); | 1199 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); |
| 1128 } | 1200 } |
| 1129 | 1201 |
| 1130 // Verifies that the alternative proxy server job is not created if the main job | 1202 // Verifies that the alternative proxy server job is not created if the main job |
| 1131 // does not fetch the resource through a proxy. | 1203 // does not fetch the resource through a proxy. |
| 1132 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) { | 1204 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) { |
| 1133 // Using hanging resolver will cause the alternative job to hang indefinitely. | 1205 // Using hanging resolver will cause the alternative job to hang indefinitely. |
| 1134 HangingResolver* resolver = new HangingResolver(); | 1206 HangingResolver* resolver = new HangingResolver(); |
| 1135 session_deps_.host_resolver.reset(resolver); | 1207 session_deps_.host_resolver.reset(resolver); |
| 1136 | 1208 |
| 1137 HttpRequestInfo request_info; | 1209 HttpRequestInfo request_info; |
| 1138 request_info.method = "GET"; | 1210 request_info.method = "GET"; |
| 1139 request_info.url = GURL("http://mail.example.org/"); | 1211 request_info.url = GURL("http://mail.example.org/"); |
| 1140 | 1212 |
| 1141 Initialize(request_info); | 1213 Initialize(request_info); |
| 1142 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); | 1214 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
| 1143 | 1215 |
| 1144 request_.reset( | 1216 request_.reset( |
| 1145 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1217 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 1146 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1218 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 1147 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 1148 EXPECT_TRUE(job_controller_->main_job()); | 1219 EXPECT_TRUE(job_controller_->main_job()); |
| 1149 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); | 1220 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); |
| 1150 EXPECT_FALSE(job_controller_->alternative_job()); | 1221 EXPECT_FALSE(job_controller_->alternative_job()); |
| 1151 | 1222 |
| 1152 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | 1223 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); |
| 1153 base::RunLoop().RunUntilIdle(); | 1224 base::RunLoop().RunUntilIdle(); |
| 1154 | 1225 |
| 1155 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); | 1226 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); |
| 1156 } | 1227 } |
| 1157 | 1228 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1178 | 1249 |
| 1179 // Enable delayed TCP and set time delay for waiting job. | 1250 // Enable delayed TCP and set time delay for waiting job. |
| 1180 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 1251 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
| 1181 quic_stream_factory->set_require_confirmation(false); | 1252 quic_stream_factory->set_require_confirmation(false); |
| 1182 ServerNetworkStats stats1; | 1253 ServerNetworkStats stats1; |
| 1183 stats1.srtt = base::TimeDelta::FromMicroseconds(10); | 1254 stats1.srtt = base::TimeDelta::FromMicroseconds(10); |
| 1184 session_->http_server_properties()->SetServerNetworkStats( | 1255 session_->http_server_properties()->SetServerNetworkStats( |
| 1185 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); | 1256 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); |
| 1186 | 1257 |
| 1187 request_.reset( | 1258 request_.reset( |
| 1188 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1259 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 1189 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1260 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 1190 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 1191 EXPECT_TRUE(job_controller_->main_job()); | 1261 EXPECT_TRUE(job_controller_->main_job()); |
| 1192 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1262 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 1193 EXPECT_TRUE(job_controller_->alternative_job()); | 1263 EXPECT_TRUE(job_controller_->alternative_job()); |
| 1194 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 1264 // The main job is unblocked but is resumed one message loop iteration later. |
| 1195 | 1265 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| 1196 // Alternative proxy server job will start in the next message loop. | 1266 EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_)); |
| 1197 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | |
| 1198 | |
| 1199 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | |
| 1200 // Run tasks with no remaining delay, this will start the alternative proxy | |
| 1201 // server job. The alternative proxy server job stalls when connecting to the | |
| 1202 // alternative proxy server, and should schedule a task to resume the main job | |
| 1203 // after delay. That task will be queued. | |
| 1204 test_task_runner->RunUntilIdle(); | |
| 1205 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1267 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 1206 | 1268 |
| 1207 // Move forward the delay and verify the main job is resumed. | 1269 // Move forward the delay and verify the main job is resumed. |
| 1208 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 1270 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| 1209 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); | 1271 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); |
| 1210 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 1272 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| 1273 EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_)); | |
| 1211 | 1274 |
| 1212 test_task_runner->RunUntilIdle(); | 1275 test_task_runner->RunUntilIdle(); |
| 1213 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); | 1276 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); |
| 1214 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); | 1277 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); |
| 1215 EXPECT_FALSE(test_task_runner->HasPendingTask()); | 1278 EXPECT_FALSE(test_task_runner->HasPendingTask()); |
| 1216 | 1279 |
| 1217 // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can | 1280 // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can |
| 1218 // be cleaned up. | 1281 // be cleaned up. |
| 1219 session_deps_.host_resolver->ResolveAllPending(); | 1282 session_deps_.host_resolver->ResolveAllPending(); |
| 1220 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1283 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 1221 test_task_runner->FastForwardUntilNoTasksRemain(); | 1284 test_task_runner->FastForwardUntilNoTasksRemain(); |
| 1222 EXPECT_FALSE(job_controller_->alternative_job()); | 1285 EXPECT_FALSE(job_controller_->alternative_job()); |
| 1223 } | 1286 } |
| 1224 | 1287 |
| 1225 // Verifies that the alternative proxy server job fails immediately, and the | 1288 // Verifies that if the alternative proxy server job fails immediately, the |
| 1226 // main job is not blocked. | 1289 // main job is not blocked. |
| 1227 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { | 1290 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { |
| 1228 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; | 1291 quic_data_ = base::MakeUnique<test::MockQuicData>(); |
| 1229 // Using failing resolver will cause the alternative job to fail. | 1292 quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED); |
| 1230 FailingHostResolver* resolver = new FailingHostResolver(); | 1293 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 1231 session_deps_.host_resolver.reset(resolver); | 1294 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); |
| 1295 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
| 1296 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 1232 | 1297 |
| 1233 UseAlternativeProxy(); | 1298 UseAlternativeProxy(); |
| 1234 | 1299 |
| 1235 HttpRequestInfo request_info; | 1300 HttpRequestInfo request_info; |
| 1236 request_info.method = "GET"; | 1301 request_info.method = "GET"; |
| 1237 request_info.url = GURL("http://mail.example.org/"); | 1302 request_info.url = GURL("http://mail.example.org/"); |
| 1238 Initialize(request_info); | 1303 Initialize(request_info); |
| 1239 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); | 1304 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
| 1240 | 1305 |
| 1241 // Enable delayed TCP and set time delay for waiting job. | 1306 // Enable delayed TCP and set time delay for waiting job. |
| 1242 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 1307 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
| 1243 quic_stream_factory->set_require_confirmation(false); | 1308 quic_stream_factory->set_require_confirmation(false); |
| 1244 ServerNetworkStats stats1; | 1309 ServerNetworkStats stats1; |
| 1245 stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000); | 1310 stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000); |
| 1246 session_->http_server_properties()->SetServerNetworkStats( | 1311 session_->http_server_properties()->SetServerNetworkStats( |
| 1247 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); | 1312 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); |
| 1248 | 1313 |
| 1249 request_.reset( | 1314 request_.reset( |
| 1250 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1315 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 1251 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1316 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 1252 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | 1317 EXPECT_TRUE(job_controller_->main_job()); |
| 1253 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | |
| 1254 EXPECT_TRUE(job_controller_->alternative_job()); | 1318 EXPECT_TRUE(job_controller_->alternative_job()); |
| 1255 | 1319 |
| 1256 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | 1320 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| 1321 .WillOnce(Invoke(DeleteHttpStreamPointer)); | |
| 1257 | 1322 |
| 1258 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)).Times(0); | 1323 base::RunLoop().RunUntilIdle(); |
| 1259 | |
| 1260 // Since the alternative proxy server job is started in the next message loop, | |
| 1261 // the main job would remain blocked until the alternative proxy starts, and | |
| 1262 // fails. | |
| 1263 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | |
| 1264 | |
| 1265 // Run tasks with no remaining delay. | |
| 1266 test_task_runner->RunUntilIdle(); | |
| 1267 | 1324 |
| 1268 EXPECT_FALSE(job_controller_->alternative_job()); | 1325 EXPECT_FALSE(job_controller_->alternative_job()); |
| 1269 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1326 EXPECT_TRUE(job_controller_->main_job()); |
| 1270 // Since the main job did not complete successfully, the alternative proxy | 1327 |
| 1271 // server should not be marked as bad. | 1328 // The alternative proxy server should be marked as bad. |
| 1272 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); | 1329 EXPECT_FALSE(test_proxy_delegate()->alternative_proxy_server().is_valid()); |
| 1273 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); | 1330 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); |
| 1274 EXPECT_FALSE(test_task_runner->HasPendingTask()); | 1331 request_.reset(); |
| 1332 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | |
| 1275 } | 1333 } |
| 1276 | 1334 |
| 1277 TEST_F(HttpStreamFactoryImplJobControllerTest, | 1335 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 1278 AlternativeProxyServerJobFailsAfterMainJobSucceeds) { | 1336 AlternativeProxyServerJobFailsAfterMainJobSucceeds) { |
| 1279 base::HistogramTester histogram_tester; | 1337 base::HistogramTester histogram_tester; |
| 1280 | 1338 |
| 1339 // Use COLD_START to make the alt job pending. | |
| 1340 crypto_client_stream_factory_.set_handshake_mode( | |
| 1341 MockCryptoClientStream::COLD_START); | |
| 1342 quic_data_ = base::MakeUnique<test::MockQuicData>(); | |
| 1343 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING); | |
| 1344 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
| 1345 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
| 1346 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
| 1347 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 1348 | |
| 1281 UseAlternativeProxy(); | 1349 UseAlternativeProxy(); |
| 1282 | 1350 |
| 1283 HttpRequestInfo request_info; | 1351 HttpRequestInfo request_info; |
| 1284 request_info.method = "GET"; | 1352 request_info.method = "GET"; |
| 1285 request_info.url = GURL("http://www.google.com"); | 1353 request_info.url = GURL("http://www.google.com"); |
| 1286 Initialize(request_info); | 1354 Initialize(request_info); |
| 1287 | 1355 |
| 1288 url::SchemeHostPort server(request_info.url); | 1356 url::SchemeHostPort server(request_info.url); |
| 1289 | 1357 |
| 1290 request_.reset( | 1358 request_.reset( |
| 1291 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1359 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 1292 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1360 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 1293 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 1294 EXPECT_TRUE(job_controller_->main_job()); | 1361 EXPECT_TRUE(job_controller_->main_job()); |
| 1295 EXPECT_TRUE(job_controller_->alternative_job()); | 1362 EXPECT_TRUE(job_controller_->alternative_job()); |
| 1296 | 1363 |
| 1297 // Main job succeeds, starts serving Request and it should report status | 1364 // Main job succeeds, starts serving Request and it should report status |
| 1298 // to Request. The alternative job will mark the main job complete and gets | 1365 // to Request. The alternative job will mark the main job complete and gets |
| 1299 // orphaned. | 1366 // orphaned. |
| 1300 HttpStream* http_stream = | 1367 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| 1301 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | 1368 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 1302 job_factory_.main_job()->SetStream(http_stream); | |
| 1303 | 1369 |
| 1304 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | 1370 base::RunLoop().RunUntilIdle(); |
| 1305 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 1371 |
| 1306 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | 1372 EXPECT_TRUE(job_controller_->main_job()); |
| 1373 EXPECT_TRUE(job_controller_->alternative_job()); | |
| 1307 | 1374 |
| 1308 // JobController shouldn't report the status of alternative server job as | 1375 // JobController shouldn't report the status of alternative server job as |
| 1309 // request is already successfully served. | 1376 // request is already successfully served. |
| 1310 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 1377 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 1311 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, | 1378 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, |
| 1312 SSLConfig()); | 1379 SSLConfig()); |
| 1313 | 1380 |
| 1314 // Reset the request as it's been successfully served. | 1381 // Reset the request as it's been successfully served. |
| 1315 request_.reset(); | 1382 request_.reset(); |
| 1316 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1383 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1317 | 1384 |
| 1318 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", | 1385 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", |
| 1319 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, | 1386 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, |
| 1320 1); | 1387 1); |
| 1321 } | 1388 } |
| 1322 | 1389 |
| 1323 // When preconnect to a H2 supported server, only 1 connection is opened. | 1390 // When preconnect to a H2 supported server, only 1 connection is opened. |
| 1324 TEST_F(HttpStreamFactoryImplJobControllerTest, | 1391 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 1325 PreconnectMultipleStreamsToH2Server) { | 1392 PreconnectMultipleStreamsToH2Server) { |
| 1326 MockRead reads[] = {MockRead(ASYNC, OK)}; | 1393 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); |
| 1327 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); | 1394 tcp_data_->set_connect_data(MockConnect(ASYNC, OK)); |
| 1328 session_deps_.socket_factory->AddSocketDataProvider(&data); | |
| 1329 | |
| 1330 SetPreconnect(); | 1395 SetPreconnect(); |
| 1331 | 1396 |
| 1332 HttpRequestInfo request_info; | 1397 HttpRequestInfo request_info; |
| 1333 request_info.method = "GET"; | 1398 request_info.method = "GET"; |
| 1334 request_info.url = GURL("http://www.example.com"); | 1399 request_info.url = GURL("http://www.example.com"); |
| 1335 Initialize(request_info); | 1400 Initialize(request_info); |
| 1336 | 1401 |
| 1337 url::SchemeHostPort server(request_info.url); | 1402 url::SchemeHostPort server(request_info.url); |
| 1338 | 1403 |
| 1339 // Sets server support Http/2. | 1404 // Sets server support Http/2. |
| 1340 session_->http_server_properties()->SetSupportsSpdy(server, true); | 1405 session_->http_server_properties()->SetSupportsSpdy(server, true); |
| 1341 | 1406 |
| 1342 job_controller_->Preconnect(/*num_streams=*/5, request_info, SSLConfig(), | 1407 job_controller_->Preconnect(/*num_streams=*/5); |
| 1343 SSLConfig()); | |
| 1344 // Only one job is started. | 1408 // Only one job is started. |
| 1345 EXPECT_TRUE(job_controller_->main_job()); | 1409 EXPECT_TRUE(job_controller_->main_job()); |
| 1346 EXPECT_FALSE(job_controller_->alternative_job()); | 1410 EXPECT_FALSE(job_controller_->alternative_job()); |
| 1347 // There is only 1 connect even though multiple streams were requested. | 1411 // There is only 1 connect even though multiple streams were requested. |
| 1348 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams( | 1412 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams( |
| 1349 job_controller_->main_job())); | 1413 job_controller_->main_job())); |
| 1350 | 1414 |
| 1351 base::RunLoop().RunUntilIdle(); | 1415 base::RunLoop().RunUntilIdle(); |
| 1352 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1416 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1353 } | 1417 } |
| 1354 | 1418 |
| 1355 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry | 1419 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry |
| 1356 : public HttpStreamFactoryImplJobControllerTest, | 1420 : public HttpStreamFactoryImplJobControllerTest, |
| 1357 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; | 1421 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; |
| 1358 | 1422 |
| 1359 INSTANTIATE_TEST_CASE_P( | 1423 INSTANTIATE_TEST_CASE_P( |
| 1360 /* no prefix */, | 1424 /* no prefix */, |
| 1361 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, | 1425 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
| 1362 ::testing::Combine(::testing::Bool(), ::testing::Bool())); | 1426 ::testing::Combine(::testing::Bool(), ::testing::Bool())); |
| 1363 | 1427 |
| 1364 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, | 1428 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, |
| 1365 DisableIPBasedPoolingAndAlternativeServices) { | 1429 DisableIPBasedPoolingAndAlternativeServices) { |
| 1366 const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); | 1430 const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); |
| 1367 const bool enable_alternative_services = ::testing::get<1>(GetParam()); | 1431 const bool enable_alternative_services = ::testing::get<1>(GetParam()); |
| 1432 if (enable_alternative_services) { | |
| 1433 quic_data_ = base::MakeUnique<test::MockQuicData>(); | |
| 1434 quic_data_->AddConnect(SYNCHRONOUS, OK); | |
| 1435 quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr)); | |
| 1436 quic_data_->AddRead(ASYNC, OK); | |
| 1437 } | |
| 1438 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0); | |
| 1439 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
| 1440 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK); | |
| 1441 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get()); | |
| 1368 | 1442 |
| 1369 ProxyConfig proxy_config; | |
| 1370 proxy_config.set_auto_detect(true); | |
| 1371 // Use asynchronous proxy resolver. | |
| 1372 MockAsyncProxyResolverFactory* proxy_resolver_factory = | |
| 1373 new MockAsyncProxyResolverFactory(false); | |
| 1374 session_deps_.proxy_service.reset( | |
| 1375 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), | |
| 1376 base::WrapUnique(proxy_resolver_factory), nullptr)); | |
| 1377 HttpRequestInfo request_info; | 1443 HttpRequestInfo request_info; |
| 1378 request_info.method = "GET"; | 1444 request_info.method = "GET"; |
| 1379 request_info.url = GURL("https://www.google.com"); | 1445 request_info.url = GURL("https://www.google.com"); |
| 1380 | 1446 |
| 1381 if (!enable_ip_based_pooling) | 1447 if (!enable_ip_based_pooling) |
| 1382 DisableIPBasedPooling(); | 1448 DisableIPBasedPooling(); |
| 1383 if (!enable_alternative_services) | 1449 if (!enable_alternative_services) |
| 1384 DisableAlternativeServices(); | 1450 DisableAlternativeServices(); |
| 1385 | 1451 |
| 1386 Initialize(request_info); | 1452 Initialize(request_info); |
| 1387 | 1453 |
| 1388 url::SchemeHostPort server(request_info.url); | 1454 url::SchemeHostPort server(request_info.url); |
| 1389 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1455 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 1390 SetAlternativeService(request_info, alternative_service); | 1456 SetAlternativeService(request_info, alternative_service); |
| 1391 | 1457 |
| 1392 request_.reset( | 1458 request_.reset( |
| 1393 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1459 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(), |
| 1394 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1460 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY)); |
| 1395 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 1396 EXPECT_TRUE(job_controller_->main_job()); | 1461 EXPECT_TRUE(job_controller_->main_job()); |
| 1397 if (enable_alternative_services) { | 1462 if (enable_alternative_services) { |
| 1398 EXPECT_TRUE(job_controller_->alternative_job()); | 1463 EXPECT_TRUE(job_controller_->alternative_job()); |
| 1399 } else { | 1464 } else { |
| 1400 EXPECT_FALSE(job_controller_->alternative_job()); | 1465 EXPECT_FALSE(job_controller_->alternative_job()); |
| 1401 } | 1466 } |
| 1402 | 1467 |
| 1403 // |main_job| succeeds and should report status to Request. | 1468 // |main_job| succeeds and should report status to Request. |
| 1404 HttpStream* http_stream = | 1469 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)) |
| 1405 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); | |
| 1406 job_factory_.main_job()->SetStream(http_stream); | |
| 1407 | |
| 1408 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) | |
| 1409 .WillOnce(Invoke(DeleteHttpStreamPointer)); | 1470 .WillOnce(Invoke(DeleteHttpStreamPointer)); |
| 1410 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); | 1471 base::RunLoop().RunUntilIdle(); |
| 1411 } | 1472 } |
| 1412 | 1473 |
| 1413 class HttpStreamFactoryImplJobControllerPreconnectTest | 1474 class HttpStreamFactoryImplJobControllerPreconnectTest |
| 1414 : public HttpStreamFactoryImplJobControllerTest, | 1475 : public HttpStreamFactoryImplJobControllerTest, |
| 1415 public ::testing::WithParamInterface<bool> { | 1476 public ::testing::WithParamInterface<bool> { |
| 1416 protected: | 1477 protected: |
| 1417 void SetUp() override { | 1478 void SetUp() override { |
| 1418 if (GetParam()) { | 1479 if (GetParam()) { |
| 1419 scoped_feature_list_.InitFromCommandLine("LimitEarlyPreconnects", | 1480 scoped_feature_list_.InitFromCommandLine("LimitEarlyPreconnects", |
| 1420 std::string()); | 1481 std::string()); |
| 1421 } | 1482 } |
| 1422 } | 1483 } |
| 1423 | 1484 |
| 1424 void Initialize() { | 1485 void Initialize() { |
| 1425 session_deps_.http_server_properties = | 1486 session_deps_.http_server_properties = |
| 1426 base::MakeUnique<MockHttpServerProperties>(); | 1487 base::MakeUnique<MockHttpServerProperties>(); |
| 1427 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); | 1488 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); |
| 1428 factory_ = | 1489 factory_ = |
| 1429 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); | 1490 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); |
| 1430 request_info_.method = "GET"; | 1491 request_info_.method = "GET"; |
| 1431 request_info_.url = GURL("https://www.example.com"); | 1492 request_info_.url = GURL("https://www.example.com"); |
| 1432 job_controller_ = new HttpStreamFactoryImpl::JobController( | 1493 job_controller_ = new HttpStreamFactoryImpl::JobController( |
| 1433 factory_, &request_delegate_, session_.get(), &job_factory_, | 1494 factory_, &request_delegate_, session_.get(), &job_factory_, |
| 1434 request_info_, /* is_preconnect = */ true, | 1495 request_info_, /* is_preconnect = */ true, |
| 1435 /* enable_ip_based_pooling = */ true, | 1496 /* enable_ip_based_pooling = */ true, |
| 1436 /* enable_alternative_services = */ true); | 1497 /* enable_alternative_services = */ true, SSLConfig(), SSLConfig()); |
| 1437 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); | 1498 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); |
| 1438 } | 1499 } |
| 1439 | 1500 |
| 1440 protected: | 1501 protected: |
| 1441 void Preconnect(int num_streams) { | 1502 void Preconnect(int num_streams) { |
| 1442 job_controller_->Preconnect(num_streams, request_info_, SSLConfig(), | 1503 job_controller_->Preconnect(num_streams); |
| 1443 SSLConfig()); | |
| 1444 // Only one job is started. | 1504 // Only one job is started. |
| 1445 EXPECT_TRUE(job_controller_->main_job()); | 1505 EXPECT_TRUE(job_controller_->main_job()); |
| 1446 EXPECT_FALSE(job_controller_->alternative_job()); | 1506 EXPECT_FALSE(job_controller_->alternative_job()); |
| 1447 } | 1507 } |
| 1448 | 1508 |
| 1449 private: | 1509 private: |
| 1450 base::test::ScopedFeatureList scoped_feature_list_; | 1510 base::test::ScopedFeatureList scoped_feature_list_; |
| 1451 HttpRequestInfo request_info_; | 1511 HttpRequestInfo request_info_; |
| 1452 }; | 1512 }; |
| 1453 | 1513 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1477 Preconnect(kNumPreconects); | 1537 Preconnect(kNumPreconects); |
| 1478 // If experiment is enabled, only 1 stream is requested. | 1538 // If experiment is enabled, only 1 stream is requested. |
| 1479 EXPECT_EQ( | 1539 EXPECT_EQ( |
| 1480 (int)actual_num_connects, | 1540 (int)actual_num_connects, |
| 1481 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); | 1541 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); |
| 1482 base::RunLoop().RunUntilIdle(); | 1542 base::RunLoop().RunUntilIdle(); |
| 1483 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1543 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1484 } | 1544 } |
| 1485 | 1545 |
| 1486 } // namespace net | 1546 } // namespace net |
| OLD | NEW |