1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "net/http/http_server_properties.h"
- #include "base/bind.h"
- #include "base/check_op.h"
- #include "base/containers/adapters.h"
- #include "base/containers/contains.h"
- #include "base/feature_list.h"
- #include "base/location.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/time/default_clock.h"
- #include "base/time/default_tick_clock.h"
- #include "base/values.h"
- #include "net/base/features.h"
- #include "net/base/url_util.h"
- #include "net/http/http_network_session.h"
- #include "net/http/http_server_properties_manager.h"
- #include "net/socket/ssl_client_socket.h"
- #include "net/ssl/ssl_config.h"
- namespace net {
- namespace {
- // Time to wait before starting an update the preferences from the
- // http_server_properties_impl_ cache. Scheduling another update during this
- // period will be a no-op.
- constexpr base::TimeDelta kUpdatePrefsDelay = base::Seconds(60);
- url::SchemeHostPort NormalizeSchemeHostPort(
- const url::SchemeHostPort& scheme_host_port) {
- if (scheme_host_port.scheme() == url::kWssScheme) {
- return url::SchemeHostPort(url::kHttpsScheme, scheme_host_port.host(),
- scheme_host_port.port());
- }
- if (scheme_host_port.scheme() == url::kWsScheme) {
- return url::SchemeHostPort(url::kHttpScheme, scheme_host_port.host(),
- scheme_host_port.port());
- }
- return scheme_host_port;
- }
- } // namespace
- HttpServerProperties::PrefDelegate::~PrefDelegate() = default;
- HttpServerProperties::ServerInfo::ServerInfo() = default;
- HttpServerProperties::ServerInfo::ServerInfo(const ServerInfo& server_info) =
- default;
- HttpServerProperties::ServerInfo::ServerInfo(ServerInfo&& server_info) =
- default;
- HttpServerProperties::ServerInfo::~ServerInfo() = default;
- bool HttpServerProperties::ServerInfo::empty() const {
- return !supports_spdy.has_value() && !alternative_services.has_value() &&
- !server_network_stats.has_value();
- }
- bool HttpServerProperties::ServerInfo::operator==(
- const ServerInfo& other) const {
- return supports_spdy == other.supports_spdy &&
- alternative_services == other.alternative_services &&
- server_network_stats == other.server_network_stats;
- }
- HttpServerProperties::ServerInfoMapKey::ServerInfoMapKey(
- url::SchemeHostPort server,
- const NetworkIsolationKey& network_isolation_key,
- bool use_network_isolation_key)
- : server(std::move(server)),
- network_isolation_key(use_network_isolation_key ? network_isolation_key
- : NetworkIsolationKey()) {
- // Scheme should have been normalized before this method was called.
- DCHECK_NE(this->server.scheme(), url::kWsScheme);
- DCHECK_NE(this->server.scheme(), url::kWssScheme);
- }
- HttpServerProperties::ServerInfoMapKey::~ServerInfoMapKey() = default;
- bool HttpServerProperties::ServerInfoMapKey::operator<(
- const ServerInfoMapKey& other) const {
- return std::tie(server, network_isolation_key) <
- std::tie(other.server, other.network_isolation_key);
- }
- HttpServerProperties::QuicServerInfoMapKey::QuicServerInfoMapKey(
- const quic::QuicServerId& server_id,
- const NetworkIsolationKey& network_isolation_key,
- bool use_network_isolation_key)
- : server_id(server_id),
- network_isolation_key(use_network_isolation_key ? network_isolation_key
- : NetworkIsolationKey()) {
- }
- HttpServerProperties::QuicServerInfoMapKey::~QuicServerInfoMapKey() = default;
- bool HttpServerProperties::QuicServerInfoMapKey::operator<(
- const QuicServerInfoMapKey& other) const {
- return std::tie(server_id, network_isolation_key) <
- std::tie(other.server_id, other.network_isolation_key);
- }
- // Used in tests.
- bool HttpServerProperties::QuicServerInfoMapKey::operator==(
- const QuicServerInfoMapKey& other) const {
- return std::tie(server_id, network_isolation_key) ==
- std::tie(other.server_id, other.network_isolation_key);
- }
- HttpServerProperties::ServerInfoMap::ServerInfoMap()
- : base::LRUCache<ServerInfoMapKey, ServerInfo>(kMaxServerInfoEntries) {}
- HttpServerProperties::ServerInfoMap::iterator
- HttpServerProperties::ServerInfoMap::GetOrPut(const ServerInfoMapKey& key) {
- auto it = Get(key);
- if (it != end())
- return it;
- return Put(key, ServerInfo());
- }
- HttpServerProperties::ServerInfoMap::iterator
- HttpServerProperties::ServerInfoMap::EraseIfEmpty(iterator server_info_it) {
- if (server_info_it->second.empty())
- return Erase(server_info_it);
- return ++server_info_it;
- }
- HttpServerProperties::HttpServerProperties(
- std::unique_ptr<PrefDelegate> pref_delegate,
- NetLog* net_log,
- const base::TickClock* tick_clock,
- base::Clock* clock)
- : tick_clock_(tick_clock ? tick_clock
- : base::DefaultTickClock::GetInstance()),
- clock_(clock ? clock : base::DefaultClock::GetInstance()),
- use_network_isolation_key_(base::FeatureList::IsEnabled(
- features::kPartitionHttpServerPropertiesByNetworkIsolationKey)),
- is_initialized_(pref_delegate.get() == nullptr),
- properties_manager_(
- pref_delegate
- ? std::make_unique<HttpServerPropertiesManager>(
- std::move(pref_delegate),
- base::BindOnce(&HttpServerProperties::OnPrefsLoaded,
- base::Unretained(this)),
- kDefaultMaxQuicServerEntries,
- net_log,
- tick_clock_)
- : nullptr),
- broken_alternative_services_(kMaxRecentlyBrokenAlternativeServiceEntries,
- this,
- tick_clock_),
- canonical_suffixes_({".ggpht.com", ".c.youtube.com", ".googlevideo.com",
- ".googleusercontent.com", ".gvt1.com"}),
- quic_server_info_map_(kDefaultMaxQuicServerEntries),
- max_server_configs_stored_in_properties_(kDefaultMaxQuicServerEntries) {}
- HttpServerProperties::~HttpServerProperties() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (properties_manager_) {
- // Stop waiting for initial settings.
- is_initialized_ = true;
- // Stop the timer if it's running, since this will write to the properties
- // file immediately.
- prefs_update_timer_.Stop();
- WriteProperties(base::OnceClosure());
- }
- }
- void HttpServerProperties::Clear(base::OnceClosure callback) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- server_info_map_.Clear();
- broken_alternative_services_.Clear();
- canonical_alt_svc_map_.clear();
- last_local_address_when_quic_worked_ = IPAddress();
- quic_server_info_map_.Clear();
- canonical_server_info_map_.clear();
- if (properties_manager_) {
- // Stop waiting for initial settings.
- is_initialized_ = true;
- // Leaving this as-is doesn't actually have any effect, if it's true, but
- // seems best to be safe.
- queue_write_on_load_ = false;
- // Stop the timer if it's running, since this will write to the properties
- // file immediately.
- prefs_update_timer_.Stop();
- WriteProperties(std::move(callback));
- } else if (callback) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- std::move(callback));
- }
- }
- bool HttpServerProperties::SupportsRequestPriority(
- const url::SchemeHostPort& server,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (server.host().empty())
- return false;
- if (GetSupportsSpdy(server, network_isolation_key))
- return true;
- const AlternativeServiceInfoVector alternative_service_info_vector =
- GetAlternativeServiceInfos(server, network_isolation_key);
- for (const AlternativeServiceInfo& alternative_service_info :
- alternative_service_info_vector) {
- if (alternative_service_info.alternative_service().protocol == kProtoQUIC) {
- return true;
- }
- }
- return false;
- }
- bool HttpServerProperties::GetSupportsSpdy(
- const url::SchemeHostPort& server,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return GetSupportsSpdyInternal(NormalizeSchemeHostPort(server),
- network_isolation_key);
- }
- void HttpServerProperties::SetSupportsSpdy(
- const url::SchemeHostPort& server,
- const net::NetworkIsolationKey& network_isolation_key,
- bool supports_spdy) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- SetSupportsSpdyInternal(NormalizeSchemeHostPort(server),
- network_isolation_key, supports_spdy);
- }
- bool HttpServerProperties::RequiresHTTP11(
- const url::SchemeHostPort& server,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return RequiresHTTP11Internal(NormalizeSchemeHostPort(server),
- network_isolation_key);
- }
- void HttpServerProperties::SetHTTP11Required(
- const url::SchemeHostPort& server,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- SetHTTP11RequiredInternal(NormalizeSchemeHostPort(server),
- network_isolation_key);
- }
- void HttpServerProperties::MaybeForceHTTP11(
- const url::SchemeHostPort& server,
- const net::NetworkIsolationKey& network_isolation_key,
- SSLConfig* ssl_config) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- MaybeForceHTTP11Internal(NormalizeSchemeHostPort(server),
- network_isolation_key, ssl_config);
- }
- AlternativeServiceInfoVector HttpServerProperties::GetAlternativeServiceInfos(
- const url::SchemeHostPort& origin,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return GetAlternativeServiceInfosInternal(NormalizeSchemeHostPort(origin),
- network_isolation_key);
- }
- void HttpServerProperties::SetHttp2AlternativeService(
- const url::SchemeHostPort& origin,
- const NetworkIsolationKey& network_isolation_key,
- const AlternativeService& alternative_service,
- base::Time expiration) {
- DCHECK_EQ(alternative_service.protocol, kProtoHTTP2);
- SetAlternativeServices(
- origin, network_isolation_key,
- AlternativeServiceInfoVector(
- /*size=*/1, AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service, expiration)));
- }
- void HttpServerProperties::SetQuicAlternativeService(
- const url::SchemeHostPort& origin,
- const NetworkIsolationKey& network_isolation_key,
- const AlternativeService& alternative_service,
- base::Time expiration,
- const quic::ParsedQuicVersionVector& advertised_versions) {
- DCHECK(alternative_service.protocol == kProtoQUIC);
- SetAlternativeServices(
- origin, network_isolation_key,
- AlternativeServiceInfoVector(
- /*size=*/1,
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- alternative_service, expiration, advertised_versions)));
- }
- void HttpServerProperties::SetAlternativeServices(
- const url::SchemeHostPort& origin,
- const net::NetworkIsolationKey& network_isolation_key,
- const AlternativeServiceInfoVector& alternative_service_info_vector) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- SetAlternativeServicesInternal(NormalizeSchemeHostPort(origin),
- network_isolation_key,
- alternative_service_info_vector);
- }
- void HttpServerProperties::MarkAlternativeServiceBroken(
- const AlternativeService& alternative_service,
- const net::NetworkIsolationKey& network_isolation_key) {
- broken_alternative_services_.MarkBroken(BrokenAlternativeService(
- alternative_service, network_isolation_key, use_network_isolation_key_));
- MaybeQueueWriteProperties();
- }
- void HttpServerProperties::
- MarkAlternativeServiceBrokenUntilDefaultNetworkChanges(
- const AlternativeService& alternative_service,
- const net::NetworkIsolationKey& network_isolation_key) {
- broken_alternative_services_.MarkBrokenUntilDefaultNetworkChanges(
- BrokenAlternativeService(alternative_service, network_isolation_key,
- use_network_isolation_key_));
- MaybeQueueWriteProperties();
- }
- void HttpServerProperties::MarkAlternativeServiceRecentlyBroken(
- const AlternativeService& alternative_service,
- const net::NetworkIsolationKey& network_isolation_key) {
- broken_alternative_services_.MarkRecentlyBroken(BrokenAlternativeService(
- alternative_service, network_isolation_key, use_network_isolation_key_));
- MaybeQueueWriteProperties();
- }
- bool HttpServerProperties::IsAlternativeServiceBroken(
- const AlternativeService& alternative_service,
- const net::NetworkIsolationKey& network_isolation_key) const {
- return broken_alternative_services_.IsBroken(BrokenAlternativeService(
- alternative_service, network_isolation_key, use_network_isolation_key_));
- }
- bool HttpServerProperties::WasAlternativeServiceRecentlyBroken(
- const AlternativeService& alternative_service,
- const net::NetworkIsolationKey& network_isolation_key) {
- return broken_alternative_services_.WasRecentlyBroken(
- BrokenAlternativeService(alternative_service, network_isolation_key,
- use_network_isolation_key_));
- }
- void HttpServerProperties::ConfirmAlternativeService(
- const AlternativeService& alternative_service,
- const net::NetworkIsolationKey& network_isolation_key) {
- bool old_value =
- IsAlternativeServiceBroken(alternative_service, network_isolation_key);
- broken_alternative_services_.Confirm(BrokenAlternativeService(
- alternative_service, network_isolation_key, use_network_isolation_key_));
- bool new_value =
- IsAlternativeServiceBroken(alternative_service, network_isolation_key);
- // For persisting, we only care about the value returned by
- // IsAlternativeServiceBroken. If that value changes, then call persist.
- if (old_value != new_value)
- MaybeQueueWriteProperties();
- }
- void HttpServerProperties::OnDefaultNetworkChanged() {
- bool changed = broken_alternative_services_.OnDefaultNetworkChanged();
- if (changed)
- MaybeQueueWriteProperties();
- }
- base::Value HttpServerProperties::GetAlternativeServiceInfoAsValue() const {
- const base::Time now = clock_->Now();
- const base::TimeTicks now_ticks = tick_clock_->NowTicks();
- base::Value::List dict_list;
- for (const auto& server_info : server_info_map_) {
- if (!server_info.second.alternative_services.has_value())
- continue;
- base::Value::List alternative_service_list;
- const ServerInfoMapKey& key = server_info.first;
- for (const AlternativeServiceInfo& alternative_service_info :
- server_info.second.alternative_services.value()) {
- std::string alternative_service_string(
- alternative_service_info.ToString());
- AlternativeService alternative_service(
- alternative_service_info.alternative_service());
- if (alternative_service.host.empty()) {
- alternative_service.host = key.server.host();
- }
- base::TimeTicks brokenness_expiration_ticks;
- if (broken_alternative_services_.IsBroken(
- BrokenAlternativeService(alternative_service,
- server_info.first.network_isolation_key,
- use_network_isolation_key_),
- &brokenness_expiration_ticks)) {
- // Convert |brokenness_expiration| from TimeTicks to Time
- base::Time brokenness_expiration =
- now + (brokenness_expiration_ticks - now_ticks);
- base::Time::Exploded exploded;
- brokenness_expiration.LocalExplode(&exploded);
- std::string broken_info_string =
- " (broken until " +
- base::StringPrintf("%04d-%02d-%02d %0d:%0d:%0d", exploded.year,
- exploded.month, exploded.day_of_month,
- exploded.hour, exploded.minute,
- exploded.second) +
- ")";
- alternative_service_string.append(broken_info_string);
- }
- alternative_service_list.Append(std::move(alternative_service_string));
- }
- if (alternative_service_list.empty())
- continue;
- base::Value::Dict dict;
- dict.Set("server", key.server.Serialize());
- dict.Set("network_isolation_key",
- key.network_isolation_key.ToDebugString());
- dict.Set("alternative_service", std::move(alternative_service_list));
- dict_list.Append(std::move(dict));
- }
- return base::Value(std::move(dict_list));
- }
- bool HttpServerProperties::WasLastLocalAddressWhenQuicWorked(
- const IPAddress& local_address) const {
- return !last_local_address_when_quic_worked_.empty() &&
- last_local_address_when_quic_worked_ == local_address;
- }
- bool HttpServerProperties::HasLastLocalAddressWhenQuicWorked() const {
- return !last_local_address_when_quic_worked_.empty();
- }
- void HttpServerProperties::SetLastLocalAddressWhenQuicWorked(
- IPAddress last_local_address_when_quic_worked) {
- DCHECK(!last_local_address_when_quic_worked.empty());
- if (last_local_address_when_quic_worked_ ==
- last_local_address_when_quic_worked) {
- return;
- }
- last_local_address_when_quic_worked_ = last_local_address_when_quic_worked;
- MaybeQueueWriteProperties();
- }
- void HttpServerProperties::ClearLastLocalAddressWhenQuicWorked() {
- if (last_local_address_when_quic_worked_.empty())
- return;
- last_local_address_when_quic_worked_ = IPAddress();
- MaybeQueueWriteProperties();
- }
- void HttpServerProperties::SetServerNetworkStats(
- const url::SchemeHostPort& server,
- const NetworkIsolationKey& network_isolation_key,
- ServerNetworkStats stats) {
- SetServerNetworkStatsInternal(NormalizeSchemeHostPort(server),
- network_isolation_key, std::move(stats));
- }
- void HttpServerProperties::ClearServerNetworkStats(
- const url::SchemeHostPort& server,
- const NetworkIsolationKey& network_isolation_key) {
- ClearServerNetworkStatsInternal(NormalizeSchemeHostPort(server),
- network_isolation_key);
- }
- const ServerNetworkStats* HttpServerProperties::GetServerNetworkStats(
- const url::SchemeHostPort& server,
- const NetworkIsolationKey& network_isolation_key) {
- return GetServerNetworkStatsInternal(NormalizeSchemeHostPort(server),
- network_isolation_key);
- }
- void HttpServerProperties::SetQuicServerInfo(
- const quic::QuicServerId& server_id,
- const NetworkIsolationKey& network_isolation_key,
- const std::string& server_info) {
- QuicServerInfoMapKey key =
- CreateQuicServerInfoKey(server_id, network_isolation_key);
- auto it = quic_server_info_map_.Peek(key);
- bool changed =
- (it == quic_server_info_map_.end() || it->second != server_info);
- quic_server_info_map_.Put(key, server_info);
- UpdateCanonicalServerInfoMap(key);
- if (changed)
- MaybeQueueWriteProperties();
- }
- const std::string* HttpServerProperties::GetQuicServerInfo(
- const quic::QuicServerId& server_id,
- const NetworkIsolationKey& network_isolation_key) {
- QuicServerInfoMapKey key =
- CreateQuicServerInfoKey(server_id, network_isolation_key);
- auto it = quic_server_info_map_.Get(key);
- if (it != quic_server_info_map_.end()) {
- // Since |canonical_server_info_map_| should always map to the most
- // recent host, update it with the one that became MRU in
- // |quic_server_info_map_|.
- UpdateCanonicalServerInfoMap(key);
- return &it->second;
- }
- // If the exact match for |server_id| wasn't found, check
- // |canonical_server_info_map_| whether there is server info for a host with
- // the same canonical host suffix.
- auto canonical_itr = GetCanonicalServerInfoHost(key);
- if (canonical_itr == canonical_server_info_map_.end())
- return nullptr;
- // When search in |quic_server_info_map_|, do not change the MRU order.
- it = quic_server_info_map_.Peek(
- CreateQuicServerInfoKey(canonical_itr->second, network_isolation_key));
- if (it != quic_server_info_map_.end())
- return &it->second;
- return nullptr;
- }
- const HttpServerProperties::QuicServerInfoMap&
- HttpServerProperties::quic_server_info_map() const {
- return quic_server_info_map_;
- }
- size_t HttpServerProperties::max_server_configs_stored_in_properties() const {
- return max_server_configs_stored_in_properties_;
- }
- void HttpServerProperties::SetMaxServerConfigsStoredInProperties(
- size_t max_server_configs_stored_in_properties) {
- // Do nothing if the new size is the same as the old one.
- if (max_server_configs_stored_in_properties_ ==
- max_server_configs_stored_in_properties) {
- return;
- }
- max_server_configs_stored_in_properties_ =
- max_server_configs_stored_in_properties;
- // LRUCache doesn't allow the capacity of the cache to be changed. Thus create
- // a new map with the new size and add current elements and swap the new map.
- quic_server_info_map_.ShrinkToSize(max_server_configs_stored_in_properties_);
- QuicServerInfoMap temp_map(max_server_configs_stored_in_properties_);
- // Update the |canonical_server_info_map_| as well, so it stays in sync with
- // |quic_server_info_map_|.
- canonical_server_info_map_ = QuicCanonicalMap();
- for (const auto& [key, server_info] : base::Reversed(quic_server_info_map_)) {
- temp_map.Put(key, server_info);
- UpdateCanonicalServerInfoMap(key);
- }
- quic_server_info_map_.Swap(temp_map);
- if (properties_manager_) {
- properties_manager_->set_max_server_configs_stored_in_properties(
- max_server_configs_stored_in_properties);
- }
- }
- void HttpServerProperties::SetBrokenAlternativeServicesDelayParams(
- absl::optional<base::TimeDelta> initial_delay,
- absl::optional<bool> exponential_backoff_on_initial_delay) {
- broken_alternative_services_.SetDelayParams(
- initial_delay, exponential_backoff_on_initial_delay);
- }
- bool HttpServerProperties::IsInitialized() const {
- return is_initialized_;
- }
- void HttpServerProperties::OnExpireBrokenAlternativeService(
- const AlternativeService& expired_alternative_service,
- const NetworkIsolationKey& network_isolation_key) {
- // Remove every occurrence of |expired_alternative_service| from
- // |alternative_service_map_|.
- for (auto map_it = server_info_map_.begin();
- map_it != server_info_map_.end();) {
- if (!map_it->second.alternative_services.has_value() ||
- map_it->first.network_isolation_key != network_isolation_key) {
- ++map_it;
- continue;
- }
- AlternativeServiceInfoVector* service_info =
- &map_it->second.alternative_services.value();
- for (auto it = service_info->begin(); it != service_info->end();) {
- AlternativeService alternative_service(it->alternative_service());
- // Empty hostname in map means hostname of key: substitute before
- // comparing to |expired_alternative_service|.
- if (alternative_service.host.empty()) {
- alternative_service.host = map_it->first.server.host();
- }
- if (alternative_service == expired_alternative_service) {
- it = service_info->erase(it);
- continue;
- }
- ++it;
- }
- // If an origin has an empty list of alternative services, then remove it
- // from both |canonical_alt_svc_map_| and
- // |alternative_service_map_|.
- if (service_info->empty()) {
- RemoveAltSvcCanonicalHost(map_it->first.server, network_isolation_key);
- map_it->second.alternative_services.reset();
- map_it = server_info_map_.EraseIfEmpty(map_it);
- continue;
- }
- ++map_it;
- }
- }
- base::TimeDelta HttpServerProperties::GetUpdatePrefsDelayForTesting() {
- return kUpdatePrefsDelay;
- }
- bool HttpServerProperties::GetSupportsSpdyInternal(
- url::SchemeHostPort server,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(server.scheme(), url::kWsScheme);
- DCHECK_NE(server.scheme(), url::kWssScheme);
- if (server.host().empty())
- return false;
- auto server_info = server_info_map_.Get(
- CreateServerInfoKey(std::move(server), network_isolation_key));
- return server_info != server_info_map_.end() &&
- server_info->second.supports_spdy.value_or(false);
- }
- void HttpServerProperties::SetSupportsSpdyInternal(
- url::SchemeHostPort server,
- const net::NetworkIsolationKey& network_isolation_key,
- bool supports_spdy) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(server.scheme(), url::kWsScheme);
- DCHECK_NE(server.scheme(), url::kWssScheme);
- if (server.host().empty())
- return;
- auto server_info = server_info_map_.GetOrPut(
- CreateServerInfoKey(std::move(server), network_isolation_key));
- // If value is already the same as |supports_spdy|, or value is unset and
- // |supports_spdy| is false, don't queue a write.
- bool queue_write =
- server_info->second.supports_spdy.value_or(false) != supports_spdy;
- server_info->second.supports_spdy = supports_spdy;
- if (queue_write)
- MaybeQueueWriteProperties();
- }
- bool HttpServerProperties::RequiresHTTP11Internal(
- url::SchemeHostPort server,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(server.scheme(), url::kWsScheme);
- DCHECK_NE(server.scheme(), url::kWssScheme);
- if (server.host().empty())
- return false;
- auto spdy_info = server_info_map_.Get(
- CreateServerInfoKey(std::move(server), network_isolation_key));
- return spdy_info != server_info_map_.end() &&
- spdy_info->second.requires_http11.value_or(false);
- }
- void HttpServerProperties::SetHTTP11RequiredInternal(
- url::SchemeHostPort server,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(server.scheme(), url::kWsScheme);
- DCHECK_NE(server.scheme(), url::kWssScheme);
- if (server.host().empty())
- return;
- server_info_map_
- .GetOrPut(CreateServerInfoKey(std::move(server), network_isolation_key))
- ->second.requires_http11 = true;
- // No need to call MaybeQueueWriteProperties(), as this information is not
- // persisted to preferences.
- }
- void HttpServerProperties::MaybeForceHTTP11Internal(
- url::SchemeHostPort server,
- const net::NetworkIsolationKey& network_isolation_key,
- SSLConfig* ssl_config) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(server.scheme(), url::kWsScheme);
- DCHECK_NE(server.scheme(), url::kWssScheme);
- if (RequiresHTTP11(std::move(server), network_isolation_key)) {
- ssl_config->alpn_protos.clear();
- ssl_config->alpn_protos.push_back(kProtoHTTP11);
- }
- }
- AlternativeServiceInfoVector
- HttpServerProperties::GetAlternativeServiceInfosInternal(
- const url::SchemeHostPort& origin,
- const net::NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(origin.scheme(), url::kWsScheme);
- DCHECK_NE(origin.scheme(), url::kWssScheme);
- // Copy valid alternative service infos into
- // |valid_alternative_service_infos|.
- AlternativeServiceInfoVector valid_alternative_service_infos;
- const base::Time now = clock_->Now();
- auto map_it =
- server_info_map_.Get(CreateServerInfoKey(origin, network_isolation_key));
- if (map_it != server_info_map_.end() &&
- map_it->second.alternative_services.has_value()) {
- AlternativeServiceInfoVector* service_info =
- &map_it->second.alternative_services.value();
- HostPortPair host_port_pair(origin.host(), origin.port());
- for (auto it = service_info->begin(); it != service_info->end();) {
- if (it->expiration() < now) {
- it = service_info->erase(it);
- continue;
- }
- AlternativeService alternative_service(it->alternative_service());
- if (alternative_service.host.empty()) {
- alternative_service.host = origin.host();
- }
- // If the alternative service is equivalent to the origin (same host, same
- // port, and both TCP), skip it.
- if (host_port_pair.Equals(alternative_service.host_port_pair()) &&
- alternative_service.protocol == kProtoHTTP2) {
- ++it;
- continue;
- }
- if (alternative_service.protocol == kProtoQUIC) {
- valid_alternative_service_infos.push_back(
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- alternative_service, it->expiration(),
- it->advertised_versions()));
- } else {
- valid_alternative_service_infos.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service, it->expiration()));
- }
- ++it;
- }
- if (service_info->empty()) {
- map_it->second.alternative_services.reset();
- server_info_map_.EraseIfEmpty(map_it);
- }
- return valid_alternative_service_infos;
- }
- auto canonical = GetCanonicalAltSvcHost(origin, network_isolation_key);
- if (canonical == canonical_alt_svc_map_.end()) {
- return AlternativeServiceInfoVector();
- }
- map_it = server_info_map_.Get(
- CreateServerInfoKey(canonical->second, network_isolation_key));
- if (map_it == server_info_map_.end() ||
- !map_it->second.alternative_services.has_value()) {
- return AlternativeServiceInfoVector();
- }
- AlternativeServiceInfoVector* service_info =
- &map_it->second.alternative_services.value();
- for (auto it = service_info->begin(); it != service_info->end();) {
- if (it->expiration() < now) {
- it = service_info->erase(it);
- continue;
- }
- AlternativeService alternative_service(it->alternative_service());
- if (alternative_service.host.empty()) {
- alternative_service.host = canonical->second.host();
- if (IsAlternativeServiceBroken(alternative_service,
- network_isolation_key)) {
- ++it;
- continue;
- }
- alternative_service.host = origin.host();
- } else if (IsAlternativeServiceBroken(alternative_service,
- network_isolation_key)) {
- ++it;
- continue;
- }
- if (alternative_service.protocol == kProtoQUIC) {
- valid_alternative_service_infos.push_back(
- AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
- alternative_service, it->expiration(),
- it->advertised_versions()));
- } else {
- valid_alternative_service_infos.push_back(
- AlternativeServiceInfo::CreateHttp2AlternativeServiceInfo(
- alternative_service, it->expiration()));
- }
- ++it;
- }
- if (service_info->empty())
- server_info_map_.EraseIfEmpty(map_it);
- return valid_alternative_service_infos;
- }
- void HttpServerProperties::SetAlternativeServicesInternal(
- const url::SchemeHostPort& origin,
- const net::NetworkIsolationKey& network_isolation_key,
- const AlternativeServiceInfoVector& alternative_service_info_vector) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(origin.scheme(), url::kWsScheme);
- DCHECK_NE(origin.scheme(), url::kWssScheme);
- if (alternative_service_info_vector.empty()) {
- RemoveAltSvcCanonicalHost(origin, network_isolation_key);
- // Don't bother moving to front when erasing information.
- auto it = server_info_map_.Peek(
- CreateServerInfoKey(origin, network_isolation_key));
- if (it == server_info_map_.end() ||
- !it->second.alternative_services.has_value()) {
- return;
- }
- it->second.alternative_services.reset();
- server_info_map_.EraseIfEmpty(it);
- MaybeQueueWriteProperties();
- return;
- }
- auto it = server_info_map_.GetOrPut(
- CreateServerInfoKey(origin, network_isolation_key));
- bool need_update_pref = true;
- if (it->second.alternative_services.has_value()) {
- DCHECK(!it->second.empty());
- if (it->second.alternative_services->size() ==
- alternative_service_info_vector.size()) {
- const base::Time now = clock_->Now();
- need_update_pref = false;
- auto new_it = alternative_service_info_vector.begin();
- for (const auto& old : *it->second.alternative_services) {
- // Persist to disk immediately if new entry has different scheme, host,
- // or port.
- if (old.alternative_service() != new_it->alternative_service()) {
- need_update_pref = true;
- break;
- }
- // Also persist to disk if new expiration it more that twice as far or
- // less than half as far in the future.
- base::Time old_time = old.expiration();
- base::Time new_time = new_it->expiration();
- if (new_time - now > 2 * (old_time - now) ||
- 2 * (new_time - now) < (old_time - now)) {
- need_update_pref = true;
- break;
- }
- // Also persist to disk if new entry has a different list of advertised
- // versions.
- if (old.advertised_versions() != new_it->advertised_versions()) {
- need_update_pref = true;
- break;
- }
- ++new_it;
- }
- }
- }
- const bool previously_no_alternative_services =
- (GetIteratorWithAlternativeServiceInfo(origin, network_isolation_key) ==
- server_info_map_.end());
- it->second.alternative_services = alternative_service_info_vector;
- if (previously_no_alternative_services &&
- !GetAlternativeServiceInfos(origin, network_isolation_key).empty()) {
- // TODO(rch): Consider the case where multiple requests are started
- // before the first completes. In this case, only one of the jobs
- // would reach this code, whereas all of them should should have.
- HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING,
- IsGoogleHost(origin.host()));
- }
- // If this host ends with a canonical suffix, then set it as the
- // canonical host.
- const char* kCanonicalScheme = "https";
- if (origin.scheme() == kCanonicalScheme) {
- const std::string* canonical_suffix = GetCanonicalSuffix(origin.host());
- if (canonical_suffix != nullptr) {
- url::SchemeHostPort canonical_server(kCanonicalScheme, *canonical_suffix,
- origin.port());
- canonical_alt_svc_map_[CreateServerInfoKey(
- canonical_server, network_isolation_key)] = origin;
- }
- }
- if (need_update_pref)
- MaybeQueueWriteProperties();
- }
- void HttpServerProperties::SetServerNetworkStatsInternal(
- url::SchemeHostPort server,
- const NetworkIsolationKey& network_isolation_key,
- ServerNetworkStats stats) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(server.scheme(), url::kWsScheme);
- DCHECK_NE(server.scheme(), url::kWssScheme);
- auto server_info = server_info_map_.GetOrPut(
- CreateServerInfoKey(std::move(server), network_isolation_key));
- bool changed = !server_info->second.server_network_stats.has_value() ||
- server_info->second.server_network_stats.value() != stats;
- if (changed) {
- server_info->second.server_network_stats = stats;
- MaybeQueueWriteProperties();
- }
- }
- void HttpServerProperties::ClearServerNetworkStatsInternal(
- url::SchemeHostPort server,
- const NetworkIsolationKey& network_isolation_key) {
- auto server_info = server_info_map_.Peek(
- CreateServerInfoKey(std::move(server), network_isolation_key));
- // If stats are empty, nothing to do.
- if (server_info == server_info_map_.end() ||
- !server_info->second.server_network_stats.has_value()) {
- return;
- }
- // Otherwise, clear and delete if needed. No need to bring to front of MRU
- // cache when clearing data.
- server_info->second.server_network_stats.reset();
- if (server_info->second.empty())
- server_info_map_.EraseIfEmpty(server_info);
- MaybeQueueWriteProperties();
- }
- const ServerNetworkStats* HttpServerProperties::GetServerNetworkStatsInternal(
- url::SchemeHostPort server,
- const NetworkIsolationKey& network_isolation_key) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK_NE(server.scheme(), url::kWsScheme);
- DCHECK_NE(server.scheme(), url::kWssScheme);
- auto server_info = server_info_map_.Get(
- CreateServerInfoKey(std::move(server), network_isolation_key));
- if (server_info == server_info_map_.end() ||
- !server_info->second.server_network_stats.has_value()) {
- return nullptr;
- }
- return &server_info->second.server_network_stats.value();
- }
- HttpServerProperties::QuicServerInfoMapKey
- HttpServerProperties::CreateQuicServerInfoKey(
- const quic::QuicServerId& server_id,
- const NetworkIsolationKey& network_isolation_key) const {
- return QuicServerInfoMapKey(server_id, network_isolation_key,
- use_network_isolation_key_);
- }
- HttpServerProperties::ServerInfoMapKey
- HttpServerProperties::CreateServerInfoKey(
- const url::SchemeHostPort& server,
- const NetworkIsolationKey& network_isolation_key) const {
- return ServerInfoMapKey(server, network_isolation_key,
- use_network_isolation_key_);
- }
- HttpServerProperties::ServerInfoMap::const_iterator
- HttpServerProperties::GetIteratorWithAlternativeServiceInfo(
- const url::SchemeHostPort& server,
- const net::NetworkIsolationKey& network_isolation_key) {
- ServerInfoMap::const_iterator it =
- server_info_map_.Get(CreateServerInfoKey(server, network_isolation_key));
- if (it != server_info_map_.end() && it->second.alternative_services)
- return it;
- auto canonical = GetCanonicalAltSvcHost(server, network_isolation_key);
- if (canonical == canonical_alt_svc_map_.end()) {
- return server_info_map_.end();
- }
- const url::SchemeHostPort canonical_server = canonical->second;
- it = server_info_map_.Get(
- CreateServerInfoKey(canonical_server, network_isolation_key));
- if (it == server_info_map_.end() || !it->second.alternative_services)
- return server_info_map_.end();
- for (const AlternativeServiceInfo& alternative_service_info :
- it->second.alternative_services.value()) {
- AlternativeService alternative_service(
- alternative_service_info.alternative_service());
- if (alternative_service.host.empty()) {
- alternative_service.host = canonical_server.host();
- }
- if (!IsAlternativeServiceBroken(alternative_service,
- network_isolation_key)) {
- return it;
- }
- }
- RemoveAltSvcCanonicalHost(canonical_server, network_isolation_key);
- return server_info_map_.end();
- }
- HttpServerProperties::CanonicalMap::const_iterator
- HttpServerProperties::GetCanonicalAltSvcHost(
- const url::SchemeHostPort& server,
- const net::NetworkIsolationKey& network_isolation_key) const {
- const char* kCanonicalScheme = "https";
- if (server.scheme() != kCanonicalScheme)
- return canonical_alt_svc_map_.end();
- const std::string* canonical_suffix = GetCanonicalSuffix(server.host());
- if (canonical_suffix == nullptr)
- return canonical_alt_svc_map_.end();
- url::SchemeHostPort canonical_server(kCanonicalScheme, *canonical_suffix,
- server.port());
- return canonical_alt_svc_map_.find(
- CreateServerInfoKey(canonical_server, network_isolation_key));
- }
- HttpServerProperties::QuicCanonicalMap::const_iterator
- HttpServerProperties::GetCanonicalServerInfoHost(
- const QuicServerInfoMapKey& key) const {
- const std::string* canonical_suffix =
- GetCanonicalSuffix(key.server_id.host());
- if (canonical_suffix == nullptr)
- return canonical_server_info_map_.end();
- quic::QuicServerId canonical_server_id(*canonical_suffix,
- key.server_id.privacy_mode_enabled(),
- key.server_id.port());
- return canonical_server_info_map_.find(
- CreateQuicServerInfoKey(canonical_server_id, key.network_isolation_key));
- }
- void HttpServerProperties::RemoveAltSvcCanonicalHost(
- const url::SchemeHostPort& server,
- const NetworkIsolationKey& network_isolation_key) {
- auto canonical = GetCanonicalAltSvcHost(server, network_isolation_key);
- if (canonical == canonical_alt_svc_map_.end())
- return;
- canonical_alt_svc_map_.erase(canonical->first);
- }
- void HttpServerProperties::UpdateCanonicalServerInfoMap(
- const QuicServerInfoMapKey& key) {
- const std::string* suffix = GetCanonicalSuffix(key.server_id.host());
- if (!suffix)
- return;
- quic::QuicServerId canonical_server(
- *suffix, key.server_id.privacy_mode_enabled(), key.server_id.port());
- canonical_server_info_map_[CreateQuicServerInfoKey(
- canonical_server, key.network_isolation_key)] = key.server_id;
- }
- const std::string* HttpServerProperties::GetCanonicalSuffix(
- const std::string& host) const {
- // If this host ends with a canonical suffix, then return the canonical
- // suffix.
- for (const std::string& canonical_suffix : canonical_suffixes_) {
- if (base::EndsWith(host, canonical_suffix,
- base::CompareCase::INSENSITIVE_ASCII)) {
- return &canonical_suffix;
- }
- }
- return nullptr;
- }
- void HttpServerProperties::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) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!is_initialized_);
- // Either all of these are nullptr, or none of them are (except the broken alt
- // service fields).
- if (server_info_map) {
- OnServerInfoLoaded(std::move(server_info_map));
- OnLastLocalAddressWhenQuicWorkedLoaded(last_local_address_when_quic_worked);
- OnQuicServerInfoMapLoaded(std::move(quic_server_info_map));
- if (recently_broken_alternative_services) {
- DCHECK(broken_alternative_service_list);
- OnBrokenAndRecentlyBrokenAlternativeServicesLoaded(
- std::move(broken_alternative_service_list),
- std::move(recently_broken_alternative_services));
- }
- }
- is_initialized_ = true;
- if (queue_write_on_load_) {
- // Leaving this as true doesn't actually have any effect, but seems best to
- // be safe.
- queue_write_on_load_ = false;
- MaybeQueueWriteProperties();
- }
- }
- void HttpServerProperties::OnServerInfoLoaded(
- std::unique_ptr<ServerInfoMap> server_info_map) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- // Perform a simple sanity check on loaded data, when DCHECKs are enabled.
- #if DCHECK_IS_ON()
- if (!use_network_isolation_key_) {
- for (auto server_info = server_info_map->begin();
- server_info != server_info_map->end(); ++server_info) {
- DCHECK(server_info->first.network_isolation_key.IsEmpty());
- }
- }
- #endif // DCHECK_IS_ON()
- // Swap in the entries from persisted data. This allows the MRU cache to be
- // sorted based on the order of the entries in the newer in-memory cache.
- server_info_map_.Swap(*server_info_map);
- // Add the entries from the memory cache.
- for (auto& [key, server_info] : base::Reversed(*server_info_map)) {
- // If there's no corresponding old entry, add the new entry directly.
- auto old_entry = server_info_map_.Get(key);
- if (old_entry == server_info_map_.end()) {
- server_info_map_.Put(key, std::move(server_info));
- continue;
- }
- // Otherwise, merge the old and new entries. Prefer values from older
- // entries.
- if (!old_entry->second.supports_spdy.has_value())
- old_entry->second.supports_spdy = server_info.supports_spdy;
- if (!old_entry->second.alternative_services.has_value())
- old_entry->second.alternative_services = server_info.alternative_services;
- if (!old_entry->second.server_network_stats.has_value())
- old_entry->second.server_network_stats = server_info.server_network_stats;
- // |requires_http11| isn't saved to prefs, so the loaded entry should not
- // have it set. Unconditionally copy it from the new entry.
- DCHECK(!old_entry->second.requires_http11.has_value());
- old_entry->second.requires_http11 = server_info.requires_http11;
- }
- // Attempt to find canonical servers. Canonical suffix only apply to HTTPS.
- const uint16_t kCanonicalPort = 443;
- const char* kCanonicalScheme = "https";
- for (const auto& it : server_info_map_) {
- if (!it.second.alternative_services ||
- it.first.server.scheme() != kCanonicalScheme) {
- continue;
- }
- const std::string* canonical_suffix =
- GetCanonicalSuffix(it.first.server.host());
- if (!canonical_suffix)
- continue;
- ServerInfoMapKey key = CreateServerInfoKey(
- url::SchemeHostPort(kCanonicalScheme, *canonical_suffix,
- kCanonicalPort),
- it.first.network_isolation_key);
- // If we already have a valid canonical server, we're done.
- if (base::Contains(canonical_alt_svc_map_, key)) {
- auto key_it = server_info_map_.Peek(key);
- if (key_it != server_info_map_.end() &&
- key_it->second.alternative_services.has_value()) {
- continue;
- }
- }
- canonical_alt_svc_map_[key] = it.first.server;
- }
- }
- void HttpServerProperties::OnLastLocalAddressWhenQuicWorkedLoaded(
- const IPAddress& last_local_address_when_quic_worked) {
- last_local_address_when_quic_worked_ = last_local_address_when_quic_worked;
- }
- void HttpServerProperties::OnQuicServerInfoMapLoaded(
- std::unique_ptr<QuicServerInfoMap> quic_server_info_map) {
- DCHECK_EQ(quic_server_info_map->max_size(), quic_server_info_map_.max_size());
- // Add the entries from persisted data.
- quic_server_info_map_.Swap(*quic_server_info_map);
- // Add the entries from the memory cache.
- for (const auto& [key, server_info] : base::Reversed(*quic_server_info_map)) {
- if (quic_server_info_map_.Get(key) == quic_server_info_map_.end()) {
- quic_server_info_map_.Put(key, server_info);
- }
- }
- // Repopulate |canonical_server_info_map_| to stay in sync with
- // |quic_server_info_map_|.
- canonical_server_info_map_.clear();
- for (const auto& [key, server_info] : base::Reversed(quic_server_info_map_)) {
- UpdateCanonicalServerInfoMap(key);
- }
- }
- void HttpServerProperties::OnBrokenAndRecentlyBrokenAlternativeServicesLoaded(
- std::unique_ptr<BrokenAlternativeServiceList>
- broken_alternative_service_list,
- std::unique_ptr<RecentlyBrokenAlternativeServices>
- recently_broken_alternative_services) {
- broken_alternative_services_.SetBrokenAndRecentlyBrokenAlternativeServices(
- std::move(broken_alternative_service_list),
- std::move(recently_broken_alternative_services));
- }
- void HttpServerProperties::MaybeQueueWriteProperties() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (prefs_update_timer_.IsRunning() || !properties_manager_)
- return;
- if (!is_initialized_) {
- queue_write_on_load_ = true;
- return;
- }
- prefs_update_timer_.Start(
- FROM_HERE, kUpdatePrefsDelay,
- base::BindOnce(&HttpServerProperties::WriteProperties,
- base::Unretained(this), base::OnceClosure()));
- }
- void HttpServerProperties::WriteProperties(base::OnceClosure callback) const {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(properties_manager_);
- // |this| shouldn't be waiting to load properties cached to disk when this
- // method is invoked, since this method will overwrite any cached properties.
- DCHECK(is_initialized_);
- // There shouldn't be a queued update when this is run, since this method
- // removes the need for any update to be queued.
- DCHECK(!prefs_update_timer_.IsRunning());
- properties_manager_->WriteToPrefs(
- server_info_map_,
- base::BindRepeating(&HttpServerProperties::GetCanonicalSuffix,
- base::Unretained(this)),
- last_local_address_when_quic_worked_, quic_server_info_map_,
- broken_alternative_services_.broken_alternative_service_list(),
- broken_alternative_services_.recently_broken_alternative_services(),
- std::move(callback));
- }
- } // namespace net
|