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