xref: /aosp_15_r20/external/cronet/net/http/http_stream_factory_job_controller_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_stream_factory_job_controller.h"
6 
7 #include <list>
8 #include <memory>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include "base/containers/contains.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/memory/scoped_refptr.h"
17 #include "base/run_loop.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/test/bind.h"
20 #include "base/test/metrics/histogram_tester.h"
21 #include "base/test/scoped_feature_list.h"
22 #include "base/test/task_environment.h"
23 #include "base/test/test_mock_time_task_runner.h"
24 #include "base/threading/platform_thread.h"
25 #include "base/values.h"
26 #include "net/base/completion_once_callback.h"
27 #include "net/base/features.h"
28 #include "net/base/host_port_pair.h"
29 #include "net/base/proxy_chain.h"
30 #include "net/base/proxy_server.h"
31 #include "net/base/proxy_string_util.h"
32 #include "net/base/schemeful_site.h"
33 #include "net/base/session_usage.h"
34 #include "net/base/test_proxy_delegate.h"
35 #include "net/dns/mock_host_resolver.h"
36 #include "net/dns/public/secure_dns_policy.h"
37 #include "net/http/alternative_service.h"
38 #include "net/http/http_basic_stream.h"
39 #include "net/http/http_network_session_peer.h"
40 #include "net/http/http_response_headers.h"
41 #include "net/http/http_server_properties.h"
42 #include "net/http/http_server_properties_manager.h"
43 #include "net/http/http_stream_factory.h"
44 #include "net/http/http_stream_factory_job.h"
45 #include "net/http/http_stream_factory_test_util.h"
46 #include "net/log/net_log.h"
47 #include "net/log/net_log_with_source.h"
48 #include "net/log/test_net_log.h"
49 #include "net/log/test_net_log_util.h"
50 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
51 #include "net/proxy_resolution/mock_proxy_resolver.h"
52 #include "net/proxy_resolution/proxy_config_service_fixed.h"
53 #include "net/proxy_resolution/proxy_info.h"
54 #include "net/proxy_resolution/proxy_list.h"
55 #include "net/proxy_resolution/proxy_resolution_service.h"
56 #include "net/quic/crypto/proof_verifier_chromium.h"
57 #include "net/quic/mock_crypto_client_stream_factory.h"
58 #include "net/quic/mock_quic_context.h"
59 #include "net/quic/mock_quic_data.h"
60 #include "net/quic/quic_http_stream.h"
61 #include "net/quic/quic_session_pool.h"
62 #include "net/quic/quic_session_pool_peer.h"
63 #include "net/quic/quic_test_packet_maker.h"
64 #include "net/socket/socket_test_util.h"
65 #include "net/spdy/spdy_session_key.h"
66 #include "net/spdy/spdy_test_util_common.h"
67 #include "net/test/cert_test_util.h"
68 #include "net/test/test_data_directory.h"
69 #include "net/test/test_with_task_environment.h"
70 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
71 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
72 #include "testing/gmock/include/gmock/gmock.h"
73 #include "testing/gtest/include/gtest/gtest.h"
74 #include "url/gurl.h"
75 #include "url/scheme_host_port.h"
76 
77 using ::testing::_;
78 using ::testing::Contains;
79 using ::testing::ElementsAre;
80 using ::testing::Invoke;
81 using ::testing::IsEmpty;
82 using ::testing::Key;
83 using ::testing::SizeIs;
84 
85 namespace net::test {
86 
87 namespace {
88 
89 const char kServerHostname[] = "www.example.com";
90 
91 // The default delay for main job defined in QuicSessionPool::
92 // GetTimeDelayForWaitingJob().
93 const int kDefaultDelayMilliSecsForWaitingJob = 300;
94 
95 class FailingProxyResolverFactory : public ProxyResolverFactory {
96  public:
FailingProxyResolverFactory()97   FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
98 
99   // ProxyResolverFactory override.
CreateProxyResolver(const scoped_refptr<PacFileData> & script_data,std::unique_ptr<ProxyResolver> * result,CompletionOnceCallback callback,std::unique_ptr<Request> * request)100   int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
101                           std::unique_ptr<ProxyResolver>* result,
102                           CompletionOnceCallback callback,
103                           std::unique_ptr<Request>* request) override {
104     return ERR_PAC_SCRIPT_FAILED;
105   }
106 };
107 
108 // A mock HttpServerProperties::PrefDelegate that never finishes loading, so
109 // HttpServerProperties::IsInitialized() always returns false.
110 class MockPrefDelegate : public HttpServerProperties::PrefDelegate {
111  public:
112   MockPrefDelegate() = default;
113 
114   MockPrefDelegate(const MockPrefDelegate&) = delete;
115   MockPrefDelegate& operator=(const MockPrefDelegate&) = delete;
116 
117   ~MockPrefDelegate() override = default;
118 
119   // HttpServerProperties::PrefDelegate implementation:
GetServerProperties() const120   const base::Value::Dict& GetServerProperties() const override {
121     return empty_dict_;
122   }
SetServerProperties(base::Value::Dict dict,base::OnceClosure callback)123   void SetServerProperties(base::Value::Dict dict,
124                            base::OnceClosure callback) override {}
WaitForPrefLoad(base::OnceClosure pref_loaded_callback)125   void WaitForPrefLoad(base::OnceClosure pref_loaded_callback) override {}
126 
127   base::Value::Dict empty_dict_;
128 };
129 
130 // A `TestProxyDelegate` which always sets a `ProxyChain` with
131 // `is_for_ip_protection` set to true on the `ProxyInfo` it receives in
132 // `OnResolveProxy()`.
133 class TestProxyDelegateForIpProtection : public TestProxyDelegate {
134  public:
TestProxyDelegateForIpProtection()135   TestProxyDelegateForIpProtection() {
136     set_proxy_chain(net::ProxyChain::ForIpProtection(
137         {net::ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS,
138                                                  "ip-pro", 443)}));
139     set_extra_header_name(net::HttpRequestHeaders::kAuthorization);
140   }
OnResolveProxy(const GURL & url,const NetworkAnonymizationKey & network_anonymization_key,const std::string & method,const ProxyRetryInfoMap & proxy_retry_info,ProxyInfo * result)141   void OnResolveProxy(const GURL& url,
142                       const NetworkAnonymizationKey& network_anonymization_key,
143                       const std::string& method,
144                       const ProxyRetryInfoMap& proxy_retry_info,
145                       ProxyInfo* result) override {
146     net::ProxyList proxy_list;
147     proxy_list.AddProxyChain(proxy_chain());
148     proxy_list.AddProxyChain(net::ProxyChain::Direct());
149     result->UseProxyList(proxy_list);
150   }
151 };
152 
153 }  // anonymous namespace
154 
155 class HttpStreamFactoryJobPeer {
156  public:
157   // Returns |num_streams_| of |job|. It should be 0 for non-preconnect Jobs.
GetNumStreams(const HttpStreamFactory::Job * job)158   static int GetNumStreams(const HttpStreamFactory::Job* job) {
159     return job->num_streams_;
160   }
161 
162   // Return SpdySessionKey of |job|.
GetSpdySessionKey(const HttpStreamFactory::Job * job)163   static const SpdySessionKey GetSpdySessionKey(
164       const HttpStreamFactory::Job* job) {
165     return job->spdy_session_key_;
166   }
167 
SetShouldReconsiderProxy(HttpStreamFactory::Job * job)168   static void SetShouldReconsiderProxy(HttpStreamFactory::Job* job) {
169     job->should_reconsider_proxy_ = true;
170   }
171 
SetStream(HttpStreamFactory::Job * job,std::unique_ptr<HttpStream> http_stream)172   static void SetStream(HttpStreamFactory::Job* job,
173                         std::unique_ptr<HttpStream> http_stream) {
174     job->stream_ = std::move(http_stream);
175   }
176 
SetQuicConnectionFailedOnDefaultNetwork(HttpStreamFactory::Job * job)177   static void SetQuicConnectionFailedOnDefaultNetwork(
178       HttpStreamFactory::Job* job) {
179     job->quic_request_.OnConnectionFailedOnDefaultNetwork();
180   }
181 };
182 
183 class JobControllerPeer {
184  public:
main_job_is_blocked(HttpStreamFactory::JobController * job_controller)185   static bool main_job_is_blocked(
186       HttpStreamFactory::JobController* job_controller) {
187     return job_controller->main_job_is_blocked_;
188   }
189 
main_job_is_resumed(HttpStreamFactory::JobController * job_controller)190   static bool main_job_is_resumed(
191       HttpStreamFactory::JobController* job_controller) {
192     return job_controller->main_job_is_resumed_;
193   }
194 
InitializeProxyInfo(HttpStreamFactory::JobController * job_controller)195   static void InitializeProxyInfo(
196       HttpStreamFactory::JobController* job_controller) {
197     job_controller->proxy_info_.UseDirect();
198   }
199 
GetAlternativeServiceInfoFor(HttpStreamFactory::JobController * job_controller,const HttpRequestInfo & request_info,HttpStreamRequest::Delegate * delegate,HttpStreamRequest::StreamType stream_type)200   static AlternativeServiceInfo GetAlternativeServiceInfoFor(
201       HttpStreamFactory::JobController* job_controller,
202       const HttpRequestInfo& request_info,
203       HttpStreamRequest::Delegate* delegate,
204       HttpStreamRequest::StreamType stream_type) {
205     return job_controller->GetAlternativeServiceInfoFor(
206         request_info.url, HttpStreamFactory::StreamRequestInfo(request_info),
207         delegate, stream_type);
208   }
209 
SelectQuicVersion(HttpStreamFactory::JobController * job_controller,const quic::ParsedQuicVersionVector & advertised_versions)210   static quic::ParsedQuicVersion SelectQuicVersion(
211       HttpStreamFactory::JobController* job_controller,
212       const quic::ParsedQuicVersionVector& advertised_versions) {
213     return job_controller->SelectQuicVersion(advertised_versions);
214   }
215 
SetAltJobFailedOnDefaultNetwork(HttpStreamFactory::JobController * job_controller)216   static void SetAltJobFailedOnDefaultNetwork(
217       HttpStreamFactory::JobController* job_controller) {
218     DCHECK(job_controller->alternative_job() != nullptr);
219     HttpStreamFactoryJobPeer::SetQuicConnectionFailedOnDefaultNetwork(
220         job_controller->alternative_job_.get());
221   }
SetDnsAlpnH3JobFailedOnDefaultNetwork(HttpStreamFactory::JobController * job_controller)222   static void SetDnsAlpnH3JobFailedOnDefaultNetwork(
223       HttpStreamFactory::JobController* job_controller) {
224     DCHECK(job_controller->dns_alpn_h3_job() != nullptr);
225     HttpStreamFactoryJobPeer::SetQuicConnectionFailedOnDefaultNetwork(
226         job_controller->dns_alpn_h3_job_.get());
227   }
228 };
229 
230 class HttpStreamFactoryJobControllerTestBase : public TestWithTaskEnvironment {
231  public:
HttpStreamFactoryJobControllerTestBase(bool dns_https_alpn_enabled,std::vector<base::test::FeatureRef> enabled_features={})232   explicit HttpStreamFactoryJobControllerTestBase(
233       bool dns_https_alpn_enabled,
234       std::vector<base::test::FeatureRef> enabled_features = {})
235       : TestWithTaskEnvironment(
236             base::test::TaskEnvironment::TimeSource::MOCK_TIME),
237         dns_https_alpn_enabled_(dns_https_alpn_enabled) {
238     std::vector<base::test::FeatureRef> disabled_features;
239     if (dns_https_alpn_enabled_) {
240       enabled_features.push_back(features::kUseDnsHttpsSvcbAlpn);
241     } else {
242       disabled_features.push_back(features::kUseDnsHttpsSvcbAlpn);
243     }
244     feature_list_.InitWithFeatures(enabled_features, disabled_features);
245     FLAGS_quic_enable_http3_grease_randomness = false;
246     CreateSessionDeps();
247   }
248 
249   // Creates / re-creates `session_deps_`, and clears test fixture fields
250   // referencing it.
CreateSessionDeps()251   void CreateSessionDeps() {
252     factory_ = nullptr;
253     job_controller_ = nullptr;
254     session_.reset();
255 
256     session_deps_.proxy_resolution_service->SetProxyDelegate(nullptr);
257 
258     session_deps_ = SpdySessionDependencies(
259         ConfiguredProxyResolutionService::CreateDirect());
260     session_deps_.enable_quic = true;
261     session_deps_.host_resolver->set_synchronous_mode(true);
262   }
263 
SetPreconnect()264   void SetPreconnect() {
265     ASSERT_FALSE(session_deps_.proxy_delegate);
266     is_preconnect_ = true;
267   }
268 
DisableIPBasedPooling()269   void DisableIPBasedPooling() {
270     ASSERT_FALSE(session_deps_.proxy_delegate);
271     enable_ip_based_pooling_ = false;
272   }
273 
SetNotDelayMainJobWithAvailableSpdySession()274   void SetNotDelayMainJobWithAvailableSpdySession() {
275     ASSERT_FALSE(session_deps_.proxy_delegate);
276     delay_main_job_with_available_spdy_session_ = false;
277   }
278 
DisableAlternativeServices()279   void DisableAlternativeServices() {
280     ASSERT_FALSE(session_deps_.proxy_delegate);
281     enable_alternative_services_ = false;
282   }
283 
SkipCreatingJobController()284   void SkipCreatingJobController() {
285     ASSERT_FALSE(job_controller_);
286     create_job_controller_ = false;
287   }
288 
Initialize(const HttpRequestInfo & request_info)289   void Initialize(const HttpRequestInfo& request_info) {
290     ASSERT_FALSE(session_deps_.proxy_delegate);
291     session_deps_.proxy_delegate = std::make_unique<TestProxyDelegate>();
292 
293     if (quic_data_) {
294       quic_data_->AddSocketDataToFactory(session_deps_.socket_factory.get());
295     }
296     if (quic_data2_) {
297       quic_data2_->AddSocketDataToFactory(session_deps_.socket_factory.get());
298     }
299     if (tcp_data_) {
300       session_deps_.socket_factory->AddSocketDataProvider(tcp_data_.get());
301     }
302     if (tcp_data2_) {
303       session_deps_.socket_factory->AddSocketDataProvider(tcp_data2_.get());
304     }
305 
306     session_deps_.proxy_resolution_service->SetProxyDelegate(
307         session_deps_.proxy_delegate.get());
308 
309     session_deps_.net_log = NetLog::Get();
310     HttpNetworkSessionParams params =
311         SpdySessionDependencies::CreateSessionParams(&session_deps_);
312     HttpNetworkSessionContext session_context =
313         SpdySessionDependencies::CreateSessionContext(&session_deps_);
314 
315     session_context.quic_crypto_client_stream_factory =
316         &crypto_client_stream_factory_;
317     session_context.quic_context = &quic_context_;
318     session_ = std::make_unique<HttpNetworkSession>(params, session_context);
319     factory_ = static_cast<HttpStreamFactory*>(session_->http_stream_factory());
320     if (create_job_controller_) {
321       auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
322           factory_, &request_delegate_, session_.get(), &job_factory_,
323           request_info, is_preconnect_, /*is_websocket=*/false,
324           enable_ip_based_pooling_, enable_alternative_services_,
325           delay_main_job_with_available_spdy_session_,
326           /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
327       job_controller_ = job_controller.get();
328       HttpStreamFactoryPeer::AddJobController(factory_,
329                                               std::move(job_controller));
330     }
331   }
332 
333   HttpStreamFactoryJobControllerTestBase(
334       const HttpStreamFactoryJobControllerTestBase&) = delete;
335   HttpStreamFactoryJobControllerTestBase& operator=(
336       const HttpStreamFactoryJobControllerTestBase&) = delete;
337 
~HttpStreamFactoryJobControllerTestBase()338   ~HttpStreamFactoryJobControllerTestBase() override {
339     if (should_check_data_consumed_) {
340       if (quic_data_) {
341         EXPECT_TRUE(quic_data_->AllReadDataConsumed());
342         EXPECT_TRUE(quic_data_->AllWriteDataConsumed());
343       }
344       if (quic_data2_) {
345         EXPECT_TRUE(quic_data2_->AllReadDataConsumed());
346         EXPECT_TRUE(quic_data2_->AllWriteDataConsumed());
347       }
348       if (tcp_data_) {
349         EXPECT_TRUE(tcp_data_->AllReadDataConsumed());
350         EXPECT_TRUE(tcp_data_->AllWriteDataConsumed());
351       }
352       if (tcp_data2_) {
353         EXPECT_TRUE(tcp_data2_->AllReadDataConsumed());
354         EXPECT_TRUE(tcp_data2_->AllWriteDataConsumed());
355       }
356     }
357   }
358 
SetAlternativeService(const HttpRequestInfo & request_info,AlternativeService alternative_service)359   void SetAlternativeService(const HttpRequestInfo& request_info,
360                              AlternativeService alternative_service) {
361     url::SchemeHostPort server(request_info.url);
362     base::Time expiration = base::Time::Now() + base::Days(1);
363     if (alternative_service.protocol == kProtoQUIC) {
364       session_->http_server_properties()->SetQuicAlternativeService(
365           server, NetworkAnonymizationKey(), alternative_service, expiration,
366           quic_context_.params()->supported_versions);
367     } else {
368       session_->http_server_properties()->SetHttp2AlternativeService(
369           server, NetworkAnonymizationKey(), alternative_service, expiration);
370     }
371   }
372 
VerifyBrokenAlternateProtocolMapping(const HttpRequestInfo & request_info,bool should_mark_broken)373   void VerifyBrokenAlternateProtocolMapping(const HttpRequestInfo& request_info,
374                                             bool should_mark_broken) {
375     const url::SchemeHostPort server(request_info.url);
376     const AlternativeServiceInfoVector alternative_service_info_vector =
377         session_->http_server_properties()->GetAlternativeServiceInfos(
378             server, NetworkAnonymizationKey());
379     EXPECT_EQ(1u, alternative_service_info_vector.size());
380     EXPECT_EQ(should_mark_broken,
381               session_->http_server_properties()->IsAlternativeServiceBroken(
382                   alternative_service_info_vector[0].alternative_service(),
383                   NetworkAnonymizationKey()));
384   }
385 
SetAsyncQuicSession(bool async_quic_session)386   void SetAsyncQuicSession(bool async_quic_session) {
387     std::vector<base::test::FeatureRef> enabled_features = {};
388     if (dns_https_alpn_enabled_) {
389       enabled_features.push_back(features::kUseDnsHttpsSvcbAlpn);
390     }
391     if (async_quic_session) {
392       feature_list_.Reset();
393       enabled_features.push_back(features::kAsyncQuicSession);
394       feature_list_.InitWithFeatures(enabled_features, {});
395     } else {
396       feature_list_.Reset();
397       feature_list_.InitWithFeatures(enabled_features,
398                                      {features::kAsyncQuicSession});
399     }
400   }
401 
402   void TestAltJobSucceedsAfterMainJobFailed(
403       bool alt_job_retried_on_non_default_network,
404       bool async_quic_session);
405   void TestMainJobSucceedsAfterAltJobFailed(
406       bool alt_job_retried_on_non_default_network,
407       bool async_quic_session);
408   void TestMainJobSucceedsAfterIgnoredError(int net_error,
409                                             bool async_quic_session,
410                                             bool expect_broken = false,
411                                             std::string alternate_host = "");
412   void TestAltJobSucceedsAfterMainJobSucceeded(
413       bool alt_job_retried_on_non_default_network,
414       bool async_quic_session);
415   void TestOnStreamFailedForBothJobs(
416       bool alt_job_retried_on_non_default_network,
417       bool async_quic_session);
418   void TestAltJobFailsAfterMainJobSucceeded(
419       bool alt_job_retried_on_non_default_network,
420       bool async_quic_session);
421   void TestMainJobSucceedsAfterAltJobSucceeded(
422       bool alt_job_retried_on_non_default_network,
423       bool async_quic_session);
424   void TestMainJobFailsAfterAltJobSucceeded(
425       bool alt_job_retried_on_non_default_network,
426       bool async_quic_session);
427   void TestAltSvcVersionSelection(
428       const std::string& alt_svc_header,
429       const quic::ParsedQuicVersion& expected_version,
430       const quic::ParsedQuicVersionVector& supported_versions);
431   void TestResumeMainJobWhenAltJobStalls(bool async_quic_session);
432   void TestAltJobSucceedsMainJobDestroyed(bool async_quic_session);
433   void TestOrphanedJobCompletesControllerDestroyed(bool async_quic_session);
434   void TestDoNotDelayMainJobIfQuicWasRecentlyBroken(bool async_quic_session);
435   void TestDelayMainJobAfterRecentlyBrokenQuicWasConfirmed(
436       bool async_quic_session);
437   void TestDoNotDelayMainJobIfHasAvailableSpdySession(bool async_quic_session);
438 
dns_https_alpn_enabled() const439   bool dns_https_alpn_enabled() const { return dns_https_alpn_enabled_; }
440 
441   quic::ParsedQuicVersion version_ = DefaultSupportedQuicVersions().front();
442   RecordingNetLogObserver net_log_observer_;
443   NetLogWithSource net_log_with_source_{
444       NetLogWithSource::Make(NetLogSourceType::NONE)};
445   TestJobFactory job_factory_;
446   MockHttpStreamRequestDelegate request_delegate_;
447   MockQuicContext quic_context_;
448   SpdySessionDependencies session_deps_;
449   std::unique_ptr<HttpNetworkSession> session_;
450   raw_ptr<HttpStreamFactory> factory_ = nullptr;
451   raw_ptr<HttpStreamFactory::JobController, AcrossTasksDanglingUntriaged>
452       job_controller_ = nullptr;
453   std::unique_ptr<HttpStreamRequest> request_;
454   std::unique_ptr<SequencedSocketData> tcp_data_;
455   std::unique_ptr<SequencedSocketData> tcp_data2_;
456   std::unique_ptr<MockQuicData> quic_data_;
457   std::unique_ptr<MockQuicData> quic_data2_;
458   MockCryptoClientStreamFactory crypto_client_stream_factory_;
459   QuicTestPacketMaker client_maker_{version_,
460                                     quic::QuicUtils::CreateRandomConnectionId(
461                                         quic_context_.random_generator()),
462                                     quic_context_.clock(),
463                                     kServerHostname,
464                                     quic::Perspective::IS_CLIENT,
465                                     false};
466 
467  protected:
468   bool is_preconnect_ = false;
469   bool enable_ip_based_pooling_ = true;
470   bool enable_alternative_services_ = true;
471   bool delay_main_job_with_available_spdy_session_ = true;
472   bool should_check_data_consumed_ = true;
473 
474  private:
475   bool dns_https_alpn_enabled_;
476   bool create_job_controller_ = true;
477 
478   base::test::ScopedFeatureList feature_list_;
479 };
480 
481 class HttpStreamFactoryJobControllerTest
482     : public HttpStreamFactoryJobControllerTestBase,
483       public ::testing::WithParamInterface<bool> {
484  protected:
HttpStreamFactoryJobControllerTest()485   HttpStreamFactoryJobControllerTest()
486       : HttpStreamFactoryJobControllerTestBase(GetParam()) {}
487 };
488 
489 INSTANTIATE_TEST_SUITE_P(All,
490                          HttpStreamFactoryJobControllerTest,
491                          testing::Bool());
492 
TEST_P(HttpStreamFactoryJobControllerTest,ProxyResolutionFailsSync)493 TEST_P(HttpStreamFactoryJobControllerTest, ProxyResolutionFailsSync) {
494   ProxyConfig proxy_config;
495   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
496   proxy_config.set_pac_mandatory(true);
497   session_deps_.proxy_resolution_service =
498       std::make_unique<ConfiguredProxyResolutionService>(
499 
500           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
501               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
502           std::make_unique<FailingProxyResolverFactory>(), nullptr,
503           /*quick_check_enabled=*/true);
504   HttpRequestInfo request_info;
505   request_info.method = "GET";
506   request_info.url = GURL("http://www.google.com");
507 
508   Initialize(request_info);
509 
510   EXPECT_CALL(request_delegate_,
511               OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _, _, _))
512       .Times(1);
513   request_ =
514       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
515                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
516 
517   EXPECT_FALSE(job_controller_->main_job());
518   EXPECT_FALSE(job_controller_->alternative_job());
519 
520   // Make sure calling GetLoadState() when before job creation does not crash.
521   // Regression test for crbug.com/723920.
522   EXPECT_EQ(LOAD_STATE_IDLE, job_controller_->GetLoadState());
523 
524   base::RunLoop().RunUntilIdle();
525   request_.reset();
526   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
527 }
528 
TEST_P(HttpStreamFactoryJobControllerTest,ProxyResolutionFailsAsync)529 TEST_P(HttpStreamFactoryJobControllerTest, ProxyResolutionFailsAsync) {
530   ProxyConfig proxy_config;
531   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
532   proxy_config.set_pac_mandatory(true);
533   auto proxy_resolver_factory =
534       std::make_unique<MockAsyncProxyResolverFactory>(false);
535   auto* proxy_resolver_factory_ptr = proxy_resolver_factory.get();
536   MockAsyncProxyResolver resolver;
537   session_deps_.proxy_resolution_service =
538       std::make_unique<ConfiguredProxyResolutionService>(
539 
540           std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
541               proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
542           std::move(proxy_resolver_factory), nullptr,
543           /*quick_check_enabled=*/true);
544   HttpRequestInfo request_info;
545   request_info.method = "GET";
546   request_info.url = GURL("http://www.google.com");
547 
548   Initialize(request_info);
549 
550   request_ =
551       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
552                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
553 
554   EXPECT_FALSE(job_controller_->main_job());
555   EXPECT_FALSE(job_controller_->alternative_job());
556 
557   EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL,
558             job_controller_->GetLoadState());
559 
560   EXPECT_CALL(request_delegate_,
561               OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _, _, _))
562       .Times(1);
563   proxy_resolver_factory_ptr->pending_requests()[0]->CompleteNowWithForwarder(
564       ERR_FAILED, &resolver);
565   base::RunLoop().RunUntilIdle();
566   request_.reset();
567   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
568 }
569 
TEST_P(HttpStreamFactoryJobControllerTest,NoSupportedProxies)570 TEST_P(HttpStreamFactoryJobControllerTest, NoSupportedProxies) {
571   session_deps_.proxy_resolution_service =
572       ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
573           {ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC,
574                                              "myproxy.org", 443)},
575           TRAFFIC_ANNOTATION_FOR_TESTS);
576   session_deps_.enable_quic = false;
577   HttpRequestInfo request_info;
578   request_info.method = "GET";
579   request_info.url = GURL("http://www.google.com");
580 
581   Initialize(request_info);
582 
583   EXPECT_CALL(request_delegate_,
584               OnStreamFailed(ERR_NO_SUPPORTED_PROXIES, _, _, _))
585       .Times(1);
586   request_ =
587       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
588                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
589 
590   EXPECT_FALSE(job_controller_->main_job());
591   EXPECT_FALSE(job_controller_->alternative_job());
592 
593   base::RunLoop().RunUntilIdle();
594   request_.reset();
595   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
596 }
597 
598 class JobControllerReconsiderProxyAfterErrorTest
599     : public HttpStreamFactoryJobControllerTestBase {
600  public:
JobControllerReconsiderProxyAfterErrorTest()601   JobControllerReconsiderProxyAfterErrorTest()
602       : HttpStreamFactoryJobControllerTestBase(false) {}
Initialize(std::unique_ptr<ProxyResolutionService> proxy_resolution_service,std::unique_ptr<ProxyDelegate> proxy_delegate=nullptr)603   void Initialize(
604       std::unique_ptr<ProxyResolutionService> proxy_resolution_service,
605       std::unique_ptr<ProxyDelegate> proxy_delegate = nullptr) {
606     session_deps_.proxy_delegate = std::move(proxy_delegate);
607     session_deps_.proxy_resolution_service =
608         std::move(proxy_resolution_service);
609     session_deps_.proxy_resolution_service->SetProxyDelegate(
610         session_deps_.proxy_delegate.get());
611     session_ = std::make_unique<HttpNetworkSession>(
612         SpdySessionDependencies::CreateSessionParams(&session_deps_),
613         SpdySessionDependencies::CreateSessionContext(&session_deps_));
614     factory_ = session_->http_stream_factory();
615   }
616 
CreateJobController(const HttpRequestInfo & request_info)617   std::unique_ptr<HttpStreamRequest> CreateJobController(
618       const HttpRequestInfo& request_info) {
619     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
620         factory_, &request_delegate_, session_.get(), &default_job_factory_,
621         request_info, is_preconnect_, /*is_websocket=*/false,
622         enable_ip_based_pooling_, enable_alternative_services_,
623         delay_main_job_with_available_spdy_session_,
624         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
625     auto* job_controller_ptr = job_controller.get();
626     HttpStreamFactoryPeer::AddJobController(factory_,
627                                             std::move(job_controller));
628     return job_controller_ptr->Start(
629         &request_delegate_, nullptr, net_log_with_source_,
630         HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
631   }
632 
633  private:
634   // Use real Jobs so that Job::Resume() is not mocked out. When main job is
635   // resumed it will use mock socket data.
636   HttpStreamFactory::JobFactory default_job_factory_;
637 };
638 
639 // Test proxy fallback logic in the case connecting through an HTTP proxy.
640 //
641 // TODO(eroman): The testing should be expanded to test cases where proxy
642 //               fallback is NOT supposed to occur, and also vary across all of
643 //               the proxy types.
TEST_F(JobControllerReconsiderProxyAfterErrorTest,ReconsiderProxyAfterErrorHttpProxy)644 TEST_F(JobControllerReconsiderProxyAfterErrorTest,
645        ReconsiderProxyAfterErrorHttpProxy) {
646   enum class ErrorPhase {
647     kHostResolution,
648     kTcpConnect,
649     kTunnelRead,
650   };
651 
652   const struct {
653     ErrorPhase phase;
654     net::Error error;
655   } kRetriableErrors[] = {
656       // These largely correspond to the list of errors in
657       // CanFalloverToNextProxy() which can occur with an HTTP proxy.
658       //
659       // We omit `ERR_CONNECTION_CLOSED` because it is largely unreachable. The
660       // HTTP/1.1 parser maps it to `ERR_EMPTY_RESPONSE` or
661       // `ERR_RESPONSE_HEADERS_TRUNCATED` in most cases.
662       //
663       // TODO(davidben): Is omitting `ERR_EMPTY_RESPONSE` a bug in proxy error
664       // handling?
665       {ErrorPhase::kHostResolution, ERR_NAME_NOT_RESOLVED},
666       {ErrorPhase::kTcpConnect, ERR_ADDRESS_UNREACHABLE},
667       {ErrorPhase::kTcpConnect, ERR_CONNECTION_TIMED_OUT},
668       {ErrorPhase::kTcpConnect, ERR_CONNECTION_RESET},
669       {ErrorPhase::kTcpConnect, ERR_CONNECTION_ABORTED},
670       {ErrorPhase::kTcpConnect, ERR_CONNECTION_REFUSED},
671       {ErrorPhase::kTunnelRead, ERR_TIMED_OUT},
672       {ErrorPhase::kTunnelRead, ERR_SSL_PROTOCOL_ERROR},
673   };
674 
675   for (GURL dest_url :
676        {GURL("http://www.example.com"), GURL("https://www.example.com")}) {
677     SCOPED_TRACE(dest_url);
678 
679     for (const auto& mock_error : kRetriableErrors) {
680       SCOPED_TRACE(ErrorToString(mock_error.error));
681 
682       CreateSessionDeps();
683 
684       std::unique_ptr<ConfiguredProxyResolutionService>
685           proxy_resolution_service =
686               ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
687                   "PROXY badproxy:99; PROXY badfallbackproxy:98; DIRECT",
688                   TRAFFIC_ANNOTATION_FOR_TESTS);
689       auto test_proxy_delegate = std::make_unique<TestProxyDelegate>();
690       test_proxy_delegate->set_extra_header_name("Foo");
691 
692       // Before starting the test, verify that there are no proxies marked as
693       // bad.
694       ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty());
695 
696       constexpr char kBadProxyTunnelRequest[] =
697           "CONNECT www.example.com:443 HTTP/1.1\r\n"
698           "Host: www.example.com:443\r\n"
699           "Proxy-Connection: keep-alive\r\n"
700           "Foo: badproxy:99\r\n\r\n";
701       constexpr char kBadFallbackProxyTunnelRequest[] =
702           "CONNECT www.example.com:443 HTTP/1.1\r\n"
703           "Host: www.example.com:443\r\n"
704           "Proxy-Connection: keep-alive\r\n"
705           "Foo: badfallbackproxy:98\r\n\r\n";
706       const MockWrite kBadProxyTunnelWrites[] = {
707           {ASYNC, kBadProxyTunnelRequest}};
708       const MockWrite kBadFallbackProxyTunnelWrites[] = {
709           {ASYNC, kBadFallbackProxyTunnelRequest}};
710       std::vector<MockRead> reads;
711 
712       // Generate identical errors for both the main proxy and the fallback
713       // proxy. No alternative job is created for either, so only need one data
714       // provider for each, when the request makes it to the socket layer.
715       std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job;
716       std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job2;
717       switch (mock_error.phase) {
718         case ErrorPhase::kHostResolution:
719           // Only ERR_NAME_NOT_RESOLVED can be returned by the mock host
720           // resolver.
721           DCHECK_EQ(ERR_NAME_NOT_RESOLVED, mock_error.error);
722           session_deps_.host_resolver->rules()->AddSimulatedFailure("badproxy");
723           session_deps_.host_resolver->rules()->AddSimulatedFailure(
724               "badfallbackproxy");
725           break;
726         case ErrorPhase::kTcpConnect:
727           socket_data_proxy_main_job =
728               std::make_unique<StaticSocketDataProvider>();
729           socket_data_proxy_main_job->set_connect_data(
730               MockConnect(ASYNC, mock_error.error));
731           socket_data_proxy_main_job2 =
732               std::make_unique<StaticSocketDataProvider>();
733           socket_data_proxy_main_job2->set_connect_data(
734               MockConnect(ASYNC, mock_error.error));
735           break;
736         case ErrorPhase::kTunnelRead:
737           // Tunnels aren't established for HTTP destinations.
738           if (dest_url.SchemeIs(url::kHttpScheme)) {
739             continue;
740           }
741           reads.emplace_back(ASYNC, mock_error.error);
742           socket_data_proxy_main_job =
743               std::make_unique<StaticSocketDataProvider>(reads,
744                                                          kBadProxyTunnelWrites);
745           socket_data_proxy_main_job2 =
746               std::make_unique<StaticSocketDataProvider>(
747                   reads, kBadFallbackProxyTunnelWrites);
748           break;
749       }
750 
751       if (socket_data_proxy_main_job) {
752         session_deps_.socket_factory->AddSocketDataProvider(
753             socket_data_proxy_main_job.get());
754         session_deps_.socket_factory->AddSocketDataProvider(
755             socket_data_proxy_main_job2.get());
756       }
757 
758       // After both proxies fail, the request should fall back to using DIRECT,
759       // and succeed.
760       SSLSocketDataProvider ssl_data_first_request(ASYNC, OK);
761       StaticSocketDataProvider socket_data_direct_first_request;
762       socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
763       session_deps_.socket_factory->AddSocketDataProvider(
764           &socket_data_direct_first_request);
765       // Only used in the HTTPS destination case, but harmless in the HTTP case.
766       session_deps_.socket_factory->AddSSLSocketDataProvider(
767           &ssl_data_first_request);
768 
769       // Second request should use DIRECT, skipping the bad proxies, and
770       // succeed.
771       SSLSocketDataProvider ssl_data_second_request(ASYNC, OK);
772       StaticSocketDataProvider socket_data_direct_second_request;
773       socket_data_direct_second_request.set_connect_data(
774           MockConnect(ASYNC, OK));
775       session_deps_.socket_factory->AddSocketDataProvider(
776           &socket_data_direct_second_request);
777       // Only used in the HTTPS destination case, but harmless in the HTTP case.
778       session_deps_.socket_factory->AddSSLSocketDataProvider(
779           &ssl_data_second_request);
780 
781       // Now request a stream. It should succeed using the DIRECT fallback proxy
782       // option.
783       HttpRequestInfo request_info;
784       request_info.method = "GET";
785       request_info.url = dest_url;
786       Initialize(std::move(proxy_resolution_service),
787                  std::move(test_proxy_delegate));
788 
789       // Start two requests. The first request should consume data from
790       // |socket_data_proxy_main_job| and |socket_data_direct_first_request|.
791       // The second request should consume data from
792       // |socket_data_direct_second_request|.
793 
794       for (size_t i = 0; i < 2; ++i) {
795         ProxyInfo used_proxy_info;
796         EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
797             .Times(1)
798             .WillOnce(::testing::SaveArg<0>(&used_proxy_info));
799 
800         std::unique_ptr<HttpStreamRequest> request =
801             CreateJobController(request_info);
802         RunUntilIdle();
803 
804         // Verify that request was fetched without proxy.
805         EXPECT_TRUE(used_proxy_info.is_direct());
806 
807         // The proxies that failed should now be known to the proxy service as
808         // bad.
809         const ProxyRetryInfoMap& retry_info =
810             session_->proxy_resolution_service()->proxy_retry_info();
811         ASSERT_THAT(retry_info, SizeIs(2));
812         EXPECT_THAT(retry_info, Contains(Key(ProxyUriToProxyChain(
813                                     "badproxy:99", ProxyServer::SCHEME_HTTP))));
814         EXPECT_THAT(retry_info,
815                     Contains(Key(ProxyUriToProxyChain(
816                         "badfallbackproxy:98", ProxyServer::SCHEME_HTTP))));
817 
818         // The idle socket should have been added back to the socket pool. Close
819         // it, so the next loop iteration creates a new socket instead of
820         // reusing the idle one.
821         auto* socket_pool = session_->GetSocketPool(
822             HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
823         EXPECT_EQ(1, socket_pool->IdleSocketCount());
824         socket_pool->CloseIdleSockets("Close socket reason");
825       }
826       EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
827     }
828   }
829 }
830 
831 // Test proxy fallback logic in the case connecting through an HTTPS proxy.
TEST_F(JobControllerReconsiderProxyAfterErrorTest,ReconsiderProxyAfterErrorHttpsProxy)832 TEST_F(JobControllerReconsiderProxyAfterErrorTest,
833        ReconsiderProxyAfterErrorHttpsProxy) {
834   enum class ErrorPhase {
835     kHostResolution,
836     kTcpConnect,
837     kProxySslHandshake,
838     kTunnelRead,
839   };
840 
841   const struct {
842     ErrorPhase phase;
843     net::Error error;
844     // Each test case simulates a connection attempt through a proxy that fails
845     // twice, followed by two connection attempts that succeed. For most cases,
846     // this is done by having a connection attempt to the first proxy fail,
847     // triggering fallback to a second proxy, which also fails, and then
848     // fallback to the final (DIRECT) proxy option. However, SslConnectJobs have
849     // their own try logic in certain cases. This value is true for those cases,
850     // in which case there are two connection attempts to the first proxy, and
851     // then the requests fall back to the second (DIRECT) proxy.
852     bool triggers_ssl_connect_job_retry_logic = false;
853   } kRetriableErrors[] = {
854       // These largely correspond to the list of errors in
855       // CanFalloverToNextProxy() which can occur with an HTTPS proxy.
856       //
857       // We omit `ERR_CONNECTION_CLOSED` because it is largely unreachable. The
858       // HTTP/1.1 parser maps it to `ERR_EMPTY_RESPONSE` or
859       // `ERR_RESPONSE_HEADERS_TRUNCATED` in most cases.
860       //
861       // TODO(davidben): Is omitting `ERR_EMPTY_RESPONSE` a bug in proxy error
862       // handling?
863       {ErrorPhase::kHostResolution, ERR_NAME_NOT_RESOLVED},
864       {ErrorPhase::kTcpConnect, ERR_ADDRESS_UNREACHABLE},
865       {ErrorPhase::kTcpConnect, ERR_CONNECTION_TIMED_OUT},
866       {ErrorPhase::kTcpConnect, ERR_CONNECTION_RESET},
867       {ErrorPhase::kTcpConnect, ERR_CONNECTION_ABORTED},
868       {ErrorPhase::kTcpConnect, ERR_CONNECTION_REFUSED},
869       {ErrorPhase::kProxySslHandshake, ERR_CERT_COMMON_NAME_INVALID},
870       {ErrorPhase::kProxySslHandshake, ERR_SSL_PROTOCOL_ERROR,
871        /*triggers_ssl_connect_job_retry_logic=*/true},
872       {ErrorPhase::kTunnelRead, ERR_TIMED_OUT},
873       {ErrorPhase::kTunnelRead, ERR_SSL_PROTOCOL_ERROR},
874   };
875 
876   for (GURL dest_url :
877        {GURL("http://www.example.com"), GURL("https://www.example.com")}) {
878     SCOPED_TRACE(dest_url);
879 
880     for (const auto& mock_error : kRetriableErrors) {
881       SCOPED_TRACE(ErrorToString(mock_error.error));
882 
883       CreateSessionDeps();
884 
885       std::unique_ptr<ConfiguredProxyResolutionService>
886           proxy_resolution_service =
887               ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
888                   "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT",
889                   TRAFFIC_ANNOTATION_FOR_TESTS);
890       if (mock_error.triggers_ssl_connect_job_retry_logic) {
891         proxy_resolution_service =
892             ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
893                 "HTTPS badproxy:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);
894       }
895       auto test_proxy_delegate = std::make_unique<TestProxyDelegate>();
896       test_proxy_delegate->set_extra_header_name("Foo");
897 
898       // Before starting the test, verify that there are no proxies marked as
899       // bad.
900       ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty());
901 
902       constexpr char kBadProxyTunnelRequest[] =
903           "CONNECT www.example.com:443 HTTP/1.1\r\n"
904           "Host: www.example.com:443\r\n"
905           "Proxy-Connection: keep-alive\r\n"
906           "Foo: https://badproxy:99\r\n\r\n";
907       constexpr char kBadFallbackProxyTunnelRequest[] =
908           "CONNECT www.example.com:443 HTTP/1.1\r\n"
909           "Host: www.example.com:443\r\n"
910           "Proxy-Connection: keep-alive\r\n"
911           "Foo: https://badfallbackproxy:98\r\n\r\n";
912       const MockWrite kBadProxyTunnelWrites[] = {
913           {ASYNC, kBadProxyTunnelRequest}};
914       const MockWrite kBadFallbackProxyTunnelWrites[] = {
915           {ASYNC, kBadFallbackProxyTunnelRequest}};
916       std::vector<MockRead> reads;
917 
918       // Generate identical errors for both the main proxy and the fallback
919       // proxy. No alternative job is created for either, so only need one data
920       // provider for each, when the request makes it to the socket layer.
921       std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job;
922       std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job;
923       std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job2;
924       std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job2;
925       switch (mock_error.phase) {
926         case ErrorPhase::kHostResolution:
927           // Only ERR_NAME_NOT_RESOLVED can be returned by the mock host
928           // resolver.
929           DCHECK_EQ(ERR_NAME_NOT_RESOLVED, mock_error.error);
930           session_deps_.host_resolver->rules()->AddSimulatedFailure("badproxy");
931           session_deps_.host_resolver->rules()->AddSimulatedFailure(
932               "badfallbackproxy");
933           break;
934         case ErrorPhase::kTcpConnect:
935           socket_data_proxy_main_job =
936               std::make_unique<StaticSocketDataProvider>();
937           socket_data_proxy_main_job->set_connect_data(
938               MockConnect(ASYNC, mock_error.error));
939           socket_data_proxy_main_job2 =
940               std::make_unique<StaticSocketDataProvider>();
941           socket_data_proxy_main_job2->set_connect_data(
942               MockConnect(ASYNC, mock_error.error));
943           break;
944         case ErrorPhase::kProxySslHandshake:
945           socket_data_proxy_main_job =
946               std::make_unique<StaticSocketDataProvider>();
947           ssl_data_proxy_main_job =
948               std::make_unique<SSLSocketDataProvider>(ASYNC, mock_error.error);
949           socket_data_proxy_main_job2 =
950               std::make_unique<StaticSocketDataProvider>();
951           ssl_data_proxy_main_job2 =
952               std::make_unique<SSLSocketDataProvider>(ASYNC, mock_error.error);
953           break;
954         case ErrorPhase::kTunnelRead:
955           // Tunnels aren't established for HTTP destinations.
956           if (dest_url.SchemeIs(url::kHttpScheme)) {
957             continue;
958           }
959           reads.emplace_back(ASYNC, mock_error.error);
960           socket_data_proxy_main_job =
961               std::make_unique<StaticSocketDataProvider>(reads,
962                                                          kBadProxyTunnelWrites);
963           ssl_data_proxy_main_job =
964               std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
965           socket_data_proxy_main_job2 =
966               std::make_unique<StaticSocketDataProvider>(
967                   reads, mock_error.triggers_ssl_connect_job_retry_logic
968                              ? kBadProxyTunnelWrites
969                              : kBadFallbackProxyTunnelWrites);
970           ssl_data_proxy_main_job2 =
971               std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
972           break;
973       }
974 
975       if (socket_data_proxy_main_job) {
976         session_deps_.socket_factory->AddSocketDataProvider(
977             socket_data_proxy_main_job.get());
978         session_deps_.socket_factory->AddSocketDataProvider(
979             socket_data_proxy_main_job2.get());
980       }
981       if (ssl_data_proxy_main_job) {
982         session_deps_.socket_factory->AddSSLSocketDataProvider(
983             ssl_data_proxy_main_job.get());
984         session_deps_.socket_factory->AddSSLSocketDataProvider(
985             ssl_data_proxy_main_job2.get());
986       }
987 
988       // After both proxies fail, the request should fall back to using DIRECT,
989       // and succeed.
990       SSLSocketDataProvider ssl_data_first_request(ASYNC, OK);
991       StaticSocketDataProvider socket_data_direct_first_request;
992       socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
993       session_deps_.socket_factory->AddSocketDataProvider(
994           &socket_data_direct_first_request);
995       // Only used in the HTTPS destination case, but harmless in the HTTP case.
996       session_deps_.socket_factory->AddSSLSocketDataProvider(
997           &ssl_data_first_request);
998 
999       // Second request should use DIRECT, skipping the bad proxies, and
1000       // succeed.
1001       SSLSocketDataProvider ssl_data_second_request(ASYNC, OK);
1002       StaticSocketDataProvider socket_data_direct_second_request;
1003       socket_data_direct_second_request.set_connect_data(
1004           MockConnect(ASYNC, OK));
1005       session_deps_.socket_factory->AddSocketDataProvider(
1006           &socket_data_direct_second_request);
1007       // Only used in the HTTPS destination case, but harmless in the HTTP case.
1008       session_deps_.socket_factory->AddSSLSocketDataProvider(
1009           &ssl_data_second_request);
1010 
1011       // Now request a stream. It should succeed using the DIRECT fallback proxy
1012       // option.
1013       HttpRequestInfo request_info;
1014       request_info.method = "GET";
1015       request_info.url = dest_url;
1016 
1017       Initialize(std::move(proxy_resolution_service),
1018                  std::move(test_proxy_delegate));
1019 
1020       // Start two requests. The first request should consume data from
1021       // |socket_data_proxy_main_job| and |socket_data_direct_first_request|.
1022       // The second request should consume data from
1023       // |socket_data_direct_second_request|.
1024 
1025       for (size_t i = 0; i < 2; ++i) {
1026         ProxyInfo used_proxy_info;
1027         EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
1028             .Times(1)
1029             .WillOnce(::testing::SaveArg<0>(&used_proxy_info));
1030 
1031         std::unique_ptr<HttpStreamRequest> request =
1032             CreateJobController(request_info);
1033         RunUntilIdle();
1034 
1035         // Verify that request was fetched without proxy.
1036         EXPECT_TRUE(used_proxy_info.is_direct());
1037 
1038         // The proxies that failed should now be known to the proxy service as
1039         // bad.
1040         const ProxyRetryInfoMap& retry_info =
1041             session_->proxy_resolution_service()->proxy_retry_info();
1042         if (!mock_error.triggers_ssl_connect_job_retry_logic) {
1043           ASSERT_THAT(retry_info, SizeIs(2));
1044           EXPECT_THAT(retry_info,
1045                       Contains(Key(ProxyUriToProxyChain(
1046                           "https://badproxy:99", ProxyServer::SCHEME_HTTP))));
1047           EXPECT_THAT(
1048               retry_info,
1049               Contains(Key(ProxyUriToProxyChain("https://badfallbackproxy:98",
1050                                                 ProxyServer::SCHEME_HTTP))));
1051         } else {
1052           ASSERT_THAT(retry_info, SizeIs(1));
1053           EXPECT_THAT(retry_info,
1054                       Contains(Key(ProxyUriToProxyChain(
1055                           "https://badproxy:99", ProxyServer::SCHEME_HTTP))));
1056         }
1057 
1058         // The idle socket should have been added back to the socket pool. Close
1059         // it, so the next loop iteration creates a new socket instead of
1060         // reusing the idle one.
1061         auto* socket_pool = session_->GetSocketPool(
1062             HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
1063         EXPECT_EQ(1, socket_pool->IdleSocketCount());
1064         socket_pool->CloseIdleSockets("Close socket reason");
1065       }
1066       EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
1067     }
1068   }
1069 }
1070 
1071 // Same as above but using a multi-proxy chain, with errors encountered by the
1072 // first proxy server in the chain.
TEST_F(JobControllerReconsiderProxyAfterErrorTest,ReconsiderProxyAfterFirstNestedProxyErrorHttps)1073 TEST_F(JobControllerReconsiderProxyAfterErrorTest,
1074        ReconsiderProxyAfterFirstNestedProxyErrorHttps) {
1075   enum class ErrorPhase {
1076     kHostResolution,
1077     kTcpConnect,
1078     kProxySslHandshake,
1079     kTunnelRead,
1080   };
1081 
1082   const struct {
1083     ErrorPhase phase;
1084     net::Error error;
1085     // For a description of this field, see the corresponding struct member
1086     // comment in `ReconsiderProxyAfterErrorHttpsProxy`.
1087     bool triggers_ssl_connect_job_retry_logic = false;
1088   } kRetriableErrors[] = {
1089       // These largely correspond to the list of errors in
1090       // CanFalloverToNextProxy() which can occur with an HTTPS proxy.
1091       //
1092       // We omit `ERR_CONNECTION_CLOSED` because it is largely unreachable. The
1093       // HTTP/1.1 parser maps it to `ERR_EMPTY_RESPONSE` or
1094       // `ERR_RESPONSE_HEADERS_TRUNCATED` in most cases.
1095       //
1096       // TODO(davidben): Is omitting `ERR_EMPTY_RESPONSE` a bug in proxy error
1097       // handling?
1098       {ErrorPhase::kHostResolution, ERR_NAME_NOT_RESOLVED},
1099       {ErrorPhase::kTcpConnect, ERR_ADDRESS_UNREACHABLE},
1100       {ErrorPhase::kTcpConnect, ERR_CONNECTION_TIMED_OUT},
1101       {ErrorPhase::kTcpConnect, ERR_CONNECTION_RESET},
1102       {ErrorPhase::kTcpConnect, ERR_CONNECTION_ABORTED},
1103       {ErrorPhase::kTcpConnect, ERR_CONNECTION_REFUSED},
1104       {ErrorPhase::kProxySslHandshake, ERR_CERT_COMMON_NAME_INVALID},
1105       {ErrorPhase::kProxySslHandshake, ERR_SSL_PROTOCOL_ERROR,
1106        /*triggers_ssl_connect_job_retry_logic=*/true},
1107       {ErrorPhase::kTunnelRead, ERR_TIMED_OUT},
1108       {ErrorPhase::kTunnelRead, ERR_SSL_PROTOCOL_ERROR},
1109   };
1110 
1111   const ProxyServer kGoodProxyServer{ProxyServer::SCHEME_HTTPS,
1112                                      HostPortPair("goodproxyserver", 100)};
1113   const ProxyServer kBadProxyServer1{ProxyServer::SCHEME_HTTPS,
1114                                      HostPortPair("badproxyserver", 99)};
1115   const ProxyServer kBadProxyServer2{
1116       ProxyServer::SCHEME_HTTPS, HostPortPair("badfallbackproxyserver", 98)};
1117   const ProxyChain kNestedProxyChain1{{kBadProxyServer1, kGoodProxyServer}};
1118   const ProxyChain kNestedProxyChain2{{kBadProxyServer2, kGoodProxyServer}};
1119 
1120   for (GURL dest_url :
1121        {GURL("http://www.example.com"), GURL("https://www.example.com")}) {
1122     SCOPED_TRACE(dest_url);
1123 
1124     for (const auto& mock_error : kRetriableErrors) {
1125       SCOPED_TRACE(ErrorToString(mock_error.error));
1126 
1127       CreateSessionDeps();
1128 
1129       ProxyList proxy_list;
1130       proxy_list.AddProxyChain(kNestedProxyChain1);
1131       proxy_list.AddProxyChain(kNestedProxyChain2);
1132       proxy_list.AddProxyChain(ProxyChain::Direct());
1133       ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
1134 
1135       std::unique_ptr<ConfiguredProxyResolutionService>
1136           proxy_resolution_service =
1137               ConfiguredProxyResolutionService::CreateFixedForTest(
1138                   ProxyConfigWithAnnotation(proxy_config,
1139                                             TRAFFIC_ANNOTATION_FOR_TESTS));
1140 
1141       if (mock_error.triggers_ssl_connect_job_retry_logic) {
1142         proxy_list.Clear();
1143         proxy_list.AddProxyChain(kNestedProxyChain1);
1144         proxy_list.AddProxyChain(ProxyChain::Direct());
1145         ProxyConfig proxy_config2 = ProxyConfig::CreateForTesting(proxy_list);
1146 
1147         proxy_resolution_service =
1148             ConfiguredProxyResolutionService::CreateFixedForTest(
1149                 ProxyConfigWithAnnotation(proxy_config2,
1150                                           TRAFFIC_ANNOTATION_FOR_TESTS));
1151       }
1152       auto test_proxy_delegate = std::make_unique<TestProxyDelegate>();
1153       test_proxy_delegate->set_extra_header_name("Foo");
1154 
1155       // Before starting the test, verify that there are no proxies marked as
1156       // bad.
1157       ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty());
1158 
1159       constexpr char kBadProxyServer1TunnelRequest[] =
1160           "CONNECT goodproxyserver:100 HTTP/1.1\r\n"
1161           "Host: goodproxyserver:100\r\n"
1162           "Proxy-Connection: keep-alive\r\n"
1163           "Foo: https://badproxyserver:99\r\n\r\n";
1164       constexpr char kBadProxyServer2TunnelRequest[] =
1165           "CONNECT goodproxyserver:100 HTTP/1.1\r\n"
1166           "Host: goodproxyserver:100\r\n"
1167           "Proxy-Connection: keep-alive\r\n"
1168           "Foo: https://badfallbackproxyserver:98\r\n\r\n";
1169       const MockWrite kBadProxyServer1TunnelWrites[] = {
1170           MockWrite(ASYNC, 0, kBadProxyServer1TunnelRequest)};
1171       const MockWrite kBadProxyServer2TunnelWrites[] = {
1172           MockWrite(ASYNC, 0, kBadProxyServer2TunnelRequest)};
1173       std::vector<MockRead> reads;
1174 
1175       // Generate identical errors for the first proxy server in both the main
1176       // proxy chain and the fallback proxy chain. No alternative job is created
1177       // for either, so only need one data provider for each, when the request
1178       // makes it to the socket layer.
1179       std::unique_ptr<SequencedSocketData> socket_data_proxy_main_job;
1180       std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job;
1181       std::unique_ptr<SequencedSocketData> socket_data_proxy_main_job2;
1182       std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job2;
1183       switch (mock_error.phase) {
1184         case ErrorPhase::kHostResolution:
1185           // Only ERR_NAME_NOT_RESOLVED can be returned by the mock host
1186           // resolver.
1187           DCHECK_EQ(ERR_NAME_NOT_RESOLVED, mock_error.error);
1188           session_deps_.host_resolver->rules()->AddSimulatedFailure(
1189               "badproxyserver");
1190           session_deps_.host_resolver->rules()->AddSimulatedFailure(
1191               "badfallbackproxyserver");
1192           break;
1193         case ErrorPhase::kTcpConnect:
1194           socket_data_proxy_main_job = std::make_unique<SequencedSocketData>();
1195           socket_data_proxy_main_job->set_connect_data(
1196               MockConnect(ASYNC, mock_error.error));
1197           socket_data_proxy_main_job2 = std::make_unique<SequencedSocketData>();
1198           socket_data_proxy_main_job2->set_connect_data(
1199               MockConnect(ASYNC, mock_error.error));
1200           break;
1201         case ErrorPhase::kProxySslHandshake:
1202           socket_data_proxy_main_job = std::make_unique<SequencedSocketData>();
1203           ssl_data_proxy_main_job =
1204               std::make_unique<SSLSocketDataProvider>(ASYNC, mock_error.error);
1205           socket_data_proxy_main_job2 = std::make_unique<SequencedSocketData>();
1206           ssl_data_proxy_main_job2 =
1207               std::make_unique<SSLSocketDataProvider>(ASYNC, mock_error.error);
1208           break;
1209         case ErrorPhase::kTunnelRead:
1210           // Note: Unlike for single-proxy chains, tunnels are established for
1211           // HTTP destinations when multi-proxy chains are in use, so simulate
1212           // tunnel read failures in all cases.
1213           reads.emplace_back(MockRead(ASYNC, mock_error.error, 1));
1214           socket_data_proxy_main_job = std::make_unique<SequencedSocketData>(
1215               reads, kBadProxyServer1TunnelWrites);
1216           ssl_data_proxy_main_job =
1217               std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
1218           socket_data_proxy_main_job2 = std::make_unique<SequencedSocketData>(
1219               reads, kBadProxyServer2TunnelWrites);
1220           ssl_data_proxy_main_job2 =
1221               std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
1222           break;
1223       }
1224 
1225       if (socket_data_proxy_main_job) {
1226         session_deps_.socket_factory->AddSocketDataProvider(
1227             socket_data_proxy_main_job.get());
1228         session_deps_.socket_factory->AddSocketDataProvider(
1229             socket_data_proxy_main_job2.get());
1230       }
1231       if (ssl_data_proxy_main_job) {
1232         session_deps_.socket_factory->AddSSLSocketDataProvider(
1233             ssl_data_proxy_main_job.get());
1234         session_deps_.socket_factory->AddSSLSocketDataProvider(
1235             ssl_data_proxy_main_job2.get());
1236       }
1237 
1238       // After both proxy chains fail, the request should fall back to using
1239       // DIRECT, and succeed.
1240       SSLSocketDataProvider ssl_data_first_request(ASYNC, OK);
1241       StaticSocketDataProvider socket_data_direct_first_request;
1242       socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
1243       session_deps_.socket_factory->AddSocketDataProvider(
1244           &socket_data_direct_first_request);
1245       // Only used in the HTTPS destination case, but harmless in the HTTP case.
1246       session_deps_.socket_factory->AddSSLSocketDataProvider(
1247           &ssl_data_first_request);
1248 
1249       // Second request should use DIRECT, skipping the bad proxies, and
1250       // succeed.
1251       SSLSocketDataProvider ssl_data_second_request(ASYNC, OK);
1252       StaticSocketDataProvider socket_data_direct_second_request;
1253       socket_data_direct_second_request.set_connect_data(
1254           MockConnect(ASYNC, OK));
1255       session_deps_.socket_factory->AddSocketDataProvider(
1256           &socket_data_direct_second_request);
1257       session_deps_.socket_factory->AddSSLSocketDataProvider(
1258           &ssl_data_second_request);
1259 
1260       // Now request a stream. It should succeed using the DIRECT fallback proxy
1261       // option.
1262       HttpRequestInfo request_info;
1263       request_info.method = "GET";
1264       request_info.url = dest_url;
1265 
1266       Initialize(std::move(proxy_resolution_service),
1267                  std::move(test_proxy_delegate));
1268 
1269       // Start two requests. The first request should consume data from
1270       // `socket_data_proxy_main_job` and `socket_data_direct_first_request`.
1271       // The second request should consume data from
1272       // `socket_data_direct_second_request`.
1273 
1274       for (size_t i = 0; i < 2; ++i) {
1275         ProxyInfo used_proxy_info;
1276         EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
1277             .Times(1)
1278             .WillOnce(::testing::SaveArg<0>(&used_proxy_info));
1279 
1280         std::unique_ptr<HttpStreamRequest> request =
1281             CreateJobController(request_info);
1282         RunUntilIdle();
1283 
1284         // Verify that request was fetched without proxy.
1285         EXPECT_TRUE(used_proxy_info.is_direct());
1286 
1287         // The proxies that failed should now be known to the proxy service as
1288         // bad.
1289         const ProxyRetryInfoMap& retry_info =
1290             session_->proxy_resolution_service()->proxy_retry_info();
1291         if (!mock_error.triggers_ssl_connect_job_retry_logic) {
1292           ASSERT_THAT(retry_info, SizeIs(2));
1293           EXPECT_THAT(retry_info, Contains(Key(kNestedProxyChain1)));
1294           EXPECT_THAT(retry_info, Contains(Key(kNestedProxyChain2)));
1295         } else {
1296           ASSERT_THAT(retry_info, SizeIs(1));
1297           EXPECT_THAT(retry_info, Contains(Key(kNestedProxyChain1)));
1298         }
1299 
1300         // The idle socket should have been added back to the socket pool. Close
1301         // it, so the next loop iteration creates a new socket instead of
1302         // reusing the idle one.
1303         auto* socket_pool = session_->GetSocketPool(
1304             HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
1305         EXPECT_EQ(1, socket_pool->IdleSocketCount());
1306         socket_pool->CloseIdleSockets("Close socket reason");
1307       }
1308       EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
1309     }
1310   }
1311 }
1312 
1313 // Same as above but using a multi-proxy chain, with errors encountered by the
1314 // second proxy server in the chain.
TEST_F(JobControllerReconsiderProxyAfterErrorTest,ReconsiderProxyAfterSecondNestedProxyErrorHttps)1315 TEST_F(JobControllerReconsiderProxyAfterErrorTest,
1316        ReconsiderProxyAfterSecondNestedProxyErrorHttps) {
1317   enum class ErrorPhase {
1318     // Note: Skip the kHostResolution and kTcpConnect cases for this test since
1319     // those only make sense for connections to the first proxy server.
1320     kProxySslHandshake,
1321     kTunnelRead,
1322   };
1323 
1324   const struct {
1325     ErrorPhase phase;
1326     net::Error error;
1327     // For a description of this field, see the corresponding struct member
1328     // comment in `ReconsiderProxyAfterErrorHttpsProxy`.
1329     bool triggers_ssl_connect_job_retry_logic = false;
1330   } kRetriableErrors[] = {
1331       // These largely correspond to the list of errors in
1332       // CanFalloverToNextProxy() which can occur with an HTTPS proxy.
1333       //
1334       // We omit `ERR_CONNECTION_CLOSED` because it is largely unreachable. The
1335       // HTTP/1.1 parser maps it to `ERR_EMPTY_RESPONSE` or
1336       // `ERR_RESPONSE_HEADERS_TRUNCATED` in most cases.
1337       //
1338       // TODO(davidben): Is omitting `ERR_EMPTY_RESPONSE` a bug in proxy error
1339       // handling?
1340       {ErrorPhase::kProxySslHandshake, ERR_CERT_COMMON_NAME_INVALID},
1341       {ErrorPhase::kProxySslHandshake, ERR_SSL_PROTOCOL_ERROR,
1342        /*triggers_ssl_connect_job_retry_logic=*/true},
1343       {ErrorPhase::kTunnelRead, ERR_TIMED_OUT},
1344       {ErrorPhase::kTunnelRead, ERR_SSL_PROTOCOL_ERROR},
1345   };
1346 
1347   const ProxyServer kGoodProxyServer{ProxyServer::SCHEME_HTTPS,
1348                                      HostPortPair("goodproxyserver", 100)};
1349   const ProxyServer kBadProxyServer1{ProxyServer::SCHEME_HTTPS,
1350                                      HostPortPair("badproxyserver", 99)};
1351   const ProxyServer kBadProxyServer2{
1352       ProxyServer::SCHEME_HTTPS, HostPortPair("badfallbackproxyserver", 98)};
1353   const ProxyChain kNestedProxyChain1{{kGoodProxyServer, kBadProxyServer1}};
1354   const ProxyChain kNestedProxyChain2{{kGoodProxyServer, kBadProxyServer2}};
1355 
1356   for (GURL dest_url :
1357        {GURL("http://www.example.com"), GURL("https://www.example.com")}) {
1358     SCOPED_TRACE(dest_url);
1359 
1360     for (const auto& mock_error : kRetriableErrors) {
1361       SCOPED_TRACE(ErrorToString(mock_error.error));
1362 
1363       CreateSessionDeps();
1364 
1365       ProxyList proxy_list;
1366       proxy_list.AddProxyChain(kNestedProxyChain1);
1367       proxy_list.AddProxyChain(kNestedProxyChain2);
1368       proxy_list.AddProxyChain(ProxyChain::Direct());
1369       ProxyConfig proxy_config = ProxyConfig::CreateForTesting(proxy_list);
1370 
1371       std::unique_ptr<ConfiguredProxyResolutionService>
1372           proxy_resolution_service =
1373               ConfiguredProxyResolutionService::CreateFixedForTest(
1374                   ProxyConfigWithAnnotation(proxy_config,
1375                                             TRAFFIC_ANNOTATION_FOR_TESTS));
1376 
1377       if (mock_error.triggers_ssl_connect_job_retry_logic) {
1378         proxy_list.Clear();
1379         proxy_list.AddProxyChain(kNestedProxyChain1);
1380         proxy_list.AddProxyChain(ProxyChain::Direct());
1381         ProxyConfig proxy_config2 = ProxyConfig::CreateForTesting(proxy_list);
1382 
1383         proxy_resolution_service =
1384             ConfiguredProxyResolutionService::CreateFixedForTest(
1385                 ProxyConfigWithAnnotation(proxy_config2,
1386                                           TRAFFIC_ANNOTATION_FOR_TESTS));
1387       }
1388       auto test_proxy_delegate = std::make_unique<TestProxyDelegate>();
1389       test_proxy_delegate->set_extra_header_name("Foo");
1390 
1391       // Before starting the test, verify that there are no proxies marked as
1392       // bad.
1393       ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty());
1394 
1395       constexpr char kBadProxyServer1TunnelRequest[] =
1396           "CONNECT badproxyserver:99 HTTP/1.1\r\n"
1397           "Host: badproxyserver:99\r\n"
1398           "Proxy-Connection: keep-alive\r\n"
1399           "Foo: https://goodproxyserver:100\r\n\r\n";
1400       constexpr char kBadProxyServer2TunnelRequest[] =
1401           "CONNECT badfallbackproxyserver:98 HTTP/1.1\r\n"
1402           "Host: badfallbackproxyserver:98\r\n"
1403           "Proxy-Connection: keep-alive\r\n"
1404           "Foo: https://goodproxyserver:100\r\n\r\n";
1405       const std::string kBadProxyServer1EndpointTunnelRequest =
1406           base::StringPrintf(
1407               "CONNECT %s HTTP/1.1\r\n"
1408               "Host: %s\r\n"
1409               "Proxy-Connection: keep-alive\r\n"
1410               "Foo: https://badproxyserver:99\r\n\r\n",
1411               HostPortPair::FromURL(dest_url).ToString().c_str(),
1412               HostPortPair::FromURL(dest_url).ToString().c_str());
1413       const std::string kBadProxyServer2EndpointTunnelRequest =
1414           base::StringPrintf(
1415               "CONNECT %s HTTP/1.1\r\n"
1416               "Host: %s\r\n"
1417               "Proxy-Connection: keep-alive\r\n"
1418               "Foo: https://badfallbackproxyserver:98\r\n\r\n",
1419               HostPortPair::FromURL(dest_url).ToString().c_str(),
1420               HostPortPair::FromURL(dest_url).ToString().c_str());
1421       const MockWrite kNestedProxyChain1TunnelWrites[] = {
1422           {ASYNC, kBadProxyServer1TunnelRequest},
1423           {ASYNC, kBadProxyServer1EndpointTunnelRequest.c_str()}};
1424       const MockWrite kNestedProxyChain2TunnelWrites[] = {
1425           {ASYNC, kBadProxyServer2TunnelRequest},
1426           {ASYNC, kBadProxyServer2EndpointTunnelRequest.c_str()}};
1427 
1428       std::vector<MockRead> reads = {
1429           MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1430       };
1431 
1432       // Generate identical errors for the second proxy server in both the main
1433       // proxy chain and the fallback proxy chain. No alternative job is created
1434       // for either, so only need one data provider for each, when the request
1435       // makes it to the socket layer.
1436       std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job;
1437       std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job_server1;
1438       std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job_server2;
1439       std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job2;
1440       std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job2_server1;
1441       std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job2_server2;
1442 
1443       ssl_data_proxy_main_job_server1 =
1444           std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
1445       ssl_data_proxy_main_job2_server1 =
1446           std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
1447 
1448       switch (mock_error.phase) {
1449         case ErrorPhase::kProxySslHandshake:
1450           ssl_data_proxy_main_job_server2 =
1451               std::make_unique<SSLSocketDataProvider>(ASYNC, mock_error.error);
1452           ssl_data_proxy_main_job2_server2 =
1453               std::make_unique<SSLSocketDataProvider>(ASYNC, mock_error.error);
1454           break;
1455         case ErrorPhase::kTunnelRead:
1456           // Note: Unlike for single-proxy chains, tunnels are established for
1457           // HTTP destinations when multi-proxy chains are in use, so simulate
1458           // tunnel read failures in all cases.
1459           reads.emplace_back(ASYNC, mock_error.error);
1460           ssl_data_proxy_main_job_server2 =
1461               std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
1462           ssl_data_proxy_main_job2_server2 =
1463               std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
1464           break;
1465       }
1466       socket_data_proxy_main_job = std::make_unique<StaticSocketDataProvider>(
1467           reads, kNestedProxyChain1TunnelWrites);
1468       socket_data_proxy_main_job2 = std::make_unique<StaticSocketDataProvider>(
1469           reads, mock_error.triggers_ssl_connect_job_retry_logic
1470                      ? kNestedProxyChain1TunnelWrites
1471                      : kNestedProxyChain2TunnelWrites);
1472 
1473       session_deps_.socket_factory->AddSocketDataProvider(
1474           socket_data_proxy_main_job.get());
1475       session_deps_.socket_factory->AddSSLSocketDataProvider(
1476           ssl_data_proxy_main_job_server1.get());
1477       session_deps_.socket_factory->AddSSLSocketDataProvider(
1478           ssl_data_proxy_main_job_server2.get());
1479 
1480       session_deps_.socket_factory->AddSocketDataProvider(
1481           socket_data_proxy_main_job2.get());
1482       session_deps_.socket_factory->AddSSLSocketDataProvider(
1483           ssl_data_proxy_main_job2_server1.get());
1484       session_deps_.socket_factory->AddSSLSocketDataProvider(
1485           ssl_data_proxy_main_job2_server2.get());
1486 
1487       // After both proxy chains fail, the request should fall back to using
1488       // DIRECT, and succeed.
1489       SSLSocketDataProvider ssl_data_first_request(ASYNC, OK);
1490       StaticSocketDataProvider socket_data_direct_first_request;
1491       socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
1492       session_deps_.socket_factory->AddSocketDataProvider(
1493           &socket_data_direct_first_request);
1494       session_deps_.socket_factory->AddSSLSocketDataProvider(
1495           &ssl_data_first_request);
1496 
1497       // Second request should use DIRECT, skipping the bad proxies, and
1498       // succeed.
1499       SSLSocketDataProvider ssl_data_second_request(ASYNC, OK);
1500       StaticSocketDataProvider socket_data_direct_second_request;
1501       socket_data_direct_second_request.set_connect_data(
1502           MockConnect(ASYNC, OK));
1503       session_deps_.socket_factory->AddSocketDataProvider(
1504           &socket_data_direct_second_request);
1505       // Only used in the HTTPS destination case, but harmless in the HTTP case.
1506       session_deps_.socket_factory->AddSSLSocketDataProvider(
1507           &ssl_data_second_request);
1508 
1509       // Now request a stream. It should succeed using the DIRECT fallback proxy
1510       // option.
1511       HttpRequestInfo request_info;
1512       request_info.method = "GET";
1513       request_info.url = dest_url;
1514 
1515       Initialize(std::move(proxy_resolution_service),
1516                  std::move(test_proxy_delegate));
1517 
1518       // Start two requests. The first request should consume data from
1519       // `socket_data_proxy_main_job` and `socket_data_direct_first_request`.
1520       // The second request should consume data from
1521       // `socket_data_direct_second_request`.
1522 
1523       for (size_t i = 0; i < 2; ++i) {
1524         ProxyInfo used_proxy_info;
1525         EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
1526             .Times(1)
1527             .WillOnce(::testing::SaveArg<0>(&used_proxy_info));
1528 
1529         std::unique_ptr<HttpStreamRequest> request =
1530             CreateJobController(request_info);
1531         RunUntilIdle();
1532 
1533         // Verify that request was fetched without proxy.
1534         EXPECT_TRUE(used_proxy_info.is_direct());
1535 
1536         // The proxies that failed should now be known to the proxy service as
1537         // bad.
1538         const ProxyRetryInfoMap& retry_info =
1539             session_->proxy_resolution_service()->proxy_retry_info();
1540         if (!mock_error.triggers_ssl_connect_job_retry_logic) {
1541           ASSERT_THAT(retry_info, SizeIs(2));
1542           EXPECT_THAT(retry_info, Contains(Key(kNestedProxyChain1)));
1543           EXPECT_THAT(retry_info, Contains(Key(kNestedProxyChain2)));
1544         } else {
1545           ASSERT_THAT(retry_info, SizeIs(1));
1546           EXPECT_THAT(retry_info, Contains(Key(kNestedProxyChain1)));
1547         }
1548 
1549         // The idle socket should have been added back to the socket pool. Close
1550         // it, so the next loop iteration creates a new socket instead of
1551         // reusing the idle one.
1552         auto* socket_pool = session_->GetSocketPool(
1553             HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
1554         EXPECT_EQ(1, socket_pool->IdleSocketCount());
1555         socket_pool->CloseIdleSockets("Close socket reason");
1556       }
1557       EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
1558     }
1559   }
1560 }
1561 
1562 // Test proxy fallback logic for an IP Protection request.
TEST_F(JobControllerReconsiderProxyAfterErrorTest,ReconsiderProxyForIpProtection)1563 TEST_F(JobControllerReconsiderProxyAfterErrorTest,
1564        ReconsiderProxyForIpProtection) {
1565   GURL dest_url = GURL("https://www.example.com");
1566 
1567   CreateSessionDeps();
1568 
1569   std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service =
1570       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
1571           "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
1572   auto test_proxy_delegate =
1573       std::make_unique<TestProxyDelegateForIpProtection>();
1574 
1575   // Before starting the test, verify that there are no proxies marked as
1576   // bad.
1577   ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty());
1578 
1579   constexpr char kTunnelRequest[] =
1580       "CONNECT www.example.com:443 HTTP/1.1\r\n"
1581       "Host: www.example.com:443\r\n"
1582       "Proxy-Connection: keep-alive\r\n"
1583       "Authorization: https://ip-pro:443\r\n\r\n";
1584   const MockWrite kTunnelWrites[] = {{ASYNC, kTunnelRequest}};
1585   std::vector<MockRead> reads;
1586 
1587   // Generate errors for the first proxy server.
1588   std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job;
1589   std::unique_ptr<SSLSocketDataProvider> ssl_data_proxy_main_job;
1590   reads.emplace_back(ASYNC, ERR_TUNNEL_CONNECTION_FAILED);
1591   socket_data_proxy_main_job =
1592       std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites);
1593   ssl_data_proxy_main_job = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
1594 
1595   session_deps_.socket_factory->AddSocketDataProvider(
1596       socket_data_proxy_main_job.get());
1597   session_deps_.socket_factory->AddSSLSocketDataProvider(
1598       ssl_data_proxy_main_job.get());
1599 
1600   // After proxying fails, the request should fall back to using DIRECT, and
1601   // succeed.
1602   SSLSocketDataProvider ssl_data_first_request(ASYNC, OK);
1603   StaticSocketDataProvider socket_data_direct_first_request;
1604   socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
1605   session_deps_.socket_factory->AddSocketDataProvider(
1606       &socket_data_direct_first_request);
1607   session_deps_.socket_factory->AddSSLSocketDataProvider(
1608       &ssl_data_first_request);
1609 
1610   HttpRequestInfo request_info;
1611   request_info.method = "GET";
1612   request_info.url = dest_url;
1613 
1614   Initialize(std::move(proxy_resolution_service),
1615              std::move(test_proxy_delegate));
1616 
1617   ProxyInfo used_proxy_info;
1618   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
1619       .Times(1)
1620       .WillOnce(::testing::SaveArg<0>(&used_proxy_info));
1621 
1622   std::unique_ptr<HttpStreamRequest> request =
1623       CreateJobController(request_info);
1624   RunUntilIdle();
1625 
1626   // Verify that request was fetched without proxy.
1627   EXPECT_TRUE(used_proxy_info.is_direct());
1628 }
1629 
1630 // Test proxy fallback logic in the case connecting through socks5 proxy.
TEST_F(JobControllerReconsiderProxyAfterErrorTest,ReconsiderProxyAfterErrorSocks5Proxy)1631 TEST_F(JobControllerReconsiderProxyAfterErrorTest,
1632        ReconsiderProxyAfterErrorSocks5Proxy) {
1633   enum class ErrorPhase {
1634     kHostResolution,
1635     kTcpConnect,
1636     kTunnelRead,
1637   };
1638 
1639   const struct {
1640     ErrorPhase phase;
1641     net::Error error;
1642   } kRetriableErrors[] = {
1643       // These largely correspond to the list of errors in
1644       // CanFalloverToNextProxy() which can occur with an HTTPS proxy.
1645       //
1646       // Unlike HTTP/HTTPS proxies, SOCKS proxies are retried in response to
1647       // `ERR_CONNECTION_CLOSED`.
1648       {ErrorPhase::kHostResolution, ERR_NAME_NOT_RESOLVED},
1649       {ErrorPhase::kTcpConnect, ERR_ADDRESS_UNREACHABLE},
1650       {ErrorPhase::kTcpConnect, ERR_CONNECTION_TIMED_OUT},
1651       {ErrorPhase::kTcpConnect, ERR_CONNECTION_RESET},
1652       {ErrorPhase::kTcpConnect, ERR_CONNECTION_ABORTED},
1653       {ErrorPhase::kTcpConnect, ERR_CONNECTION_REFUSED},
1654       {ErrorPhase::kTunnelRead, ERR_TIMED_OUT},
1655       {ErrorPhase::kTunnelRead, ERR_CONNECTION_CLOSED},
1656   };
1657 
1658   // "host" on port 80 matches the kSOCK5GreetRequest.
1659   const GURL kDestUrl = GURL("http://host:80/");
1660 
1661   for (const auto& mock_error : kRetriableErrors) {
1662     SCOPED_TRACE(ErrorToString(mock_error.error));
1663 
1664     CreateSessionDeps();
1665 
1666     std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service =
1667         ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
1668             "SOCKS5 badproxy:99; SOCKS5 badfallbackproxy:98; DIRECT",
1669             TRAFFIC_ANNOTATION_FOR_TESTS);
1670     auto test_proxy_delegate = std::make_unique<TestProxyDelegate>();
1671 
1672     // Before starting the test, verify that there are no proxies marked as bad.
1673     ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty());
1674     const MockWrite kTunnelWrites[] = {
1675         {ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength}};
1676     std::vector<MockRead> reads;
1677 
1678     // Generate identical errors for both the main proxy and the fallback proxy.
1679     // No alternative job is created for either, so only need one data provider
1680     // for each, when the request makes it to the socket layer.
1681     std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job;
1682     std::unique_ptr<StaticSocketDataProvider> socket_data_proxy_main_job2;
1683     switch (mock_error.phase) {
1684       case ErrorPhase::kHostResolution:
1685         // Only ERR_NAME_NOT_RESOLVED can be returned by the mock host resolver.
1686         DCHECK_EQ(ERR_NAME_NOT_RESOLVED, mock_error.error);
1687         session_deps_.host_resolver->rules()->AddSimulatedFailure("badproxy");
1688         session_deps_.host_resolver->rules()->AddSimulatedFailure(
1689             "badfallbackproxy");
1690         break;
1691       case ErrorPhase::kTcpConnect:
1692         socket_data_proxy_main_job =
1693             std::make_unique<StaticSocketDataProvider>();
1694         socket_data_proxy_main_job->set_connect_data(
1695             MockConnect(ASYNC, mock_error.error));
1696         socket_data_proxy_main_job2 =
1697             std::make_unique<StaticSocketDataProvider>();
1698         socket_data_proxy_main_job2->set_connect_data(
1699             MockConnect(ASYNC, mock_error.error));
1700         break;
1701       case ErrorPhase::kTunnelRead:
1702         reads.emplace_back(ASYNC, mock_error.error);
1703         socket_data_proxy_main_job =
1704             std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites);
1705         socket_data_proxy_main_job2 =
1706             std::make_unique<StaticSocketDataProvider>(reads, kTunnelWrites);
1707         break;
1708     }
1709 
1710     if (socket_data_proxy_main_job) {
1711       session_deps_.socket_factory->AddSocketDataProvider(
1712           socket_data_proxy_main_job.get());
1713       session_deps_.socket_factory->AddSocketDataProvider(
1714           socket_data_proxy_main_job2.get());
1715     }
1716 
1717     // After both proxies fail, the request should fall back to using DIRECT,
1718     // and succeed.
1719     StaticSocketDataProvider socket_data_direct_first_request;
1720     socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
1721     session_deps_.socket_factory->AddSocketDataProvider(
1722         &socket_data_direct_first_request);
1723 
1724     // Second request should use DIRECT, skipping the bad proxies, and succeed.
1725     StaticSocketDataProvider socket_data_direct_second_request;
1726     socket_data_direct_second_request.set_connect_data(MockConnect(ASYNC, OK));
1727     session_deps_.socket_factory->AddSocketDataProvider(
1728         &socket_data_direct_second_request);
1729 
1730     // Now request a stream. It should succeed using the DIRECT fallback proxy
1731     // option.
1732     HttpRequestInfo request_info;
1733     request_info.method = "GET";
1734     request_info.url = kDestUrl;
1735 
1736     Initialize(std::move(proxy_resolution_service),
1737                std::move(test_proxy_delegate));
1738 
1739     // Start two requests. The first request should consume data from
1740     // |socket_data_proxy_main_job| and |socket_data_direct_first_request|. The
1741     // second request should consume data from
1742     // |socket_data_direct_second_request|.
1743 
1744     for (size_t i = 0; i < 2; ++i) {
1745       ProxyInfo used_proxy_info;
1746       EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
1747           .Times(1)
1748           .WillOnce(::testing::SaveArg<0>(&used_proxy_info));
1749 
1750       std::unique_ptr<HttpStreamRequest> request =
1751           CreateJobController(request_info);
1752       RunUntilIdle();
1753 
1754       // Verify that request was fetched without proxy.
1755       EXPECT_TRUE(used_proxy_info.is_direct());
1756 
1757       // The proxies that failed should now be known to the proxy service as
1758       // bad.
1759       const ProxyRetryInfoMap& retry_info =
1760           session_->proxy_resolution_service()->proxy_retry_info();
1761       ASSERT_THAT(retry_info, SizeIs(2));
1762       EXPECT_THAT(retry_info,
1763                   Contains(Key(ProxyUriToProxyChain(
1764                       "socks5://badproxy:99", ProxyServer::SCHEME_SOCKS5))));
1765       EXPECT_THAT(
1766           retry_info,
1767           Contains(Key(ProxyUriToProxyChain("socks5://badfallbackproxy:98",
1768                                             ProxyServer::SCHEME_SOCKS5))));
1769 
1770       // The idle socket should have been added back to the socket pool. Close
1771       // it, so the next loop iteration creates a new socket instead of reusing
1772       // the idle one.
1773       auto* socket_pool = session_->GetSocketPool(
1774           HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct());
1775       EXPECT_EQ(1, socket_pool->IdleSocketCount());
1776       socket_pool->CloseIdleSockets("Close socket reason");
1777     }
1778     EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
1779   }
1780 }
1781 
1782 // Tests that ERR_MSG_TOO_BIG is retryable for QUIC proxy.
TEST_F(JobControllerReconsiderProxyAfterErrorTest,ReconsiderErrMsgTooBig)1783 TEST_F(JobControllerReconsiderProxyAfterErrorTest, ReconsiderErrMsgTooBig) {
1784   auto quic_proxy_chain =
1785       ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
1786           ProxyServer::SCHEME_QUIC, "bad", 99)});
1787   std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service =
1788       ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
1789           {quic_proxy_chain, ProxyChain::Direct()},
1790           TRAFFIC_ANNOTATION_FOR_TESTS);
1791 
1792   // Before starting the test, verify that there are no proxies marked as bad.
1793   ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty());
1794 
1795   // Mock data for the QUIC proxy socket.
1796   StaticSocketDataProvider quic_proxy_socket;
1797   quic_proxy_socket.set_connect_data(MockConnect(ASYNC, ERR_MSG_TOO_BIG));
1798   session_deps_.socket_factory->AddSocketDataProvider(&quic_proxy_socket);
1799 
1800   // Mock data for DIRECT.
1801   StaticSocketDataProvider socket_data_direct;
1802   socket_data_direct.set_connect_data(MockConnect(ASYNC, OK));
1803   session_deps_.socket_factory->AddSocketDataProvider(&socket_data_direct);
1804 
1805   // Now request a stream. It should fall back to DIRECT on ERR_MSG_TOO_BIG.
1806   HttpRequestInfo request_info;
1807   request_info.method = "GET";
1808   request_info.url = GURL("http://www.example.com");
1809 
1810   Initialize(std::move(proxy_resolution_service));
1811 
1812   ProxyInfo used_proxy_info;
1813   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
1814       .Times(1)
1815       .WillOnce(::testing::SaveArg<0>(&used_proxy_info));
1816 
1817   std::unique_ptr<HttpStreamRequest> request =
1818       CreateJobController(request_info);
1819   base::RunLoop().RunUntilIdle();
1820 
1821   EXPECT_TRUE(used_proxy_info.is_direct());
1822   const ProxyRetryInfoMap& retry_info =
1823       session_->proxy_resolution_service()->proxy_retry_info();
1824   EXPECT_THAT(retry_info, SizeIs(1));
1825   EXPECT_THAT(retry_info, Contains(Key(quic_proxy_chain)));
1826 
1827   request.reset();
1828   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
1829 }
1830 
1831 // Same as test above except that this is testing the retry behavior for
1832 // non-QUIC proxy on ERR_MSG_TOO_BIG.
TEST_F(JobControllerReconsiderProxyAfterErrorTest,DoNotReconsiderErrMsgTooBig)1833 TEST_F(JobControllerReconsiderProxyAfterErrorTest,
1834        DoNotReconsiderErrMsgTooBig) {
1835   std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service =
1836       ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
1837           "HTTPS badproxy:99; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);
1838 
1839   // Before starting the test, verify that there are no proxies marked as bad.
1840   ASSERT_TRUE(proxy_resolution_service->proxy_retry_info().empty());
1841 
1842   // Mock data for the HTTPS proxy socket.
1843   static constexpr char kHttpConnect[] =
1844       "CONNECT www.example.com:443 HTTP/1.1\r\n"
1845       "Host: www.example.com:443\r\n"
1846       "Proxy-Connection: keep-alive\r\n\r\n";
1847   const MockWrite kWrites[] = {{ASYNC, kHttpConnect}};
1848   const MockRead kReads[] = {{ASYNC, ERR_MSG_TOO_BIG}};
1849   SSLSocketDataProvider ssl_data(ASYNC, OK);
1850   StaticSocketDataProvider https_proxy_socket(kReads, kWrites);
1851   https_proxy_socket.set_connect_data(MockConnect(ASYNC, OK));
1852   session_deps_.socket_factory->AddSocketDataProvider(&https_proxy_socket);
1853   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
1854 
1855   // Now request a stream. It should not fallback to DIRECT on ERR_MSG_TOO_BIG.
1856   HttpRequestInfo request_info;
1857   request_info.method = "GET";
1858   request_info.url = GURL("https://www.example.com");
1859 
1860   Initialize(std::move(proxy_resolution_service));
1861 
1862   ProxyInfo used_proxy_info;
1863   EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_MSG_TOO_BIG, _, _, _))
1864       .Times(1);
1865 
1866   std::unique_ptr<HttpStreamRequest> request =
1867       CreateJobController(request_info);
1868   base::RunLoop().RunUntilIdle();
1869 
1870   const ProxyRetryInfoMap& retry_info =
1871       session_->proxy_resolution_service()->proxy_retry_info();
1872   EXPECT_THAT(retry_info, SizeIs(0));
1873 
1874   request.reset();
1875   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
1876 }
1877 
TEST_P(HttpStreamFactoryJobControllerTest,OnStreamFailedWithNoAlternativeJob)1878 TEST_P(HttpStreamFactoryJobControllerTest, OnStreamFailedWithNoAlternativeJob) {
1879   tcp_data_ = std::make_unique<SequencedSocketData>();
1880   tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
1881 
1882   HttpRequestInfo request_info;
1883   request_info.method = "GET";
1884   request_info.url = GURL("http://www.google.com");
1885 
1886   Initialize(request_info);
1887 
1888   request_ =
1889       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
1890                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1891 
1892   EXPECT_TRUE(job_controller_->main_job());
1893   EXPECT_FALSE(job_controller_->alternative_job());
1894 
1895   // There's no other alternative job. Thus when stream failed, it should
1896   // notify Request of the stream failure.
1897   EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _, _, _)).Times(1);
1898   base::RunLoop().RunUntilIdle();
1899 }
1900 
TEST_P(HttpStreamFactoryJobControllerTest,OnStreamReadyWithNoAlternativeJob)1901 TEST_P(HttpStreamFactoryJobControllerTest, OnStreamReadyWithNoAlternativeJob) {
1902   tcp_data_ = std::make_unique<SequencedSocketData>();
1903   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
1904 
1905   HttpRequestInfo request_info;
1906   request_info.method = "GET";
1907   request_info.url = GURL("http://www.google.com");
1908 
1909   Initialize(request_info);
1910 
1911   request_ =
1912       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
1913                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1914 
1915   // There's no other alternative job. Thus when a stream is ready, it should
1916   // notify Request.
1917   EXPECT_TRUE(job_controller_->main_job());
1918 
1919   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
1920   base::RunLoop().RunUntilIdle();
1921 }
1922 
1923 // Test we cancel Jobs correctly when the Request is explicitly canceled
1924 // before any Job is bound to Request.
TEST_P(HttpStreamFactoryJobControllerTest,CancelJobsBeforeBinding)1925 TEST_P(HttpStreamFactoryJobControllerTest, CancelJobsBeforeBinding) {
1926   // Use COLD_START to make the alt job pending.
1927   crypto_client_stream_factory_.set_handshake_mode(
1928       MockCryptoClientStream::COLD_START);
1929   quic_data_ = std::make_unique<MockQuicData>(version_);
1930   quic_data_->AddRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED);
1931 
1932   tcp_data_ = std::make_unique<SequencedSocketData>();
1933   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
1934   HttpRequestInfo request_info;
1935   request_info.method = "GET";
1936   request_info.url = GURL("https://www.google.com");
1937 
1938   Initialize(request_info);
1939   url::SchemeHostPort server(request_info.url);
1940   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1941   SetAlternativeService(request_info, alternative_service);
1942 
1943   request_ =
1944       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
1945                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1946   EXPECT_TRUE(job_controller_->main_job());
1947   EXPECT_TRUE(job_controller_->alternative_job());
1948   // Reset the Request will cancel all the Jobs since there's no Job determined
1949   // to serve Request yet and JobController will notify the factory to delete
1950   // itself upon completion.
1951   request_.reset();
1952   // QuicSessionPool::Job::Request will not complete since the Jobs are
1953   // canceled, so there is no need to check if all read data was consumed.
1954   should_check_data_consumed_ = false;
1955   VerifyBrokenAlternateProtocolMapping(request_info, false);
1956   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
1957 }
1958 
1959 // Test that the controller does not create alternative job when the advertised
1960 // versions in AlternativeServiceInfo do not contain any version that is
1961 // supported.
TEST_P(HttpStreamFactoryJobControllerTest,DoNotCreateAltJobIfQuicVersionsUnsupported)1962 TEST_P(HttpStreamFactoryJobControllerTest,
1963        DoNotCreateAltJobIfQuicVersionsUnsupported) {
1964   tcp_data_ = std::make_unique<SequencedSocketData>();
1965   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
1966   HttpRequestInfo request_info;
1967   request_info.method = "GET";
1968   request_info.url = GURL("https://www.google.com");
1969 
1970   Initialize(request_info);
1971   url::SchemeHostPort server(request_info.url);
1972   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1973   base::Time expiration = base::Time::Now() + base::Days(1);
1974   session_->http_server_properties()->SetQuicAlternativeService(
1975       server, NetworkAnonymizationKey(), alternative_service, expiration,
1976       {quic::ParsedQuicVersion::Unsupported()});
1977 
1978   request_ =
1979       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
1980                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1981   EXPECT_TRUE(job_controller_->main_job());
1982   EXPECT_FALSE(job_controller_->alternative_job());
1983 
1984   request_.reset();
1985   VerifyBrokenAlternateProtocolMapping(request_info, false);
1986   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
1987 }
1988 
1989 void HttpStreamFactoryJobControllerTestBase::
TestDoNotDelayMainJobIfQuicWasRecentlyBroken(bool async_quic_session)1990     TestDoNotDelayMainJobIfQuicWasRecentlyBroken(bool async_quic_session) {
1991   SetAsyncQuicSession(async_quic_session);
1992   crypto_client_stream_factory_.set_handshake_mode(
1993       MockCryptoClientStream::COLD_START);
1994   quic_data_ = std::make_unique<MockQuicData>(version_);
1995   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1996   tcp_data_ = std::make_unique<SequencedSocketData>();
1997   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
1998 
1999   HttpRequestInfo request_info;
2000   request_info.method = "GET";
2001   request_info.url = GURL("https://www.google.com");
2002 
2003   Initialize(request_info);
2004   url::SchemeHostPort server(request_info.url);
2005   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2006   base::Time expiration = base::Time::Now() + base::Days(1);
2007   session_->http_server_properties()->SetQuicAlternativeService(
2008       server, NetworkAnonymizationKey(), alternative_service, expiration,
2009       quic_context_.params()->supported_versions);
2010 
2011   // Enable QUIC but mark the alternative service as recently broken.
2012   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
2013   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
2014   session_->http_server_properties()->MarkAlternativeServiceRecentlyBroken(
2015       alternative_service, NetworkAnonymizationKey());
2016 
2017   request_ =
2018       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2019                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2020 
2021   EXPECT_TRUE(job_controller_->main_job());
2022   EXPECT_TRUE(job_controller_->alternative_job());
2023 
2024   // The main job shouldn't have any delay since QUIC was recently broken. Main
2025   // job should still be blocked as alt job has not succeeded or failed at least
2026   // once yet.
2027   EXPECT_EQ(job_controller_->get_main_job_wait_time_for_tests(),
2028             base::TimeDelta());
2029   if (async_quic_session) {
2030     EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
2031   } else {
2032     EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
2033   }
2034   // Make |alternative_job| succeed.
2035   auto http_stream = std::make_unique<HttpBasicStream>(
2036       std::make_unique<ClientSocketHandle>(), false);
2037   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, http_stream.get()));
2038 
2039   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
2040                                       std::move(http_stream));
2041   job_controller_->OnStreamReady(job_factory_.alternative_job());
2042 
2043   base::RunLoop().RunUntilIdle();
2044 
2045   // Check that alternative job is bound while main job is destroyed.
2046   EXPECT_FALSE(job_controller_->main_job());
2047   EXPECT_TRUE(job_controller_->alternative_job());
2048 
2049   request_.reset();
2050   VerifyBrokenAlternateProtocolMapping(request_info, false);
2051   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2052 }
2053 
TEST_P(HttpStreamFactoryJobControllerTest,DoNotDelayMainJobIfQuicWasRecentlyBroken)2054 TEST_P(HttpStreamFactoryJobControllerTest,
2055        DoNotDelayMainJobIfQuicWasRecentlyBroken) {
2056   TestDoNotDelayMainJobIfQuicWasRecentlyBroken(false);
2057 }
2058 
TEST_P(HttpStreamFactoryJobControllerTest,DoNotDelayMainJobIfQuicWasRecentlyBrokenAsyncQuicSession)2059 TEST_P(HttpStreamFactoryJobControllerTest,
2060        DoNotDelayMainJobIfQuicWasRecentlyBrokenAsyncQuicSession) {
2061   TestDoNotDelayMainJobIfQuicWasRecentlyBroken(true);
2062 }
2063 
2064 void HttpStreamFactoryJobControllerTestBase::
TestDelayMainJobAfterRecentlyBrokenQuicWasConfirmed(bool async_quic_session)2065     TestDelayMainJobAfterRecentlyBrokenQuicWasConfirmed(
2066         bool async_quic_session) {
2067   SetAsyncQuicSession(async_quic_session);
2068   crypto_client_stream_factory_.set_handshake_mode(
2069       MockCryptoClientStream::COLD_START);
2070   quic_data_ = std::make_unique<MockQuicData>(version_);
2071   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2072   tcp_data_ = std::make_unique<SequencedSocketData>();
2073   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
2074 
2075   HttpRequestInfo request_info;
2076   request_info.method = "GET";
2077   request_info.url = GURL("https://www.google.com");
2078 
2079   Initialize(request_info);
2080   url::SchemeHostPort server(request_info.url);
2081   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2082   base::Time expiration = base::Time::Now() + base::Days(1);
2083   session_->http_server_properties()->SetQuicAlternativeService(
2084       server, NetworkAnonymizationKey(), alternative_service, expiration,
2085       quic_context_.params()->supported_versions);
2086 
2087   // Enable QUIC but mark the alternative service as recently broken.
2088   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
2089   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
2090   session_->http_server_properties()->MarkAlternativeServiceRecentlyBroken(
2091       alternative_service, NetworkAnonymizationKey());
2092 
2093   // Confirm the alt service.
2094   session_->http_server_properties()->ConfirmAlternativeService(
2095       alternative_service, NetworkAnonymizationKey());
2096 
2097   request_ =
2098       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2099                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2100 
2101   EXPECT_TRUE(job_controller_->main_job());
2102   EXPECT_TRUE(job_controller_->alternative_job());
2103 
2104   // The main job should wait and it should still be blocked because the new
2105   // QUIC session hasn't been created yet. The wait time should be greater than
2106   // 0.
2107   EXPECT_TRUE(job_controller_->ShouldWait(
2108       const_cast<net::HttpStreamFactory::Job*>(job_controller_->main_job())));
2109   if (async_quic_session) {
2110     EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
2111   } else {
2112     EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
2113   }
2114   EXPECT_GE(job_controller_->get_main_job_wait_time_for_tests(),
2115             base::TimeDelta());
2116 
2117   // Make |alternative_job| succeed.
2118   auto http_stream = std::make_unique<HttpBasicStream>(
2119       std::make_unique<ClientSocketHandle>(), false);
2120   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, http_stream.get()));
2121 
2122   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
2123                                       std::move(http_stream));
2124   job_controller_->OnStreamReady(job_factory_.alternative_job());
2125 
2126   base::RunLoop().RunUntilIdle();
2127 
2128   // Check that alternative job is bound while main job is destroyed.
2129   EXPECT_FALSE(job_controller_->main_job());
2130   EXPECT_TRUE(job_controller_->alternative_job());
2131 
2132   request_.reset();
2133   VerifyBrokenAlternateProtocolMapping(request_info, false);
2134   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2135 }
2136 
TEST_P(HttpStreamFactoryJobControllerTest,DelayMainJobAfterRecentlyBrokenQuicWasConfirmed)2137 TEST_P(HttpStreamFactoryJobControllerTest,
2138        DelayMainJobAfterRecentlyBrokenQuicWasConfirmed) {
2139   TestDelayMainJobAfterRecentlyBrokenQuicWasConfirmed(false);
2140 }
2141 
TEST_P(HttpStreamFactoryJobControllerTest,DelayMainJobAfterRecentlyBrokenQuicWasConfirmedAsyncQuicSession)2142 TEST_P(HttpStreamFactoryJobControllerTest,
2143        DelayMainJobAfterRecentlyBrokenQuicWasConfirmedAsyncQuicSession) {
2144   TestDelayMainJobAfterRecentlyBrokenQuicWasConfirmed(true);
2145 }
2146 
TestOnStreamFailedForBothJobs(bool alt_job_retried_on_non_default_network,bool async_quic_session)2147 void HttpStreamFactoryJobControllerTestBase::TestOnStreamFailedForBothJobs(
2148     bool alt_job_retried_on_non_default_network,
2149     bool async_quic_session) {
2150   SetAsyncQuicSession(async_quic_session);
2151   quic_data_ = std::make_unique<MockQuicData>(version_);
2152   quic_data_->AddConnect(ASYNC, ERR_FAILED);
2153   tcp_data_ = std::make_unique<SequencedSocketData>();
2154   tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
2155 
2156   HttpRequestInfo request_info;
2157   request_info.method = "GET";
2158   request_info.url = GURL("https://www.google.com");
2159 
2160   Initialize(request_info);
2161   url::SchemeHostPort server(request_info.url);
2162   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2163   SetAlternativeService(request_info, alternative_service);
2164 
2165   request_ =
2166       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2167                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2168   EXPECT_TRUE(job_controller_->main_job());
2169   EXPECT_TRUE(job_controller_->alternative_job());
2170 
2171   if (alt_job_retried_on_non_default_network) {
2172     // Set the alt job as if it failed on the default network and is retired on
2173     // the alternate network.
2174     JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
2175   }
2176 
2177   if (async_quic_session) {
2178     EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1).WillOnce([this]() {
2179       job_factory_.main_job()->DoResume();
2180     });
2181   }
2182   // The failure of second Job should be reported to Request as there's no more
2183   // pending Job to serve the Request.
2184   EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _, _)).Times(1);
2185   base::RunLoop().RunUntilIdle();
2186   VerifyBrokenAlternateProtocolMapping(request_info, false);
2187   request_.reset();
2188   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2189 }
2190 
2191 // This test verifies that the alternative service is not marked broken if both
2192 // jobs fail, and the alternative job is not retried on the alternate network.
TEST_P(HttpStreamFactoryJobControllerTest,OnStreamFailedForBothJobsWithoutQuicRetry)2193 TEST_P(HttpStreamFactoryJobControllerTest,
2194        OnStreamFailedForBothJobsWithoutQuicRetry) {
2195   TestOnStreamFailedForBothJobs(false, false);
2196 }
2197 
2198 // This test verifies that the alternative service is not marked broken if both
2199 // jobs fail, and the alternative job is retried on the alternate network.
TEST_P(HttpStreamFactoryJobControllerTest,OnStreamFailedForBothJobsWithQuicRetriedOnAlternateNetwork)2200 TEST_P(HttpStreamFactoryJobControllerTest,
2201        OnStreamFailedForBothJobsWithQuicRetriedOnAlternateNetwork) {
2202   TestOnStreamFailedForBothJobs(true, false);
2203 }
2204 
2205 // This test verifies that the alternative service is not marked broken if both
2206 // jobs fail, and the alternative job is not retried on the alternate network.
2207 // This test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,OnStreamFailedForBothJobsWithoutQuicRetryAsyncQuicSession)2208 TEST_P(HttpStreamFactoryJobControllerTest,
2209        OnStreamFailedForBothJobsWithoutQuicRetryAsyncQuicSession) {
2210   TestOnStreamFailedForBothJobs(false, true);
2211 }
2212 
2213 // This test verifies that the alternative service is not marked broken if both
2214 // jobs fail, and the alternative job is retried on the alternate network. This
2215 // test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,OnStreamFailedForBothJobsWithQuicRetriedOnAlternateNetworkAsyncQuicSession)2216 TEST_P(
2217     HttpStreamFactoryJobControllerTest,
2218     OnStreamFailedForBothJobsWithQuicRetriedOnAlternateNetworkAsyncQuicSession) {
2219   TestOnStreamFailedForBothJobs(true, true);
2220 }
2221 
2222 void HttpStreamFactoryJobControllerTestBase::
TestAltJobFailsAfterMainJobSucceeded(bool alt_job_retried_on_non_default_network,bool async_quic_session)2223     TestAltJobFailsAfterMainJobSucceeded(
2224         bool alt_job_retried_on_non_default_network,
2225         bool async_quic_session) {
2226   SetAsyncQuicSession(async_quic_session);
2227   quic_data_ = std::make_unique<MockQuicData>(version_);
2228   quic_data_->AddRead(ASYNC, ERR_FAILED);
2229   crypto_client_stream_factory_.set_handshake_mode(
2230       MockCryptoClientStream::COLD_START);
2231 
2232   tcp_data_ = std::make_unique<SequencedSocketData>();
2233   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
2234   SSLSocketDataProvider ssl_data(SYNCHRONOUS, OK);
2235   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
2236 
2237   HttpRequestInfo request_info;
2238   request_info.method = "GET";
2239   request_info.url = GURL("https://www.google.com");
2240 
2241   Initialize(request_info);
2242   url::SchemeHostPort server(request_info.url);
2243   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2244   SetAlternativeService(request_info, alternative_service);
2245 
2246   request_ =
2247       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2248                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2249   EXPECT_TRUE(job_controller_->main_job());
2250   EXPECT_TRUE(job_controller_->alternative_job());
2251 
2252   if (alt_job_retried_on_non_default_network) {
2253     // Set the alt job as if it failed on the default network and is retired on
2254     // the alternate network.
2255     JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
2256   }
2257 
2258   if (async_quic_session) {
2259     EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1).WillOnce([this]() {
2260       job_factory_.main_job()->DoResume();
2261     });
2262   }
2263   // Main job succeeds, starts serving Request and it should report status
2264   // to Request. The alternative job will mark the main job complete and gets
2265   // orphaned.
2266   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
2267   // JobController shouldn't report the status of second job as request
2268   // is already successfully served.
2269   EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _, _)).Times(0);
2270 
2271   base::RunLoop().RunUntilIdle();
2272 
2273   // Reset the request as it's been successfully served.
2274   request_.reset();
2275   base::RunLoop().RunUntilIdle();
2276   VerifyBrokenAlternateProtocolMapping(request_info, true);
2277   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2278 
2279   // Verify the brokenness is not cleared when the default network changes.
2280   session_->http_server_properties()->OnDefaultNetworkChanged();
2281   VerifyBrokenAlternateProtocolMapping(request_info, true);
2282 }
2283 
2284 // This test verifies that the alternative service is marked broken when the
2285 // alternative job fails on default after the main job succeeded.  The
2286 // brokenness should not be cleared when the default network changes.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobFailsOnDefaultNetworkAfterMainJobSucceeded)2287 TEST_P(HttpStreamFactoryJobControllerTest,
2288        AltJobFailsOnDefaultNetworkAfterMainJobSucceeded) {
2289   TestAltJobFailsAfterMainJobSucceeded(false, false);
2290 }
2291 
2292 // This test verifies that the alternative service is marked broken when the
2293 // alternative job fails on both networks after the main job succeeded.  The
2294 // brokenness should not be cleared when the default network changes.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobFailsOnBothNetworksAfterMainJobSucceeded)2295 TEST_P(HttpStreamFactoryJobControllerTest,
2296        AltJobFailsOnBothNetworksAfterMainJobSucceeded) {
2297   TestAltJobFailsAfterMainJobSucceeded(true, false);
2298 }
2299 
2300 // This test verifies that the alternative service is marked broken when the
2301 // alternative job fails on default after the main job succeeded. The
2302 // brokenness should not be cleared when the default network changes. This test
2303 // uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobFailsOnDefaultNetworkAfterMainJobSucceededAsyncQuicSession)2304 TEST_P(HttpStreamFactoryJobControllerTest,
2305        AltJobFailsOnDefaultNetworkAfterMainJobSucceededAsyncQuicSession) {
2306   TestAltJobFailsAfterMainJobSucceeded(false, true);
2307 }
2308 
2309 // This test verifies that the alternative service is marked broken when the
2310 // alternative job fails on both networks after the main job succeeded.  The
2311 // brokenness should not be cleared when the default network changes. This test
2312 // uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobFailsOnBothNetworksAfterMainJobSucceededAsyncQuicSession)2313 TEST_P(HttpStreamFactoryJobControllerTest,
2314        AltJobFailsOnBothNetworksAfterMainJobSucceededAsyncQuicSession) {
2315   TestAltJobFailsAfterMainJobSucceeded(true, true);
2316 }
2317 
TestAltJobSucceedsMainJobDestroyed(bool async_quic_session)2318 void HttpStreamFactoryJobControllerTestBase::TestAltJobSucceedsMainJobDestroyed(
2319     bool async_quic_session) {
2320   SetAsyncQuicSession(async_quic_session);
2321   quic_data_ = std::make_unique<MockQuicData>(version_);
2322   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2323   // Use cold start and complete alt job manually.
2324   crypto_client_stream_factory_.set_handshake_mode(
2325       MockCryptoClientStream::COLD_START);
2326   tcp_data_ = std::make_unique<SequencedSocketData>();
2327   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
2328 
2329   HttpRequestInfo request_info;
2330   request_info.method = "GET";
2331   request_info.url = GURL("https://www.google.com");
2332 
2333   Initialize(request_info);
2334 
2335   url::SchemeHostPort server(request_info.url);
2336   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2337   SetAlternativeService(request_info, alternative_service);
2338   request_ =
2339       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2340                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2341   EXPECT_TRUE(job_controller_->main_job());
2342   EXPECT_TRUE(job_controller_->alternative_job());
2343   if (async_quic_session) {
2344     EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
2345   } else {
2346     EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
2347   }
2348   // Make |alternative_job| succeed.
2349   auto http_stream = std::make_unique<HttpBasicStream>(
2350       std::make_unique<ClientSocketHandle>(), false);
2351   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, http_stream.get()));
2352 
2353   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
2354                                       std::move(http_stream));
2355   job_controller_->OnStreamReady(job_factory_.alternative_job());
2356 
2357   base::RunLoop().RunUntilIdle();
2358 
2359   EXPECT_FALSE(job_controller_->main_job());
2360   EXPECT_TRUE(job_controller_->alternative_job());
2361 
2362   request_.reset();
2363   VerifyBrokenAlternateProtocolMapping(request_info, false);
2364   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2365 }
2366 
2367 // Tests that when alt job succeeds, main job is destroyed.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsMainJobDestroyed)2368 TEST_P(HttpStreamFactoryJobControllerTest, AltJobSucceedsMainJobDestroyed) {
2369   TestAltJobSucceedsMainJobDestroyed(false);
2370 }
2371 
2372 // Tests that when alt job succeeds, main job is destroyed.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsMainJobDestroyedAsyncQuicSession)2373 TEST_P(HttpStreamFactoryJobControllerTest,
2374        AltJobSucceedsMainJobDestroyedAsyncQuicSession) {
2375   TestAltJobSucceedsMainJobDestroyed(true);
2376 }
2377 
2378 // Tests that if alt job succeeds and main job is blocked, main job should be
2379 // cancelled immediately. |request_| completion will clean up the JobController.
2380 // Regression test for crbug.com/678768.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsMainJobBlockedControllerDestroyed)2381 TEST_P(HttpStreamFactoryJobControllerTest,
2382        AltJobSucceedsMainJobBlockedControllerDestroyed) {
2383   quic_data_ = std::make_unique<MockQuicData>(version_);
2384   quic_data_->AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
2385   quic_data_->AddRead(ASYNC, ERR_CONNECTION_CLOSED);
2386 
2387   HttpRequestInfo request_info;
2388   request_info.method = "GET";
2389   request_info.url = GURL("https://www.google.com");
2390 
2391   Initialize(request_info);
2392 
2393   url::SchemeHostPort server(request_info.url);
2394   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2395   SetAlternativeService(request_info, alternative_service);
2396   request_ =
2397       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2398                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2399   EXPECT_TRUE(job_controller_->main_job());
2400   EXPECT_TRUE(job_controller_->alternative_job());
2401   EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
2402 
2403   // |alternative_job| succeeds and should report status to |request_delegate_|.
2404   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
2405   base::RunLoop().RunUntilIdle();
2406 
2407   EXPECT_FALSE(job_controller_->main_job());
2408   EXPECT_TRUE(job_controller_->alternative_job());
2409 
2410   // Invoke OnRequestComplete() which should delete |job_controller_| from
2411   // |factory_|.
2412   request_.reset();
2413   // base::RunLoop().RunUntilIdle();
2414   VerifyBrokenAlternateProtocolMapping(request_info, false);
2415   // This fails without the fix for crbug.com/678768.
2416   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2417 }
2418 
TEST_P(HttpStreamFactoryJobControllerTest,SpdySessionKeyHasOriginHostPortPair)2419 TEST_P(HttpStreamFactoryJobControllerTest,
2420        SpdySessionKeyHasOriginHostPortPair) {
2421   session_deps_.enable_http2_alternative_service = true;
2422 
2423   const char origin_host[] = "www.example.org";
2424   const uint16_t origin_port = 443;
2425   const char alternative_host[] = "mail.example.org";
2426   const uint16_t alternative_port = 123;
2427 
2428   HttpRequestInfo request_info;
2429   request_info.method = "GET";
2430   request_info.url =
2431       GURL(base::StringPrintf("https://%s:%u", origin_host, origin_port));
2432   Initialize(request_info);
2433 
2434   url::SchemeHostPort server(request_info.url);
2435   AlternativeService alternative_service(kProtoHTTP2, alternative_host,
2436                                          alternative_port);
2437   SetAlternativeService(request_info, alternative_service);
2438 
2439   request_ =
2440       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2441                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2442 
2443   HostPortPair main_host_port_pair =
2444       HttpStreamFactoryJobPeer::GetSpdySessionKey(job_controller_->main_job())
2445           .host_port_pair();
2446   EXPECT_EQ(origin_host, main_host_port_pair.host());
2447   EXPECT_EQ(origin_port, main_host_port_pair.port());
2448 
2449   HostPortPair alternative_host_port_pair =
2450       HttpStreamFactoryJobPeer::GetSpdySessionKey(
2451           job_controller_->alternative_job())
2452           .host_port_pair();
2453   EXPECT_EQ(origin_host, alternative_host_port_pair.host());
2454   EXPECT_EQ(origin_port, alternative_host_port_pair.port());
2455 }
2456 
2457 void HttpStreamFactoryJobControllerTestBase::
TestOrphanedJobCompletesControllerDestroyed(bool async_quic_session)2458     TestOrphanedJobCompletesControllerDestroyed(bool async_quic_session) {
2459   SetAsyncQuicSession(async_quic_session);
2460   quic_data_ = std::make_unique<MockQuicData>(version_);
2461   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2462   // Use cold start and complete alt job manually.
2463   crypto_client_stream_factory_.set_handshake_mode(
2464       MockCryptoClientStream::COLD_START);
2465 
2466   tcp_data_ = std::make_unique<SequencedSocketData>();
2467   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
2468   SSLSocketDataProvider ssl_data(ASYNC, OK);
2469   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
2470 
2471   HttpRequestInfo request_info;
2472   request_info.method = "GET";
2473   request_info.url = GURL("https://www.google.com");
2474 
2475   Initialize(request_info);
2476 
2477   url::SchemeHostPort server(request_info.url);
2478   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2479   SetAlternativeService(request_info, alternative_service);
2480 
2481   request_ =
2482       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2483                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2484   EXPECT_TRUE(job_controller_->main_job());
2485   EXPECT_TRUE(job_controller_->alternative_job());
2486 
2487   if (async_quic_session) {
2488     EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1).WillOnce([this]() {
2489       job_factory_.main_job()->DoResume();
2490     });
2491   }
2492 
2493   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
2494 
2495   // Complete main job now.
2496   base::RunLoop().RunUntilIdle();
2497 
2498   // Invoke OnRequestComplete() which should not delete |job_controller_| from
2499   // |factory_| because alt job is yet to finish.
2500   request_.reset();
2501   ASSERT_FALSE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2502   EXPECT_FALSE(job_controller_->main_job());
2503   EXPECT_TRUE(job_controller_->alternative_job());
2504 
2505   // Make |alternative_job| succeed.
2506   auto http_stream = std::make_unique<HttpBasicStream>(
2507       std::make_unique<ClientSocketHandle>(), false);
2508   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
2509                                       std::move(http_stream));
2510   // This should not call request_delegate_::OnStreamReady.
2511   job_controller_->OnStreamReady(job_factory_.alternative_job());
2512   // Make sure that controller does not leak.
2513   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2514 }
2515 
2516 // Tests that if an orphaned job completes after |request_| is gone,
2517 // JobController will be cleaned up.
TEST_P(HttpStreamFactoryJobControllerTest,OrphanedJobCompletesControllerDestroyed)2518 TEST_P(HttpStreamFactoryJobControllerTest,
2519        OrphanedJobCompletesControllerDestroyed) {
2520   TestOrphanedJobCompletesControllerDestroyed(false);
2521 }
2522 
2523 // Tests that if an orphaned job completes after |request_| is gone,
2524 // JobController will be cleaned up.
TEST_P(HttpStreamFactoryJobControllerTest,OrphanedJobCompletesControllerDestroyedAsyncQuicSession)2525 TEST_P(HttpStreamFactoryJobControllerTest,
2526        OrphanedJobCompletesControllerDestroyedAsyncQuicSession) {
2527   TestOrphanedJobCompletesControllerDestroyed(true);
2528 }
2529 
2530 void HttpStreamFactoryJobControllerTestBase::
TestAltJobSucceedsAfterMainJobFailed(bool alt_job_retried_on_non_default_network,bool async_quic_session)2531     TestAltJobSucceedsAfterMainJobFailed(
2532         bool alt_job_retried_on_non_default_network,
2533         bool async_quic_session) {
2534   SetAsyncQuicSession(async_quic_session);
2535   quic_data_ = std::make_unique<MockQuicData>(version_);
2536   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2537   // Use cold start and complete alt job manually.
2538   crypto_client_stream_factory_.set_handshake_mode(
2539       MockCryptoClientStream::COLD_START);
2540 
2541   // One failed TCP connect.
2542   tcp_data_ = std::make_unique<SequencedSocketData>();
2543   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED));
2544 
2545   HttpRequestInfo request_info;
2546   request_info.method = "GET";
2547   request_info.url = GURL("https://www.google.com");
2548 
2549   Initialize(request_info);
2550 
2551   url::SchemeHostPort server(request_info.url);
2552   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2553   SetAlternativeService(request_info, alternative_service);
2554 
2555   // |main_job| fails but should not report status to Request.
2556   EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _, _)).Times(0);
2557 
2558   request_ =
2559       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2560                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2561   EXPECT_TRUE(job_controller_->main_job());
2562   EXPECT_TRUE(job_controller_->alternative_job());
2563 
2564   if (alt_job_retried_on_non_default_network) {
2565     // Set the alt job as if it failed on the default network and is retried on
2566     // the alternate network.
2567     JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
2568   }
2569 
2570   // Make |alternative_job| succeed.
2571   auto http_stream = std::make_unique<HttpBasicStream>(
2572       std::make_unique<ClientSocketHandle>(), false);
2573   if (async_quic_session) {
2574     base::RunLoop run_loop;
2575     EXPECT_CALL(*job_factory_.main_job(), Resume())
2576         .Times(1)
2577         .WillOnce([&run_loop, this]() {
2578           run_loop.Quit();
2579           job_factory_.main_job()->DoResume();
2580         });
2581     run_loop.Run();
2582   }
2583   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, http_stream.get()));
2584 
2585   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
2586                                       std::move(http_stream));
2587   job_controller_->OnStreamReady(job_factory_.alternative_job());
2588   base::RunLoop().RunUntilIdle();
2589   // |alternative_job| succeeds and should report status to Request.
2590   VerifyBrokenAlternateProtocolMapping(request_info, false);
2591   request_.reset();
2592   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2593 }
2594 
2595 // This test verifies that the alternative service is not mark broken if the
2596 // alternative job succeeds on the default network after the main job failed.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsOnDefaultNetworkAfterMainJobFailed)2597 TEST_P(HttpStreamFactoryJobControllerTest,
2598        AltJobSucceedsOnDefaultNetworkAfterMainJobFailed) {
2599   TestAltJobSucceedsAfterMainJobFailed(false, false);
2600 }
2601 
2602 // This test verifies that the alternative service is not mark broken if the
2603 // alternative job succeeds on the alternate network after the main job failed.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsOnAlternateNetworkAfterMainJobFailed)2604 TEST_P(HttpStreamFactoryJobControllerTest,
2605        AltJobSucceedsOnAlternateNetworkAfterMainJobFailed) {
2606   TestAltJobSucceedsAfterMainJobFailed(true, false);
2607 }
2608 
2609 // This test verifies that the alternative service is not mark broken if the
2610 // alternative job succeeds on the default network after the main job failed.
2611 // This test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsOnDefaultNetworkAfterMainJobFailedAsyncQuicSession)2612 TEST_P(HttpStreamFactoryJobControllerTest,
2613        AltJobSucceedsOnDefaultNetworkAfterMainJobFailedAsyncQuicSession) {
2614   TestAltJobSucceedsAfterMainJobFailed(false, true);
2615 }
2616 
2617 // This test verifies that the alternative service is not mark broken if the
2618 // alternative job succeeds on the alternate network after the main job failed.
2619 // This test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsOnAlternateNetworkAfterMainJobFailedAsyncQuicSession)2620 TEST_P(HttpStreamFactoryJobControllerTest,
2621        AltJobSucceedsOnAlternateNetworkAfterMainJobFailedAsyncQuicSession) {
2622   TestAltJobSucceedsAfterMainJobFailed(true, true);
2623 }
2624 
2625 void HttpStreamFactoryJobControllerTestBase::
TestAltJobSucceedsAfterMainJobSucceeded(bool alt_job_retried_on_non_default_network,bool async_quic_session)2626     TestAltJobSucceedsAfterMainJobSucceeded(
2627         bool alt_job_retried_on_non_default_network,
2628         bool async_quic_session) {
2629   SetAsyncQuicSession(async_quic_session);
2630   quic_data_ = std::make_unique<MockQuicData>(version_);
2631   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2632   // Use cold start and complete alt job manually.
2633   crypto_client_stream_factory_.set_handshake_mode(
2634       MockCryptoClientStream::COLD_START);
2635 
2636   tcp_data_ = std::make_unique<SequencedSocketData>();
2637   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
2638   SSLSocketDataProvider ssl_data(ASYNC, OK);
2639   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
2640 
2641   HttpRequestInfo request_info;
2642   request_info.method = "GET";
2643   request_info.url = GURL("https://www.google.com");
2644 
2645   Initialize(request_info);
2646 
2647   url::SchemeHostPort server(request_info.url);
2648   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2649   SetAlternativeService(request_info, alternative_service);
2650 
2651   // |main_job| fails but should not report status to Request.
2652   EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _, _)).Times(0);
2653 
2654   request_ =
2655       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2656                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2657   EXPECT_TRUE(job_controller_->main_job());
2658   EXPECT_TRUE(job_controller_->alternative_job());
2659 
2660   if (async_quic_session) {
2661     EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1).WillOnce([this]() {
2662       job_factory_.main_job()->DoResume();
2663     });
2664   }
2665 
2666   // Run the message loop to make |main_job| succeed and status will be
2667   // reported to Request.
2668   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
2669   base::RunLoop().RunUntilIdle();
2670   VerifyBrokenAlternateProtocolMapping(request_info, false);
2671 
2672   if (alt_job_retried_on_non_default_network) {
2673     // Set the alt job as if it failed on the default network and is retired on
2674     // the alternate network.
2675     JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
2676   }
2677 
2678   // Make |alternative_job| succeed.
2679   auto http_stream = std::make_unique<HttpBasicStream>(
2680       std::make_unique<ClientSocketHandle>(), false);
2681 
2682   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
2683                                       std::move(http_stream));
2684   job_controller_->OnStreamReady(job_factory_.alternative_job());
2685 
2686   request_.reset();
2687   // If alt job was retried on the alternate network, the alternative service
2688   // should be marked broken until the default network changes.
2689   VerifyBrokenAlternateProtocolMapping(request_info,
2690                                        alt_job_retried_on_non_default_network);
2691   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2692   if (alt_job_retried_on_non_default_network) {
2693     // Verify the brokenness is cleared when the default network changes.
2694     session_->http_server_properties()->OnDefaultNetworkChanged();
2695     VerifyBrokenAlternateProtocolMapping(request_info, false);
2696   }
2697 }
2698 
2699 // This test verifies that the alternative service is not marked broken if the
2700 // alternative job succeeds on the default network after the main job succeeded.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsOnDefaultNetworkAfterMainJobSucceeded)2701 TEST_P(HttpStreamFactoryJobControllerTest,
2702        AltJobSucceedsOnDefaultNetworkAfterMainJobSucceeded) {
2703   TestAltJobSucceedsAfterMainJobSucceeded(false, false);
2704 }
2705 
2706 // This test verifies that the alternative service is marked broken until the
2707 // default network changes if the alternative job succeeds on the non-default
2708 // network, which failed on the default network previously, after the main job
2709 // succeeded.  The brokenness should be cleared when the default network
2710 // changes.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsOnAlternateNetworkAfterMainJobSucceeded)2711 TEST_P(HttpStreamFactoryJobControllerTest,
2712        AltJobSucceedsOnAlternateNetworkAfterMainJobSucceeded) {
2713   TestAltJobSucceedsAfterMainJobSucceeded(true, false);
2714 }
2715 
2716 // This test verifies that the alternative service is not marked broken if the
2717 // alternative job succeeds on the default network after the main job succeeded.
2718 // This test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsOnDefaultNetworkAfterMainJobSucceededAsyncQuicSession)2719 TEST_P(HttpStreamFactoryJobControllerTest,
2720        AltJobSucceedsOnDefaultNetworkAfterMainJobSucceededAsyncQuicSession) {
2721   TestAltJobSucceedsAfterMainJobSucceeded(false, true);
2722 }
2723 
2724 // This test verifies that the alternative service is marked broken until the
2725 // default network changes if the alternative job succeeds on the non-default
2726 // network, which failed on the default network previously, after the main job
2727 // succeeded.  The brokenness should be cleared when the default network
2728 // changes. This test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,AltJobSucceedsOnAlternateNetworkAfterMainJobSucceededAsyncQuicSession)2729 TEST_P(HttpStreamFactoryJobControllerTest,
2730        AltJobSucceedsOnAlternateNetworkAfterMainJobSucceededAsyncQuicSession) {
2731   TestAltJobSucceedsAfterMainJobSucceeded(true, true);
2732 }
2733 
2734 void HttpStreamFactoryJobControllerTestBase::
TestMainJobSucceedsAfterAltJobSucceeded(bool alt_job_retried_on_non_default_network,bool async_quic_session)2735     TestMainJobSucceedsAfterAltJobSucceeded(
2736         bool alt_job_retried_on_non_default_network,
2737         bool async_quic_session) {
2738   SetAsyncQuicSession(async_quic_session);
2739   quic_data_ = std::make_unique<MockQuicData>(version_);
2740   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2741   // Use cold start and complete alt job manually.
2742   crypto_client_stream_factory_.set_handshake_mode(
2743       MockCryptoClientStream::COLD_START);
2744 
2745   tcp_data_ = std::make_unique<SequencedSocketData>();
2746   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
2747   SSLSocketDataProvider ssl_data(ASYNC, OK);
2748   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
2749 
2750   HttpRequestInfo request_info;
2751   request_info.method = "GET";
2752   request_info.url = GURL("https://www.google.com");
2753 
2754   Initialize(request_info);
2755 
2756   url::SchemeHostPort server(request_info.url);
2757   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2758   SetAlternativeService(request_info, alternative_service);
2759 
2760   request_ =
2761       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2762                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2763   EXPECT_TRUE(job_controller_->main_job());
2764   EXPECT_TRUE(job_controller_->alternative_job());
2765 
2766   if (alt_job_retried_on_non_default_network) {
2767     // Set the alt job as if it failed on the default network and is retired on
2768     // the alternate network.
2769     JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
2770   }
2771   // Make |alternative_job| succeed.
2772   auto http_stream = std::make_unique<HttpBasicStream>(
2773       std::make_unique<ClientSocketHandle>(), false);
2774   if (async_quic_session) {
2775     base::RunLoop run_loop;
2776     EXPECT_CALL(*job_factory_.main_job(), Resume())
2777         .Times(1)
2778         .WillOnce([&run_loop, this]() {
2779           run_loop.Quit();
2780           job_factory_.main_job()->DoResume();
2781         });
2782     run_loop.Run();
2783   }
2784   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, http_stream.get()));
2785 
2786   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
2787                                       std::move(http_stream));
2788   job_controller_->OnStreamReady(job_factory_.alternative_job());
2789 
2790   // Run message loop to make the main job succeed.
2791   base::RunLoop().RunUntilIdle();
2792   request_.reset();
2793 
2794   // If alt job was retried on the alternate network, the alternative service
2795   // should be marked broken until the default network changes.
2796   VerifyBrokenAlternateProtocolMapping(request_info,
2797                                        alt_job_retried_on_non_default_network);
2798   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2799   if (alt_job_retried_on_non_default_network) {
2800     // Verify the brokenness is cleared when the default network changes.
2801     session_->http_server_properties()->OnDefaultNetworkChanged();
2802     VerifyBrokenAlternateProtocolMapping(request_info, false);
2803   }
2804 }
2805 
2806 // This test verifies that the alternative service is not marked broken if the
2807 // main job succeeds after the alternative job succeeded on the default network.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterAltJobSucceededOnDefaultNetwork)2808 TEST_P(HttpStreamFactoryJobControllerTest,
2809        MainJobSucceedsAfterAltJobSucceededOnDefaultNetwork) {
2810   TestMainJobSucceedsAfterAltJobSucceeded(false, false);
2811 }
2812 
2813 // This test verifies that the alternative service is marked broken until the
2814 // default network changes if the main job succeeds after the alternative job
2815 // succeeded on the non-default network, i.e., failed on the default network
2816 // previously.  The brokenness should be cleared when the default network
2817 // changes.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterAltJobSucceededOnAlternateNetwork)2818 TEST_P(HttpStreamFactoryJobControllerTest,
2819        MainJobSucceedsAfterAltJobSucceededOnAlternateNetwork) {
2820   TestMainJobSucceedsAfterAltJobSucceeded(true, false);
2821 }
2822 
2823 // This test verifies that the alternative service is not marked broken if the
2824 // main job succeeds after the alternative job succeeded on the default network.
2825 // This test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterAltJobSucceededOnDefaultNetworkAsyncQuicSession)2826 TEST_P(HttpStreamFactoryJobControllerTest,
2827        MainJobSucceedsAfterAltJobSucceededOnDefaultNetworkAsyncQuicSession) {
2828   TestMainJobSucceedsAfterAltJobSucceeded(false, true);
2829 }
2830 
2831 // This test verifies that the alternative service is marked broken until the
2832 // default network changes if the main job succeeds after the alternative job
2833 // succeeded on the non-default network, i.e., failed on the default network
2834 // previously.  The brokenness should be cleared when the default network
2835 // changes. This test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterAltJobSucceededOnAlternateNetworkAsyncQuicSession)2836 TEST_P(HttpStreamFactoryJobControllerTest,
2837        MainJobSucceedsAfterAltJobSucceededOnAlternateNetworkAsyncQuicSession) {
2838   TestMainJobSucceedsAfterAltJobSucceeded(true, true);
2839 }
2840 
2841 void HttpStreamFactoryJobControllerTestBase::
TestMainJobFailsAfterAltJobSucceeded(bool alt_job_retried_on_non_default_network,bool async_quic_session)2842     TestMainJobFailsAfterAltJobSucceeded(
2843         bool alt_job_retried_on_non_default_network,
2844         bool async_quic_session) {
2845   SetAsyncQuicSession(async_quic_session);
2846   quic_data_ = std::make_unique<MockQuicData>(version_);
2847   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2848   // Use cold start and complete alt job manually.
2849   crypto_client_stream_factory_.set_handshake_mode(
2850       MockCryptoClientStream::COLD_START);
2851 
2852   tcp_data_ = std::make_unique<SequencedSocketData>();
2853   tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
2854 
2855   HttpRequestInfo request_info;
2856   request_info.method = "GET";
2857   request_info.url = GURL("https://www.google.com");
2858 
2859   Initialize(request_info);
2860 
2861   url::SchemeHostPort server(request_info.url);
2862   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2863   SetAlternativeService(request_info, alternative_service);
2864 
2865   request_ =
2866       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2867                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2868   EXPECT_TRUE(job_controller_->main_job());
2869   EXPECT_TRUE(job_controller_->alternative_job());
2870 
2871   if (alt_job_retried_on_non_default_network) {
2872     // Set the alt job as if it failed on the default network and is retired on
2873     // the alternate network.
2874     JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
2875   }
2876   // Make |alternative_job| succeed.
2877   auto http_stream = std::make_unique<HttpBasicStream>(
2878       std::make_unique<ClientSocketHandle>(), false);
2879   if (async_quic_session) {
2880     base::RunLoop run_loop;
2881     EXPECT_CALL(*job_factory_.main_job(), Resume())
2882         .Times(1)
2883         .WillOnce([&run_loop, this]() {
2884           run_loop.Quit();
2885           job_factory_.main_job()->DoResume();
2886         });
2887     run_loop.Run();
2888   }
2889   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, http_stream.get()));
2890 
2891   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
2892                                       std::move(http_stream));
2893   job_controller_->OnStreamReady(job_factory_.alternative_job());
2894 
2895   // Run message loop to make the main job fail.
2896   base::RunLoop().RunUntilIdle();
2897   VerifyBrokenAlternateProtocolMapping(request_info, false);
2898   request_.reset();
2899   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2900 }
2901 
2902 // This test verifies that the alternative service is not marked broken if the
2903 // main job fails after the alternative job succeeded on the default network.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobFailsAfterAltJobSucceededOnDefaultNetwork)2904 TEST_P(HttpStreamFactoryJobControllerTest,
2905        MainJobFailsAfterAltJobSucceededOnDefaultNetwork) {
2906   TestMainJobFailsAfterAltJobSucceeded(false, false);
2907 }
2908 
2909 // This test verifies that the alternative service is not marked broken if the
2910 // main job fails after the alternative job succeeded on the non-default
2911 // network, i.e., failed on the default network previously.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobFailsAfterAltJobSucceededOnAlternateNetwork)2912 TEST_P(HttpStreamFactoryJobControllerTest,
2913        MainJobFailsAfterAltJobSucceededOnAlternateNetwork) {
2914   TestMainJobFailsAfterAltJobSucceeded(true, false);
2915 }
2916 
2917 // This test verifies that the alternative service is not marked broken if the
2918 // main job fails after the alternative job succeeded on the default network.
2919 // This test uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobFailsAfterAltJobSucceededOnDefaultNetworkAsyncQuicSession)2920 TEST_P(HttpStreamFactoryJobControllerTest,
2921        MainJobFailsAfterAltJobSucceededOnDefaultNetworkAsyncQuicSession) {
2922   TestMainJobFailsAfterAltJobSucceeded(false, true);
2923 }
2924 
2925 // This test verifies that the alternative service is not marked broken if the
2926 // main job fails after the alternative job succeeded on the non-default
2927 // network, i.e., failed on the default network previously. This test uses
2928 // asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobFailsAfterAltJobSucceededOnAlternateNetworkAsyncQuicSession)2929 TEST_P(HttpStreamFactoryJobControllerTest,
2930        MainJobFailsAfterAltJobSucceededOnAlternateNetworkAsyncQuicSession) {
2931   TestMainJobFailsAfterAltJobSucceeded(true, true);
2932 }
2933 
2934 void HttpStreamFactoryJobControllerTestBase::
TestMainJobSucceedsAfterAltJobFailed(bool alt_job_retried_on_non_default_network,bool async_quic_session)2935     TestMainJobSucceedsAfterAltJobFailed(
2936         bool alt_job_retried_on_non_default_network,
2937         bool async_quic_session) {
2938   SetAsyncQuicSession(async_quic_session);
2939   quic_data_ = std::make_unique<MockQuicData>(version_);
2940   quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED);
2941 
2942   tcp_data_ = std::make_unique<SequencedSocketData>();
2943   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
2944   SSLSocketDataProvider ssl_data(ASYNC, OK);
2945   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
2946 
2947   base::HistogramTester histogram_tester;
2948   HttpRequestInfo request_info;
2949   request_info.method = "GET";
2950   request_info.url = GURL("https://www.google.com");
2951 
2952   Initialize(request_info);
2953 
2954   url::SchemeHostPort server(request_info.url);
2955   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
2956   SetAlternativeService(request_info, alternative_service);
2957 
2958   request_ =
2959       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
2960                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
2961   EXPECT_TRUE(job_controller_->main_job());
2962   EXPECT_TRUE(job_controller_->alternative_job());
2963 
2964   // |alternative_job| fails but should not report status to Request.
2965   EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _, _)).Times(0);
2966   if (async_quic_session) {
2967     EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1).WillOnce([this]() {
2968       job_factory_.main_job()->DoResume();
2969     });
2970   }
2971   // |main_job| succeeds and should report status to Request.
2972   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
2973 
2974   if (alt_job_retried_on_non_default_network) {
2975     // Set the alt job as if it failed on the default network and is retired on
2976     // the alternate network.
2977     JobControllerPeer::SetAltJobFailedOnDefaultNetwork(job_controller_);
2978   }
2979 
2980   base::RunLoop().RunUntilIdle();
2981 
2982   request_.reset();
2983   // Verify that the alternate protocol is marked as broken.
2984   VerifyBrokenAlternateProtocolMapping(request_info, true);
2985   histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED,
2986                                       1);
2987   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
2988   // Verify the brokenness is not cleared when the default network changes.
2989   session_->http_server_properties()->OnDefaultNetworkChanged();
2990   VerifyBrokenAlternateProtocolMapping(request_info, true);
2991 }
2992 
2993 // This test verifies that the alternative service will be marked broken when
2994 // the alternative job fails on the default network and main job succeeds later.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterAltJobFailedOnDefaultNetwork)2995 TEST_P(HttpStreamFactoryJobControllerTest,
2996        MainJobSucceedsAfterAltJobFailedOnDefaultNetwork) {
2997   TestMainJobSucceedsAfterAltJobFailed(false, false);
2998 }
2999 
3000 // This test verifies that the alternative service will be marked broken when
3001 // the alternative job fails on both default and alternate networks and main job
3002 // succeeds later.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterAltJobFailedOnBothNetworks)3003 TEST_P(HttpStreamFactoryJobControllerTest,
3004        MainJobSucceedsAfterAltJobFailedOnBothNetworks) {
3005   TestMainJobSucceedsAfterAltJobFailed(true, false);
3006 }
3007 
3008 // This test verifies that the alternative service will be marked broken when
3009 // the alternative job fails on the default network and main job succeeds later.
3010 // This test uses asynchronous Quic session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterAltJobFailedOnDefaultNetworkAsyncQuicSession)3011 TEST_P(HttpStreamFactoryJobControllerTest,
3012        MainJobSucceedsAfterAltJobFailedOnDefaultNetworkAsyncQuicSession) {
3013   TestMainJobSucceedsAfterAltJobFailed(false, true);
3014 }
3015 
3016 // This test verifies that the alternative service will be marked broken when
3017 // the alternative job fails on both default and alternate networks and main job
3018 // succeeds later. This test uses asynchronous Quic session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterAltJobFailedOnBothNetworksAsyncQuicSession)3019 TEST_P(HttpStreamFactoryJobControllerTest,
3020        MainJobSucceedsAfterAltJobFailedOnBothNetworksAsyncQuicSession) {
3021   TestMainJobSucceedsAfterAltJobFailed(true, true);
3022 }
3023 
3024 void HttpStreamFactoryJobControllerTestBase::
TestMainJobSucceedsAfterIgnoredError(int net_error,bool async_quic_session,bool expect_broken,std::string alternate_host)3025     TestMainJobSucceedsAfterIgnoredError(int net_error,
3026                                          bool async_quic_session,
3027                                          bool expect_broken,
3028                                          std::string alternate_host) {
3029   SetAsyncQuicSession(async_quic_session);
3030   quic_data_ = std::make_unique<MockQuicData>(version_);
3031   quic_data_->AddConnect(SYNCHRONOUS, net_error);
3032   tcp_data_ = std::make_unique<SequencedSocketData>();
3033   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
3034   SSLSocketDataProvider ssl_data(ASYNC, OK);
3035   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
3036 
3037   base::HistogramTester histogram_tester;
3038 
3039   HttpRequestInfo request_info;
3040   request_info.method = "GET";
3041   request_info.url = GURL("https://www.google.com");
3042   Initialize(request_info);
3043 
3044   url::SchemeHostPort server(request_info.url);
3045   if (alternate_host.empty()) {
3046     alternate_host = server.host();
3047   }
3048   AlternativeService alternative_service(kProtoQUIC, alternate_host, 443);
3049   SetAlternativeService(request_info, alternative_service);
3050 
3051   request_ =
3052       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3053                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3054   EXPECT_TRUE(job_controller_->main_job());
3055   EXPECT_TRUE(job_controller_->alternative_job());
3056 
3057   // |alternative_job| fails but should not report status to Request.
3058   EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _, _)).Times(0);
3059   if (async_quic_session) {
3060     EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1).WillOnce([this]() {
3061       job_factory_.main_job()->DoResume();
3062     });
3063   }
3064   // |main_job| succeeds and should report status to Request.
3065   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
3066   base::RunLoop().RunUntilIdle();
3067   request_.reset();
3068 
3069   // Verify that the alternate protocol is not marked as broken.
3070   VerifyBrokenAlternateProtocolMapping(request_info, expect_broken);
3071   if (expect_broken) {
3072     histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed",
3073                                         -net_error, 1);
3074   }
3075   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
3076 }
3077 
3078 // Verifies that if the alternative job fails due to a connection change event,
3079 // then the alternative service is not marked as broken.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterConnectionChanged)3080 TEST_P(HttpStreamFactoryJobControllerTest,
3081        MainJobSucceedsAfterConnectionChanged) {
3082   TestMainJobSucceedsAfterIgnoredError(ERR_NETWORK_CHANGED, false);
3083 }
3084 
3085 // Verifies that if the alternative job fails due to a disconnected network,
3086 // then the alternative service is not marked as broken.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterInternetDisconnected)3087 TEST_P(HttpStreamFactoryJobControllerTest,
3088        MainJobSucceedsAfterInternetDisconnected) {
3089   TestMainJobSucceedsAfterIgnoredError(ERR_INTERNET_DISCONNECTED, false);
3090 }
3091 
3092 // Verifies that if the alternative job fails due to a connection change event,
3093 // then the alternative service is not marked as broken. This test uses
3094 // asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterConnectionChangedAsyncQuicSession)3095 TEST_P(HttpStreamFactoryJobControllerTest,
3096        MainJobSucceedsAfterConnectionChangedAsyncQuicSession) {
3097   TestMainJobSucceedsAfterIgnoredError(ERR_NETWORK_CHANGED, true);
3098 }
3099 
3100 // Verifies that if the alternative job fails due to a disconnected network,
3101 // then the alternative service is not marked as broken. This test uses
3102 // asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterInternetDisconnectedAsyncQuicSession)3103 TEST_P(HttpStreamFactoryJobControllerTest,
3104        MainJobSucceedsAfterInternetDisconnectedAsyncQuicSession) {
3105   TestMainJobSucceedsAfterIgnoredError(ERR_INTERNET_DISCONNECTED, true);
3106 }
3107 
3108 // Verifies that if the alternative job fails due to a DNS failure,
3109 // then the alternative service is not marked as broken.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterDnsFailure)3110 TEST_P(HttpStreamFactoryJobControllerTest, MainJobSucceedsAfterDnsFailure) {
3111   TestMainJobSucceedsAfterIgnoredError(ERR_NAME_NOT_RESOLVED, false);
3112 }
3113 
3114 // Verifies that if the alternative job fails due to a DNS failure,
3115 // then the alternative service is not marked as broken. This test uses
3116 // asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterDnsFailureAsyncQuicSession)3117 TEST_P(HttpStreamFactoryJobControllerTest,
3118        MainJobSucceedsAfterDnsFailureAsyncQuicSession) {
3119   TestMainJobSucceedsAfterIgnoredError(ERR_NAME_NOT_RESOLVED, true);
3120 }
3121 
3122 // Verifies that if the alternative job fails due to a DNS failure on a
3123 // different name, then the alternative service is marked as broken.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterDnsFailureWithAlternateName)3124 TEST_P(HttpStreamFactoryJobControllerTest,
3125        MainJobSucceedsAfterDnsFailureWithAlternateName) {
3126   TestMainJobSucceedsAfterIgnoredError(ERR_NAME_NOT_RESOLVED, false, true,
3127                                        "alternate.google.com");
3128 }
3129 
3130 // Verifies that if the alternative job fails due to a DNS failure on a
3131 // different name, then the alternative service is marked as broken. This test
3132 // uses asynchronous QUIC session creation.
TEST_P(HttpStreamFactoryJobControllerTest,MainJobSucceedsAfterDnsFailureWithAlternateNameAsyncQuicSession)3133 TEST_P(HttpStreamFactoryJobControllerTest,
3134        MainJobSucceedsAfterDnsFailureWithAlternateNameAsyncQuicSession) {
3135   TestMainJobSucceedsAfterIgnoredError(ERR_NAME_NOT_RESOLVED, true, true,
3136                                        "alternate.google.com");
3137 }
3138 
3139 // Regression test for crbug/621069.
3140 // Get load state after main job fails and before alternative job succeeds.
TEST_P(HttpStreamFactoryJobControllerTest,GetLoadStateAfterMainJobFailed)3141 TEST_P(HttpStreamFactoryJobControllerTest, GetLoadStateAfterMainJobFailed) {
3142   // Use COLD_START to complete alt job manually.
3143   quic_data_ = std::make_unique<MockQuicData>(version_);
3144   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3145   crypto_client_stream_factory_.set_handshake_mode(
3146       MockCryptoClientStream::COLD_START);
3147 
3148   tcp_data_ = std::make_unique<SequencedSocketData>();
3149   tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
3150 
3151   HttpRequestInfo request_info;
3152   request_info.method = "GET";
3153   request_info.url = GURL("https://www.google.com");
3154 
3155   Initialize(request_info);
3156   url::SchemeHostPort server(request_info.url);
3157   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
3158   SetAlternativeService(request_info, alternative_service);
3159 
3160   request_ =
3161       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3162                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3163   EXPECT_TRUE(job_controller_->main_job());
3164   EXPECT_TRUE(job_controller_->alternative_job());
3165 
3166   // |main_job| fails but should not report status to Request.
3167   // The alternative job will mark the main job complete.
3168   EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _, _)).Times(0);
3169 
3170   base::RunLoop().RunUntilIdle();
3171 
3172   // Controller should use alternative job to get load state.
3173   job_controller_->GetLoadState();
3174 
3175   // |alternative_job| succeeds and should report status to Request.
3176   auto http_stream = std::make_unique<HttpBasicStream>(
3177       std::make_unique<ClientSocketHandle>(), false);
3178   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, http_stream.get()));
3179 
3180   HttpStreamFactoryJobPeer::SetStream(job_factory_.alternative_job(),
3181                                       std::move(http_stream));
3182   job_controller_->OnStreamReady(job_factory_.alternative_job());
3183 
3184   request_.reset();
3185   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
3186 }
3187 
TestResumeMainJobWhenAltJobStalls(bool async_quic_session)3188 void HttpStreamFactoryJobControllerTestBase::TestResumeMainJobWhenAltJobStalls(
3189     bool async_quic_session) {
3190   SetAsyncQuicSession(async_quic_session);
3191   // Use COLD_START to stall alt job.
3192   quic_data_ = std::make_unique<MockQuicData>(version_);
3193   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3194   crypto_client_stream_factory_.set_handshake_mode(
3195       MockCryptoClientStream::COLD_START);
3196 
3197   tcp_data_ = std::make_unique<SequencedSocketData>();
3198   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
3199   SSLSocketDataProvider ssl_data(ASYNC, OK);
3200   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
3201 
3202   HttpRequestInfo request_info;
3203   request_info.method = "GET";
3204   request_info.url = GURL("https://www.google.com");
3205 
3206   Initialize(request_info);
3207   url::SchemeHostPort server(request_info.url);
3208   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
3209   SetAlternativeService(request_info, alternative_service);
3210 
3211   request_ =
3212       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3213                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3214   EXPECT_TRUE(job_controller_->main_job());
3215   EXPECT_TRUE(job_controller_->alternative_job());
3216   if (async_quic_session) {
3217     EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1).WillOnce([this]() {
3218       job_factory_.main_job()->DoResume();
3219     });
3220   }
3221   // Alt job is stalled and main job should complete successfully.
3222   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
3223 
3224   base::RunLoop().RunUntilIdle();
3225 }
3226 
TEST_P(HttpStreamFactoryJobControllerTest,ResumeMainJobWhenAltJobStalls)3227 TEST_P(HttpStreamFactoryJobControllerTest, ResumeMainJobWhenAltJobStalls) {
3228   TestResumeMainJobWhenAltJobStalls(false);
3229 }
3230 
TEST_P(HttpStreamFactoryJobControllerTest,ResumeMainJobWhenAltJobStallsAsyncQuicSession)3231 TEST_P(HttpStreamFactoryJobControllerTest,
3232        ResumeMainJobWhenAltJobStallsAsyncQuicSession) {
3233   TestResumeMainJobWhenAltJobStalls(true);
3234 }
3235 
TEST_P(HttpStreamFactoryJobControllerTest,InvalidPortForQuic)3236 TEST_P(HttpStreamFactoryJobControllerTest, InvalidPortForQuic) {
3237   HttpRequestInfo request_info;
3238   request_info.method = "GET";
3239   request_info.url = GURL("https://www.google.com");
3240 
3241   // Using a restricted port 101 for QUIC should fail and the alternative job
3242   // should post OnStreamFailedCall on the controller to resume the main job.
3243   Initialize(request_info);
3244 
3245   url::SchemeHostPort server(request_info.url);
3246   AlternativeService alternative_service(kProtoQUIC, server.host(), 101);
3247   SetAlternativeService(request_info, alternative_service);
3248 
3249   request_ =
3250       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3251                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3252 
3253   EXPECT_TRUE(job_factory_.main_job()->is_waiting());
3254 
3255   // Wait until OnStreamFailedCallback is executed on the alternative job.
3256   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
3257   base::RunLoop().RunUntilIdle();
3258 }
3259 
3260 // Verifies that the main job is not resumed until after the alt job completes
3261 // host resolution.
TEST_P(HttpStreamFactoryJobControllerTest,HostResolutionHang)3262 TEST_P(HttpStreamFactoryJobControllerTest, HostResolutionHang) {
3263   auto hanging_resolver = std::make_unique<MockHostResolver>();
3264   hanging_resolver->set_ondemand_mode(true);
3265   hanging_resolver->rules()->AddRule("www.google.com", "1.2.3.4");
3266   session_deps_.host_resolver = std::move(hanging_resolver);
3267 
3268   HttpRequestInfo request_info;
3269   request_info.method = "GET";
3270   request_info.url = GURL("https://www.google.com");
3271 
3272   Initialize(request_info);
3273 
3274   // handshake will fail asynchronously after mock data is unpaused.
3275   MockQuicData quic_data(version_);
3276   quic_data.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
3277   quic_data.AddRead(ASYNC, ERR_FAILED);
3278   quic_data.AddWrite(ASYNC, ERR_FAILED);
3279   quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
3280 
3281   // Enable delayed TCP and set time delay for waiting job.
3282   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
3283   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
3284   ServerNetworkStats stats1;
3285   stats1.srtt = base::Microseconds(10);
3286   session_->http_server_properties()->SetServerNetworkStats(
3287       url::SchemeHostPort(GURL("https://www.google.com")),
3288       NetworkAnonymizationKey(), stats1);
3289 
3290   url::SchemeHostPort server(request_info.url);
3291   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
3292   SetAlternativeService(request_info, alternative_service);
3293 
3294   // This prevents handshake from immediately succeeding.
3295   crypto_client_stream_factory_.set_handshake_mode(
3296       MockCryptoClientStream::COLD_START);
3297 
3298   request_ =
3299       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3300                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3301 
3302   EXPECT_TRUE(job_controller_->main_job());
3303   EXPECT_TRUE(job_controller_->alternative_job());
3304   EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
3305 
3306   // Since the alt job has not finished host resolution, there should be no
3307   // delayed task posted to resume the main job.
3308   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
3309   FastForwardBy(base::Microseconds(50));
3310   EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
3311 
3312   // Allow alt job host resolution to complete.
3313   session_deps_.host_resolver->ResolveAllPending();
3314 
3315   // Task to resume main job in 15 microseconds should be posted.
3316   EXPECT_NE(0u, GetPendingMainThreadTaskCount());
3317   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
3318   FastForwardBy(base::Microseconds(14));
3319   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
3320   FastForwardBy(base::Microseconds(1));
3321 
3322   EXPECT_TRUE(job_controller_->main_job());
3323   EXPECT_TRUE(job_controller_->alternative_job());
3324 
3325   // Unpause mock quic data.
3326   // Will cause |alternative_job| to fail, but its failure should not be
3327   // reported to Request.
3328   EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _, _)).Times(0);
3329   EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
3330   EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
3331   // OnStreamFailed will post a task to resume the main job immediately but
3332   // won't call Resume() on the main job since it's been resumed already.
3333   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
3334   quic_data.Resume();
3335   FastForwardUntilNoTasksRemain();
3336   // Alt job should be cleaned up
3337   EXPECT_FALSE(job_controller_->alternative_job());
3338 }
3339 
3340 // Regression test for crbug.com/789560.
TEST_P(HttpStreamFactoryJobControllerTest,ResumeMainJobLaterCanceled)3341 TEST_P(HttpStreamFactoryJobControllerTest, ResumeMainJobLaterCanceled) {
3342   std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service =
3343       ConfiguredProxyResolutionService::CreateDirect();
3344   ConfiguredProxyResolutionService* proxy_resolution_service_raw =
3345       proxy_resolution_service.get();
3346   session_deps_.proxy_resolution_service = std::move(proxy_resolution_service);
3347 
3348   // Using hanging resolver will cause the alternative job to hang indefinitely.
3349   session_deps_.alternate_host_resolver =
3350       std::make_unique<HangingHostResolver>();
3351 
3352   HttpRequestInfo request_info;
3353   request_info.method = "GET";
3354   request_info.url = GURL("https://www.google.com");
3355 
3356   Initialize(request_info);
3357 
3358   // Enable delayed TCP and set time delay for waiting job.
3359   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
3360   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
3361   ServerNetworkStats stats1;
3362   stats1.srtt = base::Microseconds(10);
3363   session_->http_server_properties()->SetServerNetworkStats(
3364       url::SchemeHostPort(GURL("https://www.google.com")),
3365       NetworkAnonymizationKey(), stats1);
3366 
3367   url::SchemeHostPort server(request_info.url);
3368   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
3369   SetAlternativeService(request_info, alternative_service);
3370 
3371   request_ =
3372       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3373                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3374   EXPECT_TRUE(job_controller_->main_job());
3375   EXPECT_TRUE(job_controller_->alternative_job());
3376   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
3377 
3378   base::RunLoop run_loop;
3379   // The main job should be resumed without delay when alt job fails.
3380   EXPECT_CALL(*job_factory_.main_job(), Resume())
3381       .Times(1)
3382       .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
3383   job_controller_->OnStreamFailed(job_factory_.alternative_job(),
3384                                   ERR_QUIC_PROTOCOL_ERROR);
3385   FastForwardBy(base::Microseconds(0));
3386   run_loop.Run();
3387   EXPECT_FALSE(job_controller_->alternative_job());
3388 
3389   // Calling ForceReloadProxyConfig will cause the proxy configuration to
3390   // change. It will still be the direct connection but the configuration
3391   // version will be bumped. That is enough for the job controller to restart
3392   // the jobs.
3393   proxy_resolution_service_raw->ForceReloadProxyConfig();
3394   HttpStreamFactoryJobPeer::SetShouldReconsiderProxy(job_factory_.main_job());
3395   // Now the alt service is marked as broken (e.g. through a different request),
3396   // so only non-alt job is restarted.
3397   session_->http_server_properties()->MarkAlternativeServiceBroken(
3398       alternative_service, NetworkAnonymizationKey());
3399 
3400   job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED);
3401   // Jobs are restarted.
3402   EXPECT_TRUE(job_controller_->main_job());
3403   EXPECT_FALSE(job_controller_->alternative_job());
3404 
3405   // There shouldn't be any ResumeMainJobLater() delayed tasks.
3406   // This EXPECT_CALL will fail before crbug.com/789560 fix.
3407   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
3408   FastForwardBy(base::Microseconds(15));
3409 
3410   EXPECT_TRUE(job_controller_->main_job());
3411   request_.reset();
3412 }
3413 
3414 // Test that main job is blocked for kMaxDelayTimeForMainJob(3s) if
3415 // http_server_properties cached an inappropriate large srtt for the server,
3416 // which would potentially delay the main job for a extremely long time in
3417 // delayed tcp case.
TEST_P(HttpStreamFactoryJobControllerTest,DelayedTCPWithLargeSrtt)3418 TEST_P(HttpStreamFactoryJobControllerTest, DelayedTCPWithLargeSrtt) {
3419   // The max delay time should be in sync with .cc file.
3420   base::TimeDelta kMaxDelayTimeForMainJob = base::Seconds(3);
3421 
3422   HttpRequestInfo request_info;
3423   request_info.method = "GET";
3424   request_info.url = GURL("https://www.google.com");
3425 
3426   Initialize(request_info);
3427 
3428   // handshake will fail asynchronously after mock data is unpaused.
3429   MockQuicData quic_data(version_);
3430   quic_data.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
3431   quic_data.AddRead(ASYNC, ERR_FAILED);
3432   quic_data.AddWrite(ASYNC, ERR_FAILED);
3433   quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
3434 
3435   // Enable delayed TCP and set time delay for waiting job.
3436   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
3437   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
3438   ServerNetworkStats stats1;
3439   stats1.srtt = base::Seconds(100);
3440   session_->http_server_properties()->SetServerNetworkStats(
3441       url::SchemeHostPort(GURL("https://www.google.com")),
3442       NetworkAnonymizationKey(), stats1);
3443 
3444   url::SchemeHostPort server(request_info.url);
3445   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
3446   SetAlternativeService(request_info, alternative_service);
3447 
3448   // This prevents handshake from immediately succeeding.
3449   crypto_client_stream_factory_.set_handshake_mode(
3450       MockCryptoClientStream::COLD_START);
3451 
3452   request_ =
3453       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3454                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3455 
3456   EXPECT_TRUE(job_controller_->main_job());
3457   EXPECT_TRUE(job_controller_->alternative_job());
3458   base::RunLoop().RunUntilIdle();
3459   // Main job is not blocked but hasn't resumed yet; it should resume in 3s.
3460   EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
3461   EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_));
3462 
3463   // Task to resume main job in 3 seconds should be posted.
3464   EXPECT_NE(0u, GetPendingMainThreadTaskCount());
3465   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
3466   FastForwardBy(kMaxDelayTimeForMainJob - base::Microseconds(1));
3467   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
3468   FastForwardBy(base::Microseconds(1));
3469 
3470   EXPECT_TRUE(job_controller_->main_job());
3471   EXPECT_TRUE(job_controller_->alternative_job());
3472   EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
3473 
3474   // Unpause mock quic data and run all remaining tasks. Alt-job  should fail
3475   // and be cleaned up.
3476   quic_data.Resume();
3477   FastForwardUntilNoTasksRemain();
3478   EXPECT_FALSE(job_controller_->alternative_job());
3479 }
3480 
3481 // TODO(https://crbug.com/1007502): Disabled because the pending task count does
3482 //                                  not match expectations.
TEST_P(HttpStreamFactoryJobControllerTest,DISABLED_ResumeMainJobImmediatelyOnStreamFailed)3483 TEST_P(HttpStreamFactoryJobControllerTest,
3484        DISABLED_ResumeMainJobImmediatelyOnStreamFailed) {
3485   HttpRequestInfo request_info;
3486   request_info.method = "GET";
3487   request_info.url = GURL("https://www.google.com");
3488 
3489   Initialize(request_info);
3490 
3491   // handshake will fail asynchronously after mock data is unpaused.
3492   MockQuicData quic_data(version_);
3493   quic_data.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
3494   quic_data.AddRead(ASYNC, ERR_FAILED);
3495   quic_data.AddWrite(ASYNC, ERR_FAILED);
3496   quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
3497 
3498   // Enable delayed TCP and set time delay for waiting job.
3499   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
3500   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
3501   ServerNetworkStats stats1;
3502   stats1.srtt = base::Microseconds(10);
3503   session_->http_server_properties()->SetServerNetworkStats(
3504       url::SchemeHostPort(GURL("https://www.google.com")),
3505       NetworkAnonymizationKey(), stats1);
3506 
3507   url::SchemeHostPort server(request_info.url);
3508   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
3509   SetAlternativeService(request_info, alternative_service);
3510 
3511   // This prevents handshake from immediately succeeding.
3512   crypto_client_stream_factory_.set_handshake_mode(
3513       MockCryptoClientStream::COLD_START);
3514 
3515   request_ =
3516       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3517                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3518 
3519   EXPECT_TRUE(job_controller_->main_job());
3520   EXPECT_TRUE(job_controller_->alternative_job());
3521   // Main job is not blocked but hasn't resumed yet; it's scheduled to resume
3522   // in 15us.
3523   EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
3524   EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_));
3525 
3526   // Task to resume main job in 15us should be posted.
3527   EXPECT_NE(0u, GetPendingMainThreadTaskCount());
3528 
3529   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
3530   FastForwardBy(base::Microseconds(1));
3531 
3532   // Now unpause the mock quic data to fail the alt job. This should immediately
3533   // resume the main job.
3534   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
3535   quic_data.Resume();
3536   FastForwardBy(base::TimeDelta());
3537 
3538   EXPECT_TRUE(job_controller_->main_job());
3539   EXPECT_FALSE(job_controller_->alternative_job());
3540   EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
3541 
3542   // Verify there is another task to resume main job with delay but should
3543   // not call Resume() on the main job as main job has been resumed.
3544   EXPECT_NE(0u, GetPendingMainThreadTaskCount());
3545   EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
3546   FastForwardBy(base::Microseconds(15));
3547 
3548   FastForwardUntilNoTasksRemain();
3549 }
3550 
TEST_P(HttpStreamFactoryJobControllerTest,PreconnectToHostWithValidAltSvc)3551 TEST_P(HttpStreamFactoryJobControllerTest, PreconnectToHostWithValidAltSvc) {
3552   quic_data_ = std::make_unique<MockQuicData>(version_);
3553   quic_data_->AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
3554   quic_data_->AddRead(ASYNC, ERR_CONNECTION_CLOSED);
3555 
3556   HttpRequestInfo request_info;
3557   request_info.method = "GET";
3558   request_info.url = GURL("https://www.example.com");
3559   SetPreconnect();
3560 
3561   Initialize(request_info);
3562 
3563   url::SchemeHostPort server(request_info.url);
3564   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
3565   SetAlternativeService(request_info, alternative_service);
3566 
3567   job_controller_->Preconnect(1);
3568   EXPECT_TRUE(job_controller_->main_job());
3569   EXPECT_EQ(HttpStreamFactory::PRECONNECT,
3570             job_controller_->main_job()->job_type());
3571   EXPECT_FALSE(job_controller_->alternative_job());
3572 
3573   base::RunLoop().RunUntilIdle();
3574   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
3575 }
3576 
3577 // When preconnect to a H2 supported server, only 1 connection is opened.
TEST_P(HttpStreamFactoryJobControllerTest,PreconnectMultipleStreamsToH2Server)3578 TEST_P(HttpStreamFactoryJobControllerTest,
3579        PreconnectMultipleStreamsToH2Server) {
3580   tcp_data_ = std::make_unique<SequencedSocketData>();
3581   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
3582   SetPreconnect();
3583 
3584   HttpRequestInfo request_info;
3585   request_info.method = "GET";
3586   request_info.url = GURL("http://www.example.com");
3587   Initialize(request_info);
3588 
3589   // Sets server support HTTP/2.
3590   url::SchemeHostPort server(request_info.url);
3591   session_->http_server_properties()->SetSupportsSpdy(
3592       server, NetworkAnonymizationKey(), true);
3593 
3594   job_controller_->Preconnect(/*num_streams=*/5);
3595   // Only one job is started.
3596   EXPECT_TRUE(job_controller_->main_job());
3597   EXPECT_FALSE(job_controller_->alternative_job());
3598   EXPECT_EQ(HttpStreamFactory::PRECONNECT,
3599             job_controller_->main_job()->job_type());
3600   // There is only 1 connect even though multiple streams were requested.
3601   EXPECT_EQ(
3602       1, HttpStreamFactoryJobPeer::GetNumStreams(job_controller_->main_job()));
3603 
3604   base::RunLoop().RunUntilIdle();
3605   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
3606 }
3607 
3608 // Check that the logic to only preconnect a single socket to servers with H2
3609 // support respects NetworkIsolationKeys.
TEST_P(HttpStreamFactoryJobControllerTest,PreconnectMultipleStreamsToH2ServerWithNetworkIsolationKey)3610 TEST_P(HttpStreamFactoryJobControllerTest,
3611        PreconnectMultipleStreamsToH2ServerWithNetworkIsolationKey) {
3612   base::test::ScopedFeatureList feature_list;
3613   // It's not strictly necessary to enable
3614   // |kPartitionConnectionsByNetworkIsolationKey|, but the second phase of the
3615   // test would only make 4 connections, reusing the first connection, without
3616   // it.
3617   feature_list.InitWithFeatures(
3618       {// enabled_features
3619        features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3620        features::kPartitionConnectionsByNetworkIsolationKey},
3621       // disabled_features
3622       {});
3623   // Need to re-create HttpServerProperties after enabling the field trial,
3624   // since it caches the field trial value on construction.
3625   session_deps_.http_server_properties =
3626       std::make_unique<HttpServerProperties>();
3627 
3628   const SchemefulSite kSite1(GURL("https://foo.test/"));
3629   const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
3630   const auto kNetworkAnonymizationKey1 =
3631       NetworkAnonymizationKey::CreateSameSite(kSite1);
3632   const SchemefulSite kSite2(GURL("https://bar.test/"));
3633   const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
3634   const auto kNetworkAnonymizationKey2 =
3635       NetworkAnonymizationKey::CreateSameSite(kSite2);
3636 
3637   tcp_data_ = std::make_unique<SequencedSocketData>();
3638   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
3639   SetPreconnect();
3640 
3641   HttpRequestInfo request_info;
3642   request_info.method = "GET";
3643   request_info.url = GURL("http://www.example.com");
3644   request_info.network_isolation_key = kNetworkIsolationKey1;
3645   request_info.network_anonymization_key = kNetworkAnonymizationKey1;
3646   Initialize(request_info);
3647 
3648   // Sets server support HTTP/2, using kNetworkIsolationKey.
3649   url::SchemeHostPort server(request_info.url);
3650   session_->http_server_properties()->SetSupportsSpdy(
3651       server, kNetworkAnonymizationKey1, true);
3652 
3653   job_controller_->Preconnect(/*num_streams=*/5);
3654   // Only one job is started.
3655   EXPECT_TRUE(job_controller_->main_job());
3656   EXPECT_FALSE(job_controller_->alternative_job());
3657   EXPECT_EQ(HttpStreamFactory::PRECONNECT,
3658             job_controller_->main_job()->job_type());
3659   // There is only 1 connect even though multiple streams were requested.
3660   EXPECT_EQ(
3661       1, HttpStreamFactoryJobPeer::GetNumStreams(job_controller_->main_job()));
3662 
3663   base::RunLoop().RunUntilIdle();
3664   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
3665 
3666   // Now try using two different NetworkIsolationKeys, one empty, one not, and
3667   // make sure that 5 sockets are preconnected with each one.
3668   std::vector<std::unique_ptr<SequencedSocketData>> socket_data;
3669   for (auto other_network_isolation_key :
3670        {NetworkIsolationKey(), kNetworkIsolationKey2}) {
3671     for (int i = 0; i < 5; ++i) {
3672       socket_data.emplace_back(std::make_unique<SequencedSocketData>(
3673           MockConnect(ASYNC, OK), base::span<const MockRead>(),
3674           base::span<const MockWrite>()));
3675       session_deps_.socket_factory->AddSocketDataProvider(
3676           socket_data.back().get());
3677     }
3678 
3679     request_info.network_isolation_key = other_network_isolation_key;
3680     request_info.network_anonymization_key =
3681         net::NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
3682             other_network_isolation_key);
3683     MockHttpStreamRequestDelegate request_delegate;
3684     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
3685         factory_, &request_delegate, session_.get(), &job_factory_,
3686         request_info, is_preconnect_, /*is_websocket=*/false,
3687         enable_ip_based_pooling_, enable_alternative_services_,
3688         delay_main_job_with_available_spdy_session_,
3689         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
3690     auto* job_controller_ptr = job_controller.get();
3691     HttpStreamFactoryPeer::AddJobController(factory_,
3692                                             std::move(job_controller));
3693     job_controller_ptr->Preconnect(/*num_streams=*/5);
3694     // Five jobs should be started.
3695     EXPECT_TRUE(job_controller_ptr->main_job());
3696     EXPECT_FALSE(job_controller_ptr->alternative_job());
3697     EXPECT_EQ(HttpStreamFactory::PRECONNECT,
3698               job_controller_ptr->main_job()->job_type());
3699     EXPECT_EQ(5, HttpStreamFactoryJobPeer::GetNumStreams(
3700                      job_controller_ptr->main_job()));
3701 
3702     base::RunLoop().RunUntilIdle();
3703     EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
3704   }
3705 }
3706 
3707 void HttpStreamFactoryJobControllerTestBase::
TestDoNotDelayMainJobIfHasAvailableSpdySession(bool async_quic_session)3708     TestDoNotDelayMainJobIfHasAvailableSpdySession(bool async_quic_session) {
3709   SetAsyncQuicSession(async_quic_session);
3710 
3711   SetNotDelayMainJobWithAvailableSpdySession();
3712   HttpRequestInfo request_info;
3713   request_info.method = "GET";
3714   request_info.url = GURL("https://www.google.com");
3715 
3716   Initialize(request_info);
3717   // Put a SpdySession in the pool.
3718   HostPortPair host_port_pair("www.google.com", 443);
3719   SpdySessionKey key(host_port_pair, PRIVACY_MODE_DISABLED,
3720                      ProxyChain::Direct(), SessionUsage::kDestination,
3721                      SocketTag(), NetworkAnonymizationKey(),
3722                      SecureDnsPolicy::kAllow,
3723                      /*disable_cert_verification_network_fetches=*/false);
3724   std::ignore = CreateFakeSpdySession(session_->spdy_session_pool(), key);
3725 
3726   // Handshake will fail asynchronously after mock data is unpaused.
3727   MockQuicData quic_data(version_);
3728   quic_data.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
3729   quic_data.AddRead(ASYNC, ERR_FAILED);
3730   quic_data.AddWrite(ASYNC, ERR_FAILED);
3731   quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
3732 
3733   // Enable delayed TCP and set time delay for waiting job.
3734   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
3735   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
3736   ServerNetworkStats stats1;
3737   stats1.srtt = base::Milliseconds(100);
3738   session_->http_server_properties()->SetServerNetworkStats(
3739       url::SchemeHostPort(GURL("https://www.google.com")),
3740       NetworkAnonymizationKey(), stats1);
3741 
3742   url::SchemeHostPort server(request_info.url);
3743   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
3744   SetAlternativeService(request_info, alternative_service);
3745 
3746   // This prevents handshake from immediately succeeding.
3747   crypto_client_stream_factory_.set_handshake_mode(
3748       MockCryptoClientStream::COLD_START);
3749 
3750   request_ =
3751       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
3752                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3753 
3754   EXPECT_TRUE(job_controller_->main_job());
3755   EXPECT_TRUE(job_controller_->alternative_job());
3756   // The main job shouldn't have any delay since request can be sent on
3757   // available SPDY session. When QUIC session creation is async, the main job
3758   // should still be blocked as alt job has not succeeded or failed at least
3759   // once yet. Otherwise the main job should not be blocked
3760   EXPECT_EQ(job_controller_->get_main_job_wait_time_for_tests(),
3761             base::TimeDelta());
3762   if (async_quic_session) {
3763     EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
3764     // The main job should have a SPDY session available.
3765     EXPECT_TRUE(job_controller_->main_job()->HasAvailableSpdySession());
3766     // Wait for QUIC session creation attempt to resume and unblock the main
3767     // job.
3768     FastForwardBy(base::Milliseconds(1));
3769     // Main job should still have no delay and should be unblocked now.
3770     EXPECT_EQ(job_controller_->get_main_job_wait_time_for_tests(),
3771               base::TimeDelta());
3772     EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
3773   } else {
3774     EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
3775     EXPECT_TRUE(job_controller_->main_job()->HasAvailableSpdySession());
3776   }
3777 }
3778 
TEST_P(HttpStreamFactoryJobControllerTest,DoNotDelayMainJobIfHasAvailableSpdySession)3779 TEST_P(HttpStreamFactoryJobControllerTest,
3780        DoNotDelayMainJobIfHasAvailableSpdySession) {
3781   TestDoNotDelayMainJobIfHasAvailableSpdySession(false);
3782 }
3783 
TEST_P(HttpStreamFactoryJobControllerTest,DoNotDelayMainJobIfHasAvailableSpdySessionAsyncQuicSession)3784 TEST_P(HttpStreamFactoryJobControllerTest,
3785        DoNotDelayMainJobIfHasAvailableSpdySessionAsyncQuicSession) {
3786   TestDoNotDelayMainJobIfHasAvailableSpdySession(true);
3787 }
3788 
3789 // Check the case that while a preconnect is waiting in the H2 request queue,
3790 // and a SPDY session appears, the job completes successfully.
TEST_P(HttpStreamFactoryJobControllerTest,SpdySessionInterruptsPreconnect)3791 TEST_P(HttpStreamFactoryJobControllerTest, SpdySessionInterruptsPreconnect) {
3792   // Make sure there is only one socket connect.
3793   MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 0)};
3794   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
3795   tcp_data_ = std::make_unique<SequencedSocketData>(reads, writes);
3796   // connect needs to be async, so the H2 session isn't created immediately.
3797   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
3798   SSLSocketDataProvider ssl_data(ASYNC, OK);
3799   ssl_data.next_proto = kProtoHTTP2;
3800   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
3801   HttpRequestInfo request_info;
3802   request_info.method = "GET";
3803   request_info.url = GURL("https://www.example.com");
3804   Initialize(request_info);
3805 
3806   // Sets server support HTTP/2.
3807   url::SchemeHostPort server(request_info.url);
3808   session_->http_server_properties()->SetSupportsSpdy(
3809       server, NetworkAnonymizationKey(), true);
3810 
3811   // Start a non-preconnect request.
3812   std::unique_ptr<HttpStreamRequest> stream_request = job_controller_->Start(
3813       &request_delegate_, nullptr /* websocket_handshake_create_helper */,
3814       NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3815   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
3816 
3817   // Create and start a preconnect request, which should start watching the
3818   // SpdySessionPool.
3819   MockHttpStreamRequestDelegate preconnect_request_delegate;
3820   auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
3821       factory_, &preconnect_request_delegate, session_.get(), &job_factory_,
3822       request_info, /*is_preconnect=*/true, /*is_websocket=*/false,
3823       enable_ip_based_pooling_, enable_alternative_services_,
3824       delay_main_job_with_available_spdy_session_,
3825       /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
3826   auto* job_controller_ptr = job_controller.get();
3827   HttpStreamFactoryPeer::AddJobController(factory_, std::move(job_controller));
3828   job_controller_ptr->Preconnect(1);
3829   EXPECT_TRUE(job_controller_ptr->main_job());
3830   EXPECT_FALSE(job_controller_ptr->alternative_job());
3831 
3832   // The non-preconnect request should create an H2 session, which the
3833   // preconnect then sees, and the preconnect request should complete and be
3834   // torn down without ever requesting a socket. If it did request a socket, the
3835   // test would fail since the mock socket factory would see an unexpected
3836   // socket request.
3837   base::RunLoop().RunUntilIdle();
3838 
3839   stream_request.reset();
3840 
3841   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
3842 
3843   // Sanity check - make sure the SpdySession was created.
3844   base::WeakPtr<SpdySession> spdy_session =
3845       session_->spdy_session_pool()->FindAvailableSession(
3846           SpdySessionKey(HostPortPair::FromURL(request_info.url),
3847                          request_info.privacy_mode, ProxyChain::Direct(),
3848                          SessionUsage::kDestination, request_info.socket_tag,
3849                          request_info.network_anonymization_key,
3850                          request_info.secure_dns_policy,
3851                          /*disable_cert_verification_network_fetches=*/false),
3852           false /* enable_ip_based_pooling */, /*is_websocket=*/false,
3853           NetLogWithSource());
3854   EXPECT_TRUE(spdy_session);
3855 }
3856 
3857 // This test verifies that a preconnect job doesn't block subsequent requests
3858 // which can use an existing IP based pooled SpdySession.
3859 // This test uses "wildcard.pem" to support IpBasedPooling for *.example.org,
3860 // and starts 3 requests:
3861 //   [1] Normal non-preconnect request to www.example.org.
3862 //   [2] Preconnect request to other.example.org. The connection is paused until
3863 //       OnConnectComplete() is called in the end of the test.
3864 //   [3] Normal non-preconnect request to other.example.org. This request must
3865 //       succeed even while the preconnect request [2] is paused.
TEST_P(HttpStreamFactoryJobControllerTest,PreconnectJobDoesntBlockIpBasedPooling)3866 TEST_P(HttpStreamFactoryJobControllerTest,
3867        PreconnectJobDoesntBlockIpBasedPooling) {
3868   // Make sure that both "www.example.org" and "other.example.org" are pointing
3869   // to the same IP address.
3870   session_deps_.host_resolver->rules()->AddRule(
3871       "www.example.org", IPAddress::IPv4Localhost().ToString());
3872   session_deps_.host_resolver->rules()->AddRule(
3873       "other.example.org", IPAddress::IPv4Localhost().ToString());
3874   // Make |host_resolver| asynchronous to simulate the issue of
3875   // crbug.com/1320608.
3876   session_deps_.host_resolver->set_synchronous_mode(false);
3877 
3878   // This is used for the non-preconnect requests [1] and [3].
3879   MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 0)};
3880   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
3881   SequencedSocketData first_socket(reads, writes);
3882   first_socket.set_connect_data(MockConnect(ASYNC, OK));
3883   session_deps_.socket_factory->AddSocketDataProvider(&first_socket);
3884 
3885   // This is used for the non-preconnect requests.
3886   SSLSocketDataProvider ssl_data1(ASYNC, OK);
3887   ssl_data1.next_proto = kProtoHTTP2;
3888   // "wildcard.pem" supports "*.example.org".
3889   ssl_data1.ssl_info.cert =
3890       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
3891   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
3892 
3893   // This is used for the preconnect request.
3894   SequencedSocketData second_socket;
3895   // The connection is paused. And it will be completed with
3896   // ERR_CONNECTION_FAILED.
3897   second_socket.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING));
3898   session_deps_.socket_factory->AddSocketDataProvider(&second_socket);
3899 
3900   HttpRequestInfo request_info;
3901   request_info.method = "GET";
3902   request_info.url = GURL("https://www.example.org");
3903   Initialize(request_info);
3904 
3905   // Start a non-preconnect request [1].
3906   {
3907     std::unique_ptr<HttpStreamRequest> stream_request = job_controller_->Start(
3908         &request_delegate_,
3909         /*websocket_handshake_stream_create_helper=*/nullptr,
3910         NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
3911     if (dns_https_alpn_enabled()) {
3912       EXPECT_CALL(*job_factory_.main_job(), Resume())
3913           .Times(1)
3914           .WillOnce([this]() { job_factory_.main_job()->DoResume(); });
3915     }
3916     base::RunLoop run_loop;
3917     EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
3918         .WillOnce([&run_loop]() { run_loop.Quit(); });
3919     run_loop.Run();
3920   }
3921 
3922   // Sanity check - make sure the SpdySession was created.
3923   {
3924     base::WeakPtr<SpdySession> spdy_session =
3925         session_->spdy_session_pool()->FindAvailableSession(
3926             SpdySessionKey(HostPortPair::FromURL(request_info.url),
3927                            request_info.privacy_mode, ProxyChain::Direct(),
3928                            SessionUsage::kDestination, request_info.socket_tag,
3929                            request_info.network_anonymization_key,
3930                            request_info.secure_dns_policy,
3931                            /*disable_cert_verification_network_fetches=*/false),
3932             /*enable_ip_based_pooling=*/false, /*is_websocket=*/false,
3933             NetLogWithSource());
3934     EXPECT_TRUE(spdy_session);
3935   }
3936 
3937   HttpRequestInfo other_request_info;
3938   other_request_info.method = "GET";
3939   other_request_info.url = GURL("https://other.example.org");
3940 
3941   // Create and start a preconnect request [2].
3942   MockHttpStreamRequestDelegate preconnect_request_delegate;
3943   auto preconnect_job_controller =
3944       std::make_unique<HttpStreamFactory::JobController>(
3945           factory_, &preconnect_request_delegate, session_.get(), &job_factory_,
3946           other_request_info, /*is_preconnect=*/true,
3947           /*is_websocket=*/false, /*enable_ip_based_pooling=*/true,
3948           enable_alternative_services_,
3949           delay_main_job_with_available_spdy_session_,
3950           /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
3951   auto* preconnect_job_controller_ptr = preconnect_job_controller.get();
3952   HttpStreamFactoryPeer::AddJobController(factory_,
3953                                           std::move(preconnect_job_controller));
3954   preconnect_job_controller_ptr->Preconnect(1);
3955   base::RunLoop().RunUntilIdle();
3956 
3957   // The SpdySession is available for IP based pooling when the host resolution
3958   // has finished.
3959   {
3960     const SpdySessionKey spdy_session_key = SpdySessionKey(
3961         HostPortPair::FromURL(other_request_info.url),
3962         other_request_info.privacy_mode, ProxyChain::Direct(),
3963         SessionUsage::kDestination, other_request_info.socket_tag,
3964         other_request_info.network_anonymization_key,
3965         other_request_info.secure_dns_policy,
3966         /*disable_cert_verification_network_fetches=*/false);
3967     EXPECT_FALSE(session_->spdy_session_pool()->FindAvailableSession(
3968         spdy_session_key, /*enable_ip_based_pooling=*/false,
3969         /*is_websocket=*/false, NetLogWithSource()));
3970     EXPECT_TRUE(session_->spdy_session_pool()->FindAvailableSession(
3971         spdy_session_key, /*enable_ip_based_pooling=*/true,
3972         /*is_websocket=*/false, NetLogWithSource()));
3973   }
3974 
3975   // Create and start a second non-preconnect request [3].
3976   {
3977     MockHttpStreamRequestDelegate request_delegate;
3978     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
3979         factory_, &request_delegate, session_.get(), &job_factory_,
3980         other_request_info, /*is_preconnect=*/false,
3981         /*is_websocket=*/false, /*enable_ip_based_pooling=*/true,
3982         enable_alternative_services_,
3983         delay_main_job_with_available_spdy_session_,
3984         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
3985     auto* job_controller_ptr = job_controller.get();
3986     HttpStreamFactoryPeer::AddJobController(factory_,
3987                                             std::move(job_controller));
3988     std::unique_ptr<HttpStreamRequest> second_stream_request =
3989         job_controller_ptr->Start(
3990             &request_delegate,
3991             /*websocket_handshake_stream_create_helper=*/nullptr,
3992             NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
3993             DEFAULT_PRIORITY);
3994 
3995     base::RunLoop run_loop;
3996     EXPECT_CALL(request_delegate, OnStreamReadyImpl(_, _))
3997         .WillOnce([&run_loop]() { run_loop.Quit(); });
3998     run_loop.Run();
3999     second_stream_request.reset();
4000   }
4001 
4002   second_socket.socket()->OnConnectComplete(
4003       MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
4004   base::RunLoop().RunUntilIdle();
4005 
4006   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4007   EXPECT_TRUE(first_socket.AllReadDataConsumed());
4008   EXPECT_TRUE(first_socket.AllWriteDataConsumed());
4009 }
4010 
4011 class JobControllerLimitMultipleH2Requests
4012     : public HttpStreamFactoryJobControllerTestBase {
4013  protected:
JobControllerLimitMultipleH2Requests()4014   JobControllerLimitMultipleH2Requests()
4015       : HttpStreamFactoryJobControllerTestBase(false) {}
4016   const int kNumRequests = 5;
SetUp()4017   void SetUp() override { SkipCreatingJobController(); }
4018 };
4019 
TEST_F(JobControllerLimitMultipleH2Requests,MultipleRequests)4020 TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequests) {
4021   // Make sure there is only one socket connect.
4022   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
4023   tcp_data_ =
4024       std::make_unique<SequencedSocketData>(reads, base::span<MockWrite>());
4025   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
4026   SSLSocketDataProvider ssl_data(ASYNC, OK);
4027   ssl_data.next_proto = kProtoHTTP2;
4028   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
4029   HttpRequestInfo request_info;
4030   request_info.method = "GET";
4031   request_info.url = GURL("https://www.example.com");
4032   Initialize(request_info);
4033   SpdySessionPoolPeer pool_peer(session_->spdy_session_pool());
4034   pool_peer.SetEnableSendingInitialData(false);
4035 
4036   // Sets server support HTTP/2.
4037   url::SchemeHostPort server(request_info.url);
4038   session_->http_server_properties()->SetSupportsSpdy(
4039       server, NetworkAnonymizationKey(), true);
4040 
4041   std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates;
4042   std::vector<std::unique_ptr<HttpStreamRequest>> requests;
4043   for (int i = 0; i < kNumRequests; ++i) {
4044     request_delegates.emplace_back(
4045         std::make_unique<MockHttpStreamRequestDelegate>());
4046     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
4047         factory_, request_delegates[i].get(), session_.get(), &job_factory_,
4048         request_info, is_preconnect_, /*is_websocket=*/false,
4049         enable_ip_based_pooling_, enable_alternative_services_,
4050         delay_main_job_with_available_spdy_session_,
4051         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
4052     auto* job_controller_ptr = job_controller.get();
4053     HttpStreamFactoryPeer::AddJobController(factory_,
4054                                             std::move(job_controller));
4055     auto request = job_controller_ptr->Start(
4056         request_delegates[i].get(), nullptr, net_log_with_source_,
4057         HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
4058     EXPECT_TRUE(job_controller_ptr->main_job());
4059     EXPECT_FALSE(job_controller_ptr->alternative_job());
4060     requests.push_back(std::move(request));
4061   }
4062 
4063   for (int i = 0; i < kNumRequests; ++i) {
4064     EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _));
4065   }
4066 
4067   base::RunLoop().RunUntilIdle();
4068   requests.clear();
4069   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4070   auto entries = net_log_observer_.GetEntries();
4071   size_t log_position = 0;
4072   for (int i = 0; i < kNumRequests - 1; ++i) {
4073     log_position = ExpectLogContainsSomewhereAfter(
4074         entries, log_position, NetLogEventType::HTTP_STREAM_JOB_THROTTLED,
4075         NetLogEventPhase::NONE);
4076   }
4077 }
4078 
4079 // Check that throttling simultaneous requests to a single H2 server respects
4080 // NetworkIsolationKeys.
TEST_F(JobControllerLimitMultipleH2Requests,MultipleRequestsNetworkIsolationKey)4081 TEST_F(JobControllerLimitMultipleH2Requests,
4082        MultipleRequestsNetworkIsolationKey) {
4083   base::test::ScopedFeatureList feature_list;
4084   feature_list.InitWithFeatures(
4085       {// enabled_features
4086        features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4087        features::kPartitionConnectionsByNetworkIsolationKey},
4088       // disabled_features
4089       {});
4090   // Need to re-create HttpServerProperties after enabling the field trial,
4091   // since it caches the field trial value on construction.
4092   session_deps_.http_server_properties =
4093       std::make_unique<HttpServerProperties>();
4094 
4095   const SchemefulSite kSite1(GURL("https://foo.test/"));
4096   const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4097   const auto kNetworkAnonymizationKey1 =
4098       NetworkAnonymizationKey::CreateSameSite(kSite1);
4099   const SchemefulSite kSite2(GURL("https://bar.test/"));
4100   const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
4101   const auto kNetworkAnonymizationKey2 =
4102       NetworkAnonymizationKey::CreateSameSite(kSite2);
4103 
4104   tcp_data_ = std::make_unique<SequencedSocketData>(
4105       MockConnect(SYNCHRONOUS, ERR_IO_PENDING), base::span<MockRead>(),
4106       base::span<MockWrite>());
4107   HttpRequestInfo request_info;
4108   request_info.method = "GET";
4109   request_info.url = GURL("https://www.example.com");
4110   Initialize(request_info);
4111 
4112   // Sets server support HTTP/2.
4113   url::SchemeHostPort server(request_info.url);
4114   session_->http_server_properties()->SetSupportsSpdy(
4115       server, kNetworkAnonymizationKey1, true);
4116 
4117   std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates;
4118   std::vector<std::unique_ptr<HttpStreamRequest>> requests;
4119   std::vector<std::unique_ptr<SequencedSocketData>> socket_data;
4120   for (int i = 0; i < kNumRequests; ++i) {
4121     // Shouldn't matter whether requests are interleaved by NetworkIsolationKey
4122     // or not.
4123     for (const auto& network_isolation_key :
4124          {NetworkIsolationKey(), kNetworkIsolationKey1,
4125           kNetworkIsolationKey2}) {
4126       request_info.network_isolation_key = network_isolation_key;
4127       request_info.network_anonymization_key =
4128           net::NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
4129               network_isolation_key);
4130       // For kNetworkIsolationKey1, all requests but the first will be
4131       // throttled.
4132       if (i == 0 || network_isolation_key != kNetworkIsolationKey1) {
4133         socket_data.emplace_back(std::make_unique<SequencedSocketData>(
4134             MockConnect(ASYNC, OK), base::span<const MockRead>(),
4135             base::span<const MockWrite>()));
4136         session_deps_.socket_factory->AddSocketDataProvider(
4137             socket_data.back().get());
4138       }
4139       request_delegates.emplace_back(
4140           std::make_unique<MockHttpStreamRequestDelegate>());
4141       auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
4142           factory_, request_delegates[i].get(), session_.get(), &job_factory_,
4143           request_info, is_preconnect_, /*is_websocket=*/false,
4144           enable_ip_based_pooling_, enable_alternative_services_,
4145           delay_main_job_with_available_spdy_session_,
4146           /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
4147       auto* job_controller_ptr = job_controller.get();
4148       HttpStreamFactoryPeer::AddJobController(factory_,
4149                                               std::move(job_controller));
4150       auto request = job_controller_ptr->Start(
4151           request_delegates[i].get(), nullptr, net_log_with_source_,
4152           HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
4153       EXPECT_TRUE(job_controller_ptr->main_job());
4154       EXPECT_FALSE(job_controller_ptr->alternative_job());
4155       requests.push_back(std::move(request));
4156     }
4157   }
4158   TransportClientSocketPool* socket_pool =
4159       reinterpret_cast<TransportClientSocketPool*>(session_->GetSocketPool(
4160           HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct()));
4161   ClientSocketPool::GroupId group_id0(
4162       url::SchemeHostPort(request_info.url), request_info.privacy_mode,
4163       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
4164       /*disable_cert_network_fetches=*/false);
4165   ClientSocketPool::GroupId group_id1(
4166       url::SchemeHostPort(request_info.url), request_info.privacy_mode,
4167       kNetworkAnonymizationKey1, SecureDnsPolicy::kAllow,
4168       /*disable_cert_network_fetches=*/false);
4169   ClientSocketPool::GroupId group_id2(
4170       url::SchemeHostPort(request_info.url), request_info.privacy_mode,
4171       kNetworkAnonymizationKey2, SecureDnsPolicy::kAllow,
4172       /*disable_cert_network_fetches=*/false);
4173   EXPECT_EQ(static_cast<uint32_t>(kNumRequests),
4174             socket_pool->NumConnectJobsInGroupForTesting(group_id0));
4175   EXPECT_EQ(1u, socket_pool->NumConnectJobsInGroupForTesting(group_id1));
4176   EXPECT_EQ(static_cast<uint32_t>(kNumRequests),
4177             socket_pool->NumConnectJobsInGroupForTesting(group_id2));
4178 }
4179 
TEST_F(JobControllerLimitMultipleH2Requests,MultipleRequestsFirstRequestHang)4180 TEST_F(JobControllerLimitMultipleH2Requests, MultipleRequestsFirstRequestHang) {
4181   // First socket connect hang.
4182   SequencedSocketData hangdata;
4183   hangdata.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
4184   session_deps_.socket_factory->AddSocketDataProvider(&hangdata);
4185   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
4186   std::list<SequencedSocketData> socket_data;
4187   std::list<SSLSocketDataProvider> ssl_socket_data;
4188   // kNumRequests - 1 will resume themselves after a delay. There will be
4189   // kNumRequests - 1 sockets opened.
4190   for (int i = 0; i < kNumRequests - 1; i++) {
4191     // Only the first one needs a MockRead because subsequent sockets are
4192     // not used to establish a SpdySession.
4193     if (i == 0) {
4194       socket_data.emplace_back(reads, base::span<MockWrite>());
4195     } else {
4196       socket_data.emplace_back();
4197     }
4198     socket_data.back().set_connect_data(MockConnect(ASYNC, OK));
4199     session_deps_.socket_factory->AddSocketDataProvider(&socket_data.back());
4200     ssl_socket_data.emplace_back(ASYNC, OK);
4201     ssl_socket_data.back().next_proto = kProtoHTTP2;
4202     session_deps_.socket_factory->AddSSLSocketDataProvider(
4203         &ssl_socket_data.back());
4204   }
4205   HttpRequestInfo request_info;
4206   request_info.method = "GET";
4207   request_info.url = GURL("https://www.example.com");
4208   Initialize(request_info);
4209   SpdySessionPoolPeer pool_peer(session_->spdy_session_pool());
4210   pool_peer.SetEnableSendingInitialData(false);
4211 
4212   // Sets server support HTTP/2.
4213   url::SchemeHostPort server(request_info.url);
4214   session_->http_server_properties()->SetSupportsSpdy(
4215       server, NetworkAnonymizationKey(), true);
4216 
4217   std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates;
4218   std::vector<std::unique_ptr<HttpStreamRequest>> requests;
4219   for (int i = 0; i < kNumRequests; ++i) {
4220     request_delegates.push_back(
4221         std::make_unique<MockHttpStreamRequestDelegate>());
4222     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
4223         factory_, request_delegates[i].get(), session_.get(), &job_factory_,
4224         request_info, is_preconnect_, /*is_websocket=*/false,
4225         enable_ip_based_pooling_, enable_alternative_services_,
4226         delay_main_job_with_available_spdy_session_,
4227         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
4228     auto* job_controller_ptr = job_controller.get();
4229     HttpStreamFactoryPeer::AddJobController(factory_,
4230                                             std::move(job_controller));
4231     auto request = job_controller_ptr->Start(
4232         request_delegates[i].get(), nullptr, net_log_with_source_,
4233         HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
4234     EXPECT_TRUE(job_controller_ptr->main_job());
4235     EXPECT_FALSE(job_controller_ptr->alternative_job());
4236     requests.push_back(std::move(request));
4237   }
4238 
4239   for (int i = 0; i < kNumRequests; ++i) {
4240     EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _));
4241   }
4242 
4243   EXPECT_GT(GetPendingMainThreadTaskCount(), 0u);
4244   FastForwardBy(base::Milliseconds(HttpStreamFactory::Job::kHTTP2ThrottleMs));
4245   base::RunLoop().RunUntilIdle();
4246 
4247   EXPECT_FALSE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4248   requests.clear();
4249   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4250 
4251   EXPECT_TRUE(hangdata.AllReadDataConsumed());
4252   for (const auto& data : socket_data) {
4253     EXPECT_TRUE(data.AllReadDataConsumed());
4254     EXPECT_TRUE(data.AllWriteDataConsumed());
4255   }
4256 }
4257 
TEST_F(JobControllerLimitMultipleH2Requests,MultipleRequestsFirstRequestCanceled)4258 TEST_F(JobControllerLimitMultipleH2Requests,
4259        MultipleRequestsFirstRequestCanceled) {
4260   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
4261   SequencedSocketData first_socket(reads, base::span<MockWrite>());
4262   first_socket.set_connect_data(MockConnect(ASYNC, OK));
4263   SSLSocketDataProvider first_ssl_data(ASYNC, OK);
4264   first_ssl_data.next_proto = kProtoHTTP2;
4265   session_deps_.socket_factory->AddSocketDataProvider(&first_socket);
4266   session_deps_.socket_factory->AddSSLSocketDataProvider(&first_ssl_data);
4267   std::list<SequencedSocketData> socket_data;
4268   std::list<SSLSocketDataProvider> ssl_socket_data;
4269   // kNumRequests - 1 will be resumed when the first request is canceled.
4270   for (int i = 0; i < kNumRequests - 1; i++) {
4271     socket_data.emplace_back();
4272     socket_data.back().set_connect_data(MockConnect(ASYNC, OK));
4273     session_deps_.socket_factory->AddSocketDataProvider(&socket_data.back());
4274     ssl_socket_data.emplace_back(ASYNC, OK);
4275     ssl_socket_data.back().next_proto = kProtoHTTP2;
4276     session_deps_.socket_factory->AddSSLSocketDataProvider(
4277         &ssl_socket_data.back());
4278   }
4279 
4280   HttpRequestInfo request_info;
4281   request_info.method = "GET";
4282   request_info.url = GURL("https://www.example.com");
4283   Initialize(request_info);
4284   SpdySessionPoolPeer pool_peer(session_->spdy_session_pool());
4285   pool_peer.SetEnableSendingInitialData(false);
4286 
4287   // Sets server support HTTP/2.
4288   url::SchemeHostPort server(request_info.url);
4289   session_->http_server_properties()->SetSupportsSpdy(
4290       server, NetworkAnonymizationKey(), true);
4291 
4292   std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates;
4293   std::vector<std::unique_ptr<HttpStreamRequest>> requests;
4294   for (int i = 0; i < kNumRequests; ++i) {
4295     request_delegates.emplace_back(
4296         std::make_unique<MockHttpStreamRequestDelegate>());
4297     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
4298         factory_, request_delegates[i].get(), session_.get(), &job_factory_,
4299         request_info, is_preconnect_, /*is_websocket=*/false,
4300         enable_ip_based_pooling_, enable_alternative_services_,
4301         delay_main_job_with_available_spdy_session_,
4302         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
4303     auto* job_controller_ptr = job_controller.get();
4304     HttpStreamFactoryPeer::AddJobController(factory_,
4305                                             std::move(job_controller));
4306     auto request = job_controller_ptr->Start(
4307         request_delegates[i].get(), nullptr, net_log_with_source_,
4308         HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
4309     EXPECT_TRUE(job_controller_ptr->main_job());
4310     EXPECT_FALSE(job_controller_ptr->alternative_job());
4311     requests.push_back(std::move(request));
4312   }
4313   // Cancel the first one.
4314   requests[0].reset();
4315 
4316   for (int i = 1; i < kNumRequests; ++i) {
4317     EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _));
4318   }
4319   base::RunLoop().RunUntilIdle();
4320 
4321   EXPECT_FALSE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4322   requests.clear();
4323   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4324 
4325   EXPECT_TRUE(first_socket.AllReadDataConsumed());
4326   for (const auto& data : socket_data) {
4327     EXPECT_TRUE(data.AllReadDataConsumed());
4328     EXPECT_TRUE(data.AllWriteDataConsumed());
4329   }
4330 }
4331 
TEST_F(JobControllerLimitMultipleH2Requests,MultiplePreconnects)4332 TEST_F(JobControllerLimitMultipleH2Requests, MultiplePreconnects) {
4333   // Make sure there is only one socket connect.
4334   tcp_data_ = std::make_unique<SequencedSocketData>();
4335   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
4336   SSLSocketDataProvider ssl_data(ASYNC, OK);
4337   ssl_data.next_proto = kProtoHTTP2;
4338   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
4339   HttpRequestInfo request_info;
4340   request_info.method = "GET";
4341   request_info.url = GURL("https://www.example.com");
4342   SetPreconnect();
4343   Initialize(request_info);
4344 
4345   // Sets server support HTTP/2.
4346   url::SchemeHostPort server(request_info.url);
4347   session_->http_server_properties()->SetSupportsSpdy(
4348       server, NetworkAnonymizationKey(), true);
4349 
4350   std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates;
4351   for (int i = 0; i < kNumRequests; ++i) {
4352     request_delegates.emplace_back(
4353         std::make_unique<MockHttpStreamRequestDelegate>());
4354     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
4355         factory_, request_delegates[i].get(), session_.get(), &job_factory_,
4356         request_info, is_preconnect_, /*is_websocket=*/false,
4357         enable_ip_based_pooling_, enable_alternative_services_,
4358         delay_main_job_with_available_spdy_session_,
4359         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
4360     auto* job_controller_ptr = job_controller.get();
4361     HttpStreamFactoryPeer::AddJobController(factory_,
4362                                             std::move(job_controller));
4363     job_controller_ptr->Preconnect(1);
4364     EXPECT_TRUE(job_controller_ptr->main_job());
4365     EXPECT_FALSE(job_controller_ptr->alternative_job());
4366   }
4367   base::RunLoop().RunUntilIdle();
4368   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4369 }
4370 
TEST_F(JobControllerLimitMultipleH2Requests,H1NegotiatedForFirstRequest)4371 TEST_F(JobControllerLimitMultipleH2Requests, H1NegotiatedForFirstRequest) {
4372   // First socket is an HTTP/1.1 socket.
4373   SequencedSocketData first_socket;
4374   first_socket.set_connect_data(MockConnect(ASYNC, OK));
4375   SSLSocketDataProvider ssl_data(ASYNC, OK);
4376   session_deps_.socket_factory->AddSocketDataProvider(&first_socket);
4377   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
4378   // Second socket is an HTTP/2 socket.
4379   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
4380   SequencedSocketData second_socket(reads, base::span<MockWrite>());
4381   second_socket.set_connect_data(MockConnect(ASYNC, OK));
4382   session_deps_.socket_factory->AddSocketDataProvider(&second_socket);
4383   SSLSocketDataProvider second_ssl_data(ASYNC, OK);
4384   second_ssl_data.next_proto = kProtoHTTP2;
4385   session_deps_.socket_factory->AddSSLSocketDataProvider(&second_ssl_data);
4386 
4387   HttpRequestInfo request_info;
4388   request_info.method = "GET";
4389   request_info.url = GURL("https://www.example.com");
4390   Initialize(request_info);
4391   SpdySessionPoolPeer pool_peer(session_->spdy_session_pool());
4392   pool_peer.SetEnableSendingInitialData(false);
4393 
4394   // Sets server support HTTP/2.
4395   url::SchemeHostPort server(request_info.url);
4396   session_->http_server_properties()->SetSupportsSpdy(
4397       server, NetworkAnonymizationKey(), true);
4398 
4399   std::vector<std::unique_ptr<MockHttpStreamRequestDelegate>> request_delegates;
4400   std::vector<std::unique_ptr<HttpStreamRequest>> requests;
4401   for (int i = 0; i < 2; ++i) {
4402     request_delegates.emplace_back(
4403         std::make_unique<MockHttpStreamRequestDelegate>());
4404     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
4405         factory_, request_delegates[i].get(), session_.get(), &job_factory_,
4406         request_info, is_preconnect_, /*is_websocket=*/false,
4407         enable_ip_based_pooling_, enable_alternative_services_,
4408         delay_main_job_with_available_spdy_session_,
4409         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
4410     auto* job_controller_ptr = job_controller.get();
4411     HttpStreamFactoryPeer::AddJobController(factory_,
4412                                             std::move(job_controller));
4413     auto request = job_controller_ptr->Start(
4414         request_delegates[i].get(), nullptr, net_log_with_source_,
4415         HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
4416     EXPECT_TRUE(job_controller_ptr->main_job());
4417     EXPECT_FALSE(job_controller_ptr->alternative_job());
4418     requests.push_back(std::move(request));
4419   }
4420 
4421   for (int i = 0; i < 2; ++i) {
4422     EXPECT_CALL(*request_delegates[i].get(), OnStreamReadyImpl(_, _));
4423   }
4424   base::RunLoop().RunUntilIdle();
4425 
4426   EXPECT_FALSE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4427   requests.clear();
4428   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4429 
4430   EXPECT_TRUE(first_socket.AllReadDataConsumed());
4431   EXPECT_FALSE(second_socket.AllReadDataConsumed());
4432 }
4433 
4434 // Tests that HTTP/2 throttling logic only applies to non-QUIC jobs.
TEST_F(JobControllerLimitMultipleH2Requests,QuicJobNotThrottled)4435 TEST_F(JobControllerLimitMultipleH2Requests, QuicJobNotThrottled) {
4436   crypto_client_stream_factory_.set_handshake_mode(
4437       MockCryptoClientStream::COLD_START);
4438   quic_data_ = std::make_unique<MockQuicData>(version_);
4439   quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4440   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};
4441   tcp_data_ =
4442       std::make_unique<SequencedSocketData>(reads, base::span<MockWrite>());
4443 
4444   tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
4445   SSLSocketDataProvider ssl_data(ASYNC, OK);
4446   ssl_data.next_proto = kProtoHTTP2;
4447   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
4448 
4449   HttpRequestInfo request_info;
4450   request_info.method = "GET";
4451   request_info.url = GURL("https://www.google.com");
4452 
4453   Initialize(request_info);
4454   SpdySessionPoolPeer pool_peer(session_->spdy_session_pool());
4455   pool_peer.SetEnableSendingInitialData(false);
4456 
4457   url::SchemeHostPort server(request_info.url);
4458   // Sets server supports QUIC.
4459   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
4460   SetAlternativeService(request_info, alternative_service);
4461 
4462   // Sets server support HTTP/2.
4463   session_->http_server_properties()->SetSupportsSpdy(
4464       server, NetworkAnonymizationKey(), true);
4465 
4466   // Use default job factory so that Resume() is not mocked out.
4467   HttpStreamFactory::JobFactory default_job_factory;
4468   auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
4469       factory_, &request_delegate_, session_.get(), &default_job_factory,
4470       request_info, is_preconnect_, /*is_websocket=*/false,
4471       enable_ip_based_pooling_, enable_alternative_services_,
4472       delay_main_job_with_available_spdy_session_,
4473       /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
4474   auto* job_controller_ptr = job_controller.get();
4475   HttpStreamFactoryPeer::AddJobController(factory_, std::move(job_controller));
4476   request_ = job_controller_ptr->Start(
4477       &request_delegate_, nullptr, net_log_with_source_,
4478       HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
4479 
4480   EXPECT_TRUE(job_controller_ptr->main_job());
4481   EXPECT_TRUE(job_controller_ptr->alternative_job());
4482   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
4483   base::RunLoop().RunUntilIdle();
4484   auto entries = net_log_observer_.GetEntries();
4485   for (const auto& entry : entries) {
4486     ASSERT_NE(NetLogEventType::HTTP_STREAM_JOB_THROTTLED, entry.type);
4487   }
4488 }
4489 
4490 class HttpStreamFactoryJobControllerMisdirectedRequestRetry
4491     : public HttpStreamFactoryJobControllerTestBase,
4492       public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {
4493  public:
HttpStreamFactoryJobControllerMisdirectedRequestRetry()4494   HttpStreamFactoryJobControllerMisdirectedRequestRetry()
4495       : HttpStreamFactoryJobControllerTestBase(false) {}
4496 };
4497 
4498 INSTANTIATE_TEST_SUITE_P(All,
4499                          HttpStreamFactoryJobControllerMisdirectedRequestRetry,
4500                          ::testing::Combine(::testing::Bool(),
4501                                             ::testing::Bool()));
4502 
TEST_P(HttpStreamFactoryJobControllerMisdirectedRequestRetry,DisableIPBasedPoolingAndAlternativeServices)4503 TEST_P(HttpStreamFactoryJobControllerMisdirectedRequestRetry,
4504        DisableIPBasedPoolingAndAlternativeServices) {
4505   const bool enable_ip_based_pooling = ::testing::get<0>(GetParam());
4506   const bool enable_alternative_services = ::testing::get<1>(GetParam());
4507   if (enable_alternative_services) {
4508     quic_data_ = std::make_unique<MockQuicData>(version_);
4509     quic_data_->AddConnect(SYNCHRONOUS, OK);
4510     quic_data_->AddWrite(SYNCHRONOUS,
4511                          client_maker_.MakeInitialSettingsPacket(1));
4512     quic_data_->AddRead(ASYNC, ERR_CONNECTION_CLOSED);
4513   }
4514   tcp_data_ = std::make_unique<SequencedSocketData>();
4515   tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
4516   SSLSocketDataProvider ssl_data(ASYNC, OK);
4517   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
4518 
4519   HttpRequestInfo request_info;
4520   request_info.method = "GET";
4521   request_info.url = GURL("https://www.google.com");
4522 
4523   if (!enable_ip_based_pooling) {
4524     DisableIPBasedPooling();
4525   }
4526   if (!enable_alternative_services) {
4527     DisableAlternativeServices();
4528   }
4529 
4530   Initialize(request_info);
4531 
4532   url::SchemeHostPort server(request_info.url);
4533   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
4534   SetAlternativeService(request_info, alternative_service);
4535 
4536   request_ =
4537       job_controller_->Start(&request_delegate_, nullptr, net_log_with_source_,
4538                              HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
4539   EXPECT_TRUE(job_controller_->main_job());
4540   if (enable_alternative_services) {
4541     EXPECT_TRUE(job_controller_->alternative_job());
4542   } else {
4543     EXPECT_FALSE(job_controller_->alternative_job());
4544   }
4545 
4546   // |main_job| succeeds and should report status to Request.
4547   EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _));
4548   base::RunLoop().RunUntilIdle();
4549 }
4550 
4551 class HttpStreamFactoryJobControllerPreconnectTest
4552     : public HttpStreamFactoryJobControllerTestBase,
4553       public ::testing::WithParamInterface<bool> {
4554  protected:
HttpStreamFactoryJobControllerPreconnectTest()4555   HttpStreamFactoryJobControllerPreconnectTest()
4556       : HttpStreamFactoryJobControllerTestBase(false) {}
4557 
SetUp()4558   void SetUp() override {
4559     if (!GetParam()) {
4560       scoped_feature_list_.InitFromCommandLine(std::string(),
4561                                                "LimitEarlyPreconnects");
4562     }
4563   }
4564 
Initialize()4565   void Initialize() {
4566     session_deps_.http_server_properties =
4567         std::make_unique<HttpServerProperties>(
4568             std::make_unique<MockPrefDelegate>(), nullptr /* net_log */);
4569     session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
4570     factory_ = session_->http_stream_factory();
4571     request_info_.method = "GET";
4572     request_info_.url = GURL("https://www.example.com");
4573     auto job_controller = std::make_unique<HttpStreamFactory::JobController>(
4574         factory_, &request_delegate_, session_.get(), &job_factory_,
4575         request_info_, /* is_preconnect = */ true,
4576         /* is_websocket = */ false,
4577         /* enable_ip_based_pooling = */ true,
4578         /* enable_alternative_services = */ true,
4579         /* delay_main_job_with_available_spdy_session = */ true,
4580         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
4581     job_controller_ = job_controller.get();
4582     HttpStreamFactoryPeer::AddJobController(factory_,
4583                                             std::move(job_controller));
4584   }
4585 
4586  protected:
Preconnect(int num_streams)4587   void Preconnect(int num_streams) {
4588     job_controller_->Preconnect(num_streams);
4589     // Only one job is started.
4590     EXPECT_TRUE(job_controller_->main_job());
4591     EXPECT_FALSE(job_controller_->alternative_job());
4592   }
4593 
4594  private:
4595   base::test::ScopedFeatureList scoped_feature_list_;
4596   HttpRequestInfo request_info_;
4597 };
4598 
4599 INSTANTIATE_TEST_SUITE_P(All,
4600                          HttpStreamFactoryJobControllerPreconnectTest,
4601                          ::testing::Bool());
4602 
TEST_P(HttpStreamFactoryJobControllerPreconnectTest,LimitEarlyPreconnects)4603 TEST_P(HttpStreamFactoryJobControllerPreconnectTest, LimitEarlyPreconnects) {
4604   std::list<SequencedSocketData> providers;
4605   std::list<SSLSocketDataProvider> ssl_providers;
4606   const int kNumPreconects = 5;
4607   MockRead reads[] = {MockRead(ASYNC, OK)};
4608   // If experiment is not enabled, there are 5 socket connects.
4609   const size_t actual_num_connects = GetParam() ? 1 : kNumPreconects;
4610   for (size_t i = 0; i < actual_num_connects; ++i) {
4611     providers.emplace_back(reads, base::span<MockWrite>());
4612     session_deps_.socket_factory->AddSocketDataProvider(&providers.back());
4613     ssl_providers.emplace_back(ASYNC, OK);
4614     session_deps_.socket_factory->AddSSLSocketDataProvider(
4615         &ssl_providers.back());
4616   }
4617   Initialize();
4618   Preconnect(kNumPreconects);
4619   // If experiment is enabled, only 1 stream is requested.
4620   EXPECT_EQ((int)actual_num_connects, HttpStreamFactoryJobPeer::GetNumStreams(
4621                                           job_controller_->main_job()));
4622   base::RunLoop().RunUntilIdle();
4623   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
4624 }
4625 
4626 // Test that GetAlternativeServiceInfoFor will include a list of advertised
4627 // versions, which contains a version that is supported. Returns an empty list
4628 // if advertised versions are missing in HttpServerProperties.
TEST_P(HttpStreamFactoryJobControllerTest,GetAlternativeServiceInfoFor)4629 TEST_P(HttpStreamFactoryJobControllerTest, GetAlternativeServiceInfoFor) {
4630   HttpRequestInfo request_info;
4631   request_info.method = "GET";
4632   request_info.url = GURL("https://www.google.com");
4633 
4634   Initialize(request_info);
4635   url::SchemeHostPort server(request_info.url);
4636   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
4637   base::Time expiration = base::Time::Now() + base::Days(1);
4638 
4639   // Set alternative service with no advertised version.
4640   session_->http_server_properties()->SetQuicAlternativeService(
4641       server, NetworkAnonymizationKey(), alternative_service, expiration,
4642       quic::ParsedQuicVersionVector());
4643 
4644   // Simulate proxy resolution succeeding, after which
4645   // GetAlternativeServiceInfoFor can be called.
4646   JobControllerPeer::InitializeProxyInfo(job_controller_);
4647 
4648   AlternativeServiceInfo alt_svc_info =
4649       JobControllerPeer::GetAlternativeServiceInfoFor(
4650           job_controller_, request_info, &request_delegate_,
4651           HttpStreamRequest::HTTP_STREAM);
4652   // Verify that JobController get an empty list of supported QUIC versions.
4653   EXPECT_TRUE(alt_svc_info.advertised_versions().empty());
4654 
4655   // Set alternative service for the same server with the same list of versions
4656   // that is supported.
4657   quic::ParsedQuicVersionVector supported_versions =
4658       quic_context_.params()->supported_versions;
4659   session_->http_server_properties()->SetQuicAlternativeService(
4660       server, NetworkAnonymizationKey(), alternative_service, expiration,
4661       supported_versions);
4662 
4663   alt_svc_info = JobControllerPeer::GetAlternativeServiceInfoFor(
4664       job_controller_, request_info, &request_delegate_,
4665       HttpStreamRequest::HTTP_STREAM);
4666   std::sort(
4667       supported_versions.begin(), supported_versions.end(),
4668       [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
4669         return a.transport_version < b.transport_version;
4670       });
4671   quic::ParsedQuicVersionVector advertised_versions =
4672       alt_svc_info.advertised_versions();
4673   std::sort(
4674       advertised_versions.begin(), advertised_versions.end(),
4675       [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
4676         return a.transport_version < b.transport_version;
4677       });
4678   EXPECT_EQ(supported_versions, advertised_versions);
4679 
4680   quic::ParsedQuicVersion unsupported_version_1 =
4681       quic::ParsedQuicVersion::Unsupported();
4682   quic::ParsedQuicVersion unsupported_version_2 =
4683       quic::ParsedQuicVersion::Unsupported();
4684   for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
4685     if (base::Contains(supported_versions, version)) {
4686       continue;
4687     }
4688     if (unsupported_version_1 == quic::ParsedQuicVersion::Unsupported()) {
4689       unsupported_version_1 = version;
4690       continue;
4691     }
4692     unsupported_version_2 = version;
4693     break;
4694   }
4695 
4696   // Set alternative service for the same server with two QUIC versions:
4697   // - one unsupported version: |unsupported_version_1|,
4698   // - one supported version:
4699   // quic_context_.params()->supported_versions[0].
4700   quic::ParsedQuicVersionVector mixed_quic_versions = {
4701       unsupported_version_1, quic_context_.params()->supported_versions[0]};
4702   session_->http_server_properties()->SetQuicAlternativeService(
4703       server, NetworkAnonymizationKey(), alternative_service, expiration,
4704       mixed_quic_versions);
4705 
4706   alt_svc_info = JobControllerPeer::GetAlternativeServiceInfoFor(
4707       job_controller_, request_info, &request_delegate_,
4708       HttpStreamRequest::HTTP_STREAM);
4709   EXPECT_EQ(2u, alt_svc_info.advertised_versions().size());
4710   // Verify that JobController returns the list of versions specified in set.
4711   EXPECT_EQ(mixed_quic_versions, alt_svc_info.advertised_versions());
4712 
4713   // Set alternative service for the same server with two unsupported QUIC
4714   // versions: |unsupported_version_1|, |unsupported_version_2|.
4715   session_->http_server_properties()->SetQuicAlternativeService(
4716       server, NetworkAnonymizationKey(), alternative_service, expiration,
4717       {unsupported_version_1, unsupported_version_2});
4718 
4719   alt_svc_info = JobControllerPeer::GetAlternativeServiceInfoFor(
4720       job_controller_, request_info, &request_delegate_,
4721       HttpStreamRequest::HTTP_STREAM);
4722   // Verify that JobController returns no valid alternative service.
4723   EXPECT_EQ(kProtoUnknown, alt_svc_info.alternative_service().protocol);
4724   EXPECT_EQ(0u, alt_svc_info.advertised_versions().size());
4725 }
4726 
TestAltSvcVersionSelection(const std::string & alt_svc_header,const quic::ParsedQuicVersion & expected_version,const quic::ParsedQuicVersionVector & supported_versions)4727 void HttpStreamFactoryJobControllerTestBase::TestAltSvcVersionSelection(
4728     const std::string& alt_svc_header,
4729     const quic::ParsedQuicVersion& expected_version,
4730     const quic::ParsedQuicVersionVector& supported_versions) {
4731   quic_context_.params()->supported_versions = supported_versions;
4732   HttpRequestInfo request_info;
4733   request_info.method = "GET";
4734   request_info.url = GURL("https://example.com");
4735   NetworkIsolationKey network_isolation_key(
4736       SchemefulSite(GURL("https://example.com")),
4737       SchemefulSite(GURL("https://example.com")));
4738   auto network_anonymization_key = NetworkAnonymizationKey::CreateSameSite(
4739       SchemefulSite(GURL("https://example.com")));
4740   request_info.network_isolation_key = network_isolation_key;
4741   request_info.network_anonymization_key = network_anonymization_key;
4742 
4743   Initialize(request_info);
4744   url::SchemeHostPort origin(request_info.url);
4745   auto headers = base::MakeRefCounted<HttpResponseHeaders>("");
4746   headers->AddHeader("alt-svc", alt_svc_header);
4747   session_->http_stream_factory()->ProcessAlternativeServices(
4748       session_.get(), network_anonymization_key, headers.get(), origin);
4749   // Simulate proxy resolution succeeding, after which
4750   // GetAlternativeServiceInfoFor can be called.
4751   JobControllerPeer::InitializeProxyInfo(job_controller_);
4752   AlternativeServiceInfo alt_svc_info =
4753       JobControllerPeer::GetAlternativeServiceInfoFor(
4754           job_controller_, request_info, &request_delegate_,
4755           HttpStreamRequest::HTTP_STREAM);
4756   quic::ParsedQuicVersionVector advertised_versions =
4757       alt_svc_info.advertised_versions();
4758   quic::ParsedQuicVersion selected_version =
4759       JobControllerPeer::SelectQuicVersion(job_controller_,
4760                                            advertised_versions);
4761   EXPECT_EQ(expected_version, selected_version)
4762       << alt_svc_info.ToString() << " "
4763       << quic::ParsedQuicVersionVectorToString(advertised_versions);
4764 }
4765 
TEST_P(HttpStreamFactoryJobControllerTest,AltSvcVersionSelectionFindsFirstMatch)4766 TEST_P(HttpStreamFactoryJobControllerTest,
4767        AltSvcVersionSelectionFindsFirstMatch) {
4768   TestAltSvcVersionSelection(
4769       "h3-Q050=\":443\"; ma=2592000,"
4770       "h3-Q049=\":443\"; ma=2592000,"
4771       "h3-Q048=\":443\"; ma=2592000,"
4772       "h3-Q046=\":443\"; ma=2592000,",
4773       quic::ParsedQuicVersion::Q046(), quic::AllSupportedVersions());
4774 }
4775 
TEST_P(HttpStreamFactoryJobControllerTest,AltSvcVersionSelectionFindsFirstMatchInverse)4776 TEST_P(HttpStreamFactoryJobControllerTest,
4777        AltSvcVersionSelectionFindsFirstMatchInverse) {
4778   TestAltSvcVersionSelection(
4779       "h3-Q046=\":443\"; ma=2592000,"
4780       "h3-Q048=\":443\"; ma=2592000,"
4781       "h3-Q049=\":443\"; ma=2592000,",
4782       quic::ParsedQuicVersion::Q046(), quic::AllSupportedVersions());
4783 }
4784 
TEST_P(HttpStreamFactoryJobControllerTest,AltSvcVersionSelectionWithInverseOrderingNewFormat)4785 TEST_P(HttpStreamFactoryJobControllerTest,
4786        AltSvcVersionSelectionWithInverseOrderingNewFormat) {
4787   // Server prefers Q046 but client prefers Q050.
4788   TestAltSvcVersionSelection(
4789       "h3-Q046=\":443\"; ma=2592000,"
4790       "h3-Q050=\":443\"; ma=2592000",
4791       quic::ParsedQuicVersion::Q046(),
4792       quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::Q046()});
4793 }
4794 
4795 // Tests that if HttpNetworkSession has a non-empty QUIC host allowlist,
4796 // then GetAlternativeServiceFor() will not return any QUIC alternative service
4797 // that's not on the allowlist.
TEST_P(HttpStreamFactoryJobControllerTest,QuicHostAllowlist)4798 TEST_P(HttpStreamFactoryJobControllerTest, QuicHostAllowlist) {
4799   HttpRequestInfo request_info;
4800   request_info.method = "GET";
4801   request_info.url = GURL("https://www.google.com");
4802 
4803   Initialize(request_info);
4804 
4805   // Set HttpNetworkSession's QUIC host allowlist to only have www.example.com
4806   HttpNetworkSessionPeer session_peer(session_.get());
4807   session_peer.params()->quic_host_allowlist.insert("www.example.com");
4808   quic_context_.params()->allow_remote_alt_svc = true;
4809 
4810   // Set alternative service for www.google.com to be www.example.com over QUIC.
4811   url::SchemeHostPort server(request_info.url);
4812   base::Time expiration = base::Time::Now() + base::Days(1);
4813   quic::ParsedQuicVersionVector supported_versions =
4814       quic_context_.params()->supported_versions;
4815   session_->http_server_properties()->SetQuicAlternativeService(
4816       server, NetworkAnonymizationKey(),
4817       AlternativeService(kProtoQUIC, "www.example.com", 443), expiration,
4818       supported_versions);
4819 
4820   // Simulate proxy resolution succeeding, after which
4821   // GetAlternativeServiceInfoFor can be called.
4822   JobControllerPeer::InitializeProxyInfo(job_controller_);
4823 
4824   AlternativeServiceInfo alt_svc_info =
4825       JobControllerPeer::GetAlternativeServiceInfoFor(
4826           job_controller_, request_info, &request_delegate_,
4827           HttpStreamRequest::HTTP_STREAM);
4828 
4829   std::sort(
4830       supported_versions.begin(), supported_versions.end(),
4831       [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
4832         return a.transport_version < b.transport_version;
4833       });
4834   quic::ParsedQuicVersionVector advertised_versions =
4835       alt_svc_info.advertised_versions();
4836   std::sort(
4837       advertised_versions.begin(), advertised_versions.end(),
4838       [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
4839         return a.transport_version < b.transport_version;
4840       });
4841   EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
4842   EXPECT_EQ(supported_versions, advertised_versions);
4843 
4844   session_->http_server_properties()->SetQuicAlternativeService(
4845       server, NetworkAnonymizationKey(),
4846       AlternativeService(kProtoQUIC, "www.example.org", 443), expiration,
4847       supported_versions);
4848 
4849   alt_svc_info = JobControllerPeer::GetAlternativeServiceInfoFor(
4850       job_controller_, request_info, &request_delegate_,
4851       HttpStreamRequest::HTTP_STREAM);
4852 
4853   EXPECT_EQ(kProtoUnknown, alt_svc_info.alternative_service().protocol);
4854   EXPECT_EQ(0u, alt_svc_info.advertised_versions().size());
4855 }
4856 
4857 // Tests specific to UseDnsHttpsAlpn feature.
4858 class HttpStreamFactoryJobControllerDnsHttpsAlpnTest
4859     : public HttpStreamFactoryJobControllerTestBase {
4860  protected:
HttpStreamFactoryJobControllerDnsHttpsAlpnTest(std::vector<base::test::FeatureRef> enabled_features={})4861   explicit HttpStreamFactoryJobControllerDnsHttpsAlpnTest(
4862       std::vector<base::test::FeatureRef> enabled_features = {})
4863       : HttpStreamFactoryJobControllerTestBase(true,
4864                                                std::move(enabled_features)) {}
4865 
SetUp()4866   void SetUp() override { SkipCreatingJobController(); }
4867 
EnableOndemandHostResolver()4868   void EnableOndemandHostResolver() {
4869     session_deps_.host_resolver->set_synchronous_mode(false);
4870     session_deps_.host_resolver->set_ondemand_mode(true);
4871   }
4872 
CreateTestHttpRequestInfo()4873   HttpRequestInfo CreateTestHttpRequestInfo() {
4874     HttpRequestInfo request_info;
4875     request_info.method = "GET";
4876     request_info.url = GURL("https://www.example.org");
4877     return request_info;
4878   }
4879 
RegisterMockHttpsRecord()4880   void RegisterMockHttpsRecord() {
4881     HostResolverEndpointResult endpoint_result1;
4882     endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
4883     endpoint_result1.metadata.supported_protocol_alpns = {
4884         quic::AlpnForVersion(version_)};
4885 
4886     HostResolverEndpointResult endpoint_result2;
4887     endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
4888 
4889     std::vector<HostResolverEndpointResult> endpoints;
4890     endpoints.push_back(endpoint_result1);
4891     endpoints.push_back(endpoint_result2);
4892     session_deps_.host_resolver->rules()->AddRule(
4893         "www.example.org",
4894         MockHostResolverBase::RuleResolver::RuleResult(
4895             std::move(endpoints),
4896             /*aliases=*/std::set<std::string>{"www.example.org"}));
4897   }
4898 
CreateJobController(const HttpRequestInfo & request_info)4899   void CreateJobController(const HttpRequestInfo& request_info) {
4900     CreateJobControllerImpl(&job_controller_, &request_delegate_, request_info);
4901   }
4902 
CreateJobControllerAndStart(const HttpRequestInfo & request_info)4903   std::unique_ptr<HttpStreamRequest> CreateJobControllerAndStart(
4904       const HttpRequestInfo& request_info) {
4905     return CreateJobControllerAndStartImpl(&job_controller_, &request_delegate_,
4906                                            request_info);
4907   }
4908 
CreateSecondJobControllerAndStart(const HttpRequestInfo & request_info)4909   std::unique_ptr<HttpStreamRequest> CreateSecondJobControllerAndStart(
4910       const HttpRequestInfo& request_info) {
4911     return CreateJobControllerAndStartImpl(&job_controller2_,
4912                                            &request_delegate2_, request_info);
4913   }
4914 
PrepareForMainJob()4915   void PrepareForMainJob() { PrepareForMainJobImpl(&tcp_data_, &ssl_data_); }
PrepareForSecondMainJob()4916   void PrepareForSecondMainJob() {
4917     PrepareForMainJobImpl(&tcp_data2_, &ssl_data2_);
4918   }
4919 
PrepareForFirstQuicJob()4920   void PrepareForFirstQuicJob() { PrepareForQuicJobImpl(&quic_data_); }
PrepareForSecondQuicJob()4921   void PrepareForSecondQuicJob() { PrepareForQuicJobImpl(&quic_data2_); }
4922 
PrepareForFirstQuicJobFailure()4923   void PrepareForFirstQuicJobFailure() {
4924     PrepareForQuicJobFailureImpl(&quic_data_);
4925   }
PrepareForSecondQuicJobFailure()4926   void PrepareForSecondQuicJobFailure() {
4927     PrepareForQuicJobFailureImpl(&quic_data2_);
4928   }
4929 
MakeMainJobSucceed(bool expect_stream_ready)4930   void MakeMainJobSucceed(bool expect_stream_ready) {
4931     MakeMainJobSucceedImpl(request_delegate_, tcp_data_.get(),
4932                            expect_stream_ready);
4933   }
4934 
MakeSecondMainJobSucceed(bool expect_stream_ready)4935   void MakeSecondMainJobSucceed(bool expect_stream_ready) {
4936     MakeMainJobSucceedImpl(request_delegate2_, tcp_data2_.get(),
4937                            expect_stream_ready);
4938   }
4939 
MakeQuicJobSucceed(size_t index,bool expect_stream_ready)4940   void MakeQuicJobSucceed(size_t index, bool expect_stream_ready) {
4941     base::RunLoop().RunUntilIdle();
4942     ASSERT_GT(crypto_client_stream_factory_.streams().size(), index);
4943     MockCryptoClientStream* stream =
4944         crypto_client_stream_factory_.streams()[index].get();
4945     ASSERT_TRUE(stream);
4946 
4947     if (expect_stream_ready) {
4948       base::RunLoop run_loop;
4949       EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
4950           .Times(1)
4951           .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
4952       stream->NotifySessionOneRttKeyAvailable();
4953       run_loop.Run();
4954     } else {
4955       EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _)).Times(0);
4956       stream->NotifySessionOneRttKeyAvailable();
4957       base::RunLoop().RunUntilIdle();
4958     }
4959   }
4960 
CheckJobsStatus(bool main_job_exists,bool alternative_job_exists,bool dns_alpn_h3_job_exists,const std::string & scoped_trace_message="")4961   void CheckJobsStatus(bool main_job_exists,
4962                        bool alternative_job_exists,
4963                        bool dns_alpn_h3_job_exists,
4964                        const std::string& scoped_trace_message = "") {
4965     CheckJobsStatusImpl(job_controller_.get(), main_job_exists,
4966                         alternative_job_exists, dns_alpn_h3_job_exists,
4967                         scoped_trace_message);
4968   }
4969 
CheckSecondJobsStatus(bool main_job_exists,bool alternative_job_exists,bool dns_alpn_h3_job_exists,const std::string & scoped_trace_message="")4970   void CheckSecondJobsStatus(bool main_job_exists,
4971                              bool alternative_job_exists,
4972                              bool dns_alpn_h3_job_exists,
4973                              const std::string& scoped_trace_message = "") {
4974     CheckJobsStatusImpl(job_controller2_.get(), main_job_exists,
4975                         alternative_job_exists, dns_alpn_h3_job_exists,
4976                         scoped_trace_message);
4977   }
4978 
ConnectQuicHttpStream(bool alt_destination,bool require_dns_https_alpn)4979   std::unique_ptr<QuicHttpStream> ConnectQuicHttpStream(
4980       bool alt_destination,
4981       bool require_dns_https_alpn) {
4982     NetErrorDetails net_error_details;
4983     QuicSessionRequest quic_request(session_->quic_session_pool());
4984     url::SchemeHostPort scheme_host_port(
4985         url::kHttpsScheme,
4986         alt_destination ? "alt.example.org" : "www.example.org", 443);
4987     std::optional<int> quic_request_result;
4988 
4989     CHECK_EQ(ERR_IO_PENDING,
4990              quic_request.Request(
4991                  scheme_host_port,
4992                  require_dns_https_alpn ? quic::ParsedQuicVersion::Unsupported()
4993                                         : version_,
4994                  ProxyChain::Direct(), TRAFFIC_ANNOTATION_FOR_TESTS,
4995                  /*http_user_agent_settings=*/nullptr,
4996                  SessionUsage::kDestination, PRIVACY_MODE_DISABLED,
4997                  DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
4998                  SecureDnsPolicy::kAllow, require_dns_https_alpn,
4999                  /*cert_verify_flags=*/0, GURL("https://www.example.org/"),
5000                  net_log_with_source_, &net_error_details,
5001                  base::BindLambdaForTesting([&](int result) {}),
5002                  base::BindLambdaForTesting([&quic_request_result](int result) {
5003                    quic_request_result = result;
5004                  })));
5005     base::RunLoop().RunUntilIdle();
5006     CHECK_EQ(1u, crypto_client_stream_factory_.streams().size());
5007     CHECK(crypto_client_stream_factory_.streams()[0]);
5008     crypto_client_stream_factory_.streams()[0]
5009         ->NotifySessionOneRttKeyAvailable();
5010     base::RunLoop().RunUntilIdle();
5011     CHECK(quic_request_result);
5012     CHECK_EQ(OK, *quic_request_result);
5013 
5014     std::unique_ptr<QuicChromiumClientSession::Handle> session =
5015         quic_request.ReleaseSessionHandle();
5016     std::set<std::string> dns_aliases =
5017         session->GetDnsAliasesForSessionKey(quic_request.session_key());
5018     auto stream = std::make_unique<QuicHttpStream>(std::move(session),
5019                                                    std::move(dns_aliases));
5020     return stream;
5021   }
5022 
IsAlternativeServiceBroken(GURL & url)5023   bool IsAlternativeServiceBroken(GURL& url) {
5024     return session_->http_server_properties()->IsAlternativeServiceBroken(
5025         AlternativeService(kProtoQUIC, HostPortPair::FromURL(url)),
5026         NetworkAnonymizationKey());
5027   }
5028 
5029   raw_ptr<HttpStreamFactory::JobController, AcrossTasksDanglingUntriaged>
5030       job_controller2_ = nullptr;
5031 
5032   MockHttpStreamRequestDelegate request_delegate2_;
5033 
5034  private:
CreateQuicTestPacketMakerForClient()5035   QuicTestPacketMaker CreateQuicTestPacketMakerForClient() {
5036     return QuicTestPacketMaker(version_,
5037                                quic::QuicUtils::CreateRandomConnectionId(
5038                                    quic_context_.random_generator()),
5039                                quic_context_.clock(), "www.example.org",
5040                                quic::Perspective::IS_CLIENT, false);
5041   }
5042 
CreateJobControllerImpl(raw_ptr<HttpStreamFactory::JobController,AcrossTasksDanglingUntriaged> * job_controller,MockHttpStreamRequestDelegate * request_delegate,const HttpRequestInfo & request_info)5043   void CreateJobControllerImpl(
5044       raw_ptr<HttpStreamFactory::JobController, AcrossTasksDanglingUntriaged>*
5045           job_controller,
5046       MockHttpStreamRequestDelegate* request_delegate,
5047       const HttpRequestInfo& request_info) {
5048     auto controller = std::make_unique<HttpStreamFactory::JobController>(
5049         factory_, request_delegate, session_.get(), &default_job_factory_,
5050         request_info, is_preconnect_, /*is_websocket=*/false,
5051         enable_ip_based_pooling_, enable_alternative_services_,
5052         delay_main_job_with_available_spdy_session_,
5053         /*allowed_bad_certs=*/std::vector<SSLConfig::CertAndStatus>());
5054     *job_controller = controller.get();
5055     HttpStreamFactoryPeer::AddJobController(factory_, std::move(controller));
5056   }
5057 
CreateJobControllerAndStartImpl(raw_ptr<HttpStreamFactory::JobController,AcrossTasksDanglingUntriaged> * job_controller,MockHttpStreamRequestDelegate * request_delegate,const HttpRequestInfo & request_info)5058   std::unique_ptr<HttpStreamRequest> CreateJobControllerAndStartImpl(
5059       raw_ptr<HttpStreamFactory::JobController, AcrossTasksDanglingUntriaged>*
5060           job_controller,
5061       MockHttpStreamRequestDelegate* request_delegate,
5062       const HttpRequestInfo& request_info) {
5063     CreateJobControllerImpl(job_controller, request_delegate, request_info);
5064     return (*job_controller)
5065         ->Start(request_delegate, nullptr, net_log_with_source_,
5066                 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
5067   }
5068 
PrepareForMainJobImpl(std::unique_ptr<SequencedSocketData> * tcp_data,std::unique_ptr<SSLSocketDataProvider> * ssl_data)5069   void PrepareForMainJobImpl(std::unique_ptr<SequencedSocketData>* tcp_data,
5070                              std::unique_ptr<SSLSocketDataProvider>* ssl_data) {
5071     *tcp_data = std::make_unique<SequencedSocketData>();
5072     (*tcp_data)->set_connect_data(
5073         MockConnect(ASYNC, ERR_IO_PENDING)); /* pause */
5074     (*ssl_data) = std::make_unique<SSLSocketDataProvider>(ASYNC, OK);
5075     session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data->get());
5076   }
5077 
PrepareForQuicJobImpl(std::unique_ptr<MockQuicData> * quic_data)5078   void PrepareForQuicJobImpl(std::unique_ptr<MockQuicData>* quic_data) {
5079     crypto_client_stream_factory_.set_handshake_mode(
5080         MockCryptoClientStream::COLD_START);
5081     *quic_data = std::make_unique<MockQuicData>(version_);
5082     (*quic_data)->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5083     (*quic_data)
5084         ->AddWrite(
5085             SYNCHRONOUS,
5086             CreateQuicTestPacketMakerForClient().MakeInitialSettingsPacket(1));
5087   }
5088 
PrepareForQuicJobFailureImpl(std::unique_ptr<MockQuicData> * quic_data)5089   void PrepareForQuicJobFailureImpl(std::unique_ptr<MockQuicData>* quic_data) {
5090     crypto_client_stream_factory_.set_handshake_mode(
5091         MockCryptoClientStream::COLD_START);
5092     *quic_data = std::make_unique<MockQuicData>(version_);
5093     (*quic_data)->AddRead(ASYNC, ERR_IO_PENDING);  // Pause
5094     (*quic_data)->AddRead(ASYNC, ERR_FAILED);
5095   }
5096 
MakeMainJobSucceedImpl(MockHttpStreamRequestDelegate & request_delegate,SequencedSocketData * tcp_data,bool expect_stream_ready)5097   void MakeMainJobSucceedImpl(MockHttpStreamRequestDelegate& request_delegate,
5098                               SequencedSocketData* tcp_data,
5099                               bool expect_stream_ready) {
5100     if (expect_stream_ready) {
5101       base::RunLoop run_loop;
5102       EXPECT_CALL(request_delegate, OnStreamReadyImpl(_, _))
5103           .Times(1)
5104           .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
5105       tcp_data->socket()->OnConnectComplete(MockConnect());
5106       run_loop.Run();
5107     } else {
5108       EXPECT_CALL(request_delegate, OnStreamReadyImpl(_, _)).Times(0);
5109       tcp_data->socket()->OnConnectComplete(MockConnect());
5110       base::RunLoop().RunUntilIdle();
5111     }
5112   }
5113 
CheckJobsStatusImpl(HttpStreamFactory::JobController * job_controller,bool main_job_exists,bool alternative_job_exists,bool dns_alpn_h3_job_exists,const std::string & scoped_trace_message)5114   static void CheckJobsStatusImpl(
5115       HttpStreamFactory::JobController* job_controller,
5116       bool main_job_exists,
5117       bool alternative_job_exists,
5118       bool dns_alpn_h3_job_exists,
5119       const std::string& scoped_trace_message) {
5120     SCOPED_TRACE(scoped_trace_message);
5121     EXPECT_EQ(main_job_exists, !!job_controller->main_job());
5122     EXPECT_EQ(alternative_job_exists, !!job_controller->alternative_job());
5123     EXPECT_EQ(dns_alpn_h3_job_exists, !!job_controller->dns_alpn_h3_job());
5124   }
5125 
5126   // Use real Jobs so that Job::Resume() is not mocked out. When main job is
5127   // resumed it will use mock socket data.
5128   HttpStreamFactory::JobFactory default_job_factory_;
5129 
5130   // Used for man job connection.
5131   std::unique_ptr<SSLSocketDataProvider> ssl_data_;
5132   std::unique_ptr<SSLSocketDataProvider> ssl_data2_;
5133 };
5134 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,NoHttpsRecordSyncHostResolve)5135 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5136        NoHttpsRecordSyncHostResolve) {
5137   PrepareForMainJob();
5138   Initialize(HttpRequestInfo());
5139   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5140 
5141   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5142                   /*dns_alpn_h3_job_exists=*/true,
5143                   "Main job and DNS ALPN job must be created.");
5144 
5145   // The main job should be synchronously resumed, as host is resolved
5146   // synchronously.
5147   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5148 
5149   base::RunLoop().RunUntilIdle();
5150 
5151   // |dns_alpn_h3_job| must fail when there is no valid supported alpn. And
5152   // must be deleted.
5153   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5154                   /*dns_alpn_h3_job_exists=*/false,
5155                   "DNS ALPN job must be deleted.");
5156 
5157   base::HistogramTester histogram_tester;
5158   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5159   // Net.AlternateProtocolUsage records
5160   // ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON, when only main job exists.
5161   histogram_tester.ExpectUniqueSample(
5162       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON,
5163       1);
5164 
5165   request_.reset();
5166   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5167 }
5168 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,NoHttpsRecordAsyncHostResolveResumeMainWithoutDelay)5169 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5170        NoHttpsRecordAsyncHostResolveResumeMainWithoutDelay) {
5171   EnableOndemandHostResolver();
5172   PrepareForMainJob();
5173   Initialize(HttpRequestInfo());
5174 
5175   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5176 
5177   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5178                   /*dns_alpn_h3_job_exists=*/true,
5179                   "Main job and DNS ALPN job must be created.");
5180 
5181   // The main job should be resumed quickly after resolving the host.
5182   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5183 
5184   // Resolve the host resolve request from |dns_alpn_h3_job|.
5185   session_deps_.host_resolver->ResolveAllPending();
5186   base::RunLoop().RunUntilIdle();
5187 
5188   // |dns_alpn_h3_job| must fail when there is no valid supported alpn. And
5189   // must be deleted.
5190   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5191                   /*dns_alpn_h3_job_exists=*/false,
5192                   "DNS ALPN job must be deleted.");
5193   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5194 
5195   // The host resolve request from the main job must be resolved using the
5196   // cached result.
5197   EXPECT_TRUE(tcp_data_->socket());
5198 
5199   base::HistogramTester histogram_tester;
5200   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5201   // Net.AlternateProtocolUsage records
5202   // ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON, when only main job exists.
5203   histogram_tester.ExpectUniqueSample(
5204       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON,
5205       1);
5206 
5207   request_.reset();
5208   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5209 }
5210 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,NoHttpsRecordAsyncHostResolveResumeMainWithoutDelayQuicWorkedNetwork)5211 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5212        NoHttpsRecordAsyncHostResolveResumeMainWithoutDelayQuicWorkedNetwork) {
5213   EnableOndemandHostResolver();
5214   PrepareForMainJob();
5215   Initialize(HttpRequestInfo());
5216 
5217   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
5218   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
5219 
5220   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5221 
5222   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5223                   /*dns_alpn_h3_job_exists=*/true,
5224                   "Main job and DNS ALPN job must be created.");
5225   // Main job must be waiting.
5226   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5227 
5228   // Resolve the host resolve request from |dns_alpn_h3_job|.
5229   session_deps_.host_resolver->ResolveAllPending();
5230   base::RunLoop().RunUntilIdle();
5231 
5232   // |dns_alpn_h3_job| must fail when there is no valid supported alpn. And
5233   // must be deleted.
5234   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5235                   /*dns_alpn_h3_job_exists=*/false,
5236                   "DNS ALPN job must be deleted.");
5237   // The main job should be resumed quickly after resolving the host.
5238   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5239 
5240   // The host resolve request from the main job must be resolved using the
5241   // cached result.
5242   EXPECT_TRUE(tcp_data_->socket());
5243 
5244   base::HistogramTester histogram_tester;
5245   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5246   // Net.AlternateProtocolUsage records
5247   // ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON, when only main job exists.
5248   histogram_tester.ExpectUniqueSample(
5249       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON,
5250       1);
5251 
5252   request_.reset();
5253   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5254 }
5255 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,MainJobNoDelayOnQuicNotWorkedNetworkSyncHostResolve)5256 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5257        MainJobNoDelayOnQuicNotWorkedNetworkSyncHostResolve) {
5258   PrepareForMainJob();
5259   PrepareForFirstQuicJob();
5260   RegisterMockHttpsRecord();
5261 
5262   Initialize(HttpRequestInfo());
5263 
5264   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5265 
5266   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5267                   /*dns_alpn_h3_job_exists=*/true,
5268                   "Main job and DNS ALPN job must be created.");
5269   // `dns_alpn_h3_job` should not be waiting for dns host
5270   // resolution as that was resolved synchronously.
5271   EXPECT_FALSE(job_controller_->dns_alpn_h3_job()
5272                    ->expect_on_quic_host_resolution_for_tests());
5273 
5274   base::HistogramTester histogram_tester;
5275   // Make |dns_alpn_h3_job| succeed.
5276   MakeQuicJobSucceed(0, /*expect_stream_ready=*/true);
5277   histogram_tester.ExpectUniqueSample(
5278       "Net.AlternateProtocolUsage",
5279       ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1);
5280 
5281   // The success of |dns_alpn_h3_job| deletes |main_job|.
5282   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
5283                   /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted.");
5284 
5285   request_.reset();
5286   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5287 }
5288 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,MainJobNoDelayOnQuicNotWorkedNetworkAsyncHostResolve)5289 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5290        MainJobNoDelayOnQuicNotWorkedNetworkAsyncHostResolve) {
5291   EnableOndemandHostResolver();
5292   PrepareForMainJob();
5293   PrepareForFirstQuicJob();
5294   RegisterMockHttpsRecord();
5295 
5296   Initialize(HttpRequestInfo());
5297 
5298   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5299 
5300   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5301                   /*dns_alpn_h3_job_exists=*/true,
5302                   "Main job and DNS ALPN job must be created.");
5303 
5304   // |main_job| is blocked until host resolves.
5305   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5306   base::RunLoop().RunUntilIdle();
5307   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5308 
5309   // Resolve the host resolve request from |dns_alpn_h3_job|.
5310   session_deps_.host_resolver->ResolveAllPending();
5311   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5312   base::RunLoop().RunUntilIdle();
5313 
5314   // |main_job| should have been resumed quickly because
5315   // |is_quic_known_to_work_on_current_network| is false for this test.
5316   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5317   // |dns_alpn_h3_job| must not fail when there is a valid supported alpn.
5318   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5319                   /*dns_alpn_h3_job_exists=*/true,
5320                   "Both main job and DNS ALPN job must be alive");
5321 
5322   base::HistogramTester histogram_tester;
5323   // Make |dns_alpn_h3_job| succeed.
5324   MakeQuicJobSucceed(0, /*expect_stream_ready=*/true);
5325   histogram_tester.ExpectUniqueSample(
5326       "Net.AlternateProtocolUsage",
5327       ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1);
5328 
5329   // The success of |dns_alpn_h3_job| deletes |main_job|.
5330   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
5331                   /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted.");
5332 
5333   request_.reset();
5334   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5335 }
5336 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,MainJobDelayOnQuicWorkedNetwork)5337 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5338        MainJobDelayOnQuicWorkedNetwork) {
5339   PrepareForMainJob();
5340   PrepareForFirstQuicJob();
5341   RegisterMockHttpsRecord();
5342 
5343   Initialize(HttpRequestInfo());
5344   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
5345   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
5346 
5347   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5348 
5349   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5350                   /*dns_alpn_h3_job_exists=*/true,
5351                   "Main job and DNS ALPN job must be created.");
5352   base::RunLoop().RunUntilIdle();
5353   // |dns_alpn_h3_job| must not fail when there is a valid supported alpn.
5354   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5355                   /*dns_alpn_h3_job_exists=*/true,
5356                   "Both main job and DNS ALPN job must be alive");
5357 
5358   // The main job should be waiting until kDefaultDelayMilliSecsForWaitingJob
5359   // amount of time has passed.
5360   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5361   FastForwardBy(base::Milliseconds(kDefaultDelayMilliSecsForWaitingJob - 1));
5362   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5363   FastForwardBy(base::Milliseconds(1));
5364   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5365 
5366   base::HistogramTester histogram_tester;
5367   // Make |dns_alpn_h3_job| succeed.
5368   MakeQuicJobSucceed(0, /*expect_stream_ready=*/true);
5369   histogram_tester.ExpectUniqueSample(
5370       "Net.AlternateProtocolUsage",
5371       ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1);
5372 
5373   // The success of |dns_alpn_h3_job| deletes |main_job|.
5374   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
5375                   /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted.");
5376 
5377   request_.reset();
5378   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5379 }
5380 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,MainJobSucceedsDnsAlpnH3JobSucceeds)5381 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5382        MainJobSucceedsDnsAlpnH3JobSucceeds) {
5383   PrepareForMainJob();
5384   PrepareForFirstQuicJob();
5385   RegisterMockHttpsRecord();
5386 
5387   Initialize(HttpRequestInfo());
5388   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5389   base::RunLoop().RunUntilIdle();
5390 
5391   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5392                   /*dns_alpn_h3_job_exists=*/true,
5393                   "Main job and DNS ALPN job must be created.");
5394   // |main_job| is not blocked, because the hostname is resolved synchronously
5395   // and |is_quic_known_to_work_on_current_network| is false for this test.
5396   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5397 
5398   base::HistogramTester histogram_tester;
5399   // Make |main_job| succeed.
5400   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5401   histogram_tester.ExpectUniqueSample(
5402       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE,
5403       1);
5404 
5405   // The success of |main_job| doesn't delete |dns_alpn_h3_job|.
5406   EXPECT_TRUE(job_controller_->dns_alpn_h3_job());
5407 
5408   // Make |dns_alpn_h3_job| complete.
5409   MakeQuicJobSucceed(0, /*expect_stream_ready=*/false);
5410 
5411   request_.reset();
5412   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5413 }
5414 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,ActiveSessionAvailableForMainJob)5415 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5416        ActiveSessionAvailableForMainJob) {
5417   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5418   PrepareForFirstQuicJob();
5419 
5420   RegisterMockHttpsRecord();
5421 
5422   Initialize(HttpRequestInfo());
5423 
5424   // Set |is_quic_known_to_work_on_current_network| flag so that
5425   // the delaying logic of main job would work when the main job is blocked.
5426   // Note: In this test, we don't need this because the main job is not blocked.
5427   // But we set here because we want to check that the main job is not blocked.
5428   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
5429   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
5430 
5431   // Put a SpdySession in the pool.
5432   SpdySessionKey key(HostPortPair::FromURL(request_info.url),
5433                      PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
5434                      SessionUsage::kDestination, SocketTag(),
5435                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
5436                      /*disable_cert_verification_network_fetches=*/false);
5437   std::ignore = CreateFakeSpdySession(session_->spdy_session_pool(), key);
5438 
5439   request_ = CreateJobControllerAndStart(request_info);
5440   // |dns_alpn_h3_job| must be created even when an active session is
5441   // available for |main_job|.
5442   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5443                   /*dns_alpn_h3_job_exists=*/true,
5444                   "Main job and DNS ALPN job must be created.");
5445 
5446   // Main job must not be waiting because an active session is available.
5447   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5448 
5449   base::HistogramTester histogram_tester;
5450   // Run the message loop to make |main_job| succeed and status will be
5451   // reported to Request.
5452   {
5453     base::RunLoop run_loop;
5454     EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
5455         .Times(1)
5456         .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
5457     run_loop.Run();
5458   }
5459   histogram_tester.ExpectUniqueSample(
5460       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE,
5461       1);
5462 
5463   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5464                   /*dns_alpn_h3_job_exists=*/true,
5465                   "DNS ALPN job must be alive");
5466 
5467   // Make |dns_alpn_h3_job| succeed.
5468   MakeQuicJobSucceed(0, /*expect_stream_ready=*/false);
5469   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5470                   /*dns_alpn_h3_job_exists=*/false,
5471                   "DNS ALPN job must be deleted");
5472 
5473   request_.reset();
5474   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5475 }
5476 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,MainJobHasActiveSocket)5477 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, MainJobHasActiveSocket) {
5478   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5479 
5480   PrepareForMainJob();
5481   PrepareForSecondMainJob();
5482 
5483   PrepareForFirstQuicJobFailure();
5484   RegisterMockHttpsRecord();
5485 
5486   Initialize(HttpRequestInfo());
5487 
5488   // Set |is_quic_known_to_work_on_current_network| flag so that
5489   // the delaying logic of main job would work when the main job is blocked.
5490   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
5491   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
5492 
5493   request_ = CreateJobControllerAndStart(request_info);
5494   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5495                   /*dns_alpn_h3_job_exists=*/true,
5496                   "Main job and DNS ALPN job must be created.");
5497 
5498   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5499   FastForwardBy(base::Milliseconds(kDefaultDelayMilliSecsForWaitingJob - 1));
5500   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5501   FastForwardBy(base::Milliseconds(1));
5502   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5503 
5504   auto request2 = CreateSecondJobControllerAndStart(request_info);
5505   CheckSecondJobsStatus(
5506       /*main_job_exists=*/true, /*alternative_job_exists=*/false,
5507       /*dns_alpn_h3_job_exists=*/true,
5508       "Main job and DNS ALPN job must be created for the second request.");
5509 
5510   // When an active socket is available for the main job, the main job should
5511   // not be blocked.
5512   EXPECT_FALSE(job_controller2_->main_job()->is_waiting());
5513 
5514   quic_data_->Resume();
5515   base::RunLoop().RunUntilIdle();
5516 
5517   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5518   MakeSecondMainJobSucceed(/*expect_stream_ready=*/true);
5519 }
5520 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,MainJobHasActiveSocketAltSvcRegistered)5521 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5522        MainJobHasActiveSocketAltSvcRegistered) {
5523   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5524 
5525   PrepareForMainJob();
5526   PrepareForSecondMainJob();
5527 
5528   PrepareForFirstQuicJobFailure();
5529   PrepareForSecondQuicJobFailure();
5530 
5531   RegisterMockHttpsRecord();
5532 
5533   Initialize(HttpRequestInfo());
5534 
5535   // Set |is_quic_known_to_work_on_current_network| flag so that
5536   // the delaying logic of main job would work when the main job is blocked.
5537   QuicSessionPool* quic_session_pool = session_->quic_session_pool();
5538   quic_session_pool->set_is_quic_known_to_work_on_current_network(true);
5539 
5540   url::SchemeHostPort server(request_info.url);
5541   AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443);
5542   SetAlternativeService(request_info, alternative_service);
5543 
5544   request_ = CreateJobControllerAndStart(request_info);
5545   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5546                   /*dns_alpn_h3_job_exists=*/true,
5547                   "All types of jobs are created");
5548 
5549   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5550   FastForwardBy(base::Milliseconds(kDefaultDelayMilliSecsForWaitingJob - 1));
5551   EXPECT_TRUE(job_controller_->main_job()->is_waiting());
5552   FastForwardBy(base::Milliseconds(1));
5553   EXPECT_FALSE(job_controller_->main_job()->is_waiting());
5554 
5555   auto request2 = CreateSecondJobControllerAndStart(request_info);
5556   CheckSecondJobsStatus(
5557       /*main_job_exists=*/true, /*alternative_job_exists=*/true,
5558       /*dns_alpn_h3_job_exists=*/true,
5559       "All types of jobs must be created for the second request.");
5560 
5561   // The main job should be waiting until kDefaultDelayMilliSecsForWaitingJob
5562   // amount of time has passed, when an alternative service was registered,
5563   // even when an active socket is available for the main job.
5564   // This is intended to switch to QUIC from TCP for the first connection
5565   // when the server supports Alt-Svc but doesn't support HTTP DNS records with
5566   // alpn.
5567   // Note: When QuicParams.delay_main_job_with_available_spdy_session is false,
5568   // main job is not blocked.
5569   EXPECT_TRUE(job_controller2_->main_job()->is_waiting());
5570   FastForwardBy(base::Milliseconds(kDefaultDelayMilliSecsForWaitingJob - 1));
5571   EXPECT_TRUE(job_controller2_->main_job()->is_waiting());
5572   FastForwardBy(base::Milliseconds(1));
5573   EXPECT_FALSE(job_controller2_->main_job()->is_waiting());
5574 
5575   quic_data_->Resume();
5576   quic_data2_->Resume();
5577   base::RunLoop().RunUntilIdle();
5578 
5579   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5580   MakeSecondMainJobSucceed(/*expect_stream_ready=*/true);
5581 }
5582 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,ActiveSessionAvailableForAltSvcJob)5583 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5584        ActiveSessionAvailableForAltSvcJob) {
5585   PrepareForMainJob();
5586   RegisterMockHttpsRecord();
5587 
5588   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5589 
5590   PrepareForFirstQuicJob();
5591 
5592   Initialize(HttpRequestInfo());
5593 
5594   std::unique_ptr<QuicHttpStream> stream =
5595       ConnectQuicHttpStream(/*alt_destination=*/true,
5596                             /*require_dns_https_alpn=*/false);
5597 
5598   url::SchemeHostPort server(request_info.url);
5599   AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443);
5600   SetAlternativeService(request_info, alternative_service);
5601 
5602   request_ = CreateJobControllerAndStart(request_info);
5603 
5604   // |dns_alpn_h3_job| must not be created when an active session is
5605   // available for |alternative_job|.
5606   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5607                   /*dns_alpn_h3_job_exists=*/false,
5608                   "Main job and alternative job must be created.");
5609 
5610   base::HistogramTester histogram_tester;
5611   // Run the message loop to make |alternative_job| succeed and status will be
5612   // reported to Request.
5613   {
5614     base::RunLoop run_loop;
5615     EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
5616         .Times(1)
5617         .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
5618     run_loop.Run();
5619   }
5620   histogram_tester.ExpectUniqueSample("Net.AlternateProtocolUsage",
5621                                       ALTERNATE_PROTOCOL_USAGE_NO_RACE, 1);
5622 
5623   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/true,
5624                   /*dns_alpn_h3_job_exists=*/false,
5625                   "Main job must be deleted.");
5626 
5627   request_.reset();
5628   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5629 }
5630 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,ActiveSessionAvailableForDnsAlpnH3Job)5631 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5632        ActiveSessionAvailableForDnsAlpnH3Job) {
5633   PrepareForFirstQuicJob();
5634   RegisterMockHttpsRecord();
5635 
5636   Initialize(HttpRequestInfo());
5637 
5638   std::unique_ptr<QuicHttpStream> stream =
5639       ConnectQuicHttpStream(/*alt_destination=*/false,
5640                             /*require_dns_https_alpn=*/true);
5641   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5642 
5643   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
5644                   /*dns_alpn_h3_job_exists=*/true,
5645                   "Main job and alternative job must not be available.");
5646 
5647   base::HistogramTester histogram_tester;
5648   // Run the message loop to make |dns_alpn_h3_job| succeed and status will be
5649   // reported to Request.
5650   {
5651     base::RunLoop run_loop;
5652     EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
5653         .Times(1)
5654         .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
5655     run_loop.Run();
5656   }
5657   histogram_tester.ExpectUniqueSample(
5658       "Net.AlternateProtocolUsage",
5659       ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_WITHOUT_RACE, 1);
5660   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
5661                   /*dns_alpn_h3_job_exists=*/true,
5662                   "DNS alpn H3 job must exist.");
5663 
5664   request_.reset();
5665   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5666 }
5667 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,ActiveSessionAvailableForMainJobAndDnsAlpnH3Job)5668 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5669        ActiveSessionAvailableForMainJobAndDnsAlpnH3Job) {
5670   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5671   PrepareForFirstQuicJob();
5672 
5673   RegisterMockHttpsRecord();
5674 
5675   Initialize(HttpRequestInfo());
5676 
5677   // Put a SpdySession in the pool.
5678   SpdySessionKey key(HostPortPair::FromURL(request_info.url),
5679                      PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
5680                      SessionUsage::kDestination, SocketTag(),
5681                      NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
5682                      /*disable_cert_verification_network_fetches=*/false);
5683   std::ignore = CreateFakeSpdySession(session_->spdy_session_pool(), key);
5684 
5685   std::unique_ptr<QuicHttpStream> stream =
5686       ConnectQuicHttpStream(/*alt_destination=*/false,
5687                             /*require_dns_https_alpn=*/true);
5688   request_ = CreateJobControllerAndStart(CreateTestHttpRequestInfo());
5689 
5690   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
5691                   /*dns_alpn_h3_job_exists=*/true,
5692                   "Main job must not be available.");
5693 
5694   base::HistogramTester histogram_tester;
5695   // Run the message loop to make |dns_alpn_h3_job| succeed and status will be
5696   // reported to Request.
5697   {
5698     base::RunLoop run_loop;
5699     EXPECT_CALL(request_delegate_, OnStreamReadyImpl(_, _))
5700         .Times(1)
5701         .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
5702     run_loop.Run();
5703   }
5704   histogram_tester.ExpectUniqueSample(
5705       "Net.AlternateProtocolUsage",
5706       ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_WITHOUT_RACE, 1);
5707 
5708   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
5709                   /*dns_alpn_h3_job_exists=*/true,
5710                   "DNS alpn H3 job must exist.");
5711 
5712   request_.reset();
5713   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5714 }
5715 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,DoNotStartDnsAlpnH3JobWhenSameHostDefaultPortAltJobCreated)5716 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5717        DoNotStartDnsAlpnH3JobWhenSameHostDefaultPortAltJobCreated) {
5718   PrepareForMainJob();
5719   PrepareForFirstQuicJob();
5720 
5721   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5722 
5723   RegisterMockHttpsRecord();
5724 
5725   Initialize(HttpRequestInfo());
5726 
5727   url::SchemeHostPort server(request_info.url);
5728   AlternativeService alternative_service(kProtoQUIC, "www.example.org", 443);
5729   SetAlternativeService(request_info, alternative_service);
5730 
5731   request_ = CreateJobControllerAndStart(request_info);
5732   // |dns_alpn_h3_job| must be deleted when a same origin alt service
5733   // was registered.
5734   CheckJobsStatus(
5735       true, true, false,
5736       "All types of jobs are created, but DNS alpn job must be deleted");
5737 
5738   base::RunLoop().RunUntilIdle();
5739   base::HistogramTester histogram_tester;
5740   // Make |main_job| succeed.
5741   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5742   histogram_tester.ExpectUniqueSample(
5743       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE,
5744       1);
5745 
5746   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5747                   /*dns_alpn_h3_job_exists=*/false,
5748                   "Alternate job must not be deleted");
5749 
5750   // Make |alternative_job| succeed.
5751   MakeQuicJobSucceed(0, /*expect_stream_ready=*/false);
5752 
5753   request_.reset();
5754   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5755 }
5756 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,AllJobsCreatedMainJobSucceedAltJobSucceedDnsJobSucceed)5757 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5758        AllJobsCreatedMainJobSucceedAltJobSucceedDnsJobSucceed) {
5759   PrepareForMainJob();
5760   PrepareForFirstQuicJob();
5761   PrepareForSecondQuicJob();
5762 
5763   // Use cold start and complete `alternative_job` and `dns_alpn_h3_job`
5764   // manually.
5765   crypto_client_stream_factory_.set_handshake_mode(
5766       MockCryptoClientStream::COLD_START);
5767 
5768   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5769 
5770   RegisterMockHttpsRecord();
5771 
5772   Initialize(HttpRequestInfo());
5773 
5774   url::SchemeHostPort server(request_info.url);
5775   AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443);
5776   SetAlternativeService(request_info, alternative_service);
5777 
5778   request_ = CreateJobControllerAndStart(request_info);
5779   // |dns_alpn_h3_job| must be created when a different origin alt service
5780   // was registered.
5781   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5782                   /*dns_alpn_h3_job_exists=*/true,
5783                   "All types of jobs are created");
5784 
5785   base::HistogramTester histogram_tester;
5786   base::RunLoop().RunUntilIdle();
5787   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5788   histogram_tester.ExpectUniqueSample(
5789       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE,
5790       1);
5791 
5792   // The success of |main_job| doesn't delete |alternative_job| and
5793   // |dns_alpn_h3_job|.
5794   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5795                   /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted.");
5796 
5797   // Make |alternative_job| succeed.
5798   MakeQuicJobSucceed(0, /*expect_stream_ready=*/false);
5799   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5800                   /*dns_alpn_h3_job_exists=*/true,
5801                   "Alternate job must be deleted.");
5802 
5803   // Make |dns_alpn_h3_job| succeed.
5804   MakeQuicJobSucceed(1, /*expect_stream_ready=*/false);
5805   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5806                   /*dns_alpn_h3_job_exists=*/false,
5807                   "DNS alpn job must be deleted.");
5808 
5809   request_.reset();
5810   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5811 }
5812 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,AllJobsCreatedAltJobSucceedDnsJobSucceedMainJobSucceed)5813 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5814        AllJobsCreatedAltJobSucceedDnsJobSucceedMainJobSucceed) {
5815   PrepareForMainJob();
5816   PrepareForFirstQuicJob();
5817   PrepareForSecondQuicJob();
5818 
5819   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5820 
5821   RegisterMockHttpsRecord();
5822 
5823   Initialize(HttpRequestInfo());
5824 
5825   url::SchemeHostPort server(request_info.url);
5826   AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443);
5827   SetAlternativeService(request_info, alternative_service);
5828 
5829   request_ = CreateJobControllerAndStart(request_info);
5830   // |dns_alpn_h3_job| must be created when a different origin alt service
5831   // was registered.
5832   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5833                   /*dns_alpn_h3_job_exists=*/true,
5834                   "All types of jobs are created");
5835 
5836   base::HistogramTester histogram_tester;
5837   // Make |alternative_job| succeed.
5838   MakeQuicJobSucceed(0, /*expect_stream_ready=*/true);
5839   histogram_tester.ExpectUniqueSample("Net.AlternateProtocolUsage",
5840                                       ALTERNATE_PROTOCOL_USAGE_WON_RACE, 1);
5841 
5842   // The success of |alternative_job| doesn't delete |main_job| and
5843   // |dns_alpn_h3_job|.
5844   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5845                   /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted.");
5846 
5847   // Make |dns_alpn_h3_job| succeed.
5848   MakeQuicJobSucceed(1, /*expect_stream_ready=*/false);
5849 
5850   // The success of |dns_alpn_h3_job| doesn't delete |main_job| and
5851   // |alternative_job|.
5852   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5853                   /*dns_alpn_h3_job_exists=*/false,
5854                   "DNS alpn job must be deleted.");
5855 
5856   // Make |main_job| succeed.
5857   MakeMainJobSucceed(/*expect_stream_ready=*/false);
5858 
5859   // |main_job| should be cleared.
5860   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/true,
5861                   /*dns_alpn_h3_job_exists=*/false,
5862                   "Alternate job must be deleted.");
5863 
5864   request_.reset();
5865   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5866 }
5867 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,AllJobsCreatedDnsJobSucceedAltJobSucceedMainJobSucceed)5868 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5869        AllJobsCreatedDnsJobSucceedAltJobSucceedMainJobSucceed) {
5870   PrepareForMainJob();
5871   PrepareForFirstQuicJob();
5872   PrepareForSecondQuicJob();
5873 
5874   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5875 
5876   RegisterMockHttpsRecord();
5877 
5878   Initialize(HttpRequestInfo());
5879 
5880   url::SchemeHostPort server(request_info.url);
5881   AlternativeService alternative_service(kProtoQUIC, "alt.example.org", 443);
5882   SetAlternativeService(request_info, alternative_service);
5883 
5884   request_ = CreateJobControllerAndStart(request_info);
5885   // |dns_alpn_h3_job| must be created when a different origin alt service
5886   // was registered.
5887   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5888                   /*dns_alpn_h3_job_exists=*/true,
5889                   "All types of jobs are created");
5890 
5891   base::HistogramTester histogram_tester;
5892   // Make |dns_alpn_h3_job| succeed.
5893   MakeQuicJobSucceed(1, /*expect_stream_ready=*/true);
5894   histogram_tester.ExpectUniqueSample(
5895       "Net.AlternateProtocolUsage",
5896       ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1);
5897 
5898   // The success of |dns_alpn_h3_job| doesn't delete |main_job| and
5899   // |alternative_job|.
5900   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/true,
5901                   /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted.");
5902 
5903   // Make |alternative_job| succeed.
5904   MakeQuicJobSucceed(0, /*expect_stream_ready=*/false);
5905 
5906   // The success of |alternative_job| doesn't delete |main_job| and
5907   // |dns_alpn_h3_job|.
5908   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5909                   /*dns_alpn_h3_job_exists=*/true,
5910                   "Alternate job must be deleted.");
5911 
5912   // Make |main_job| succeed.
5913   MakeMainJobSucceed(/*expect_stream_ready=*/false);
5914 
5915   // |main_job| should be cleared.
5916   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
5917                   /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted.");
5918 
5919   request_.reset();
5920   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5921 }
5922 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,DnsJobFailOnDefaultNetworkDnsJobFailMainJobSucceed)5923 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5924        DnsJobFailOnDefaultNetworkDnsJobFailMainJobSucceed) {
5925   PrepareForMainJob();
5926   PrepareForFirstQuicJobFailure();
5927 
5928   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5929 
5930   RegisterMockHttpsRecord();
5931 
5932   Initialize(HttpRequestInfo());
5933   request_ = CreateJobControllerAndStart(request_info);
5934   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5935                   /*dns_alpn_h3_job_exists=*/true,
5936                   "Main job and DNS ALPN job must be created.");
5937 
5938   JobControllerPeer::SetDnsAlpnH3JobFailedOnDefaultNetwork(job_controller_);
5939   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5940                   /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted.");
5941 
5942   base::RunLoop().RunUntilIdle();
5943   base::HistogramTester histogram_tester;
5944   // Make |dns_alpn_h3_job| fail.
5945   quic_data_->Resume();
5946   base::RunLoop().RunUntilIdle();
5947   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5948                   /*dns_alpn_h3_job_exists=*/false, "DNS alpn job be deleted.");
5949 
5950   // Make |main_job| succeed.
5951   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5952   // Net.AlternateProtocolUsage records
5953   // ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON, when only main job exists.
5954   histogram_tester.ExpectUniqueSample(
5955       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON,
5956       1);
5957 
5958   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5959                   /*dns_alpn_h3_job_exists=*/false,
5960                   "DNS alpn job must be deleted.");
5961 
5962   request_.reset();
5963   EXPECT_TRUE(IsAlternativeServiceBroken(request_info.url));
5964   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
5965   histogram_tester.ExpectUniqueSample("Net.AlternateServiceForDnsAlpnH3Failed",
5966                                       -ERR_QUIC_PROTOCOL_ERROR, 1);
5967 
5968   // Verify the brokenness is not cleared when the default network changes.
5969   session_->http_server_properties()->OnDefaultNetworkChanged();
5970   EXPECT_TRUE(IsAlternativeServiceBroken(request_info.url));
5971 }
5972 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,DnsJobFailOnDefaultNetworkMainJobSucceedDnsJobSucceed)5973 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
5974        DnsJobFailOnDefaultNetworkMainJobSucceedDnsJobSucceed) {
5975   PrepareForMainJob();
5976   PrepareForFirstQuicJob();
5977 
5978   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
5979 
5980   RegisterMockHttpsRecord();
5981 
5982   Initialize(HttpRequestInfo());
5983   base::HistogramTester histogram_tester;
5984   request_ = CreateJobControllerAndStart(request_info);
5985   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5986                   /*dns_alpn_h3_job_exists=*/true,
5987                   "Main job and DNS ALPN job must be created.");
5988 
5989   JobControllerPeer::SetDnsAlpnH3JobFailedOnDefaultNetwork(job_controller_);
5990   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
5991                   /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted.");
5992   base::RunLoop().RunUntilIdle();
5993   // Make |main_job| succeed.
5994   MakeMainJobSucceed(/*expect_stream_ready=*/true);
5995   histogram_tester.ExpectUniqueSample(
5996       "Net.AlternateProtocolUsage", ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE,
5997       1);
5998 
5999   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
6000                   /*dns_alpn_h3_job_exists=*/true,
6001                   "DNS alpn job must not be deleted.");
6002 
6003   // Make |dns_alpn_h3_job| succeed.
6004   MakeQuicJobSucceed(0, /*expect_stream_ready=*/false);
6005 
6006   request_.reset();
6007   histogram_tester.ExpectTotalCount("Net.AlternateServiceForDnsAlpnH3Failed",
6008                                     0);
6009   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
6010   EXPECT_TRUE(IsAlternativeServiceBroken(request_info.url));
6011 
6012   // Verify the brokenness is cleared when the default network changes.
6013   session_->http_server_properties()->OnDefaultNetworkChanged();
6014   EXPECT_FALSE(IsAlternativeServiceBroken(request_info.url));
6015 }
6016 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,DnsJobSucceedMainJobCanceled)6017 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
6018        DnsJobSucceedMainJobCanceled) {
6019   PrepareForMainJob();
6020   PrepareForFirstQuicJob();
6021 
6022   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
6023 
6024   RegisterMockHttpsRecord();
6025 
6026   Initialize(HttpRequestInfo());
6027   request_ = CreateJobControllerAndStart(request_info);
6028   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
6029                   /*dns_alpn_h3_job_exists=*/true,
6030                   "Main job and DNS ALPN job must be created.");
6031 
6032   base::HistogramTester histogram_tester;
6033   // Make |dns_alpn_h3_job| succeed.
6034   MakeQuicJobSucceed(0, /*expect_stream_ready=*/true);
6035   histogram_tester.ExpectUniqueSample(
6036       "Net.AlternateProtocolUsage",
6037       ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1);
6038 
6039   // Main job is canceled.
6040   CheckJobsStatus(/*main_job_exists=*/false, /*alternative_job_exists=*/false,
6041                   /*dns_alpn_h3_job_exists=*/true, "Main job must be deleted");
6042 
6043   request_.reset();
6044   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
6045 }
6046 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,DnsJobFailOnDefaultNetworkDnsJobSucceedMainJobSucceed)6047 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
6048        DnsJobFailOnDefaultNetworkDnsJobSucceedMainJobSucceed) {
6049   PrepareForMainJob();
6050   PrepareForFirstQuicJob();
6051 
6052   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
6053 
6054   RegisterMockHttpsRecord();
6055 
6056   Initialize(HttpRequestInfo());
6057   request_ = CreateJobControllerAndStart(request_info);
6058   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
6059                   /*dns_alpn_h3_job_exists=*/true,
6060                   "Main job and DNS ALPN job must be created.");
6061 
6062   JobControllerPeer::SetDnsAlpnH3JobFailedOnDefaultNetwork(job_controller_);
6063   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
6064                   /*dns_alpn_h3_job_exists=*/true, "Jobs must not be deleted.");
6065 
6066   base::HistogramTester histogram_tester;
6067   // Make |dns_alpn_h3_job| succeed.
6068   MakeQuicJobSucceed(0, /*expect_stream_ready=*/true);
6069   histogram_tester.ExpectUniqueSample(
6070       "Net.AlternateProtocolUsage",
6071       ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE, 1);
6072 
6073   // Main job is not canceled, because |dns_alpn_h3_job| has failed on the
6074   // default network.
6075   CheckJobsStatus(/*main_job_exists=*/true, /*alternative_job_exists=*/false,
6076                   /*dns_alpn_h3_job_exists=*/true,
6077                   "Main job must not be deleted.");
6078 
6079   // Make |main_job| succeed.
6080   MakeMainJobSucceed(/*expect_stream_ready=*/false);
6081 
6082   request_.reset();
6083   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
6084 }
6085 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,PreconnectDnsAlpnH3)6086 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, PreconnectDnsAlpnH3) {
6087   SetPreconnect();
6088   PrepareForFirstQuicJob();
6089 
6090   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
6091 
6092   RegisterMockHttpsRecord();
6093 
6094   Initialize(HttpRequestInfo());
6095   CreateJobController(request_info);
6096   job_controller_->Preconnect(/*num_streams=*/5);
6097   // Only one job is started.
6098   EXPECT_TRUE(job_controller_->main_job());
6099   EXPECT_FALSE(job_controller_->alternative_job());
6100   EXPECT_EQ(HttpStreamFactory::PRECONNECT_DNS_ALPN_H3,
6101             job_controller_->main_job()->job_type());
6102 
6103   MakeQuicJobSucceed(0, /*expect_stream_ready=*/false);
6104 
6105   base::RunLoop().RunUntilIdle();
6106   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
6107 }
6108 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,PreconnectAltSvcAvailableActiveSessionAvailable)6109 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
6110        PreconnectAltSvcAvailableActiveSessionAvailable) {
6111   SetPreconnect();
6112   PrepareForFirstQuicJob();
6113 
6114   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
6115 
6116   RegisterMockHttpsRecord();
6117   Initialize(request_info);
6118 
6119   // Register Alt-Svc info.
6120   url::SchemeHostPort server(request_info.url);
6121   AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
6122   SetAlternativeService(request_info, alternative_service);
6123 
6124   // Create an active session of require_dns_https_alpn = true.
6125   std::unique_ptr<QuicHttpStream> stream =
6126       ConnectQuicHttpStream(/*alt_destination=*/false,
6127                             /*require_dns_https_alpn=*/true);
6128 
6129   CreateJobController(request_info);
6130   // Preconnect must succeed using the existing session.
6131   job_controller_->Preconnect(/*num_streams=*/1);
6132   ASSERT_TRUE(job_controller_->main_job());
6133   EXPECT_EQ(HttpStreamFactory::PRECONNECT_DNS_ALPN_H3,
6134             job_controller_->main_job()->job_type());
6135   MakeQuicJobSucceed(0, /*expect_stream_ready=*/false);
6136 
6137   base::RunLoop().RunUntilIdle();
6138   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
6139 }
6140 
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,PreconnectNoDnsAlpnH3)6141 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest, PreconnectNoDnsAlpnH3) {
6142   EnableOndemandHostResolver();
6143   PrepareForMainJob();
6144   SetPreconnect();
6145 
6146   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
6147 
6148   Initialize(HttpRequestInfo());
6149   CreateJobController(request_info);
6150   job_controller_->Preconnect(/*num_streams=*/1);
6151   // Only one job is started.
6152   EXPECT_TRUE(job_controller_->main_job());
6153   EXPECT_FALSE(job_controller_->alternative_job());
6154   EXPECT_EQ(HttpStreamFactory::PRECONNECT_DNS_ALPN_H3,
6155             job_controller_->main_job()->job_type());
6156 
6157   // Resolve the host resolve request from |dns_alpn_h3_job|.
6158   session_deps_.host_resolver->ResolveAllPending();
6159   base::RunLoop().RunUntilIdle();
6160   EXPECT_EQ(HttpStreamFactory::PRECONNECT,
6161             job_controller_->main_job()->job_type());
6162 
6163   base::RunLoop().RunUntilIdle();
6164 
6165   // Make |main_job| succeed.
6166   MakeMainJobSucceed(/*expect_stream_ready=*/false);
6167   base::RunLoop().RunUntilIdle();
6168 
6169   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
6170 }
6171 
6172 // Test that, when an Alt-Svc-based preconnect fails with
6173 // `ERR_DNS_NO_MATCHING_SUPPORTED_ALPN`, the job controller handles it
6174 // correctly. This is a regression test for https://crbug.com/1420202.
6175 //
6176 // In a general HTTPS-RR implementation, this may happen simply because there
6177 // was no A/AAAA route. However, we do not implement HTTPS-RR in full yet (see
6178 // https://crbug.com/1417033), so instead this is only possible in a corner case
6179 // with ECH.
TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,PreconnectAlternateNoDnsAlpn)6180 TEST_F(HttpStreamFactoryJobControllerDnsHttpsAlpnTest,
6181        PreconnectAlternateNoDnsAlpn) {
6182   const char kAlternateHost[] = "alt.example.com";
6183 
6184   EnableOndemandHostResolver();
6185   PrepareForMainJob();
6186   SetPreconnect();
6187 
6188   // Register a mock HTTPS record where the HTTPS-RR route is only good for h2,
6189   // which is incompatible with Alt-Svc. The A/AAAA route would be compatible,
6190   // but the server supports ECH, so we enable SVCB-reliant mode and reject it.
6191   // As a result, the alternate job will fail.
6192   HostResolverEndpointResult endpoint_result1;
6193   endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
6194   endpoint_result1.metadata.ech_config_list = {1, 2, 3, 4};
6195   endpoint_result1.metadata.supported_protocol_alpns = {"h2"};
6196   HostResolverEndpointResult endpoint_result2;
6197   endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
6198   session_deps_.host_resolver->rules()->AddRule(
6199       kAlternateHost,
6200       MockHostResolverBase::RuleResolver::RuleResult(
6201           {endpoint_result1, endpoint_result2}, {kAlternateHost}));
6202 
6203   HttpRequestInfo request_info = CreateTestHttpRequestInfo();
6204   Initialize(request_info);
6205   CreateJobController(request_info);
6206 
6207   url::SchemeHostPort server(request_info.url);
6208   AlternativeService alternative_service(kProtoQUIC, kAlternateHost, 443);
6209   SetAlternativeService(request_info, alternative_service);
6210 
6211   job_controller_->Preconnect(/*num_streams=*/1);
6212   // Only one job is started.
6213   EXPECT_TRUE(job_controller_->main_job());
6214   EXPECT_FALSE(job_controller_->alternative_job());
6215   EXPECT_EQ(HttpStreamFactory::PRECONNECT,
6216             job_controller_->main_job()->job_type());
6217 
6218   // Resolve the DNS request.
6219   session_deps_.host_resolver->ResolveAllPending();
6220   base::RunLoop().RunUntilIdle();
6221 
6222   // The jobs should have failed. We currently do not try the non-Alt-Svc route
6223   // in preconnects if Alt-Svc failed.
6224   EXPECT_TRUE(HttpStreamFactoryPeer::IsJobControllerDeleted(factory_));
6225 }
6226 
6227 }  // namespace net::test
6228