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