blob: 431623a493bf469bb7562d43bbd5ddac65402659 [file] [log] [blame]
// Copyright 2022 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 "services/network/cache_transparency_settings.h"
#include <iterator>
#include <utility>
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/string_split.h"
#include "services/network/public/cpp/features.h"
namespace network {
CacheTransparencySettings::CacheTransparencySettings()
: cache_transparency_enabled_(
base::FeatureList::IsEnabled(features::kCacheTransparency) &&
base::FeatureList::IsEnabled(features::kPervasivePayloadsList)),
pervasive_payloads_enabled_(
base::FeatureList::IsEnabled(features::kPervasivePayloadsList)),
map_(pervasive_payloads_enabled_ ? CreateMap() : PervasivePayloadsMap()) {
}
CacheTransparencySettings::~CacheTransparencySettings() = default;
absl::optional<int> CacheTransparencySettings::GetIndexForURL(
const GURL& url) const {
if (!pervasive_payloads_enabled_ || !url.is_valid())
return absl::nullopt;
auto it = map_.find(url.spec());
if (it == map_.end()) {
return absl::nullopt;
}
return std::distance(map_.begin(), it);
}
absl::optional<std::string> CacheTransparencySettings::GetChecksumForURL(
const GURL& url) const {
if (!cache_transparency_enabled_ || !url.is_valid())
return absl::nullopt;
auto it = map_.find(url.spec());
if (it == map_.end()) {
return absl::nullopt;
}
return it->second;
}
// static
CacheTransparencySettings::PervasivePayloadsMap
CacheTransparencySettings::CreateMap() {
const std::string comma_separated =
features::kCacheTransparencyPervasivePayloads.Get();
auto split = base::SplitStringPiece(
comma_separated, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
if (split.empty()) {
// The code below safely produces an empty map in this case.
DLOG(WARNING) << "Pervasive payload list is empty.";
} else {
// The number of items cannot be large, so this O(N) algorithm is
// acceptable.
split.erase(split.begin());
}
if (split.size() % 2 == 1) {
DLOG(WARNING)
<< "Pervasive payload list contains an odd number of elements."
<< comma_separated;
}
using Container = PervasivePayloadsMap::container_type;
Container pairs;
pairs.reserve(split.size() / 2);
// `split` has to fit in memory, therefore split.size() cannot be the
// largest possible value, therefore adding 1 to i will not overflow.
for (size_t i = 0; i + 1 < split.size(); i += 2) {
pairs.emplace_back(split[i], split[i + 1]);
}
return PervasivePayloadsMap(std::move(pairs));
}
} // namespace network