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