Commit 09774812 authored by Jeremy Roman's avatar Jeremy Roman Committed by Chromium LUCI CQ

extensions: Move RecordRequestHeader and RecordResponseHeader to fixed_flat_map.

Rather than copy to the heap to make a dynamically modifiable flat_map,
we can build the map into .data.rel.ro at compile time.

To support current static_assert, base::flat_tree::size is made
constexpr if the underlying collection is, as it is for fixed_flat_map
and fixed_flat_set (specifically, std::array).
For consistency, max_size and empty are similarly updated.

Bug: None
Change-Id: Ia21850b48e928e328f9cb85702b561925cca2d3e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2566034Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Auto-Submit: Jeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832358}
parent a8cac9ec
......@@ -254,9 +254,9 @@ class flat_tree {
void clear();
size_type size() const;
size_type max_size() const;
bool empty() const;
constexpr size_type size() const;
constexpr size_type max_size() const;
constexpr bool empty() const;
// --------------------------------------------------------------------------
// Iterators.
......@@ -681,19 +681,21 @@ void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::clear() {
}
template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::size() const
-> size_type {
constexpr auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::size()
const -> size_type {
return body_.size();
}
template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::max_size() const
constexpr auto
flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::max_size() const
-> size_type {
return body_.max_size();
}
template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
bool flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::empty() const {
constexpr bool flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::empty()
const {
return body_.empty();
}
......
......@@ -14,7 +14,7 @@
#include "base/bind.h"
#include "base/containers/adapters.h"
#include "base/containers/flat_map.h"
#include "base/containers/fixed_flat_map.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
......@@ -22,6 +22,7 @@
#include "base/ranges/algorithm.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
......@@ -126,9 +127,9 @@ bool IsStringLowerCaseASCII(base::StringPiece s) {
return std::none_of(s.begin(), s.end(), base::IsAsciiUpper<char>);
}
using RequestHeaderEntry = std::pair<const char*, RequestHeaderType>;
constexpr RequestHeaderEntry kRequestHeaderEntries[] = {
{"accept", RequestHeaderType::kAccept},
constexpr auto kRequestHeaderEntries =
base::MakeFixedFlatMap<base::StringPiece, RequestHeaderType>(
{{"accept", RequestHeaderType::kAccept},
{"accept-charset", RequestHeaderType::kAcceptCharset},
{"accept-encoding", RequestHeaderType::kAcceptEncoding},
{"accept-language", RequestHeaderType::kAcceptLanguage},
......@@ -167,20 +168,18 @@ constexpr RequestHeaderEntry kRequestHeaderEntries[] = {
{"te", RequestHeaderType::kTe},
{"transfer-encoding", RequestHeaderType::kTransferEncoding},
{"upgrade", RequestHeaderType::kUpgrade},
{"upgrade-insecure-requests", RequestHeaderType::kUpgradeInsecureRequests},
{"upgrade-insecure-requests",
RequestHeaderType::kUpgradeInsecureRequests},
{"user-agent", RequestHeaderType::kUserAgent},
{"via", RequestHeaderType::kVia},
{"warning", RequestHeaderType::kWarning},
{"x-forwarded-for", RequestHeaderType::kXForwardedFor},
{"x-forwarded-host", RequestHeaderType::kXForwardedHost},
{"x-forwarded-proto", RequestHeaderType::kXForwardedProto}};
{"x-forwarded-proto", RequestHeaderType::kXForwardedProto}});
constexpr bool IsValidHeaderName(const char* str) {
while (*str) {
if ((*str >= 'a' && *str <= 'z') || *str == '-') {
str++;
continue;
}
constexpr bool IsValidHeaderName(base::StringPiece str) {
for (char ch : str) {
if ((ch < 'a' || ch > 'z') && ch != '-')
return false;
}
return true;
......@@ -188,8 +187,8 @@ constexpr bool IsValidHeaderName(const char* str) {
template <typename T>
constexpr bool ValidateHeaderEntries(const T& entries) {
for (size_t i = 0; i < base::size(entries); ++i) {
if (!IsValidHeaderName(entries[i].first))
for (const auto& entry : entries) {
if (!IsValidHeaderName(entry.first))
return false;
}
return true;
......@@ -201,7 +200,7 @@ constexpr bool ValidateHeaderEntries(const T& entries) {
// sec-origin-policy which does not have a corresponding entry in
// kRequestHeaderEntries but does contribute to RequestHeaderType::kMaxValue.
static_assert(static_cast<size_t>(RequestHeaderType::kMaxValue) - 2 ==
base::size(kRequestHeaderEntries),
kRequestHeaderEntries.size(),
"Invalid number of request header entries");
static_assert(ValidateHeaderEntries(kRequestHeaderEntries),
......@@ -211,20 +210,10 @@ static_assert(ValidateHeaderEntries(kRequestHeaderEntries),
// returned.
void RecordRequestHeader(const std::string& header,
void (*record_func)(RequestHeaderType)) {
using HeaderMapType = base::flat_map<base::StringPiece, RequestHeaderType>;
static const base::NoDestructor<HeaderMapType> kHeaderMap([] {
std::vector<std::pair<base::StringPiece, RequestHeaderType>> entries;
entries.reserve(base::size(kRequestHeaderEntries));
for (const auto& entry : kRequestHeaderEntries)
entries.emplace_back(entry.first, entry.second);
return HeaderMapType(entries.begin(), entries.end());
}());
DCHECK(IsStringLowerCaseASCII(header));
auto it = kHeaderMap->find(header);
RequestHeaderType type =
it != kHeaderMap->end() ? it->second : RequestHeaderType::kOther;
record_func(type);
const auto* it = kRequestHeaderEntries.find(header);
record_func(it != kRequestHeaderEntries.end() ? it->second
: RequestHeaderType::kOther);
}
void RecordResponseHeaderChanged(ResponseHeaderType type) {
......@@ -256,8 +245,8 @@ void RecordDNRResponseHeaderRemoved(ResponseHeaderType type) {
"Extensions.DeclarativeNetRequest.ResponseHeaderRemoved", type);
}
using ResponseHeaderEntry = std::pair<const char*, ResponseHeaderType>;
constexpr ResponseHeaderEntry kResponseHeaderEntries[] = {
constexpr auto kResponseHeaderEntries =
base::MakeFixedFlatMap<base::StringPiece, ResponseHeaderType>({
{"accept-patch", ResponseHeaderType::kAcceptPatch},
{"accept-ranges", ResponseHeaderType::kAcceptRanges},
{"access-control-allow-credentials",
......@@ -310,7 +299,8 @@ constexpr ResponseHeaderEntry kResponseHeaderEntries[] = {
{"server-timing", ResponseHeaderType::kServerTiming},
{"set-cookie", ResponseHeaderType::kSetCookie},
{"sourcemap", ResponseHeaderType::kSourceMap},
{"strict-transport-security", ResponseHeaderType::kStrictTransportSecurity},
{"strict-transport-security",
ResponseHeaderType::kStrictTransportSecurity},
{"timing-allow-origin", ResponseHeaderType::kTimingAllowOrigin},
{"tk", ResponseHeaderType::kTk},
{"trailer", ResponseHeaderType::kTrailer},
......@@ -324,29 +314,19 @@ constexpr ResponseHeaderEntry kResponseHeaderEntries[] = {
{"x-dns-prefetch-control", ResponseHeaderType::kXDNSPrefetchControl},
{"x-frame-options", ResponseHeaderType::kXFrameOptions},
{"x-xss-protection", ResponseHeaderType::kXXSSProtection},
};
});
void RecordResponseHeader(base::StringPiece header,
void (*record_func)(ResponseHeaderType)) {
using HeaderMapType = base::flat_map<base::StringPiece, ResponseHeaderType>;
static const base::NoDestructor<HeaderMapType> kHeaderMap([] {
std::vector<std::pair<base::StringPiece, ResponseHeaderType>> entries;
entries.reserve(base::size(kResponseHeaderEntries));
for (const auto& entry : kResponseHeaderEntries)
entries.emplace_back(entry.first, entry.second);
return HeaderMapType(entries.begin(), entries.end());
}());
DCHECK(IsStringLowerCaseASCII(header));
auto it = kHeaderMap->find(header);
ResponseHeaderType type =
it != kHeaderMap->end() ? it->second : ResponseHeaderType::kOther;
record_func(type);
const auto* it = kResponseHeaderEntries.find(header);
record_func(it != kResponseHeaderEntries.end() ? it->second
: ResponseHeaderType::kOther);
}
// All entries other than kOther and kNone are mapped.
static_assert(static_cast<size_t>(ResponseHeaderType::kMaxValue) - 1 ==
base::size(kResponseHeaderEntries),
kResponseHeaderEntries.size(),
"Invalid number of response header entries");
static_assert(ValidateHeaderEntries(kResponseHeaderEntries),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment