• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_H_
6 #define NET_HTTP_HTTP_SERVER_PROPERTIES_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <map>
12 #include <memory>
13 #include <optional>
14 #include <set>
15 #include <string>
16 #include <tuple>
17 #include <vector>
18 
19 #include "base/containers/lru_cache.h"
20 #include "base/functional/callback.h"
21 #include "base/memory/raw_ptr.h"
22 #include "base/memory/weak_ptr.h"
23 #include "base/threading/thread_checker.h"
24 #include "base/time/time.h"
25 #include "base/timer/timer.h"
26 #include "base/values.h"
27 #include "net/base/host_port_pair.h"
28 #include "net/base/ip_address.h"
29 #include "net/base/net_export.h"
30 #include "net/base/network_anonymization_key.h"
31 #include "net/base/privacy_mode.h"
32 #include "net/http/alternative_service.h"
33 #include "net/http/broken_alternative_services.h"
34 #include "net/third_party/quiche/src/quiche/http2/core/spdy_framer.h"  // TODO(willchan): Reconsider this.
35 #include "net/third_party/quiche/src/quiche/http2/core/spdy_protocol.h"
36 #include "net/third_party/quiche/src/quiche/quic/core/quic_bandwidth.h"
37 #include "net/third_party/quiche/src/quiche/quic/core/quic_server_id.h"
38 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
39 #include "url/scheme_host_port.h"
40 
41 namespace base {
42 class Clock;
43 class TickClock;
44 }
45 
46 namespace net {
47 
48 class HttpServerPropertiesManager;
49 class IPAddress;
50 class NetLog;
51 struct SSLConfig;
52 
53 struct NET_EXPORT SupportsQuic {
SupportsQuicSupportsQuic54   SupportsQuic() : used_quic(false) {}
SupportsQuicSupportsQuic55   SupportsQuic(bool used_quic, const std::string& address)
56       : used_quic(used_quic), address(address) {}
57 
EqualsSupportsQuic58   bool Equals(const SupportsQuic& other) const {
59     return used_quic == other.used_quic && address == other.address;
60   }
61 
62   bool used_quic;
63   std::string address;
64 };
65 
66 struct NET_EXPORT ServerNetworkStats {
ServerNetworkStatsServerNetworkStats67   ServerNetworkStats() : bandwidth_estimate(quic::QuicBandwidth::Zero()) {}
68 
69   bool operator==(const ServerNetworkStats& other) const {
70     return srtt == other.srtt && bandwidth_estimate == other.bandwidth_estimate;
71   }
72 
73   bool operator!=(const ServerNetworkStats& other) const {
74     return !this->operator==(other);
75   }
76 
77   base::TimeDelta srtt;
78   quic::QuicBandwidth bandwidth_estimate;
79 };
80 
81 typedef std::vector<AlternativeService> AlternativeServiceVector;
82 
83 // Store at most 200 MRU RecentlyBrokenAlternativeServices in memory and disk.
84 // This ideally would be with the other constants in HttpServerProperties, but
85 // has to go here instead of prevent a circular dependency.
86 const int kMaxRecentlyBrokenAlternativeServiceEntries = 200;
87 
88 // Store at most 5 MRU QUIC servers by default. This is mainly used by cronet.
89 const int kDefaultMaxQuicServerEntries = 5;
90 
91 // The interface for setting/retrieving the HTTP server properties.
92 // Currently, this class manages servers':
93 // * HTTP/2 support;
94 // * Alternative Service support;
95 // * QUIC data (like ServerNetworkStats and QuicServerInfo).
96 //
97 // Optionally retrieves and saves properties from/to disk. This class is not
98 // threadsafe.
99 class NET_EXPORT HttpServerProperties
100     : public BrokenAlternativeServices::Delegate {
101  public:
102   // Store at most 500 MRU ServerInfos in memory and disk.
103   static const int kMaxServerInfoEntries = 500;
104 
105   // Provides an interface to interact with persistent preferences storage
106   // implemented by the embedder. The prefs are assumed not to have been loaded
107   // before HttpServerPropertiesManager construction.
108   class NET_EXPORT PrefDelegate {
109    public:
110     virtual ~PrefDelegate();
111 
112     // Returns the branch of the preferences system for the server properties.
113     // Returns nullptr if the pref system has no data for the server properties.
114     virtual const base::Value::Dict& GetServerProperties() const = 0;
115 
116     // Sets the server properties to the given value. If |callback| is
117     // non-empty, flushes data to persistent storage and invokes |callback|
118     // asynchronously when complete.
119     virtual void SetServerProperties(base::Value::Dict dict,
120                                      base::OnceClosure callback) = 0;
121 
122     // Starts listening for prefs to be loaded. If prefs are already loaded,
123     // |pref_loaded_callback| will be invoked asynchronously. Callback will be
124     // invoked even if prefs fail to load. Will only be called once by the
125     // HttpServerPropertiesManager.
126     virtual void WaitForPrefLoad(base::OnceClosure pref_loaded_callback) = 0;
127   };
128 
129   // Contains metadata about a particular server. Note that all methods that
130   // take a "SchemeHostPort" expect schemes of ws and wss to be mapped to http
131   // and https, respectively. See GetNormalizedSchemeHostPort().
132   struct NET_EXPORT ServerInfo {
133     ServerInfo();
134     ServerInfo(const ServerInfo& server_info);
135     ServerInfo(ServerInfo&& server_info);
136     ~ServerInfo();
137 
138     // Returns true if no fields are populated.
139     bool empty() const;
140 
141     // Used in tests.
142     bool operator==(const ServerInfo& other) const;
143 
144     // IMPORTANT:  When adding a field here, be sure to update
145     // HttpServerProperties::OnServerInfoLoaded() as well as
146     // HttpServerPropertiesManager to correctly load/save the from/to the pref
147     // store.
148 
149     // Whether or not a server is known to support H2/SPDY. False indicates
150     // known lack of support, true indicates known support, and not set
151     // indicates unknown. The difference between false and not set only matters
152     // when loading from disk, when an initialized false value will take
153     // priority over a not set value.
154     std::optional<bool> supports_spdy;
155 
156     // True if the server has previously indicated it required HTTP/1.1. Unlike
157     // other fields, not persisted to disk.
158     std::optional<bool> requires_http11;
159 
160     std::optional<AlternativeServiceInfoVector> alternative_services;
161     std::optional<ServerNetworkStats> server_network_stats;
162   };
163 
164   struct NET_EXPORT ServerInfoMapKey {
165     // If |use_network_anonymization_key| is false, an empty
166     // NetworkAnonymizationKey is used instead of |network_anonymization_key|.
167     // Note that |server| can be passed in via std::move(), since most callsites
168     // can pass a recently created SchemeHostPort.
169     ServerInfoMapKey(url::SchemeHostPort server,
170                      const NetworkAnonymizationKey& network_anonymization_key,
171                      bool use_network_anonymization_key);
172     ~ServerInfoMapKey();
173 
174     bool operator<(const ServerInfoMapKey& other) const;
175 
176     // IMPORTANT: The constructor normalizes the scheme so that "ws" is replaced
177     // by "http" and "wss" by "https", so this should never be compared directly
178     // with values passed into to HttpServerProperties methods.
179     url::SchemeHostPort server;
180 
181     NetworkAnonymizationKey network_anonymization_key;
182   };
183 
184   class NET_EXPORT ServerInfoMap
185       : public base::LRUCache<ServerInfoMapKey, ServerInfo> {
186    public:
187     ServerInfoMap();
188 
189     ServerInfoMap(const ServerInfoMap&) = delete;
190     ServerInfoMap& operator=(const ServerInfoMap&) = delete;
191 
192     // If there's an entry corresponding to |key|, brings that entry to the
193     // front and returns an iterator to it. Otherwise, inserts an empty
194     // ServerInfo using |key|, and returns an iterator to it.
195     iterator GetOrPut(const ServerInfoMapKey& key);
196 
197     // Erases the ServerInfo identified by |server_info_it| if no fields have
198     // data. The iterator must point to an entry in the map. Regardless of
199     // whether the entry is removed or not, returns iterator for the next entry.
200     iterator EraseIfEmpty(iterator server_info_it);
201   };
202 
203   struct NET_EXPORT QuicServerInfoMapKey {
204     // If |use_network_anonymization_key| is false, an empty
205     // NetworkAnonymizationKey is used instead of |network_anonymization_key|.
206     QuicServerInfoMapKey(
207         const quic::QuicServerId& server_id,
208         PrivacyMode privacy_mode,
209         const NetworkAnonymizationKey& network_anonymization_key,
210         bool use_network_anonymization_key);
211     ~QuicServerInfoMapKey();
212 
213     bool operator<(const QuicServerInfoMapKey& other) const;
214 
215     // Used in tests.
216     bool operator==(const QuicServerInfoMapKey& other) const;
217 
218     quic::QuicServerId server_id;
219     PrivacyMode privacy_mode = PRIVACY_MODE_DISABLED;
220     NetworkAnonymizationKey network_anonymization_key;
221   };
222 
223   // Max number of quic servers to store is not hardcoded and can be set.
224   // Because of this, QuicServerInfoMap will not be a subclass of LRUCache.
225   // Separate from ServerInfoMap because the key includes privacy mode (Since
226   // this is analogous to the SSL session cache, which has separate caches for
227   // privacy mode), and each entry can be quite large, so it has its own size
228   // limit, which is much smaller than the ServerInfoMap's limit.
229   typedef base::LRUCache<QuicServerInfoMapKey, std::string> QuicServerInfoMap;
230 
231   // If a |pref_delegate| is specified, it will be used to read/write the
232   // properties to a pref file. Writes are rate limited to improve performance.
233   //
234   // |tick_clock| is used for setting expiration times and scheduling the
235   // expiration of broken alternative services. If null, default clock will be
236   // used.
237   //
238   // |clock| is used for converting base::TimeTicks to base::Time for
239   // wherever base::Time is preferable.
240   explicit HttpServerProperties(
241       std::unique_ptr<PrefDelegate> pref_delegate = nullptr,
242       NetLog* net_log = nullptr,
243       const base::TickClock* tick_clock = nullptr,
244       base::Clock* clock = nullptr);
245 
246   HttpServerProperties(const HttpServerProperties&) = delete;
247   HttpServerProperties& operator=(const HttpServerProperties&) = delete;
248 
249   ~HttpServerProperties() override;
250 
251   // Deletes all data. If |callback| is non-null, flushes data to disk
252   // and invokes the callback asynchronously once changes have been written to
253   // disk.
254   void Clear(base::OnceClosure callback);
255 
256   // Returns true if |server|, in the context of |network_anonymization_key|,
257   // has previously supported a network protocol which honors request
258   // prioritization.
259   //
260   // Note that this also implies that the server supports request
261   // multiplexing, since priorities imply a relationship between
262   // multiple requests.
263   bool SupportsRequestPriority(
264       const url::SchemeHostPort& server,
265       const NetworkAnonymizationKey& network_anonymization_key);
266 
267   // Returns the value set by SetSupportsSpdy(). If not set, returns false.
268   bool GetSupportsSpdy(
269       const url::SchemeHostPort& server,
270       const NetworkAnonymizationKey& network_anonymization_key);
271 
272   // Records whether |server| supports H2 or not. Information is restricted to
273   // the context of |network_anonymization_key|, to prevent cross-site
274   // information leakage.
275   void SetSupportsSpdy(const url::SchemeHostPort& server,
276                        const NetworkAnonymizationKey& network_anonymization_key,
277                        bool supports_spdy);
278 
279   // Returns true if |server| has required HTTP/1.1 via HTTP/2 error code, in
280   // the context of |network_anonymization_key|.
281   //
282   // Any relevant HostMappingRules must already have been applied to `server`.
283   bool RequiresHTTP11(const url::SchemeHostPort& server,
284                       const NetworkAnonymizationKey& network_anonymization_key);
285 
286   // Require HTTP/1.1 on subsequent connections, in the context of
287   // |network_anonymization_key|.  Not persisted.
288   //
289   // Any relevant HostMappingRules must already have been applied to `server`.
290   void SetHTTP11Required(
291       const url::SchemeHostPort& server,
292       const NetworkAnonymizationKey& network_anonymization_key);
293 
294   // Modify SSLConfig to force HTTP/1.1 if necessary.
295   //
296   // Any relevant HostMappingRules must already have been applied to `server`.
297   void MaybeForceHTTP11(
298       const url::SchemeHostPort& server,
299       const NetworkAnonymizationKey& network_anonymization_key,
300       SSLConfig* ssl_config);
301 
302   // Return all alternative services for |origin|, learned in the context of
303   // |network_anonymization_key|, including broken ones. Returned alternative
304   // services never have empty hostnames.
305   AlternativeServiceInfoVector GetAlternativeServiceInfos(
306       const url::SchemeHostPort& origin,
307       const NetworkAnonymizationKey& network_anonymization_key);
308 
309   // Set a single HTTP/2 alternative service for |origin|.  Previous
310   // alternative services for |origin| are discarded.
311   // |alternative_service.host| may be empty.
312   void SetHttp2AlternativeService(
313       const url::SchemeHostPort& origin,
314       const NetworkAnonymizationKey& network_anonymization_key,
315       const AlternativeService& alternative_service,
316       base::Time expiration);
317 
318   // Set a single QUIC alternative service for |origin|.  Previous alternative
319   // services for |origin| are discarded.
320   // |alternative_service.host| may be empty.
321   void SetQuicAlternativeService(
322       const url::SchemeHostPort& origin,
323       const NetworkAnonymizationKey& network_anonymization_key,
324       const AlternativeService& alternative_service,
325       base::Time expiration,
326       const quic::ParsedQuicVersionVector& advertised_versions);
327 
328   // Set alternative services for |origin|, learned in the context of
329   // |network_anonymization_key|.  Previous alternative services for |origin|
330   // are discarded. Hostnames in |alternative_service_info_vector| may be empty.
331   // |alternative_service_info_vector| may be empty.
332   void SetAlternativeServices(
333       const url::SchemeHostPort& origin,
334       const NetworkAnonymizationKey& network_anonymization_key,
335       const AlternativeServiceInfoVector& alternative_service_info_vector);
336 
337   // Marks |alternative_service| as broken in the context of
338   // |network_anonymization_key|. |alternative_service.host| must not be empty.
339   void MarkAlternativeServiceBroken(
340       const AlternativeService& alternative_service,
341       const NetworkAnonymizationKey& network_anonymization_key);
342 
343   // Marks |alternative_service| as broken in the context of
344   // |network_anonymization_key| until the default network changes.
345   // |alternative_service.host| must not be empty.
346   void MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
347       const AlternativeService& alternative_service,
348       const NetworkAnonymizationKey& network_anonymization_key);
349 
350   // Marks |alternative_service| as recently broken in the context of
351   // |network_anonymization_key|. |alternative_service.host| must not be empty.
352   void MarkAlternativeServiceRecentlyBroken(
353       const AlternativeService& alternative_service,
354       const NetworkAnonymizationKey& network_anonymization_key);
355 
356   // Returns true iff |alternative_service| is currently broken in the context
357   // of |network_anonymization_key|. |alternative_service.host| must not be
358   // empty.
359   bool IsAlternativeServiceBroken(
360       const AlternativeService& alternative_service,
361       const NetworkAnonymizationKey& network_anonymization_key) const;
362 
363   // Returns true iff |alternative_service| was recently broken in the context
364   // of |network_anonymization_key|. |alternative_service.host| must not be
365   // empty.
366   bool WasAlternativeServiceRecentlyBroken(
367       const AlternativeService& alternative_service,
368       const NetworkAnonymizationKey& network_anonymization_key);
369 
370   // Confirms that |alternative_service| is working in the context of
371   // |network_anonymization_key|. |alternative_service.host| must not be empty.
372   void ConfirmAlternativeService(
373       const AlternativeService& alternative_service,
374       const NetworkAnonymizationKey& network_anonymization_key);
375 
376   // Called when the default network changes.
377   // Clears all the alternative services that were marked broken until the
378   // default network changed.
379   void OnDefaultNetworkChanged();
380 
381   // Returns all alternative service mappings as human readable strings.
382   // Empty alternative service hostnames will be printed as such.
383   base::Value GetAlternativeServiceInfoAsValue() const;
384 
385   // Tracks the last local address when QUIC was known to work. The address
386   // cannot be set to an empty address - use
387   // ClearLastLocalAddressWhenQuicWorked() if it needs to be cleared.
388   bool WasLastLocalAddressWhenQuicWorked(const IPAddress& local_address) const;
389   bool HasLastLocalAddressWhenQuicWorked() const;
390   void SetLastLocalAddressWhenQuicWorked(
391       IPAddress last_local_address_when_quic_worked);
392   void ClearLastLocalAddressWhenQuicWorked();
393 
394   // Sets |stats| for |server|.
395   void SetServerNetworkStats(
396       const url::SchemeHostPort& server,
397       const NetworkAnonymizationKey& network_anonymization_key,
398       ServerNetworkStats stats);
399 
400   // Clears any stats for |server|.
401   void ClearServerNetworkStats(
402       const url::SchemeHostPort& server,
403       const NetworkAnonymizationKey& network_anonymization_key);
404 
405   // Returns any stats for |server| or nullptr if there are none.
406   const ServerNetworkStats* GetServerNetworkStats(
407       const url::SchemeHostPort& server,
408       const NetworkAnonymizationKey& network_anonymization_key);
409 
410   // Save QuicServerInfo (in std::string form) for the given |server_id|, in the
411   // context of |network_anonymization_key|.
412   void SetQuicServerInfo(
413       const quic::QuicServerId& server_id,
414       PrivacyMode privacy_mode,
415       const NetworkAnonymizationKey& network_anonymization_key,
416       const std::string& server_info);
417 
418   // Get QuicServerInfo (in std::string form) for the given |server_id|, in the
419   // context of |network_anonymization_key|.
420   const std::string* GetQuicServerInfo(
421       const quic::QuicServerId& server_id,
422       PrivacyMode privacy_mode,
423       const NetworkAnonymizationKey& network_anonymization_key);
424 
425   // Returns all persistent QuicServerInfo objects.
426   const QuicServerInfoMap& quic_server_info_map() const;
427 
428   // Returns the number of server configs (QuicServerInfo objects) persisted.
429   size_t max_server_configs_stored_in_properties() const;
430 
431   // Sets the number of server configs (QuicServerInfo objects) to be persisted.
432   void SetMaxServerConfigsStoredInProperties(
433       size_t max_server_configs_stored_in_properties);
434 
435   // If values are present, sets initial_delay and
436   // exponential_backoff_on_initial_delay which are used to calculate delay of
437   // broken alternative services.
438   void SetBrokenAlternativeServicesDelayParams(
439       std::optional<base::TimeDelta> initial_delay,
440       std::optional<bool> exponential_backoff_on_initial_delay);
441 
442   // Returns whether HttpServerProperties is initialized.
443   bool IsInitialized() const;
444 
445   // BrokenAlternativeServices::Delegate method.
446   void OnExpireBrokenAlternativeService(
447       const AlternativeService& expired_alternative_service,
448       const NetworkAnonymizationKey& network_anonymization_key) override;
449 
450   static base::TimeDelta GetUpdatePrefsDelayForTesting();
451 
452   // Test-only routines that call the methods used to load the specified
453   // field(s) from a prefs file. Unlike OnPrefsLoaded(), these may be invoked
454   // multiple times.
OnServerInfoLoadedForTesting(std::unique_ptr<ServerInfoMap> server_info_map)455   void OnServerInfoLoadedForTesting(
456       std::unique_ptr<ServerInfoMap> server_info_map) {
457     OnServerInfoLoaded(std::move(server_info_map));
458   }
OnLastLocalAddressWhenQuicWorkedForTesting(const IPAddress & last_local_address_when_quic_worked)459   void OnLastLocalAddressWhenQuicWorkedForTesting(
460       const IPAddress& last_local_address_when_quic_worked) {
461     OnLastLocalAddressWhenQuicWorkedLoaded(last_local_address_when_quic_worked);
462   }
OnQuicServerInfoMapLoadedForTesting(std::unique_ptr<QuicServerInfoMap> quic_server_info_map)463   void OnQuicServerInfoMapLoadedForTesting(
464       std::unique_ptr<QuicServerInfoMap> quic_server_info_map) {
465     OnQuicServerInfoMapLoaded(std::move(quic_server_info_map));
466   }
OnBrokenAndRecentlyBrokenAlternativeServicesLoadedForTesting(std::unique_ptr<BrokenAlternativeServiceList> broken_alternative_service_list,std::unique_ptr<RecentlyBrokenAlternativeServices> recently_broken_alternative_services)467   void OnBrokenAndRecentlyBrokenAlternativeServicesLoadedForTesting(
468       std::unique_ptr<BrokenAlternativeServiceList>
469           broken_alternative_service_list,
470       std::unique_ptr<RecentlyBrokenAlternativeServices>
471           recently_broken_alternative_services) {
472     OnBrokenAndRecentlyBrokenAlternativeServicesLoaded(
473         std::move(broken_alternative_service_list),
474         std::move(recently_broken_alternative_services));
475   }
476 
GetCanonicalSuffixForTesting(const std::string & host)477   const std::string* GetCanonicalSuffixForTesting(
478       const std::string& host) const {
479     return GetCanonicalSuffix(host);
480   }
481 
server_info_map_for_testing()482   const ServerInfoMap& server_info_map_for_testing() const {
483     return server_info_map_;
484   }
485 
486   // This will invalidate the start-up properties if called before
487   // initialization.
488   void FlushWritePropertiesForTesting(base::OnceClosure callback);
489 
broken_alternative_services_for_testing()490   const BrokenAlternativeServices& broken_alternative_services_for_testing()
491       const {
492     return broken_alternative_services_;
493   }
494 
quic_server_info_map_for_testing()495   const QuicServerInfoMap& quic_server_info_map_for_testing() const {
496     return quic_server_info_map_;
497   }
498 
499   // TODO(mmenke): Look into removing this.
properties_manager_for_testing()500   HttpServerPropertiesManager* properties_manager_for_testing() {
501     return properties_manager_.get();
502   }
503 
504  private:
505   // TODO (wangyix): modify HttpServerProperties unit tests so this
506   // friendness is no longer required.
507   friend class HttpServerPropertiesPeer;
508 
509   typedef base::flat_map<ServerInfoMapKey, url::SchemeHostPort> CanonicalMap;
510   typedef base::flat_map<QuicServerInfoMapKey, quic::QuicServerId>
511       QuicCanonicalMap;
512   typedef std::vector<std::string> CanonicalSuffixList;
513 
514   // Internal implementations of public methods. SchemeHostPort argument must be
515   // normalized before calling (ws/wss replaced with http/https). Use wrapped
516   // functions instead of putting the normalization in the public functions to
517   // reduce chance of regression - normalization in ServerInfoMapKey's
518   // constructor would leave |server.scheme| as wrong if not access through the
519   // key, and explicit normalization to create |normalized_server| means the one
520   // with the incorrect scheme would still be available.
521   bool GetSupportsSpdyInternal(
522       url::SchemeHostPort server,
523       const NetworkAnonymizationKey& network_anonymization_key);
524   void SetSupportsSpdyInternal(
525       url::SchemeHostPort server,
526       const NetworkAnonymizationKey& network_anonymization_key,
527       bool supports_spdy);
528   bool RequiresHTTP11Internal(
529       url::SchemeHostPort server,
530       const NetworkAnonymizationKey& network_anonymization_key);
531   void SetHTTP11RequiredInternal(
532       url::SchemeHostPort server,
533       const NetworkAnonymizationKey& network_anonymization_key);
534   void MaybeForceHTTP11Internal(
535       url::SchemeHostPort server,
536       const NetworkAnonymizationKey& network_anonymization_key,
537       SSLConfig* ssl_config);
538   AlternativeServiceInfoVector GetAlternativeServiceInfosInternal(
539       const url::SchemeHostPort& origin,
540       const NetworkAnonymizationKey& network_anonymization_key);
541   void SetAlternativeServicesInternal(
542       const url::SchemeHostPort& origin,
543       const NetworkAnonymizationKey& network_anonymization_key,
544       const AlternativeServiceInfoVector& alternative_service_info_vector);
545   void SetServerNetworkStatsInternal(
546       url::SchemeHostPort server,
547       const NetworkAnonymizationKey& network_anonymization_key,
548       ServerNetworkStats stats);
549   void ClearServerNetworkStatsInternal(
550       url::SchemeHostPort server,
551       const NetworkAnonymizationKey& network_anonymization_key);
552   const ServerNetworkStats* GetServerNetworkStatsInternal(
553       url::SchemeHostPort server,
554       const NetworkAnonymizationKey& network_anonymization_key);
555 
556   // Helper functions to use the passed in parameters and
557   // |use_network_anonymization_key_| to create a [Quic]ServerInfoMapKey.
558   ServerInfoMapKey CreateServerInfoKey(
559       const url::SchemeHostPort& server,
560       const NetworkAnonymizationKey& network_anonymization_key) const;
561   QuicServerInfoMapKey CreateQuicServerInfoKey(
562       const quic::QuicServerId& server_id,
563       PrivacyMode privacy_mode,
564       const NetworkAnonymizationKey& network_anonymization_key) const;
565 
566   // Return the iterator for |server| in the context of
567   // |network_anonymization_key|, or for its canonical host, or end. Skips over
568   // ServerInfos without |alternative_service_info| populated.
569   ServerInfoMap::const_iterator GetIteratorWithAlternativeServiceInfo(
570       const url::SchemeHostPort& server,
571       const NetworkAnonymizationKey& network_anonymization_key);
572 
573   // Return the canonical host for |server|  in the context of
574   // |network_anonymization_key|, or end if none exists.
575   CanonicalMap::const_iterator GetCanonicalAltSvcHost(
576       const url::SchemeHostPort& server,
577       const NetworkAnonymizationKey& network_anonymization_key) const;
578 
579   // Return the canonical host with the same canonical suffix as |server|.
580   // The returned canonical host can be used to search for server info in
581   // |quic_server_info_map_|. Return 'end' the host doesn't exist.
582   QuicCanonicalMap::const_iterator GetCanonicalServerInfoHost(
583       const QuicServerInfoMapKey& key) const;
584 
585   // Remove the canonical alt-svc host for |server| with
586   // |network_anonymization_key|.
587   void RemoveAltSvcCanonicalHost(
588       const url::SchemeHostPort& server,
589       const NetworkAnonymizationKey& network_anonymization_key);
590 
591   // Update |canonical_server_info_map_| with the new canonical host.
592   // The |key| should have the corresponding server info associated with it
593   // in |quic_server_info_map_|. If |canonical_server_info_map_| doesn't
594   // have an entry associated with |key|, the method will add one.
595   void UpdateCanonicalServerInfoMap(const QuicServerInfoMapKey& key);
596 
597   // Returns the canonical host suffix for |host|, or nullptr if none
598   // exists.
599   const std::string* GetCanonicalSuffix(const std::string& host) const;
600 
601   void OnPrefsLoaded(std::unique_ptr<ServerInfoMap> server_info_map,
602                      const IPAddress& last_local_address_when_quic_worked,
603                      std::unique_ptr<QuicServerInfoMap> quic_server_info_map,
604                      std::unique_ptr<BrokenAlternativeServiceList>
605                          broken_alternative_service_list,
606                      std::unique_ptr<RecentlyBrokenAlternativeServices>
607                          recently_broken_alternative_services);
608 
609   // These methods are called by OnPrefsLoaded to handle merging properties
610   // loaded from prefs with what has been learned while waiting for prefs to
611   // load.
612   void OnServerInfoLoaded(std::unique_ptr<ServerInfoMap> server_info_map);
613   void OnLastLocalAddressWhenQuicWorkedLoaded(
614       const IPAddress& last_local_address_when_quic_worked);
615   void OnQuicServerInfoMapLoaded(
616       std::unique_ptr<QuicServerInfoMap> quic_server_info_map);
617   void OnBrokenAndRecentlyBrokenAlternativeServicesLoaded(
618       std::unique_ptr<BrokenAlternativeServiceList>
619           broken_alternative_service_list,
620       std::unique_ptr<RecentlyBrokenAlternativeServices>
621           recently_broken_alternative_services);
622 
623   // Queue a delayed call to WriteProperties(). If |is_initialized_| is false,
624   // or |properties_manager_| is nullptr, or there's already a queued call to
625   // WriteProperties(), does nothing.
626   void MaybeQueueWriteProperties();
627 
628   // Writes cached state to |properties_manager_|, which must not be null.
629   // Invokes |callback| on completion, if non-null.
630   void WriteProperties(base::OnceClosure callback) const;
631 
632   raw_ptr<const base::TickClock> tick_clock_;  // Unowned
633   raw_ptr<base::Clock> clock_;                 // Unowned
634 
635   // Cached value of whether network state partitioning is enabled. Cached to
636   // improve performance.
637   const bool use_network_anonymization_key_;
638 
639   // Set to true once initial properties have been retrieved from disk by
640   // |properties_manager_|. Always true if |properties_manager_| is nullptr.
641   bool is_initialized_;
642 
643   // Queue a write when resources finish loading. Set to true when
644   // MaybeQueueWriteProperties() is invoked while still waiting on
645   // initialization to complete.
646   bool queue_write_on_load_ = false;
647 
648   // Used to load/save properties from/to preferences. May be nullptr.
649   std::unique_ptr<HttpServerPropertiesManager> properties_manager_;
650 
651   ServerInfoMap server_info_map_;
652 
653   BrokenAlternativeServices broken_alternative_services_;
654 
655   IPAddress last_local_address_when_quic_worked_;
656   // Contains a map of servers which could share the same alternate protocol.
657   // Map from a Canonical scheme/host/port/NAK (host is some postfix of host
658   // names) to an actual origin, which has a plausible alternate protocol
659   // mapping.
660   CanonicalMap canonical_alt_svc_map_;
661 
662   // Contains list of suffixes (for example ".c.youtube.com",
663   // ".googlevideo.com", ".googleusercontent.com") of canonical hostnames.
664   const CanonicalSuffixList canonical_suffixes_;
665 
666   QuicServerInfoMap quic_server_info_map_;
667 
668   // Maps canonical suffixes to host names that have the same canonical suffix
669   // and have a corresponding entry in |quic_server_info_map_|. The map can be
670   // used to quickly look for server info for hosts that share the same
671   // canonical suffix but don't have exact match in |quic_server_info_map_|. The
672   // map exists solely to improve the search performance. It only contains
673   // derived data that can be recalculated by traversing
674   // |quic_server_info_map_|.
675   QuicCanonicalMap canonical_server_info_map_;
676 
677   size_t max_server_configs_stored_in_properties_;
678 
679   // Used to post calls to WriteProperties().
680   base::OneShotTimer prefs_update_timer_;
681 
682   THREAD_CHECKER(thread_checker_);
683 };
684 
685 }  // namespace net
686 
687 #endif  // NET_HTTP_HTTP_SERVER_PROPERTIES_H_
688