xref: /aosp_15_r20/external/cronet/net/http/http_server_properties.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/http/http_server_properties.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/containers/adapters.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/containers/contains.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/feature_list.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_macros.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/time/default_clock.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/time/default_tick_clock.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/base/features.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/base/network_anonymization_key.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/base/url_util.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/http/http_network_session.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/http/http_server_properties_manager.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/socket/ssl_client_socket.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_config.h"
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker namespace net {
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker namespace {
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker // Time to wait before starting an update the preferences from the
33*6777b538SAndroid Build Coastguard Worker // http_server_properties_impl_ cache. Scheduling another update during this
34*6777b538SAndroid Build Coastguard Worker // period will be a no-op.
35*6777b538SAndroid Build Coastguard Worker constexpr base::TimeDelta kUpdatePrefsDelay = base::Seconds(60);
36*6777b538SAndroid Build Coastguard Worker 
NormalizeSchemeHostPort(const url::SchemeHostPort & scheme_host_port)37*6777b538SAndroid Build Coastguard Worker url::SchemeHostPort NormalizeSchemeHostPort(
38*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& scheme_host_port) {
39*6777b538SAndroid Build Coastguard Worker   if (scheme_host_port.scheme() == url::kWssScheme) {
40*6777b538SAndroid Build Coastguard Worker     return url::SchemeHostPort(url::kHttpsScheme, scheme_host_port.host(),
41*6777b538SAndroid Build Coastguard Worker                                scheme_host_port.port());
42*6777b538SAndroid Build Coastguard Worker   }
43*6777b538SAndroid Build Coastguard Worker   if (scheme_host_port.scheme() == url::kWsScheme) {
44*6777b538SAndroid Build Coastguard Worker     return url::SchemeHostPort(url::kHttpScheme, scheme_host_port.host(),
45*6777b538SAndroid Build Coastguard Worker                                scheme_host_port.port());
46*6777b538SAndroid Build Coastguard Worker   }
47*6777b538SAndroid Build Coastguard Worker   return scheme_host_port;
48*6777b538SAndroid Build Coastguard Worker }
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker }  // namespace
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker HttpServerProperties::PrefDelegate::~PrefDelegate() = default;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfo::ServerInfo() = default;
55*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfo::ServerInfo(const ServerInfo& server_info) =
56*6777b538SAndroid Build Coastguard Worker     default;
57*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfo::ServerInfo(ServerInfo&& server_info) =
58*6777b538SAndroid Build Coastguard Worker     default;
59*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfo::~ServerInfo() = default;
60*6777b538SAndroid Build Coastguard Worker 
empty() const61*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::ServerInfo::empty() const {
62*6777b538SAndroid Build Coastguard Worker   return !supports_spdy.has_value() && !alternative_services.has_value() &&
63*6777b538SAndroid Build Coastguard Worker          !server_network_stats.has_value();
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker 
operator ==(const ServerInfo & other) const66*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::ServerInfo::operator==(
67*6777b538SAndroid Build Coastguard Worker     const ServerInfo& other) const {
68*6777b538SAndroid Build Coastguard Worker   return supports_spdy == other.supports_spdy &&
69*6777b538SAndroid Build Coastguard Worker          alternative_services == other.alternative_services &&
70*6777b538SAndroid Build Coastguard Worker          server_network_stats == other.server_network_stats;
71*6777b538SAndroid Build Coastguard Worker }
72*6777b538SAndroid Build Coastguard Worker 
ServerInfoMapKey(url::SchemeHostPort server,const NetworkAnonymizationKey & network_anonymization_key,bool use_network_anonymization_key)73*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMapKey::ServerInfoMapKey(
74*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
75*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
76*6777b538SAndroid Build Coastguard Worker     bool use_network_anonymization_key)
77*6777b538SAndroid Build Coastguard Worker     : server(std::move(server)),
78*6777b538SAndroid Build Coastguard Worker       network_anonymization_key(use_network_anonymization_key
79*6777b538SAndroid Build Coastguard Worker                                     ? network_anonymization_key
80*6777b538SAndroid Build Coastguard Worker                                     : NetworkAnonymizationKey()) {
81*6777b538SAndroid Build Coastguard Worker   // Scheme should have been normalized before this method was called.
82*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(this->server.scheme(), url::kWsScheme);
83*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(this->server.scheme(), url::kWssScheme);
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMapKey::~ServerInfoMapKey() = default;
87*6777b538SAndroid Build Coastguard Worker 
operator <(const ServerInfoMapKey & other) const88*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::ServerInfoMapKey::operator<(
89*6777b538SAndroid Build Coastguard Worker     const ServerInfoMapKey& other) const {
90*6777b538SAndroid Build Coastguard Worker   return std::tie(server, network_anonymization_key) <
91*6777b538SAndroid Build Coastguard Worker          std::tie(other.server, other.network_anonymization_key);
92*6777b538SAndroid Build Coastguard Worker }
93*6777b538SAndroid Build Coastguard Worker 
QuicServerInfoMapKey(const quic::QuicServerId & server_id,const NetworkAnonymizationKey & network_anonymization_key,bool use_network_anonymization_key)94*6777b538SAndroid Build Coastguard Worker HttpServerProperties::QuicServerInfoMapKey::QuicServerInfoMapKey(
95*6777b538SAndroid Build Coastguard Worker     const quic::QuicServerId& server_id,
96*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
97*6777b538SAndroid Build Coastguard Worker     bool use_network_anonymization_key)
98*6777b538SAndroid Build Coastguard Worker     : server_id(server_id),
99*6777b538SAndroid Build Coastguard Worker       network_anonymization_key(use_network_anonymization_key
100*6777b538SAndroid Build Coastguard Worker                                     ? network_anonymization_key
101*6777b538SAndroid Build Coastguard Worker                                     : NetworkAnonymizationKey()) {}
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker HttpServerProperties::QuicServerInfoMapKey::~QuicServerInfoMapKey() = default;
104*6777b538SAndroid Build Coastguard Worker 
operator <(const QuicServerInfoMapKey & other) const105*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::QuicServerInfoMapKey::operator<(
106*6777b538SAndroid Build Coastguard Worker     const QuicServerInfoMapKey& other) const {
107*6777b538SAndroid Build Coastguard Worker   return std::tie(server_id, network_anonymization_key) <
108*6777b538SAndroid Build Coastguard Worker          std::tie(other.server_id, other.network_anonymization_key);
109*6777b538SAndroid Build Coastguard Worker }
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker // Used in tests.
operator ==(const QuicServerInfoMapKey & other) const112*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::QuicServerInfoMapKey::operator==(
113*6777b538SAndroid Build Coastguard Worker     const QuicServerInfoMapKey& other) const {
114*6777b538SAndroid Build Coastguard Worker   return std::tie(server_id, network_anonymization_key) ==
115*6777b538SAndroid Build Coastguard Worker          std::tie(other.server_id, other.network_anonymization_key);
116*6777b538SAndroid Build Coastguard Worker }
117*6777b538SAndroid Build Coastguard Worker 
ServerInfoMap()118*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMap::ServerInfoMap()
119*6777b538SAndroid Build Coastguard Worker     : base::LRUCache<ServerInfoMapKey, ServerInfo>(kMaxServerInfoEntries) {}
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMap::iterator
GetOrPut(const ServerInfoMapKey & key)122*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMap::GetOrPut(const ServerInfoMapKey& key) {
123*6777b538SAndroid Build Coastguard Worker   auto it = Get(key);
124*6777b538SAndroid Build Coastguard Worker   if (it != end())
125*6777b538SAndroid Build Coastguard Worker     return it;
126*6777b538SAndroid Build Coastguard Worker   return Put(key, ServerInfo());
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMap::iterator
EraseIfEmpty(iterator server_info_it)130*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMap::EraseIfEmpty(iterator server_info_it) {
131*6777b538SAndroid Build Coastguard Worker   if (server_info_it->second.empty())
132*6777b538SAndroid Build Coastguard Worker     return Erase(server_info_it);
133*6777b538SAndroid Build Coastguard Worker   return ++server_info_it;
134*6777b538SAndroid Build Coastguard Worker }
135*6777b538SAndroid Build Coastguard Worker 
HttpServerProperties(std::unique_ptr<PrefDelegate> pref_delegate,NetLog * net_log,const base::TickClock * tick_clock,base::Clock * clock)136*6777b538SAndroid Build Coastguard Worker HttpServerProperties::HttpServerProperties(
137*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<PrefDelegate> pref_delegate,
138*6777b538SAndroid Build Coastguard Worker     NetLog* net_log,
139*6777b538SAndroid Build Coastguard Worker     const base::TickClock* tick_clock,
140*6777b538SAndroid Build Coastguard Worker     base::Clock* clock)
141*6777b538SAndroid Build Coastguard Worker     : tick_clock_(tick_clock ? tick_clock
142*6777b538SAndroid Build Coastguard Worker                              : base::DefaultTickClock::GetInstance()),
143*6777b538SAndroid Build Coastguard Worker       clock_(clock ? clock : base::DefaultClock::GetInstance()),
144*6777b538SAndroid Build Coastguard Worker       use_network_anonymization_key_(
145*6777b538SAndroid Build Coastguard Worker           NetworkAnonymizationKey::IsPartitioningEnabled()),
146*6777b538SAndroid Build Coastguard Worker       is_initialized_(pref_delegate.get() == nullptr),
147*6777b538SAndroid Build Coastguard Worker       properties_manager_(
148*6777b538SAndroid Build Coastguard Worker           pref_delegate
149*6777b538SAndroid Build Coastguard Worker               ? std::make_unique<HttpServerPropertiesManager>(
150*6777b538SAndroid Build Coastguard Worker                     std::move(pref_delegate),
151*6777b538SAndroid Build Coastguard Worker                     base::BindOnce(&HttpServerProperties::OnPrefsLoaded,
152*6777b538SAndroid Build Coastguard Worker                                    base::Unretained(this)),
153*6777b538SAndroid Build Coastguard Worker                     kDefaultMaxQuicServerEntries,
154*6777b538SAndroid Build Coastguard Worker                     net_log,
155*6777b538SAndroid Build Coastguard Worker                     tick_clock_)
156*6777b538SAndroid Build Coastguard Worker               : nullptr),
157*6777b538SAndroid Build Coastguard Worker       broken_alternative_services_(kMaxRecentlyBrokenAlternativeServiceEntries,
158*6777b538SAndroid Build Coastguard Worker                                    this,
159*6777b538SAndroid Build Coastguard Worker                                    tick_clock_),
160*6777b538SAndroid Build Coastguard Worker       canonical_suffixes_({".ggpht.com", ".c.youtube.com", ".googlevideo.com",
161*6777b538SAndroid Build Coastguard Worker                            ".googleusercontent.com", ".gvt1.com"}),
162*6777b538SAndroid Build Coastguard Worker       quic_server_info_map_(kDefaultMaxQuicServerEntries),
163*6777b538SAndroid Build Coastguard Worker       max_server_configs_stored_in_properties_(kDefaultMaxQuicServerEntries) {}
164*6777b538SAndroid Build Coastguard Worker 
~HttpServerProperties()165*6777b538SAndroid Build Coastguard Worker HttpServerProperties::~HttpServerProperties() {
166*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
167*6777b538SAndroid Build Coastguard Worker 
168*6777b538SAndroid Build Coastguard Worker   if (properties_manager_) {
169*6777b538SAndroid Build Coastguard Worker     // Stop waiting for initial settings.
170*6777b538SAndroid Build Coastguard Worker     is_initialized_ = true;
171*6777b538SAndroid Build Coastguard Worker 
172*6777b538SAndroid Build Coastguard Worker     // Stop the timer if it's running, since this will write to the properties
173*6777b538SAndroid Build Coastguard Worker     // file immediately.
174*6777b538SAndroid Build Coastguard Worker     prefs_update_timer_.Stop();
175*6777b538SAndroid Build Coastguard Worker 
176*6777b538SAndroid Build Coastguard Worker     WriteProperties(base::OnceClosure());
177*6777b538SAndroid Build Coastguard Worker   }
178*6777b538SAndroid Build Coastguard Worker }
179*6777b538SAndroid Build Coastguard Worker 
Clear(base::OnceClosure callback)180*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::Clear(base::OnceClosure callback) {
181*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
182*6777b538SAndroid Build Coastguard Worker   server_info_map_.Clear();
183*6777b538SAndroid Build Coastguard Worker   broken_alternative_services_.Clear();
184*6777b538SAndroid Build Coastguard Worker   canonical_alt_svc_map_.clear();
185*6777b538SAndroid Build Coastguard Worker   last_local_address_when_quic_worked_ = IPAddress();
186*6777b538SAndroid Build Coastguard Worker   quic_server_info_map_.Clear();
187*6777b538SAndroid Build Coastguard Worker   canonical_server_info_map_.clear();
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker   if (properties_manager_) {
190*6777b538SAndroid Build Coastguard Worker     // Stop waiting for initial settings.
191*6777b538SAndroid Build Coastguard Worker     is_initialized_ = true;
192*6777b538SAndroid Build Coastguard Worker     // Leaving this as-is doesn't actually have any effect, if it's true, but
193*6777b538SAndroid Build Coastguard Worker     // seems best to be safe.
194*6777b538SAndroid Build Coastguard Worker     queue_write_on_load_ = false;
195*6777b538SAndroid Build Coastguard Worker 
196*6777b538SAndroid Build Coastguard Worker     // Stop the timer if it's running, since this will write to the properties
197*6777b538SAndroid Build Coastguard Worker     // file immediately.
198*6777b538SAndroid Build Coastguard Worker     prefs_update_timer_.Stop();
199*6777b538SAndroid Build Coastguard Worker     WriteProperties(std::move(callback));
200*6777b538SAndroid Build Coastguard Worker   } else if (callback) {
201*6777b538SAndroid Build Coastguard Worker     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
202*6777b538SAndroid Build Coastguard Worker         FROM_HERE, std::move(callback));
203*6777b538SAndroid Build Coastguard Worker   }
204*6777b538SAndroid Build Coastguard Worker }
205*6777b538SAndroid Build Coastguard Worker 
SupportsRequestPriority(const url::SchemeHostPort & server,const net::NetworkAnonymizationKey & network_anonymization_key)206*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::SupportsRequestPriority(
207*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
208*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
209*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
210*6777b538SAndroid Build Coastguard Worker   if (server.host().empty())
211*6777b538SAndroid Build Coastguard Worker     return false;
212*6777b538SAndroid Build Coastguard Worker 
213*6777b538SAndroid Build Coastguard Worker   if (GetSupportsSpdy(server, network_anonymization_key))
214*6777b538SAndroid Build Coastguard Worker     return true;
215*6777b538SAndroid Build Coastguard Worker   const AlternativeServiceInfoVector alternative_service_info_vector =
216*6777b538SAndroid Build Coastguard Worker       GetAlternativeServiceInfos(server, network_anonymization_key);
217*6777b538SAndroid Build Coastguard Worker   for (const AlternativeServiceInfo& alternative_service_info :
218*6777b538SAndroid Build Coastguard Worker        alternative_service_info_vector) {
219*6777b538SAndroid Build Coastguard Worker     if (alternative_service_info.alternative_service().protocol == kProtoQUIC) {
220*6777b538SAndroid Build Coastguard Worker       return true;
221*6777b538SAndroid Build Coastguard Worker     }
222*6777b538SAndroid Build Coastguard Worker   }
223*6777b538SAndroid Build Coastguard Worker   return false;
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker 
GetSupportsSpdy(const url::SchemeHostPort & server,const net::NetworkAnonymizationKey & network_anonymization_key)226*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::GetSupportsSpdy(
227*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
228*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
229*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
230*6777b538SAndroid Build Coastguard Worker   return GetSupportsSpdyInternal(NormalizeSchemeHostPort(server),
231*6777b538SAndroid Build Coastguard Worker                                  network_anonymization_key);
232*6777b538SAndroid Build Coastguard Worker }
233*6777b538SAndroid Build Coastguard Worker 
SetSupportsSpdy(const url::SchemeHostPort & server,const net::NetworkAnonymizationKey & network_anonymization_key,bool supports_spdy)234*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetSupportsSpdy(
235*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
236*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key,
237*6777b538SAndroid Build Coastguard Worker     bool supports_spdy) {
238*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
239*6777b538SAndroid Build Coastguard Worker   SetSupportsSpdyInternal(NormalizeSchemeHostPort(server),
240*6777b538SAndroid Build Coastguard Worker                           network_anonymization_key, supports_spdy);
241*6777b538SAndroid Build Coastguard Worker }
242*6777b538SAndroid Build Coastguard Worker 
RequiresHTTP11(const url::SchemeHostPort & server,const net::NetworkAnonymizationKey & network_anonymization_key)243*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::RequiresHTTP11(
244*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
245*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
246*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
247*6777b538SAndroid Build Coastguard Worker   return RequiresHTTP11Internal(NormalizeSchemeHostPort(server),
248*6777b538SAndroid Build Coastguard Worker                                 network_anonymization_key);
249*6777b538SAndroid Build Coastguard Worker }
250*6777b538SAndroid Build Coastguard Worker 
SetHTTP11Required(const url::SchemeHostPort & server,const net::NetworkAnonymizationKey & network_anonymization_key)251*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetHTTP11Required(
252*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
253*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
254*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
255*6777b538SAndroid Build Coastguard Worker   SetHTTP11RequiredInternal(NormalizeSchemeHostPort(server),
256*6777b538SAndroid Build Coastguard Worker                             network_anonymization_key);
257*6777b538SAndroid Build Coastguard Worker }
258*6777b538SAndroid Build Coastguard Worker 
MaybeForceHTTP11(const url::SchemeHostPort & server,const net::NetworkAnonymizationKey & network_anonymization_key,SSLConfig * ssl_config)259*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::MaybeForceHTTP11(
260*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
261*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key,
262*6777b538SAndroid Build Coastguard Worker     SSLConfig* ssl_config) {
263*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
264*6777b538SAndroid Build Coastguard Worker   MaybeForceHTTP11Internal(NormalizeSchemeHostPort(server),
265*6777b538SAndroid Build Coastguard Worker                            network_anonymization_key, ssl_config);
266*6777b538SAndroid Build Coastguard Worker }
267*6777b538SAndroid Build Coastguard Worker 
GetAlternativeServiceInfos(const url::SchemeHostPort & origin,const net::NetworkAnonymizationKey & network_anonymization_key)268*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfoVector HttpServerProperties::GetAlternativeServiceInfos(
269*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& origin,
270*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
271*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
272*6777b538SAndroid Build Coastguard Worker   return GetAlternativeServiceInfosInternal(NormalizeSchemeHostPort(origin),
273*6777b538SAndroid Build Coastguard Worker                                             network_anonymization_key);
274*6777b538SAndroid Build Coastguard Worker }
275*6777b538SAndroid Build Coastguard Worker 
SetHttp2AlternativeService(const url::SchemeHostPort & origin,const NetworkAnonymizationKey & network_anonymization_key,const AlternativeService & alternative_service,base::Time expiration)276*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetHttp2AlternativeService(
277*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& origin,
278*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
279*6777b538SAndroid Build Coastguard Worker     const AlternativeService& alternative_service,
280*6777b538SAndroid Build Coastguard Worker     base::Time expiration) {
281*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(alternative_service.protocol, kProtoHTTP2);
282*6777b538SAndroid Build Coastguard Worker 
283*6777b538SAndroid Build Coastguard Worker   SetAlternativeServices(
284*6777b538SAndroid Build Coastguard Worker       origin, network_anonymization_key,
285*6777b538SAndroid Build Coastguard Worker       AlternativeServiceInfoVector(
286*6777b538SAndroid Build Coastguard Worker           /*size=*/1, AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
287*6777b538SAndroid Build Coastguard Worker                           alternative_service, expiration)));
288*6777b538SAndroid Build Coastguard Worker }
289*6777b538SAndroid Build Coastguard Worker 
SetQuicAlternativeService(const url::SchemeHostPort & origin,const NetworkAnonymizationKey & network_anonymization_key,const AlternativeService & alternative_service,base::Time expiration,const quic::ParsedQuicVersionVector & advertised_versions)290*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetQuicAlternativeService(
291*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& origin,
292*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
293*6777b538SAndroid Build Coastguard Worker     const AlternativeService& alternative_service,
294*6777b538SAndroid Build Coastguard Worker     base::Time expiration,
295*6777b538SAndroid Build Coastguard Worker     const quic::ParsedQuicVersionVector& advertised_versions) {
296*6777b538SAndroid Build Coastguard Worker   DCHECK(alternative_service.protocol == kProtoQUIC);
297*6777b538SAndroid Build Coastguard Worker 
298*6777b538SAndroid Build Coastguard Worker   SetAlternativeServices(
299*6777b538SAndroid Build Coastguard Worker       origin, network_anonymization_key,
300*6777b538SAndroid Build Coastguard Worker       AlternativeServiceInfoVector(
301*6777b538SAndroid Build Coastguard Worker           /*size=*/1,
302*6777b538SAndroid Build Coastguard Worker           AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
303*6777b538SAndroid Build Coastguard Worker               alternative_service, expiration, advertised_versions)));
304*6777b538SAndroid Build Coastguard Worker }
305*6777b538SAndroid Build Coastguard Worker 
SetAlternativeServices(const url::SchemeHostPort & origin,const net::NetworkAnonymizationKey & network_anonymization_key,const AlternativeServiceInfoVector & alternative_service_info_vector)306*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetAlternativeServices(
307*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& origin,
308*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key,
309*6777b538SAndroid Build Coastguard Worker     const AlternativeServiceInfoVector& alternative_service_info_vector) {
310*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
311*6777b538SAndroid Build Coastguard Worker   SetAlternativeServicesInternal(NormalizeSchemeHostPort(origin),
312*6777b538SAndroid Build Coastguard Worker                                  network_anonymization_key,
313*6777b538SAndroid Build Coastguard Worker                                  alternative_service_info_vector);
314*6777b538SAndroid Build Coastguard Worker }
315*6777b538SAndroid Build Coastguard Worker 
MarkAlternativeServiceBroken(const AlternativeService & alternative_service,const net::NetworkAnonymizationKey & network_anonymization_key)316*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::MarkAlternativeServiceBroken(
317*6777b538SAndroid Build Coastguard Worker     const AlternativeService& alternative_service,
318*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
319*6777b538SAndroid Build Coastguard Worker   broken_alternative_services_.MarkBroken(
320*6777b538SAndroid Build Coastguard Worker       BrokenAlternativeService(alternative_service, network_anonymization_key,
321*6777b538SAndroid Build Coastguard Worker                                use_network_anonymization_key_));
322*6777b538SAndroid Build Coastguard Worker   MaybeQueueWriteProperties();
323*6777b538SAndroid Build Coastguard Worker }
324*6777b538SAndroid Build Coastguard Worker 
325*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::
MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(const AlternativeService & alternative_service,const net::NetworkAnonymizationKey & network_anonymization_key)326*6777b538SAndroid Build Coastguard Worker     MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
327*6777b538SAndroid Build Coastguard Worker         const AlternativeService& alternative_service,
328*6777b538SAndroid Build Coastguard Worker         const net::NetworkAnonymizationKey& network_anonymization_key) {
329*6777b538SAndroid Build Coastguard Worker   broken_alternative_services_.MarkBrokenUntilDefaultNetworkChanges(
330*6777b538SAndroid Build Coastguard Worker       BrokenAlternativeService(alternative_service, network_anonymization_key,
331*6777b538SAndroid Build Coastguard Worker                                use_network_anonymization_key_));
332*6777b538SAndroid Build Coastguard Worker   MaybeQueueWriteProperties();
333*6777b538SAndroid Build Coastguard Worker }
334*6777b538SAndroid Build Coastguard Worker 
MarkAlternativeServiceRecentlyBroken(const AlternativeService & alternative_service,const net::NetworkAnonymizationKey & network_anonymization_key)335*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::MarkAlternativeServiceRecentlyBroken(
336*6777b538SAndroid Build Coastguard Worker     const AlternativeService& alternative_service,
337*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
338*6777b538SAndroid Build Coastguard Worker   broken_alternative_services_.MarkRecentlyBroken(
339*6777b538SAndroid Build Coastguard Worker       BrokenAlternativeService(alternative_service, network_anonymization_key,
340*6777b538SAndroid Build Coastguard Worker                                use_network_anonymization_key_));
341*6777b538SAndroid Build Coastguard Worker   MaybeQueueWriteProperties();
342*6777b538SAndroid Build Coastguard Worker }
343*6777b538SAndroid Build Coastguard Worker 
IsAlternativeServiceBroken(const AlternativeService & alternative_service,const net::NetworkAnonymizationKey & network_anonymization_key) const344*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::IsAlternativeServiceBroken(
345*6777b538SAndroid Build Coastguard Worker     const AlternativeService& alternative_service,
346*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) const {
347*6777b538SAndroid Build Coastguard Worker   return broken_alternative_services_.IsBroken(
348*6777b538SAndroid Build Coastguard Worker       BrokenAlternativeService(alternative_service, network_anonymization_key,
349*6777b538SAndroid Build Coastguard Worker                                use_network_anonymization_key_));
350*6777b538SAndroid Build Coastguard Worker }
351*6777b538SAndroid Build Coastguard Worker 
WasAlternativeServiceRecentlyBroken(const AlternativeService & alternative_service,const net::NetworkAnonymizationKey & network_anonymization_key)352*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::WasAlternativeServiceRecentlyBroken(
353*6777b538SAndroid Build Coastguard Worker     const AlternativeService& alternative_service,
354*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
355*6777b538SAndroid Build Coastguard Worker   return broken_alternative_services_.WasRecentlyBroken(
356*6777b538SAndroid Build Coastguard Worker       BrokenAlternativeService(alternative_service, network_anonymization_key,
357*6777b538SAndroid Build Coastguard Worker                                use_network_anonymization_key_));
358*6777b538SAndroid Build Coastguard Worker }
359*6777b538SAndroid Build Coastguard Worker 
ConfirmAlternativeService(const AlternativeService & alternative_service,const net::NetworkAnonymizationKey & network_anonymization_key)360*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::ConfirmAlternativeService(
361*6777b538SAndroid Build Coastguard Worker     const AlternativeService& alternative_service,
362*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
363*6777b538SAndroid Build Coastguard Worker   bool old_value = IsAlternativeServiceBroken(alternative_service,
364*6777b538SAndroid Build Coastguard Worker                                               network_anonymization_key);
365*6777b538SAndroid Build Coastguard Worker   broken_alternative_services_.Confirm(
366*6777b538SAndroid Build Coastguard Worker       BrokenAlternativeService(alternative_service, network_anonymization_key,
367*6777b538SAndroid Build Coastguard Worker                                use_network_anonymization_key_));
368*6777b538SAndroid Build Coastguard Worker   bool new_value = IsAlternativeServiceBroken(alternative_service,
369*6777b538SAndroid Build Coastguard Worker                                               network_anonymization_key);
370*6777b538SAndroid Build Coastguard Worker 
371*6777b538SAndroid Build Coastguard Worker   // For persisting, we only care about the value returned by
372*6777b538SAndroid Build Coastguard Worker   // IsAlternativeServiceBroken. If that value changes, then call persist.
373*6777b538SAndroid Build Coastguard Worker   if (old_value != new_value)
374*6777b538SAndroid Build Coastguard Worker     MaybeQueueWriteProperties();
375*6777b538SAndroid Build Coastguard Worker }
376*6777b538SAndroid Build Coastguard Worker 
OnDefaultNetworkChanged()377*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::OnDefaultNetworkChanged() {
378*6777b538SAndroid Build Coastguard Worker   bool changed = broken_alternative_services_.OnDefaultNetworkChanged();
379*6777b538SAndroid Build Coastguard Worker   if (changed)
380*6777b538SAndroid Build Coastguard Worker     MaybeQueueWriteProperties();
381*6777b538SAndroid Build Coastguard Worker }
382*6777b538SAndroid Build Coastguard Worker 
GetAlternativeServiceInfoAsValue() const383*6777b538SAndroid Build Coastguard Worker base::Value HttpServerProperties::GetAlternativeServiceInfoAsValue() const {
384*6777b538SAndroid Build Coastguard Worker   const base::Time now = clock_->Now();
385*6777b538SAndroid Build Coastguard Worker   const base::TimeTicks now_ticks = tick_clock_->NowTicks();
386*6777b538SAndroid Build Coastguard Worker   base::Value::List dict_list;
387*6777b538SAndroid Build Coastguard Worker   for (const auto& server_info : server_info_map_) {
388*6777b538SAndroid Build Coastguard Worker     if (!server_info.second.alternative_services.has_value())
389*6777b538SAndroid Build Coastguard Worker       continue;
390*6777b538SAndroid Build Coastguard Worker     base::Value::List alternative_service_list;
391*6777b538SAndroid Build Coastguard Worker     const ServerInfoMapKey& key = server_info.first;
392*6777b538SAndroid Build Coastguard Worker     for (const AlternativeServiceInfo& alternative_service_info :
393*6777b538SAndroid Build Coastguard Worker          server_info.second.alternative_services.value()) {
394*6777b538SAndroid Build Coastguard Worker       std::string alternative_service_string(
395*6777b538SAndroid Build Coastguard Worker           alternative_service_info.ToString());
396*6777b538SAndroid Build Coastguard Worker       AlternativeService alternative_service(
397*6777b538SAndroid Build Coastguard Worker           alternative_service_info.alternative_service());
398*6777b538SAndroid Build Coastguard Worker       if (alternative_service.host.empty()) {
399*6777b538SAndroid Build Coastguard Worker         alternative_service.host = key.server.host();
400*6777b538SAndroid Build Coastguard Worker       }
401*6777b538SAndroid Build Coastguard Worker       base::TimeTicks brokenness_expiration_ticks;
402*6777b538SAndroid Build Coastguard Worker       if (broken_alternative_services_.IsBroken(
403*6777b538SAndroid Build Coastguard Worker               BrokenAlternativeService(
404*6777b538SAndroid Build Coastguard Worker                   alternative_service,
405*6777b538SAndroid Build Coastguard Worker                   server_info.first.network_anonymization_key,
406*6777b538SAndroid Build Coastguard Worker                   use_network_anonymization_key_),
407*6777b538SAndroid Build Coastguard Worker               &brokenness_expiration_ticks)) {
408*6777b538SAndroid Build Coastguard Worker         // Convert |brokenness_expiration| from TimeTicks to Time.
409*6777b538SAndroid Build Coastguard Worker         //
410*6777b538SAndroid Build Coastguard Worker         // Note: Cannot use `base::UnlocalizedTimeFormatWithPattern()` since
411*6777b538SAndroid Build Coastguard Worker         // `net/DEPS` disallows `base/i18n`.
412*6777b538SAndroid Build Coastguard Worker         base::Time brokenness_expiration =
413*6777b538SAndroid Build Coastguard Worker             now + (brokenness_expiration_ticks - now_ticks);
414*6777b538SAndroid Build Coastguard Worker         base::Time::Exploded exploded;
415*6777b538SAndroid Build Coastguard Worker         brokenness_expiration.LocalExplode(&exploded);
416*6777b538SAndroid Build Coastguard Worker         std::string broken_info_string =
417*6777b538SAndroid Build Coastguard Worker             " (broken until " +
418*6777b538SAndroid Build Coastguard Worker             base::StringPrintf("%04d-%02d-%02d %0d:%0d:%0d", exploded.year,
419*6777b538SAndroid Build Coastguard Worker                                exploded.month, exploded.day_of_month,
420*6777b538SAndroid Build Coastguard Worker                                exploded.hour, exploded.minute,
421*6777b538SAndroid Build Coastguard Worker                                exploded.second) +
422*6777b538SAndroid Build Coastguard Worker             ")";
423*6777b538SAndroid Build Coastguard Worker         alternative_service_string.append(broken_info_string);
424*6777b538SAndroid Build Coastguard Worker       }
425*6777b538SAndroid Build Coastguard Worker       alternative_service_list.Append(std::move(alternative_service_string));
426*6777b538SAndroid Build Coastguard Worker     }
427*6777b538SAndroid Build Coastguard Worker     if (alternative_service_list.empty())
428*6777b538SAndroid Build Coastguard Worker       continue;
429*6777b538SAndroid Build Coastguard Worker     base::Value::Dict dict;
430*6777b538SAndroid Build Coastguard Worker     dict.Set("server", key.server.Serialize());
431*6777b538SAndroid Build Coastguard Worker     dict.Set("network_anonymization_key",
432*6777b538SAndroid Build Coastguard Worker              key.network_anonymization_key.ToDebugString());
433*6777b538SAndroid Build Coastguard Worker     dict.Set("alternative_service", std::move(alternative_service_list));
434*6777b538SAndroid Build Coastguard Worker     dict_list.Append(std::move(dict));
435*6777b538SAndroid Build Coastguard Worker   }
436*6777b538SAndroid Build Coastguard Worker   return base::Value(std::move(dict_list));
437*6777b538SAndroid Build Coastguard Worker }
438*6777b538SAndroid Build Coastguard Worker 
WasLastLocalAddressWhenQuicWorked(const IPAddress & local_address) const439*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::WasLastLocalAddressWhenQuicWorked(
440*6777b538SAndroid Build Coastguard Worker     const IPAddress& local_address) const {
441*6777b538SAndroid Build Coastguard Worker   return !last_local_address_when_quic_worked_.empty() &&
442*6777b538SAndroid Build Coastguard Worker          last_local_address_when_quic_worked_ == local_address;
443*6777b538SAndroid Build Coastguard Worker }
444*6777b538SAndroid Build Coastguard Worker 
HasLastLocalAddressWhenQuicWorked() const445*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::HasLastLocalAddressWhenQuicWorked() const {
446*6777b538SAndroid Build Coastguard Worker   return !last_local_address_when_quic_worked_.empty();
447*6777b538SAndroid Build Coastguard Worker }
448*6777b538SAndroid Build Coastguard Worker 
SetLastLocalAddressWhenQuicWorked(IPAddress last_local_address_when_quic_worked)449*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetLastLocalAddressWhenQuicWorked(
450*6777b538SAndroid Build Coastguard Worker     IPAddress last_local_address_when_quic_worked) {
451*6777b538SAndroid Build Coastguard Worker   DCHECK(!last_local_address_when_quic_worked.empty());
452*6777b538SAndroid Build Coastguard Worker   if (last_local_address_when_quic_worked_ ==
453*6777b538SAndroid Build Coastguard Worker       last_local_address_when_quic_worked) {
454*6777b538SAndroid Build Coastguard Worker     return;
455*6777b538SAndroid Build Coastguard Worker   }
456*6777b538SAndroid Build Coastguard Worker 
457*6777b538SAndroid Build Coastguard Worker   last_local_address_when_quic_worked_ = last_local_address_when_quic_worked;
458*6777b538SAndroid Build Coastguard Worker   MaybeQueueWriteProperties();
459*6777b538SAndroid Build Coastguard Worker }
460*6777b538SAndroid Build Coastguard Worker 
ClearLastLocalAddressWhenQuicWorked()461*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::ClearLastLocalAddressWhenQuicWorked() {
462*6777b538SAndroid Build Coastguard Worker   if (last_local_address_when_quic_worked_.empty())
463*6777b538SAndroid Build Coastguard Worker     return;
464*6777b538SAndroid Build Coastguard Worker 
465*6777b538SAndroid Build Coastguard Worker   last_local_address_when_quic_worked_ = IPAddress();
466*6777b538SAndroid Build Coastguard Worker   MaybeQueueWriteProperties();
467*6777b538SAndroid Build Coastguard Worker }
468*6777b538SAndroid Build Coastguard Worker 
SetServerNetworkStats(const url::SchemeHostPort & server,const NetworkAnonymizationKey & network_anonymization_key,ServerNetworkStats stats)469*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetServerNetworkStats(
470*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
471*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
472*6777b538SAndroid Build Coastguard Worker     ServerNetworkStats stats) {
473*6777b538SAndroid Build Coastguard Worker   SetServerNetworkStatsInternal(NormalizeSchemeHostPort(server),
474*6777b538SAndroid Build Coastguard Worker                                 network_anonymization_key, std::move(stats));
475*6777b538SAndroid Build Coastguard Worker }
476*6777b538SAndroid Build Coastguard Worker 
ClearServerNetworkStats(const url::SchemeHostPort & server,const NetworkAnonymizationKey & network_anonymization_key)477*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::ClearServerNetworkStats(
478*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
479*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) {
480*6777b538SAndroid Build Coastguard Worker   ClearServerNetworkStatsInternal(NormalizeSchemeHostPort(server),
481*6777b538SAndroid Build Coastguard Worker                                   network_anonymization_key);
482*6777b538SAndroid Build Coastguard Worker }
483*6777b538SAndroid Build Coastguard Worker 
GetServerNetworkStats(const url::SchemeHostPort & server,const NetworkAnonymizationKey & network_anonymization_key)484*6777b538SAndroid Build Coastguard Worker const ServerNetworkStats* HttpServerProperties::GetServerNetworkStats(
485*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
486*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) {
487*6777b538SAndroid Build Coastguard Worker   return GetServerNetworkStatsInternal(NormalizeSchemeHostPort(server),
488*6777b538SAndroid Build Coastguard Worker                                        network_anonymization_key);
489*6777b538SAndroid Build Coastguard Worker }
490*6777b538SAndroid Build Coastguard Worker 
SetQuicServerInfo(const quic::QuicServerId & server_id,const NetworkAnonymizationKey & network_anonymization_key,const std::string & server_info)491*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetQuicServerInfo(
492*6777b538SAndroid Build Coastguard Worker     const quic::QuicServerId& server_id,
493*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
494*6777b538SAndroid Build Coastguard Worker     const std::string& server_info) {
495*6777b538SAndroid Build Coastguard Worker   QuicServerInfoMapKey key =
496*6777b538SAndroid Build Coastguard Worker       CreateQuicServerInfoKey(server_id, network_anonymization_key);
497*6777b538SAndroid Build Coastguard Worker   auto it = quic_server_info_map_.Peek(key);
498*6777b538SAndroid Build Coastguard Worker   bool changed =
499*6777b538SAndroid Build Coastguard Worker       (it == quic_server_info_map_.end() || it->second != server_info);
500*6777b538SAndroid Build Coastguard Worker   quic_server_info_map_.Put(key, server_info);
501*6777b538SAndroid Build Coastguard Worker   UpdateCanonicalServerInfoMap(key);
502*6777b538SAndroid Build Coastguard Worker   if (changed)
503*6777b538SAndroid Build Coastguard Worker     MaybeQueueWriteProperties();
504*6777b538SAndroid Build Coastguard Worker }
505*6777b538SAndroid Build Coastguard Worker 
GetQuicServerInfo(const quic::QuicServerId & server_id,const NetworkAnonymizationKey & network_anonymization_key)506*6777b538SAndroid Build Coastguard Worker const std::string* HttpServerProperties::GetQuicServerInfo(
507*6777b538SAndroid Build Coastguard Worker     const quic::QuicServerId& server_id,
508*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) {
509*6777b538SAndroid Build Coastguard Worker   QuicServerInfoMapKey key =
510*6777b538SAndroid Build Coastguard Worker       CreateQuicServerInfoKey(server_id, network_anonymization_key);
511*6777b538SAndroid Build Coastguard Worker   auto it = quic_server_info_map_.Get(key);
512*6777b538SAndroid Build Coastguard Worker   if (it != quic_server_info_map_.end()) {
513*6777b538SAndroid Build Coastguard Worker     // Since |canonical_server_info_map_| should always map to the most
514*6777b538SAndroid Build Coastguard Worker     // recent host, update it with the one that became MRU in
515*6777b538SAndroid Build Coastguard Worker     // |quic_server_info_map_|.
516*6777b538SAndroid Build Coastguard Worker     UpdateCanonicalServerInfoMap(key);
517*6777b538SAndroid Build Coastguard Worker     return &it->second;
518*6777b538SAndroid Build Coastguard Worker   }
519*6777b538SAndroid Build Coastguard Worker 
520*6777b538SAndroid Build Coastguard Worker   // If the exact match for |server_id| wasn't found, check
521*6777b538SAndroid Build Coastguard Worker   // |canonical_server_info_map_| whether there is server info for a host with
522*6777b538SAndroid Build Coastguard Worker   // the same canonical host suffix.
523*6777b538SAndroid Build Coastguard Worker   auto canonical_itr = GetCanonicalServerInfoHost(key);
524*6777b538SAndroid Build Coastguard Worker   if (canonical_itr == canonical_server_info_map_.end())
525*6777b538SAndroid Build Coastguard Worker     return nullptr;
526*6777b538SAndroid Build Coastguard Worker 
527*6777b538SAndroid Build Coastguard Worker   // When search in |quic_server_info_map_|, do not change the MRU order.
528*6777b538SAndroid Build Coastguard Worker   it = quic_server_info_map_.Peek(CreateQuicServerInfoKey(
529*6777b538SAndroid Build Coastguard Worker       canonical_itr->second, network_anonymization_key));
530*6777b538SAndroid Build Coastguard Worker   if (it != quic_server_info_map_.end())
531*6777b538SAndroid Build Coastguard Worker     return &it->second;
532*6777b538SAndroid Build Coastguard Worker 
533*6777b538SAndroid Build Coastguard Worker   return nullptr;
534*6777b538SAndroid Build Coastguard Worker }
535*6777b538SAndroid Build Coastguard Worker 
536*6777b538SAndroid Build Coastguard Worker const HttpServerProperties::QuicServerInfoMap&
quic_server_info_map() const537*6777b538SAndroid Build Coastguard Worker HttpServerProperties::quic_server_info_map() const {
538*6777b538SAndroid Build Coastguard Worker   return quic_server_info_map_;
539*6777b538SAndroid Build Coastguard Worker }
540*6777b538SAndroid Build Coastguard Worker 
max_server_configs_stored_in_properties() const541*6777b538SAndroid Build Coastguard Worker size_t HttpServerProperties::max_server_configs_stored_in_properties() const {
542*6777b538SAndroid Build Coastguard Worker   return max_server_configs_stored_in_properties_;
543*6777b538SAndroid Build Coastguard Worker }
544*6777b538SAndroid Build Coastguard Worker 
SetMaxServerConfigsStoredInProperties(size_t max_server_configs_stored_in_properties)545*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetMaxServerConfigsStoredInProperties(
546*6777b538SAndroid Build Coastguard Worker     size_t max_server_configs_stored_in_properties) {
547*6777b538SAndroid Build Coastguard Worker   // Do nothing if the new size is the same as the old one.
548*6777b538SAndroid Build Coastguard Worker   if (max_server_configs_stored_in_properties_ ==
549*6777b538SAndroid Build Coastguard Worker       max_server_configs_stored_in_properties) {
550*6777b538SAndroid Build Coastguard Worker     return;
551*6777b538SAndroid Build Coastguard Worker   }
552*6777b538SAndroid Build Coastguard Worker 
553*6777b538SAndroid Build Coastguard Worker   max_server_configs_stored_in_properties_ =
554*6777b538SAndroid Build Coastguard Worker       max_server_configs_stored_in_properties;
555*6777b538SAndroid Build Coastguard Worker 
556*6777b538SAndroid Build Coastguard Worker   // LRUCache doesn't allow the capacity of the cache to be changed. Thus create
557*6777b538SAndroid Build Coastguard Worker   // a new map with the new size and add current elements and swap the new map.
558*6777b538SAndroid Build Coastguard Worker   quic_server_info_map_.ShrinkToSize(max_server_configs_stored_in_properties_);
559*6777b538SAndroid Build Coastguard Worker   QuicServerInfoMap temp_map(max_server_configs_stored_in_properties_);
560*6777b538SAndroid Build Coastguard Worker   // Update the |canonical_server_info_map_| as well, so it stays in sync with
561*6777b538SAndroid Build Coastguard Worker   // |quic_server_info_map_|.
562*6777b538SAndroid Build Coastguard Worker   canonical_server_info_map_ = QuicCanonicalMap();
563*6777b538SAndroid Build Coastguard Worker   for (const auto& [key, server_info] : base::Reversed(quic_server_info_map_)) {
564*6777b538SAndroid Build Coastguard Worker     temp_map.Put(key, server_info);
565*6777b538SAndroid Build Coastguard Worker     UpdateCanonicalServerInfoMap(key);
566*6777b538SAndroid Build Coastguard Worker   }
567*6777b538SAndroid Build Coastguard Worker 
568*6777b538SAndroid Build Coastguard Worker   quic_server_info_map_.Swap(temp_map);
569*6777b538SAndroid Build Coastguard Worker   if (properties_manager_) {
570*6777b538SAndroid Build Coastguard Worker     properties_manager_->set_max_server_configs_stored_in_properties(
571*6777b538SAndroid Build Coastguard Worker         max_server_configs_stored_in_properties);
572*6777b538SAndroid Build Coastguard Worker   }
573*6777b538SAndroid Build Coastguard Worker }
574*6777b538SAndroid Build Coastguard Worker 
SetBrokenAlternativeServicesDelayParams(std::optional<base::TimeDelta> initial_delay,std::optional<bool> exponential_backoff_on_initial_delay)575*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetBrokenAlternativeServicesDelayParams(
576*6777b538SAndroid Build Coastguard Worker     std::optional<base::TimeDelta> initial_delay,
577*6777b538SAndroid Build Coastguard Worker     std::optional<bool> exponential_backoff_on_initial_delay) {
578*6777b538SAndroid Build Coastguard Worker   broken_alternative_services_.SetDelayParams(
579*6777b538SAndroid Build Coastguard Worker       initial_delay, exponential_backoff_on_initial_delay);
580*6777b538SAndroid Build Coastguard Worker }
581*6777b538SAndroid Build Coastguard Worker 
IsInitialized() const582*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::IsInitialized() const {
583*6777b538SAndroid Build Coastguard Worker   return is_initialized_;
584*6777b538SAndroid Build Coastguard Worker }
585*6777b538SAndroid Build Coastguard Worker 
OnExpireBrokenAlternativeService(const AlternativeService & expired_alternative_service,const NetworkAnonymizationKey & network_anonymization_key)586*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::OnExpireBrokenAlternativeService(
587*6777b538SAndroid Build Coastguard Worker     const AlternativeService& expired_alternative_service,
588*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) {
589*6777b538SAndroid Build Coastguard Worker   // Remove every occurrence of |expired_alternative_service| from
590*6777b538SAndroid Build Coastguard Worker   // |alternative_service_map_|.
591*6777b538SAndroid Build Coastguard Worker   for (auto map_it = server_info_map_.begin();
592*6777b538SAndroid Build Coastguard Worker        map_it != server_info_map_.end();) {
593*6777b538SAndroid Build Coastguard Worker     if (!map_it->second.alternative_services.has_value() ||
594*6777b538SAndroid Build Coastguard Worker         map_it->first.network_anonymization_key != network_anonymization_key) {
595*6777b538SAndroid Build Coastguard Worker       ++map_it;
596*6777b538SAndroid Build Coastguard Worker       continue;
597*6777b538SAndroid Build Coastguard Worker     }
598*6777b538SAndroid Build Coastguard Worker     AlternativeServiceInfoVector* service_info =
599*6777b538SAndroid Build Coastguard Worker         &map_it->second.alternative_services.value();
600*6777b538SAndroid Build Coastguard Worker     for (auto it = service_info->begin(); it != service_info->end();) {
601*6777b538SAndroid Build Coastguard Worker       AlternativeService alternative_service(it->alternative_service());
602*6777b538SAndroid Build Coastguard Worker       // Empty hostname in map means hostname of key: substitute before
603*6777b538SAndroid Build Coastguard Worker       // comparing to |expired_alternative_service|.
604*6777b538SAndroid Build Coastguard Worker       if (alternative_service.host.empty()) {
605*6777b538SAndroid Build Coastguard Worker         alternative_service.host = map_it->first.server.host();
606*6777b538SAndroid Build Coastguard Worker       }
607*6777b538SAndroid Build Coastguard Worker       if (alternative_service == expired_alternative_service) {
608*6777b538SAndroid Build Coastguard Worker         it = service_info->erase(it);
609*6777b538SAndroid Build Coastguard Worker         continue;
610*6777b538SAndroid Build Coastguard Worker       }
611*6777b538SAndroid Build Coastguard Worker       ++it;
612*6777b538SAndroid Build Coastguard Worker     }
613*6777b538SAndroid Build Coastguard Worker     // If an origin has an empty list of alternative services, then remove it
614*6777b538SAndroid Build Coastguard Worker     // from both |canonical_alt_svc_map_| and
615*6777b538SAndroid Build Coastguard Worker     // |alternative_service_map_|.
616*6777b538SAndroid Build Coastguard Worker     if (service_info->empty()) {
617*6777b538SAndroid Build Coastguard Worker       RemoveAltSvcCanonicalHost(map_it->first.server,
618*6777b538SAndroid Build Coastguard Worker                                 network_anonymization_key);
619*6777b538SAndroid Build Coastguard Worker       map_it->second.alternative_services.reset();
620*6777b538SAndroid Build Coastguard Worker       map_it = server_info_map_.EraseIfEmpty(map_it);
621*6777b538SAndroid Build Coastguard Worker       continue;
622*6777b538SAndroid Build Coastguard Worker     }
623*6777b538SAndroid Build Coastguard Worker     ++map_it;
624*6777b538SAndroid Build Coastguard Worker   }
625*6777b538SAndroid Build Coastguard Worker }
626*6777b538SAndroid Build Coastguard Worker 
GetUpdatePrefsDelayForTesting()627*6777b538SAndroid Build Coastguard Worker base::TimeDelta HttpServerProperties::GetUpdatePrefsDelayForTesting() {
628*6777b538SAndroid Build Coastguard Worker   return kUpdatePrefsDelay;
629*6777b538SAndroid Build Coastguard Worker }
630*6777b538SAndroid Build Coastguard Worker 
GetSupportsSpdyInternal(url::SchemeHostPort server,const net::NetworkAnonymizationKey & network_anonymization_key)631*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::GetSupportsSpdyInternal(
632*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
633*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
634*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
635*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWsScheme);
636*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWssScheme);
637*6777b538SAndroid Build Coastguard Worker   if (server.host().empty())
638*6777b538SAndroid Build Coastguard Worker     return false;
639*6777b538SAndroid Build Coastguard Worker 
640*6777b538SAndroid Build Coastguard Worker   auto server_info = server_info_map_.Get(
641*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(std::move(server), network_anonymization_key));
642*6777b538SAndroid Build Coastguard Worker   return server_info != server_info_map_.end() &&
643*6777b538SAndroid Build Coastguard Worker          server_info->second.supports_spdy.value_or(false);
644*6777b538SAndroid Build Coastguard Worker }
645*6777b538SAndroid Build Coastguard Worker 
SetSupportsSpdyInternal(url::SchemeHostPort server,const net::NetworkAnonymizationKey & network_anonymization_key,bool supports_spdy)646*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetSupportsSpdyInternal(
647*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
648*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key,
649*6777b538SAndroid Build Coastguard Worker     bool supports_spdy) {
650*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
651*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWsScheme);
652*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWssScheme);
653*6777b538SAndroid Build Coastguard Worker   if (server.host().empty())
654*6777b538SAndroid Build Coastguard Worker     return;
655*6777b538SAndroid Build Coastguard Worker 
656*6777b538SAndroid Build Coastguard Worker   auto server_info = server_info_map_.GetOrPut(
657*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(std::move(server), network_anonymization_key));
658*6777b538SAndroid Build Coastguard Worker   // If value is already the same as |supports_spdy|, or value is unset and
659*6777b538SAndroid Build Coastguard Worker   // |supports_spdy| is false, don't queue a write.
660*6777b538SAndroid Build Coastguard Worker   bool queue_write =
661*6777b538SAndroid Build Coastguard Worker       server_info->second.supports_spdy.value_or(false) != supports_spdy;
662*6777b538SAndroid Build Coastguard Worker   server_info->second.supports_spdy = supports_spdy;
663*6777b538SAndroid Build Coastguard Worker 
664*6777b538SAndroid Build Coastguard Worker   if (queue_write)
665*6777b538SAndroid Build Coastguard Worker     MaybeQueueWriteProperties();
666*6777b538SAndroid Build Coastguard Worker }
667*6777b538SAndroid Build Coastguard Worker 
RequiresHTTP11Internal(url::SchemeHostPort server,const net::NetworkAnonymizationKey & network_anonymization_key)668*6777b538SAndroid Build Coastguard Worker bool HttpServerProperties::RequiresHTTP11Internal(
669*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
670*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
671*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
672*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWsScheme);
673*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWssScheme);
674*6777b538SAndroid Build Coastguard Worker   if (server.host().empty())
675*6777b538SAndroid Build Coastguard Worker     return false;
676*6777b538SAndroid Build Coastguard Worker 
677*6777b538SAndroid Build Coastguard Worker   auto spdy_info = server_info_map_.Get(
678*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(std::move(server), network_anonymization_key));
679*6777b538SAndroid Build Coastguard Worker   return spdy_info != server_info_map_.end() &&
680*6777b538SAndroid Build Coastguard Worker          spdy_info->second.requires_http11.value_or(false);
681*6777b538SAndroid Build Coastguard Worker }
682*6777b538SAndroid Build Coastguard Worker 
SetHTTP11RequiredInternal(url::SchemeHostPort server,const net::NetworkAnonymizationKey & network_anonymization_key)683*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetHTTP11RequiredInternal(
684*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
685*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
686*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
687*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWsScheme);
688*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWssScheme);
689*6777b538SAndroid Build Coastguard Worker   if (server.host().empty())
690*6777b538SAndroid Build Coastguard Worker     return;
691*6777b538SAndroid Build Coastguard Worker 
692*6777b538SAndroid Build Coastguard Worker   server_info_map_
693*6777b538SAndroid Build Coastguard Worker       .GetOrPut(
694*6777b538SAndroid Build Coastguard Worker           CreateServerInfoKey(std::move(server), network_anonymization_key))
695*6777b538SAndroid Build Coastguard Worker       ->second.requires_http11 = true;
696*6777b538SAndroid Build Coastguard Worker   // No need to call MaybeQueueWriteProperties(), as this information is not
697*6777b538SAndroid Build Coastguard Worker   // persisted to preferences.
698*6777b538SAndroid Build Coastguard Worker }
699*6777b538SAndroid Build Coastguard Worker 
MaybeForceHTTP11Internal(url::SchemeHostPort server,const net::NetworkAnonymizationKey & network_anonymization_key,SSLConfig * ssl_config)700*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::MaybeForceHTTP11Internal(
701*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
702*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key,
703*6777b538SAndroid Build Coastguard Worker     SSLConfig* ssl_config) {
704*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
705*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWsScheme);
706*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWssScheme);
707*6777b538SAndroid Build Coastguard Worker   if (RequiresHTTP11(std::move(server), network_anonymization_key)) {
708*6777b538SAndroid Build Coastguard Worker     ssl_config->alpn_protos.clear();
709*6777b538SAndroid Build Coastguard Worker     ssl_config->alpn_protos.push_back(kProtoHTTP11);
710*6777b538SAndroid Build Coastguard Worker   }
711*6777b538SAndroid Build Coastguard Worker }
712*6777b538SAndroid Build Coastguard Worker 
713*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfoVector
GetAlternativeServiceInfosInternal(const url::SchemeHostPort & origin,const net::NetworkAnonymizationKey & network_anonymization_key)714*6777b538SAndroid Build Coastguard Worker HttpServerProperties::GetAlternativeServiceInfosInternal(
715*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& origin,
716*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
717*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
718*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(origin.scheme(), url::kWsScheme);
719*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(origin.scheme(), url::kWssScheme);
720*6777b538SAndroid Build Coastguard Worker 
721*6777b538SAndroid Build Coastguard Worker   // Copy valid alternative service infos into
722*6777b538SAndroid Build Coastguard Worker   // |valid_alternative_service_infos|.
723*6777b538SAndroid Build Coastguard Worker   AlternativeServiceInfoVector valid_alternative_service_infos;
724*6777b538SAndroid Build Coastguard Worker   const base::Time now = clock_->Now();
725*6777b538SAndroid Build Coastguard Worker   auto map_it = server_info_map_.Get(
726*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(origin, network_anonymization_key));
727*6777b538SAndroid Build Coastguard Worker   if (map_it != server_info_map_.end() &&
728*6777b538SAndroid Build Coastguard Worker       map_it->second.alternative_services.has_value()) {
729*6777b538SAndroid Build Coastguard Worker     AlternativeServiceInfoVector* service_info =
730*6777b538SAndroid Build Coastguard Worker         &map_it->second.alternative_services.value();
731*6777b538SAndroid Build Coastguard Worker     HostPortPair host_port_pair(origin.host(), origin.port());
732*6777b538SAndroid Build Coastguard Worker     for (auto it = service_info->begin(); it != service_info->end();) {
733*6777b538SAndroid Build Coastguard Worker       if (it->expiration() < now) {
734*6777b538SAndroid Build Coastguard Worker         it = service_info->erase(it);
735*6777b538SAndroid Build Coastguard Worker         continue;
736*6777b538SAndroid Build Coastguard Worker       }
737*6777b538SAndroid Build Coastguard Worker       AlternativeService alternative_service(it->alternative_service());
738*6777b538SAndroid Build Coastguard Worker       if (alternative_service.host.empty()) {
739*6777b538SAndroid Build Coastguard Worker         alternative_service.host = origin.host();
740*6777b538SAndroid Build Coastguard Worker       }
741*6777b538SAndroid Build Coastguard Worker       // If the alternative service is equivalent to the origin (same host, same
742*6777b538SAndroid Build Coastguard Worker       // port, and both TCP), skip it.
743*6777b538SAndroid Build Coastguard Worker       if (host_port_pair.Equals(alternative_service.host_port_pair()) &&
744*6777b538SAndroid Build Coastguard Worker           alternative_service.protocol == kProtoHTTP2) {
745*6777b538SAndroid Build Coastguard Worker         ++it;
746*6777b538SAndroid Build Coastguard Worker         continue;
747*6777b538SAndroid Build Coastguard Worker       }
748*6777b538SAndroid Build Coastguard Worker       if (alternative_service.protocol == kProtoQUIC) {
749*6777b538SAndroid Build Coastguard Worker         valid_alternative_service_infos.push_back(
750*6777b538SAndroid Build Coastguard Worker             AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
751*6777b538SAndroid Build Coastguard Worker                 alternative_service, it->expiration(),
752*6777b538SAndroid Build Coastguard Worker                 it->advertised_versions()));
753*6777b538SAndroid Build Coastguard Worker       } else {
754*6777b538SAndroid Build Coastguard Worker         valid_alternative_service_infos.push_back(
755*6777b538SAndroid Build Coastguard Worker             AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
756*6777b538SAndroid Build Coastguard Worker                 alternative_service, it->expiration()));
757*6777b538SAndroid Build Coastguard Worker       }
758*6777b538SAndroid Build Coastguard Worker       ++it;
759*6777b538SAndroid Build Coastguard Worker     }
760*6777b538SAndroid Build Coastguard Worker     if (service_info->empty()) {
761*6777b538SAndroid Build Coastguard Worker       map_it->second.alternative_services.reset();
762*6777b538SAndroid Build Coastguard Worker       server_info_map_.EraseIfEmpty(map_it);
763*6777b538SAndroid Build Coastguard Worker     }
764*6777b538SAndroid Build Coastguard Worker     return valid_alternative_service_infos;
765*6777b538SAndroid Build Coastguard Worker   }
766*6777b538SAndroid Build Coastguard Worker 
767*6777b538SAndroid Build Coastguard Worker   auto canonical = GetCanonicalAltSvcHost(origin, network_anonymization_key);
768*6777b538SAndroid Build Coastguard Worker   if (canonical == canonical_alt_svc_map_.end()) {
769*6777b538SAndroid Build Coastguard Worker     return AlternativeServiceInfoVector();
770*6777b538SAndroid Build Coastguard Worker   }
771*6777b538SAndroid Build Coastguard Worker   map_it = server_info_map_.Get(
772*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(canonical->second, network_anonymization_key));
773*6777b538SAndroid Build Coastguard Worker   if (map_it == server_info_map_.end() ||
774*6777b538SAndroid Build Coastguard Worker       !map_it->second.alternative_services.has_value()) {
775*6777b538SAndroid Build Coastguard Worker     return AlternativeServiceInfoVector();
776*6777b538SAndroid Build Coastguard Worker   }
777*6777b538SAndroid Build Coastguard Worker   AlternativeServiceInfoVector* service_info =
778*6777b538SAndroid Build Coastguard Worker       &map_it->second.alternative_services.value();
779*6777b538SAndroid Build Coastguard Worker   for (auto it = service_info->begin(); it != service_info->end();) {
780*6777b538SAndroid Build Coastguard Worker     if (it->expiration() < now) {
781*6777b538SAndroid Build Coastguard Worker       it = service_info->erase(it);
782*6777b538SAndroid Build Coastguard Worker       continue;
783*6777b538SAndroid Build Coastguard Worker     }
784*6777b538SAndroid Build Coastguard Worker     AlternativeService alternative_service(it->alternative_service());
785*6777b538SAndroid Build Coastguard Worker     if (alternative_service.host.empty()) {
786*6777b538SAndroid Build Coastguard Worker       alternative_service.host = canonical->second.host();
787*6777b538SAndroid Build Coastguard Worker       if (IsAlternativeServiceBroken(alternative_service,
788*6777b538SAndroid Build Coastguard Worker                                      network_anonymization_key)) {
789*6777b538SAndroid Build Coastguard Worker         ++it;
790*6777b538SAndroid Build Coastguard Worker         continue;
791*6777b538SAndroid Build Coastguard Worker       }
792*6777b538SAndroid Build Coastguard Worker       alternative_service.host = origin.host();
793*6777b538SAndroid Build Coastguard Worker     } else if (IsAlternativeServiceBroken(alternative_service,
794*6777b538SAndroid Build Coastguard Worker                                           network_anonymization_key)) {
795*6777b538SAndroid Build Coastguard Worker       ++it;
796*6777b538SAndroid Build Coastguard Worker       continue;
797*6777b538SAndroid Build Coastguard Worker     }
798*6777b538SAndroid Build Coastguard Worker     if (alternative_service.protocol == kProtoQUIC) {
799*6777b538SAndroid Build Coastguard Worker       valid_alternative_service_infos.push_back(
800*6777b538SAndroid Build Coastguard Worker           AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
801*6777b538SAndroid Build Coastguard Worker               alternative_service, it->expiration(),
802*6777b538SAndroid Build Coastguard Worker               it->advertised_versions()));
803*6777b538SAndroid Build Coastguard Worker     } else {
804*6777b538SAndroid Build Coastguard Worker       valid_alternative_service_infos.push_back(
805*6777b538SAndroid Build Coastguard Worker           AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
806*6777b538SAndroid Build Coastguard Worker               alternative_service, it->expiration()));
807*6777b538SAndroid Build Coastguard Worker     }
808*6777b538SAndroid Build Coastguard Worker     ++it;
809*6777b538SAndroid Build Coastguard Worker   }
810*6777b538SAndroid Build Coastguard Worker   if (service_info->empty())
811*6777b538SAndroid Build Coastguard Worker     server_info_map_.EraseIfEmpty(map_it);
812*6777b538SAndroid Build Coastguard Worker   return valid_alternative_service_infos;
813*6777b538SAndroid Build Coastguard Worker }
814*6777b538SAndroid Build Coastguard Worker 
SetAlternativeServicesInternal(const url::SchemeHostPort & origin,const net::NetworkAnonymizationKey & network_anonymization_key,const AlternativeServiceInfoVector & alternative_service_info_vector)815*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetAlternativeServicesInternal(
816*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& origin,
817*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key,
818*6777b538SAndroid Build Coastguard Worker     const AlternativeServiceInfoVector& alternative_service_info_vector) {
819*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
820*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(origin.scheme(), url::kWsScheme);
821*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(origin.scheme(), url::kWssScheme);
822*6777b538SAndroid Build Coastguard Worker 
823*6777b538SAndroid Build Coastguard Worker   if (alternative_service_info_vector.empty()) {
824*6777b538SAndroid Build Coastguard Worker     RemoveAltSvcCanonicalHost(origin, network_anonymization_key);
825*6777b538SAndroid Build Coastguard Worker     // Don't bother moving to front when erasing information.
826*6777b538SAndroid Build Coastguard Worker     auto it = server_info_map_.Peek(
827*6777b538SAndroid Build Coastguard Worker         CreateServerInfoKey(origin, network_anonymization_key));
828*6777b538SAndroid Build Coastguard Worker 
829*6777b538SAndroid Build Coastguard Worker     if (it == server_info_map_.end() ||
830*6777b538SAndroid Build Coastguard Worker         !it->second.alternative_services.has_value()) {
831*6777b538SAndroid Build Coastguard Worker       return;
832*6777b538SAndroid Build Coastguard Worker     }
833*6777b538SAndroid Build Coastguard Worker 
834*6777b538SAndroid Build Coastguard Worker     it->second.alternative_services.reset();
835*6777b538SAndroid Build Coastguard Worker     server_info_map_.EraseIfEmpty(it);
836*6777b538SAndroid Build Coastguard Worker     MaybeQueueWriteProperties();
837*6777b538SAndroid Build Coastguard Worker     return;
838*6777b538SAndroid Build Coastguard Worker   }
839*6777b538SAndroid Build Coastguard Worker 
840*6777b538SAndroid Build Coastguard Worker   auto it = server_info_map_.GetOrPut(
841*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(origin, network_anonymization_key));
842*6777b538SAndroid Build Coastguard Worker   bool need_update_pref = true;
843*6777b538SAndroid Build Coastguard Worker   if (it->second.alternative_services.has_value()) {
844*6777b538SAndroid Build Coastguard Worker     DCHECK(!it->second.empty());
845*6777b538SAndroid Build Coastguard Worker     if (it->second.alternative_services->size() ==
846*6777b538SAndroid Build Coastguard Worker         alternative_service_info_vector.size()) {
847*6777b538SAndroid Build Coastguard Worker       const base::Time now = clock_->Now();
848*6777b538SAndroid Build Coastguard Worker       need_update_pref = false;
849*6777b538SAndroid Build Coastguard Worker       auto new_it = alternative_service_info_vector.begin();
850*6777b538SAndroid Build Coastguard Worker       for (const auto& old : *it->second.alternative_services) {
851*6777b538SAndroid Build Coastguard Worker         // Persist to disk immediately if new entry has different scheme, host,
852*6777b538SAndroid Build Coastguard Worker         // or port.
853*6777b538SAndroid Build Coastguard Worker         if (old.alternative_service() != new_it->alternative_service()) {
854*6777b538SAndroid Build Coastguard Worker           need_update_pref = true;
855*6777b538SAndroid Build Coastguard Worker           break;
856*6777b538SAndroid Build Coastguard Worker         }
857*6777b538SAndroid Build Coastguard Worker         // Also persist to disk if new expiration it more that twice as far or
858*6777b538SAndroid Build Coastguard Worker         // less than half as far in the future.
859*6777b538SAndroid Build Coastguard Worker         base::Time old_time = old.expiration();
860*6777b538SAndroid Build Coastguard Worker         base::Time new_time = new_it->expiration();
861*6777b538SAndroid Build Coastguard Worker         if (new_time - now > 2 * (old_time - now) ||
862*6777b538SAndroid Build Coastguard Worker             2 * (new_time - now) < (old_time - now)) {
863*6777b538SAndroid Build Coastguard Worker           need_update_pref = true;
864*6777b538SAndroid Build Coastguard Worker           break;
865*6777b538SAndroid Build Coastguard Worker         }
866*6777b538SAndroid Build Coastguard Worker         // Also persist to disk if new entry has a different list of advertised
867*6777b538SAndroid Build Coastguard Worker         // versions.
868*6777b538SAndroid Build Coastguard Worker         if (old.advertised_versions() != new_it->advertised_versions()) {
869*6777b538SAndroid Build Coastguard Worker           need_update_pref = true;
870*6777b538SAndroid Build Coastguard Worker           break;
871*6777b538SAndroid Build Coastguard Worker         }
872*6777b538SAndroid Build Coastguard Worker         ++new_it;
873*6777b538SAndroid Build Coastguard Worker       }
874*6777b538SAndroid Build Coastguard Worker     }
875*6777b538SAndroid Build Coastguard Worker   }
876*6777b538SAndroid Build Coastguard Worker 
877*6777b538SAndroid Build Coastguard Worker   const bool previously_no_alternative_services =
878*6777b538SAndroid Build Coastguard Worker       (GetIteratorWithAlternativeServiceInfo(
879*6777b538SAndroid Build Coastguard Worker            origin, network_anonymization_key) == server_info_map_.end());
880*6777b538SAndroid Build Coastguard Worker 
881*6777b538SAndroid Build Coastguard Worker   it->second.alternative_services = alternative_service_info_vector;
882*6777b538SAndroid Build Coastguard Worker 
883*6777b538SAndroid Build Coastguard Worker   if (previously_no_alternative_services &&
884*6777b538SAndroid Build Coastguard Worker       !GetAlternativeServiceInfos(origin, network_anonymization_key).empty()) {
885*6777b538SAndroid Build Coastguard Worker     // TODO(rch): Consider the case where multiple requests are started
886*6777b538SAndroid Build Coastguard Worker     // before the first completes. In this case, only one of the jobs
887*6777b538SAndroid Build Coastguard Worker     // would reach this code, whereas all of them should should have.
888*6777b538SAndroid Build Coastguard Worker     HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING,
889*6777b538SAndroid Build Coastguard Worker                                     IsGoogleHost(origin.host()));
890*6777b538SAndroid Build Coastguard Worker   }
891*6777b538SAndroid Build Coastguard Worker 
892*6777b538SAndroid Build Coastguard Worker   // If this host ends with a canonical suffix, then set it as the
893*6777b538SAndroid Build Coastguard Worker   // canonical host.
894*6777b538SAndroid Build Coastguard Worker   const char* kCanonicalScheme = "https";
895*6777b538SAndroid Build Coastguard Worker   if (origin.scheme() == kCanonicalScheme) {
896*6777b538SAndroid Build Coastguard Worker     const std::string* canonical_suffix = GetCanonicalSuffix(origin.host());
897*6777b538SAndroid Build Coastguard Worker     if (canonical_suffix != nullptr) {
898*6777b538SAndroid Build Coastguard Worker       url::SchemeHostPort canonical_server(kCanonicalScheme, *canonical_suffix,
899*6777b538SAndroid Build Coastguard Worker                                            origin.port());
900*6777b538SAndroid Build Coastguard Worker       canonical_alt_svc_map_[CreateServerInfoKey(
901*6777b538SAndroid Build Coastguard Worker           canonical_server, network_anonymization_key)] = origin;
902*6777b538SAndroid Build Coastguard Worker     }
903*6777b538SAndroid Build Coastguard Worker   }
904*6777b538SAndroid Build Coastguard Worker 
905*6777b538SAndroid Build Coastguard Worker   if (need_update_pref)
906*6777b538SAndroid Build Coastguard Worker     MaybeQueueWriteProperties();
907*6777b538SAndroid Build Coastguard Worker }
908*6777b538SAndroid Build Coastguard Worker 
SetServerNetworkStatsInternal(url::SchemeHostPort server,const NetworkAnonymizationKey & network_anonymization_key,ServerNetworkStats stats)909*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::SetServerNetworkStatsInternal(
910*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
911*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
912*6777b538SAndroid Build Coastguard Worker     ServerNetworkStats stats) {
913*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
914*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWsScheme);
915*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWssScheme);
916*6777b538SAndroid Build Coastguard Worker 
917*6777b538SAndroid Build Coastguard Worker   auto server_info = server_info_map_.GetOrPut(
918*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(std::move(server), network_anonymization_key));
919*6777b538SAndroid Build Coastguard Worker   bool changed = !server_info->second.server_network_stats.has_value() ||
920*6777b538SAndroid Build Coastguard Worker                  server_info->second.server_network_stats.value() != stats;
921*6777b538SAndroid Build Coastguard Worker 
922*6777b538SAndroid Build Coastguard Worker   if (changed) {
923*6777b538SAndroid Build Coastguard Worker     server_info->second.server_network_stats = stats;
924*6777b538SAndroid Build Coastguard Worker     MaybeQueueWriteProperties();
925*6777b538SAndroid Build Coastguard Worker   }
926*6777b538SAndroid Build Coastguard Worker }
927*6777b538SAndroid Build Coastguard Worker 
ClearServerNetworkStatsInternal(url::SchemeHostPort server,const NetworkAnonymizationKey & network_anonymization_key)928*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::ClearServerNetworkStatsInternal(
929*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
930*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) {
931*6777b538SAndroid Build Coastguard Worker   auto server_info = server_info_map_.Peek(
932*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(std::move(server), network_anonymization_key));
933*6777b538SAndroid Build Coastguard Worker   // If stats are empty, nothing to do.
934*6777b538SAndroid Build Coastguard Worker   if (server_info == server_info_map_.end() ||
935*6777b538SAndroid Build Coastguard Worker       !server_info->second.server_network_stats.has_value()) {
936*6777b538SAndroid Build Coastguard Worker     return;
937*6777b538SAndroid Build Coastguard Worker   }
938*6777b538SAndroid Build Coastguard Worker 
939*6777b538SAndroid Build Coastguard Worker   // Otherwise, clear and delete if needed. No need to bring to front of MRU
940*6777b538SAndroid Build Coastguard Worker   // cache when clearing data.
941*6777b538SAndroid Build Coastguard Worker   server_info->second.server_network_stats.reset();
942*6777b538SAndroid Build Coastguard Worker   if (server_info->second.empty())
943*6777b538SAndroid Build Coastguard Worker     server_info_map_.EraseIfEmpty(server_info);
944*6777b538SAndroid Build Coastguard Worker   MaybeQueueWriteProperties();
945*6777b538SAndroid Build Coastguard Worker }
946*6777b538SAndroid Build Coastguard Worker 
GetServerNetworkStatsInternal(url::SchemeHostPort server,const NetworkAnonymizationKey & network_anonymization_key)947*6777b538SAndroid Build Coastguard Worker const ServerNetworkStats* HttpServerProperties::GetServerNetworkStatsInternal(
948*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort server,
949*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) {
950*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
951*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWsScheme);
952*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(server.scheme(), url::kWssScheme);
953*6777b538SAndroid Build Coastguard Worker 
954*6777b538SAndroid Build Coastguard Worker   auto server_info = server_info_map_.Get(
955*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(std::move(server), network_anonymization_key));
956*6777b538SAndroid Build Coastguard Worker   if (server_info == server_info_map_.end() ||
957*6777b538SAndroid Build Coastguard Worker       !server_info->second.server_network_stats.has_value()) {
958*6777b538SAndroid Build Coastguard Worker     return nullptr;
959*6777b538SAndroid Build Coastguard Worker   }
960*6777b538SAndroid Build Coastguard Worker   return &server_info->second.server_network_stats.value();
961*6777b538SAndroid Build Coastguard Worker }
962*6777b538SAndroid Build Coastguard Worker 
963*6777b538SAndroid Build Coastguard Worker HttpServerProperties::QuicServerInfoMapKey
CreateQuicServerInfoKey(const quic::QuicServerId & server_id,const NetworkAnonymizationKey & network_anonymization_key) const964*6777b538SAndroid Build Coastguard Worker HttpServerProperties::CreateQuicServerInfoKey(
965*6777b538SAndroid Build Coastguard Worker     const quic::QuicServerId& server_id,
966*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) const {
967*6777b538SAndroid Build Coastguard Worker   return QuicServerInfoMapKey(server_id, network_anonymization_key,
968*6777b538SAndroid Build Coastguard Worker                               use_network_anonymization_key_);
969*6777b538SAndroid Build Coastguard Worker }
970*6777b538SAndroid Build Coastguard Worker 
971*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMapKey
CreateServerInfoKey(const url::SchemeHostPort & server,const NetworkAnonymizationKey & network_anonymization_key) const972*6777b538SAndroid Build Coastguard Worker HttpServerProperties::CreateServerInfoKey(
973*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
974*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) const {
975*6777b538SAndroid Build Coastguard Worker   return ServerInfoMapKey(server, network_anonymization_key,
976*6777b538SAndroid Build Coastguard Worker                           use_network_anonymization_key_);
977*6777b538SAndroid Build Coastguard Worker }
978*6777b538SAndroid Build Coastguard Worker 
979*6777b538SAndroid Build Coastguard Worker HttpServerProperties::ServerInfoMap::const_iterator
GetIteratorWithAlternativeServiceInfo(const url::SchemeHostPort & server,const net::NetworkAnonymizationKey & network_anonymization_key)980*6777b538SAndroid Build Coastguard Worker HttpServerProperties::GetIteratorWithAlternativeServiceInfo(
981*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
982*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) {
983*6777b538SAndroid Build Coastguard Worker   ServerInfoMap::const_iterator it = server_info_map_.Get(
984*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(server, network_anonymization_key));
985*6777b538SAndroid Build Coastguard Worker   if (it != server_info_map_.end() && it->second.alternative_services)
986*6777b538SAndroid Build Coastguard Worker     return it;
987*6777b538SAndroid Build Coastguard Worker 
988*6777b538SAndroid Build Coastguard Worker   auto canonical = GetCanonicalAltSvcHost(server, network_anonymization_key);
989*6777b538SAndroid Build Coastguard Worker   if (canonical == canonical_alt_svc_map_.end()) {
990*6777b538SAndroid Build Coastguard Worker     return server_info_map_.end();
991*6777b538SAndroid Build Coastguard Worker   }
992*6777b538SAndroid Build Coastguard Worker 
993*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort canonical_server = canonical->second;
994*6777b538SAndroid Build Coastguard Worker   it = server_info_map_.Get(
995*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(canonical_server, network_anonymization_key));
996*6777b538SAndroid Build Coastguard Worker   if (it == server_info_map_.end() || !it->second.alternative_services)
997*6777b538SAndroid Build Coastguard Worker     return server_info_map_.end();
998*6777b538SAndroid Build Coastguard Worker 
999*6777b538SAndroid Build Coastguard Worker   for (const AlternativeServiceInfo& alternative_service_info :
1000*6777b538SAndroid Build Coastguard Worker        it->second.alternative_services.value()) {
1001*6777b538SAndroid Build Coastguard Worker     AlternativeService alternative_service(
1002*6777b538SAndroid Build Coastguard Worker         alternative_service_info.alternative_service());
1003*6777b538SAndroid Build Coastguard Worker     if (alternative_service.host.empty()) {
1004*6777b538SAndroid Build Coastguard Worker       alternative_service.host = canonical_server.host();
1005*6777b538SAndroid Build Coastguard Worker     }
1006*6777b538SAndroid Build Coastguard Worker     if (!IsAlternativeServiceBroken(alternative_service,
1007*6777b538SAndroid Build Coastguard Worker                                     network_anonymization_key)) {
1008*6777b538SAndroid Build Coastguard Worker       return it;
1009*6777b538SAndroid Build Coastguard Worker     }
1010*6777b538SAndroid Build Coastguard Worker   }
1011*6777b538SAndroid Build Coastguard Worker 
1012*6777b538SAndroid Build Coastguard Worker   RemoveAltSvcCanonicalHost(canonical_server, network_anonymization_key);
1013*6777b538SAndroid Build Coastguard Worker   return server_info_map_.end();
1014*6777b538SAndroid Build Coastguard Worker }
1015*6777b538SAndroid Build Coastguard Worker 
1016*6777b538SAndroid Build Coastguard Worker HttpServerProperties::CanonicalMap::const_iterator
GetCanonicalAltSvcHost(const url::SchemeHostPort & server,const net::NetworkAnonymizationKey & network_anonymization_key) const1017*6777b538SAndroid Build Coastguard Worker HttpServerProperties::GetCanonicalAltSvcHost(
1018*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
1019*6777b538SAndroid Build Coastguard Worker     const net::NetworkAnonymizationKey& network_anonymization_key) const {
1020*6777b538SAndroid Build Coastguard Worker   const char* kCanonicalScheme = "https";
1021*6777b538SAndroid Build Coastguard Worker   if (server.scheme() != kCanonicalScheme)
1022*6777b538SAndroid Build Coastguard Worker     return canonical_alt_svc_map_.end();
1023*6777b538SAndroid Build Coastguard Worker 
1024*6777b538SAndroid Build Coastguard Worker   const std::string* canonical_suffix = GetCanonicalSuffix(server.host());
1025*6777b538SAndroid Build Coastguard Worker   if (canonical_suffix == nullptr)
1026*6777b538SAndroid Build Coastguard Worker     return canonical_alt_svc_map_.end();
1027*6777b538SAndroid Build Coastguard Worker 
1028*6777b538SAndroid Build Coastguard Worker   url::SchemeHostPort canonical_server(kCanonicalScheme, *canonical_suffix,
1029*6777b538SAndroid Build Coastguard Worker                                        server.port());
1030*6777b538SAndroid Build Coastguard Worker   return canonical_alt_svc_map_.find(
1031*6777b538SAndroid Build Coastguard Worker       CreateServerInfoKey(canonical_server, network_anonymization_key));
1032*6777b538SAndroid Build Coastguard Worker }
1033*6777b538SAndroid Build Coastguard Worker 
1034*6777b538SAndroid Build Coastguard Worker HttpServerProperties::QuicCanonicalMap::const_iterator
GetCanonicalServerInfoHost(const QuicServerInfoMapKey & key) const1035*6777b538SAndroid Build Coastguard Worker HttpServerProperties::GetCanonicalServerInfoHost(
1036*6777b538SAndroid Build Coastguard Worker     const QuicServerInfoMapKey& key) const {
1037*6777b538SAndroid Build Coastguard Worker   const std::string* canonical_suffix =
1038*6777b538SAndroid Build Coastguard Worker       GetCanonicalSuffix(key.server_id.host());
1039*6777b538SAndroid Build Coastguard Worker   if (canonical_suffix == nullptr)
1040*6777b538SAndroid Build Coastguard Worker     return canonical_server_info_map_.end();
1041*6777b538SAndroid Build Coastguard Worker 
1042*6777b538SAndroid Build Coastguard Worker   quic::QuicServerId canonical_server_id(*canonical_suffix,
1043*6777b538SAndroid Build Coastguard Worker                                          key.server_id.privacy_mode_enabled(),
1044*6777b538SAndroid Build Coastguard Worker                                          key.server_id.port());
1045*6777b538SAndroid Build Coastguard Worker   return canonical_server_info_map_.find(CreateQuicServerInfoKey(
1046*6777b538SAndroid Build Coastguard Worker       canonical_server_id, key.network_anonymization_key));
1047*6777b538SAndroid Build Coastguard Worker }
1048*6777b538SAndroid Build Coastguard Worker 
RemoveAltSvcCanonicalHost(const url::SchemeHostPort & server,const NetworkAnonymizationKey & network_anonymization_key)1049*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::RemoveAltSvcCanonicalHost(
1050*6777b538SAndroid Build Coastguard Worker     const url::SchemeHostPort& server,
1051*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key) {
1052*6777b538SAndroid Build Coastguard Worker   auto canonical = GetCanonicalAltSvcHost(server, network_anonymization_key);
1053*6777b538SAndroid Build Coastguard Worker   if (canonical == canonical_alt_svc_map_.end())
1054*6777b538SAndroid Build Coastguard Worker     return;
1055*6777b538SAndroid Build Coastguard Worker 
1056*6777b538SAndroid Build Coastguard Worker   canonical_alt_svc_map_.erase(canonical->first);
1057*6777b538SAndroid Build Coastguard Worker }
1058*6777b538SAndroid Build Coastguard Worker 
UpdateCanonicalServerInfoMap(const QuicServerInfoMapKey & key)1059*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::UpdateCanonicalServerInfoMap(
1060*6777b538SAndroid Build Coastguard Worker     const QuicServerInfoMapKey& key) {
1061*6777b538SAndroid Build Coastguard Worker   const std::string* suffix = GetCanonicalSuffix(key.server_id.host());
1062*6777b538SAndroid Build Coastguard Worker   if (!suffix)
1063*6777b538SAndroid Build Coastguard Worker     return;
1064*6777b538SAndroid Build Coastguard Worker   quic::QuicServerId canonical_server(
1065*6777b538SAndroid Build Coastguard Worker       *suffix, key.server_id.privacy_mode_enabled(), key.server_id.port());
1066*6777b538SAndroid Build Coastguard Worker 
1067*6777b538SAndroid Build Coastguard Worker   canonical_server_info_map_[CreateQuicServerInfoKey(
1068*6777b538SAndroid Build Coastguard Worker       canonical_server, key.network_anonymization_key)] = key.server_id;
1069*6777b538SAndroid Build Coastguard Worker }
1070*6777b538SAndroid Build Coastguard Worker 
GetCanonicalSuffix(const std::string & host) const1071*6777b538SAndroid Build Coastguard Worker const std::string* HttpServerProperties::GetCanonicalSuffix(
1072*6777b538SAndroid Build Coastguard Worker     const std::string& host) const {
1073*6777b538SAndroid Build Coastguard Worker   // If this host ends with a canonical suffix, then return the canonical
1074*6777b538SAndroid Build Coastguard Worker   // suffix.
1075*6777b538SAndroid Build Coastguard Worker   for (const std::string& canonical_suffix : canonical_suffixes_) {
1076*6777b538SAndroid Build Coastguard Worker     if (base::EndsWith(host, canonical_suffix,
1077*6777b538SAndroid Build Coastguard Worker                        base::CompareCase::INSENSITIVE_ASCII)) {
1078*6777b538SAndroid Build Coastguard Worker       return &canonical_suffix;
1079*6777b538SAndroid Build Coastguard Worker     }
1080*6777b538SAndroid Build Coastguard Worker   }
1081*6777b538SAndroid Build Coastguard Worker   return nullptr;
1082*6777b538SAndroid Build Coastguard Worker }
1083*6777b538SAndroid Build Coastguard Worker 
OnPrefsLoaded(std::unique_ptr<ServerInfoMap> server_info_map,const IPAddress & last_local_address_when_quic_worked,std::unique_ptr<QuicServerInfoMap> quic_server_info_map,std::unique_ptr<BrokenAlternativeServiceList> broken_alternative_service_list,std::unique_ptr<RecentlyBrokenAlternativeServices> recently_broken_alternative_services)1084*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::OnPrefsLoaded(
1085*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<ServerInfoMap> server_info_map,
1086*6777b538SAndroid Build Coastguard Worker     const IPAddress& last_local_address_when_quic_worked,
1087*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<QuicServerInfoMap> quic_server_info_map,
1088*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<BrokenAlternativeServiceList>
1089*6777b538SAndroid Build Coastguard Worker         broken_alternative_service_list,
1090*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<RecentlyBrokenAlternativeServices>
1091*6777b538SAndroid Build Coastguard Worker         recently_broken_alternative_services) {
1092*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
1093*6777b538SAndroid Build Coastguard Worker 
1094*6777b538SAndroid Build Coastguard Worker   DCHECK(!is_initialized_);
1095*6777b538SAndroid Build Coastguard Worker 
1096*6777b538SAndroid Build Coastguard Worker   // Either all of these are nullptr, or none of them are (except the broken alt
1097*6777b538SAndroid Build Coastguard Worker   // service fields).
1098*6777b538SAndroid Build Coastguard Worker   if (server_info_map) {
1099*6777b538SAndroid Build Coastguard Worker     OnServerInfoLoaded(std::move(server_info_map));
1100*6777b538SAndroid Build Coastguard Worker     OnLastLocalAddressWhenQuicWorkedLoaded(last_local_address_when_quic_worked);
1101*6777b538SAndroid Build Coastguard Worker     OnQuicServerInfoMapLoaded(std::move(quic_server_info_map));
1102*6777b538SAndroid Build Coastguard Worker     if (recently_broken_alternative_services) {
1103*6777b538SAndroid Build Coastguard Worker       DCHECK(broken_alternative_service_list);
1104*6777b538SAndroid Build Coastguard Worker       OnBrokenAndRecentlyBrokenAlternativeServicesLoaded(
1105*6777b538SAndroid Build Coastguard Worker           std::move(broken_alternative_service_list),
1106*6777b538SAndroid Build Coastguard Worker           std::move(recently_broken_alternative_services));
1107*6777b538SAndroid Build Coastguard Worker     }
1108*6777b538SAndroid Build Coastguard Worker   }
1109*6777b538SAndroid Build Coastguard Worker 
1110*6777b538SAndroid Build Coastguard Worker   is_initialized_ = true;
1111*6777b538SAndroid Build Coastguard Worker 
1112*6777b538SAndroid Build Coastguard Worker   if (queue_write_on_load_) {
1113*6777b538SAndroid Build Coastguard Worker     // Leaving this as true doesn't actually have any effect, but seems best to
1114*6777b538SAndroid Build Coastguard Worker     // be safe.
1115*6777b538SAndroid Build Coastguard Worker     queue_write_on_load_ = false;
1116*6777b538SAndroid Build Coastguard Worker     MaybeQueueWriteProperties();
1117*6777b538SAndroid Build Coastguard Worker   }
1118*6777b538SAndroid Build Coastguard Worker }
1119*6777b538SAndroid Build Coastguard Worker 
OnServerInfoLoaded(std::unique_ptr<ServerInfoMap> server_info_map)1120*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::OnServerInfoLoaded(
1121*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<ServerInfoMap> server_info_map) {
1122*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
1123*6777b538SAndroid Build Coastguard Worker 
1124*6777b538SAndroid Build Coastguard Worker   // Perform a simple sanity check on loaded data, when DCHECKs are enabled.
1125*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
1126*6777b538SAndroid Build Coastguard Worker   if (!use_network_anonymization_key_) {
1127*6777b538SAndroid Build Coastguard Worker     for (auto server_info = server_info_map->begin();
1128*6777b538SAndroid Build Coastguard Worker          server_info != server_info_map->end(); ++server_info) {
1129*6777b538SAndroid Build Coastguard Worker       DCHECK(server_info->first.network_anonymization_key.IsEmpty());
1130*6777b538SAndroid Build Coastguard Worker     }
1131*6777b538SAndroid Build Coastguard Worker   }
1132*6777b538SAndroid Build Coastguard Worker #endif  // DCHECK_IS_ON()
1133*6777b538SAndroid Build Coastguard Worker 
1134*6777b538SAndroid Build Coastguard Worker   // Swap in the entries from persisted data. This allows the MRU cache to be
1135*6777b538SAndroid Build Coastguard Worker   // sorted based on the order of the entries in the newer in-memory cache.
1136*6777b538SAndroid Build Coastguard Worker   server_info_map_.Swap(*server_info_map);
1137*6777b538SAndroid Build Coastguard Worker 
1138*6777b538SAndroid Build Coastguard Worker   // Add the entries from the memory cache.
1139*6777b538SAndroid Build Coastguard Worker   for (auto& [key, server_info] : base::Reversed(*server_info_map)) {
1140*6777b538SAndroid Build Coastguard Worker     // If there's no corresponding old entry, add the new entry directly.
1141*6777b538SAndroid Build Coastguard Worker     auto old_entry = server_info_map_.Get(key);
1142*6777b538SAndroid Build Coastguard Worker     if (old_entry == server_info_map_.end()) {
1143*6777b538SAndroid Build Coastguard Worker       server_info_map_.Put(key, std::move(server_info));
1144*6777b538SAndroid Build Coastguard Worker       continue;
1145*6777b538SAndroid Build Coastguard Worker     }
1146*6777b538SAndroid Build Coastguard Worker 
1147*6777b538SAndroid Build Coastguard Worker     // Otherwise, merge the old and new entries. Prefer values from older
1148*6777b538SAndroid Build Coastguard Worker     // entries.
1149*6777b538SAndroid Build Coastguard Worker     if (!old_entry->second.supports_spdy.has_value())
1150*6777b538SAndroid Build Coastguard Worker       old_entry->second.supports_spdy = server_info.supports_spdy;
1151*6777b538SAndroid Build Coastguard Worker     if (!old_entry->second.alternative_services.has_value())
1152*6777b538SAndroid Build Coastguard Worker       old_entry->second.alternative_services = server_info.alternative_services;
1153*6777b538SAndroid Build Coastguard Worker     if (!old_entry->second.server_network_stats.has_value())
1154*6777b538SAndroid Build Coastguard Worker       old_entry->second.server_network_stats = server_info.server_network_stats;
1155*6777b538SAndroid Build Coastguard Worker 
1156*6777b538SAndroid Build Coastguard Worker     // |requires_http11| isn't saved to prefs, so the loaded entry should not
1157*6777b538SAndroid Build Coastguard Worker     // have it set. Unconditionally copy it from the new entry.
1158*6777b538SAndroid Build Coastguard Worker     DCHECK(!old_entry->second.requires_http11.has_value());
1159*6777b538SAndroid Build Coastguard Worker     old_entry->second.requires_http11 = server_info.requires_http11;
1160*6777b538SAndroid Build Coastguard Worker   }
1161*6777b538SAndroid Build Coastguard Worker 
1162*6777b538SAndroid Build Coastguard Worker   // Attempt to find canonical servers. Canonical suffix only apply to HTTPS.
1163*6777b538SAndroid Build Coastguard Worker   const uint16_t kCanonicalPort = 443;
1164*6777b538SAndroid Build Coastguard Worker   const char* kCanonicalScheme = "https";
1165*6777b538SAndroid Build Coastguard Worker   for (const auto& it : server_info_map_) {
1166*6777b538SAndroid Build Coastguard Worker     if (!it.second.alternative_services ||
1167*6777b538SAndroid Build Coastguard Worker         it.first.server.scheme() != kCanonicalScheme) {
1168*6777b538SAndroid Build Coastguard Worker       continue;
1169*6777b538SAndroid Build Coastguard Worker     }
1170*6777b538SAndroid Build Coastguard Worker     const std::string* canonical_suffix =
1171*6777b538SAndroid Build Coastguard Worker         GetCanonicalSuffix(it.first.server.host());
1172*6777b538SAndroid Build Coastguard Worker     if (!canonical_suffix)
1173*6777b538SAndroid Build Coastguard Worker       continue;
1174*6777b538SAndroid Build Coastguard Worker     ServerInfoMapKey key = CreateServerInfoKey(
1175*6777b538SAndroid Build Coastguard Worker         url::SchemeHostPort(kCanonicalScheme, *canonical_suffix,
1176*6777b538SAndroid Build Coastguard Worker                             kCanonicalPort),
1177*6777b538SAndroid Build Coastguard Worker         it.first.network_anonymization_key);
1178*6777b538SAndroid Build Coastguard Worker     // If we already have a valid canonical server, we're done.
1179*6777b538SAndroid Build Coastguard Worker     if (base::Contains(canonical_alt_svc_map_, key)) {
1180*6777b538SAndroid Build Coastguard Worker       auto key_it = server_info_map_.Peek(key);
1181*6777b538SAndroid Build Coastguard Worker       if (key_it != server_info_map_.end() &&
1182*6777b538SAndroid Build Coastguard Worker           key_it->second.alternative_services.has_value()) {
1183*6777b538SAndroid Build Coastguard Worker         continue;
1184*6777b538SAndroid Build Coastguard Worker       }
1185*6777b538SAndroid Build Coastguard Worker     }
1186*6777b538SAndroid Build Coastguard Worker     canonical_alt_svc_map_[key] = it.first.server;
1187*6777b538SAndroid Build Coastguard Worker   }
1188*6777b538SAndroid Build Coastguard Worker }
1189*6777b538SAndroid Build Coastguard Worker 
OnLastLocalAddressWhenQuicWorkedLoaded(const IPAddress & last_local_address_when_quic_worked)1190*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::OnLastLocalAddressWhenQuicWorkedLoaded(
1191*6777b538SAndroid Build Coastguard Worker     const IPAddress& last_local_address_when_quic_worked) {
1192*6777b538SAndroid Build Coastguard Worker   last_local_address_when_quic_worked_ = last_local_address_when_quic_worked;
1193*6777b538SAndroid Build Coastguard Worker }
1194*6777b538SAndroid Build Coastguard Worker 
OnQuicServerInfoMapLoaded(std::unique_ptr<QuicServerInfoMap> quic_server_info_map)1195*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::OnQuicServerInfoMapLoaded(
1196*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<QuicServerInfoMap> quic_server_info_map) {
1197*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(quic_server_info_map->max_size(), quic_server_info_map_.max_size());
1198*6777b538SAndroid Build Coastguard Worker 
1199*6777b538SAndroid Build Coastguard Worker   // Add the entries from persisted data.
1200*6777b538SAndroid Build Coastguard Worker   quic_server_info_map_.Swap(*quic_server_info_map);
1201*6777b538SAndroid Build Coastguard Worker 
1202*6777b538SAndroid Build Coastguard Worker   // Add the entries from the memory cache.
1203*6777b538SAndroid Build Coastguard Worker   for (const auto& [key, server_info] : base::Reversed(*quic_server_info_map)) {
1204*6777b538SAndroid Build Coastguard Worker     if (quic_server_info_map_.Get(key) == quic_server_info_map_.end()) {
1205*6777b538SAndroid Build Coastguard Worker       quic_server_info_map_.Put(key, server_info);
1206*6777b538SAndroid Build Coastguard Worker     }
1207*6777b538SAndroid Build Coastguard Worker   }
1208*6777b538SAndroid Build Coastguard Worker 
1209*6777b538SAndroid Build Coastguard Worker   // Repopulate |canonical_server_info_map_| to stay in sync with
1210*6777b538SAndroid Build Coastguard Worker   // |quic_server_info_map_|.
1211*6777b538SAndroid Build Coastguard Worker   canonical_server_info_map_.clear();
1212*6777b538SAndroid Build Coastguard Worker   for (const auto& [key, server_info] : base::Reversed(quic_server_info_map_)) {
1213*6777b538SAndroid Build Coastguard Worker     UpdateCanonicalServerInfoMap(key);
1214*6777b538SAndroid Build Coastguard Worker   }
1215*6777b538SAndroid Build Coastguard Worker }
1216*6777b538SAndroid Build Coastguard Worker 
OnBrokenAndRecentlyBrokenAlternativeServicesLoaded(std::unique_ptr<BrokenAlternativeServiceList> broken_alternative_service_list,std::unique_ptr<RecentlyBrokenAlternativeServices> recently_broken_alternative_services)1217*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::OnBrokenAndRecentlyBrokenAlternativeServicesLoaded(
1218*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<BrokenAlternativeServiceList>
1219*6777b538SAndroid Build Coastguard Worker         broken_alternative_service_list,
1220*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<RecentlyBrokenAlternativeServices>
1221*6777b538SAndroid Build Coastguard Worker         recently_broken_alternative_services) {
1222*6777b538SAndroid Build Coastguard Worker   broken_alternative_services_.SetBrokenAndRecentlyBrokenAlternativeServices(
1223*6777b538SAndroid Build Coastguard Worker       std::move(broken_alternative_service_list),
1224*6777b538SAndroid Build Coastguard Worker       std::move(recently_broken_alternative_services));
1225*6777b538SAndroid Build Coastguard Worker }
1226*6777b538SAndroid Build Coastguard Worker 
MaybeQueueWriteProperties()1227*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::MaybeQueueWriteProperties() {
1228*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
1229*6777b538SAndroid Build Coastguard Worker   if (prefs_update_timer_.IsRunning() || !properties_manager_)
1230*6777b538SAndroid Build Coastguard Worker     return;
1231*6777b538SAndroid Build Coastguard Worker 
1232*6777b538SAndroid Build Coastguard Worker   if (!is_initialized_) {
1233*6777b538SAndroid Build Coastguard Worker     queue_write_on_load_ = true;
1234*6777b538SAndroid Build Coastguard Worker     return;
1235*6777b538SAndroid Build Coastguard Worker   }
1236*6777b538SAndroid Build Coastguard Worker 
1237*6777b538SAndroid Build Coastguard Worker   prefs_update_timer_.Start(
1238*6777b538SAndroid Build Coastguard Worker       FROM_HERE, kUpdatePrefsDelay,
1239*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&HttpServerProperties::WriteProperties,
1240*6777b538SAndroid Build Coastguard Worker                      base::Unretained(this), base::OnceClosure()));
1241*6777b538SAndroid Build Coastguard Worker }
1242*6777b538SAndroid Build Coastguard Worker 
FlushWritePropertiesForTesting(base::OnceClosure callback)1243*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::FlushWritePropertiesForTesting(
1244*6777b538SAndroid Build Coastguard Worker     base::OnceClosure callback) {
1245*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
1246*6777b538SAndroid Build Coastguard Worker   if (!properties_manager_) {
1247*6777b538SAndroid Build Coastguard Worker     return;
1248*6777b538SAndroid Build Coastguard Worker   }
1249*6777b538SAndroid Build Coastguard Worker 
1250*6777b538SAndroid Build Coastguard Worker   // initialising the |properties_manager_| is not a concern here. So skip
1251*6777b538SAndroid Build Coastguard Worker   // it and set |is_initalized_| to true.
1252*6777b538SAndroid Build Coastguard Worker   is_initialized_ = true;
1253*6777b538SAndroid Build Coastguard Worker   // Stop the timer if it's running, since this will write to the properties
1254*6777b538SAndroid Build Coastguard Worker   // file immediately.
1255*6777b538SAndroid Build Coastguard Worker   prefs_update_timer_.Stop();
1256*6777b538SAndroid Build Coastguard Worker   WriteProperties(std::move(callback));
1257*6777b538SAndroid Build Coastguard Worker }
1258*6777b538SAndroid Build Coastguard Worker 
WriteProperties(base::OnceClosure callback) const1259*6777b538SAndroid Build Coastguard Worker void HttpServerProperties::WriteProperties(base::OnceClosure callback) const {
1260*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
1261*6777b538SAndroid Build Coastguard Worker   DCHECK(properties_manager_);
1262*6777b538SAndroid Build Coastguard Worker 
1263*6777b538SAndroid Build Coastguard Worker   // |this| shouldn't be waiting to load properties cached to disk when this
1264*6777b538SAndroid Build Coastguard Worker   // method is invoked, since this method will overwrite any cached properties.
1265*6777b538SAndroid Build Coastguard Worker   DCHECK(is_initialized_);
1266*6777b538SAndroid Build Coastguard Worker 
1267*6777b538SAndroid Build Coastguard Worker   // There shouldn't be a queued update when this is run, since this method
1268*6777b538SAndroid Build Coastguard Worker   // removes the need for any update to be queued.
1269*6777b538SAndroid Build Coastguard Worker   DCHECK(!prefs_update_timer_.IsRunning());
1270*6777b538SAndroid Build Coastguard Worker 
1271*6777b538SAndroid Build Coastguard Worker   properties_manager_->WriteToPrefs(
1272*6777b538SAndroid Build Coastguard Worker       server_info_map_,
1273*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(&HttpServerProperties::GetCanonicalSuffix,
1274*6777b538SAndroid Build Coastguard Worker                           base::Unretained(this)),
1275*6777b538SAndroid Build Coastguard Worker       last_local_address_when_quic_worked_, quic_server_info_map_,
1276*6777b538SAndroid Build Coastguard Worker       broken_alternative_services_.broken_alternative_service_list(),
1277*6777b538SAndroid Build Coastguard Worker       broken_alternative_services_.recently_broken_alternative_services(),
1278*6777b538SAndroid Build Coastguard Worker       std::move(callback));
1279*6777b538SAndroid Build Coastguard Worker }
1280*6777b538SAndroid Build Coastguard Worker 
1281*6777b538SAndroid Build Coastguard Worker }  // namespace net
1282