| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_MANAGER_H_ |
| #define NET_HTTP_HTTP_SERVER_PROPERTIES_MANAGER_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/functional/callback.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/sequence_checker.h" |
| #include "net/base/host_port_pair.h" |
| #include "net/base/net_export.h" |
| #include "net/http/alternative_service.h" |
| #include "net/http/broken_alternative_services.h" |
| #include "net/http/http_server_properties.h" |
| #include "net/log/net_log_with_source.h" |
| |
| namespace base { |
| class TickClock; |
| } |
| |
| namespace net { |
| |
| class IPAddress; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // HttpServerPropertiesManager |
| |
| // Class responsible for serializing/deserializing HttpServerProperties and |
| // reading from/writing to preferences. |
| class NET_EXPORT_PRIVATE HttpServerPropertiesManager { |
| public: |
| // Called when prefs are loaded. If prefs completely failed to load, |
| // everything will be nullptr. Otherwise, everything will be populated, except |
| // |broken_alternative_service_list| and |
| // |recently_broken_alternative_services|, which may be null. |
| using OnPrefsLoadedCallback = base::OnceCallback<void( |
| std::unique_ptr<HttpServerProperties::ServerInfoMap> server_info_map, |
| const IPAddress& last_local_address_when_quic_worked, |
| std::unique_ptr<HttpServerProperties::QuicServerInfoMap> |
| quic_server_info_map, |
| std::unique_ptr<BrokenAlternativeServiceList> |
| broken_alternative_service_list, |
| std::unique_ptr<RecentlyBrokenAlternativeServices> |
| recently_broken_alternative_services)>; |
| |
| using GetCannonicalSuffix = |
| base::RepeatingCallback<const std::string*(const std::string& host)>; |
| |
| // Create an instance of the HttpServerPropertiesManager. |
| // |
| // |on_prefs_loaded_callback| will be invoked with values loaded from |
| // |prefs_delegate| once prefs have been loaded from disk. |
| // If WriteToPrefs() is invoked before this happens, |
| // |on_prefs_loaded_callback| will never be invoked, since the written prefs |
| // take precedence over the ones previously stored on disk. |
| // |
| // |clock| is used for setting expiration times and scheduling the |
| // expiration of broken alternative services, and must not be nullptr. |
| HttpServerPropertiesManager( |
| std::unique_ptr<HttpServerProperties::PrefDelegate> pref_delegate, |
| OnPrefsLoadedCallback on_prefs_loaded_callback, |
| size_t max_server_configs_stored_in_properties, |
| NetLog* net_log, |
| const base::TickClock* clock = nullptr); |
| |
| HttpServerPropertiesManager(const HttpServerPropertiesManager&) = delete; |
| HttpServerPropertiesManager& operator=(const HttpServerPropertiesManager&) = |
| delete; |
| |
| ~HttpServerPropertiesManager(); |
| |
| // Populates passed in objects with data from preferences. If pref data is not |
| // present, leaves all values alone. Otherwise, populates them all, with the |
| // possible exception of the two broken alt services lists. |
| // |
| // Corrupted data is ignored. |
| // |
| // TODO(mmenke): Consider always populating fields, unconditionally, for a |
| // simpler API. |
| void ReadPrefs( |
| std::unique_ptr<HttpServerProperties::ServerInfoMap>* server_info_map, |
| IPAddress* last_local_address_when_quic_worked, |
| std::unique_ptr<HttpServerProperties::QuicServerInfoMap>* |
| quic_server_info_map, |
| std::unique_ptr<BrokenAlternativeServiceList>* |
| broken_alternative_service_list, |
| std::unique_ptr<RecentlyBrokenAlternativeServices>* |
| recently_broken_alternative_services); |
| |
| void set_max_server_configs_stored_in_properties( |
| size_t max_server_configs_stored_in_properties) { |
| max_server_configs_stored_in_properties_ = |
| max_server_configs_stored_in_properties; |
| } |
| |
| // Update preferences with caller-provided data. Invokes |callback| when |
| // changes have been committed, if non-null. |
| // |
| // If the OnPrefLoadCallback() passed to the constructor hasn't been invoked |
| // by the time this method is called, calling this will prevent it from ever |
| // being invoked, as this method will overwrite any previous preferences. |
| // |
| // Entries associated with NetworkAnonymizationKeys for opaque origins are not |
| // written to disk. |
| void WriteToPrefs( |
| const HttpServerProperties::ServerInfoMap& server_info_map, |
| const GetCannonicalSuffix& get_canonical_suffix, |
| const IPAddress& last_local_address_when_quic_worked, |
| const HttpServerProperties::QuicServerInfoMap& quic_server_info_map, |
| const BrokenAlternativeServiceList& broken_alternative_service_list, |
| const RecentlyBrokenAlternativeServices& |
| recently_broken_alternative_services, |
| base::OnceClosure callback); |
| |
| private: |
| // TODO(mmenke): Remove these friend methods, and make all methods static that |
| // can be. |
| FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest, |
| ParseAlternativeServiceInfo); |
| FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest, |
| ReadAdvertisedVersionsFromPref); |
| FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest, |
| DoNotLoadAltSvcForInsecureOrigins); |
| FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest, |
| DoNotLoadExpiredAlternativeService); |
| FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest, |
| AdvertisedVersionsRoundTrip); |
| |
| void AddServerData(const base::Value::Dict& server_dict, |
| HttpServerProperties::ServerInfoMap* server_info_map, |
| bool use_network_anonymization_key); |
| |
| // Helper method used for parsing an alternative service from JSON. |
| // |dict| is the JSON dictionary to be parsed. It should contain fields |
| // corresponding to members of AlternativeService. |
| // |host_optional| determines whether or not the "host" field is optional. If |
| // optional, the default value is empty string. |
| // |parsing_under| is used only for debug log outputs in case of error; it |
| // should describe what section of the JSON prefs is currently being parsed. |
| // |alternative_service| is the output of parsing |dict|. |
| // Return value is true if parsing is successful. |
| static bool ParseAlternativeServiceDict( |
| const base::Value::Dict& dict, |
| bool host_optional, |
| const std::string& parsing_under, |
| AlternativeService* alternative_service); |
| |
| static bool ParseAlternativeServiceInfoDictOfServer( |
| const base::Value::Dict& dict, |
| const std::string& server_str, |
| AlternativeServiceInfo* alternative_service_info); |
| |
| // Attempts to populate |server_info|'s |alternative_service_info| field from |
| // |server_dict|. Returns true if the data was no corrupted (Lack of data is |
| // not considered corruption). |
| static bool ParseAlternativeServiceInfo( |
| const url::SchemeHostPort& server, |
| const base::Value::Dict& server_dict, |
| HttpServerProperties::ServerInfo* server_info); |
| |
| void ReadLastLocalAddressWhenQuicWorked( |
| const base::Value::Dict& server_dict, |
| IPAddress* last_local_address_when_quic_worked); |
| void ParseNetworkStats(const url::SchemeHostPort& server, |
| const base::Value::Dict& server_dict, |
| HttpServerProperties::ServerInfo* server_info); |
| void AddToQuicServerInfoMap( |
| const base::Value::Dict& server_dict, |
| bool use_network_anonymization_key, |
| HttpServerProperties::QuicServerInfoMap* quic_server_info_map); |
| void AddToBrokenAlternativeServices( |
| const base::Value::Dict& broken_alt_svc_entry_dict, |
| bool use_network_anonymization_key, |
| BrokenAlternativeServiceList* broken_alternative_service_list, |
| RecentlyBrokenAlternativeServices* recently_broken_alternative_services); |
| |
| void SaveAlternativeServiceToServerPrefs( |
| const AlternativeServiceInfoVector& alternative_service_info_vector, |
| base::Value::Dict& server_pref_dict); |
| void SaveLastLocalAddressWhenQuicWorkedToPrefs( |
| const IPAddress& last_local_address_when_quic_worked, |
| base::Value::Dict& http_server_properties_dict); |
| void SaveNetworkStatsToServerPrefs( |
| const ServerNetworkStats& server_network_stats, |
| base::Value::Dict& server_pref_dict); |
| void SaveQuicServerInfoMapToServerPrefs( |
| const HttpServerProperties::QuicServerInfoMap& quic_server_info_map, |
| base::Value::Dict& http_server_properties_dict); |
| void SaveBrokenAlternativeServicesToPrefs( |
| const BrokenAlternativeServiceList& broken_alternative_service_list, |
| size_t max_broken_alternative_services, |
| const RecentlyBrokenAlternativeServices& |
| recently_broken_alternative_services, |
| base::Value::Dict& http_server_properties_dict); |
| |
| void OnHttpServerPropertiesLoaded(); |
| |
| std::unique_ptr<HttpServerProperties::PrefDelegate> pref_delegate_; |
| |
| OnPrefsLoadedCallback on_prefs_loaded_callback_; |
| |
| size_t max_server_configs_stored_in_properties_; |
| |
| raw_ptr<const base::TickClock> clock_; // Unowned |
| |
| const NetLogWithSource net_log_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| base::WeakPtrFactory<HttpServerPropertiesManager> pref_load_weak_ptr_factory_{ |
| this}; |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_HTTP_HTTP_SERVER_PROPERTIES_MANAGER_H_ |