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 { ...@@ -254,9 +254,9 @@ class flat_tree {
void clear(); void clear();
size_type size() const; constexpr size_type size() const;
size_type max_size() const; constexpr size_type max_size() const;
bool empty() const; constexpr bool empty() const;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Iterators. // Iterators.
...@@ -681,19 +681,21 @@ void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::clear() { ...@@ -681,19 +681,21 @@ void flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::clear() {
} }
template <class Key, class GetKeyFromValue, class KeyCompare, class Container> template <class Key, class GetKeyFromValue, class KeyCompare, class Container>
auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::size() const constexpr auto flat_tree<Key, GetKeyFromValue, KeyCompare, Container>::size()
-> size_type { const -> size_type {
return body_.size(); return body_.size();
} }
template <class Key, class GetKeyFromValue, class KeyCompare, class Container> 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 { -> size_type {
return body_.max_size(); return body_.max_size();
} }
template <class Key, class GetKeyFromValue, class KeyCompare, class Container> 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(); return body_.empty();
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/containers/adapters.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/macros.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "base/ranges/algorithm.h" #include "base/ranges/algorithm.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -126,9 +127,9 @@ bool IsStringLowerCaseASCII(base::StringPiece s) { ...@@ -126,9 +127,9 @@ bool IsStringLowerCaseASCII(base::StringPiece s) {
return std::none_of(s.begin(), s.end(), base::IsAsciiUpper<char>); return std::none_of(s.begin(), s.end(), base::IsAsciiUpper<char>);
} }
using RequestHeaderEntry = std::pair<const char*, RequestHeaderType>; constexpr auto kRequestHeaderEntries =
constexpr RequestHeaderEntry kRequestHeaderEntries[] = { base::MakeFixedFlatMap<base::StringPiece, RequestHeaderType>(
{"accept", RequestHeaderType::kAccept}, {{"accept", RequestHeaderType::kAccept},
{"accept-charset", RequestHeaderType::kAcceptCharset}, {"accept-charset", RequestHeaderType::kAcceptCharset},
{"accept-encoding", RequestHeaderType::kAcceptEncoding}, {"accept-encoding", RequestHeaderType::kAcceptEncoding},
{"accept-language", RequestHeaderType::kAcceptLanguage}, {"accept-language", RequestHeaderType::kAcceptLanguage},
...@@ -167,20 +168,18 @@ constexpr RequestHeaderEntry kRequestHeaderEntries[] = { ...@@ -167,20 +168,18 @@ constexpr RequestHeaderEntry kRequestHeaderEntries[] = {
{"te", RequestHeaderType::kTe}, {"te", RequestHeaderType::kTe},
{"transfer-encoding", RequestHeaderType::kTransferEncoding}, {"transfer-encoding", RequestHeaderType::kTransferEncoding},
{"upgrade", RequestHeaderType::kUpgrade}, {"upgrade", RequestHeaderType::kUpgrade},
{"upgrade-insecure-requests", RequestHeaderType::kUpgradeInsecureRequests}, {"upgrade-insecure-requests",
RequestHeaderType::kUpgradeInsecureRequests},
{"user-agent", RequestHeaderType::kUserAgent}, {"user-agent", RequestHeaderType::kUserAgent},
{"via", RequestHeaderType::kVia}, {"via", RequestHeaderType::kVia},
{"warning", RequestHeaderType::kWarning}, {"warning", RequestHeaderType::kWarning},
{"x-forwarded-for", RequestHeaderType::kXForwardedFor}, {"x-forwarded-for", RequestHeaderType::kXForwardedFor},
{"x-forwarded-host", RequestHeaderType::kXForwardedHost}, {"x-forwarded-host", RequestHeaderType::kXForwardedHost},
{"x-forwarded-proto", RequestHeaderType::kXForwardedProto}}; {"x-forwarded-proto", RequestHeaderType::kXForwardedProto}});
constexpr bool IsValidHeaderName(const char* str) { constexpr bool IsValidHeaderName(base::StringPiece str) {
while (*str) { for (char ch : str) {
if ((*str >= 'a' && *str <= 'z') || *str == '-') { if ((ch < 'a' || ch > 'z') && ch != '-')
str++;
continue;
}
return false; return false;
} }
return true; return true;
...@@ -188,8 +187,8 @@ constexpr bool IsValidHeaderName(const char* str) { ...@@ -188,8 +187,8 @@ constexpr bool IsValidHeaderName(const char* str) {
template <typename T> template <typename T>
constexpr bool ValidateHeaderEntries(const T& entries) { constexpr bool ValidateHeaderEntries(const T& entries) {
for (size_t i = 0; i < base::size(entries); ++i) { for (const auto& entry : entries) {
if (!IsValidHeaderName(entries[i].first)) if (!IsValidHeaderName(entry.first))
return false; return false;
} }
return true; return true;
...@@ -201,7 +200,7 @@ constexpr bool ValidateHeaderEntries(const T& entries) { ...@@ -201,7 +200,7 @@ constexpr bool ValidateHeaderEntries(const T& entries) {
// sec-origin-policy which does not have a corresponding entry in // sec-origin-policy which does not have a corresponding entry in
// kRequestHeaderEntries but does contribute to RequestHeaderType::kMaxValue. // kRequestHeaderEntries but does contribute to RequestHeaderType::kMaxValue.
static_assert(static_cast<size_t>(RequestHeaderType::kMaxValue) - 2 == static_assert(static_cast<size_t>(RequestHeaderType::kMaxValue) - 2 ==
base::size(kRequestHeaderEntries), kRequestHeaderEntries.size(),
"Invalid number of request header entries"); "Invalid number of request header entries");
static_assert(ValidateHeaderEntries(kRequestHeaderEntries), static_assert(ValidateHeaderEntries(kRequestHeaderEntries),
...@@ -211,20 +210,10 @@ static_assert(ValidateHeaderEntries(kRequestHeaderEntries), ...@@ -211,20 +210,10 @@ static_assert(ValidateHeaderEntries(kRequestHeaderEntries),
// returned. // returned.
void RecordRequestHeader(const std::string& header, void RecordRequestHeader(const std::string& header,
void (*record_func)(RequestHeaderType)) { 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)); DCHECK(IsStringLowerCaseASCII(header));
auto it = kHeaderMap->find(header); const auto* it = kRequestHeaderEntries.find(header);
RequestHeaderType type = record_func(it != kRequestHeaderEntries.end() ? it->second
it != kHeaderMap->end() ? it->second : RequestHeaderType::kOther; : RequestHeaderType::kOther);
record_func(type);
} }
void RecordResponseHeaderChanged(ResponseHeaderType type) { void RecordResponseHeaderChanged(ResponseHeaderType type) {
...@@ -256,8 +245,8 @@ void RecordDNRResponseHeaderRemoved(ResponseHeaderType type) { ...@@ -256,8 +245,8 @@ void RecordDNRResponseHeaderRemoved(ResponseHeaderType type) {
"Extensions.DeclarativeNetRequest.ResponseHeaderRemoved", type); "Extensions.DeclarativeNetRequest.ResponseHeaderRemoved", type);
} }
using ResponseHeaderEntry = std::pair<const char*, ResponseHeaderType>; constexpr auto kResponseHeaderEntries =
constexpr ResponseHeaderEntry kResponseHeaderEntries[] = { base::MakeFixedFlatMap<base::StringPiece, ResponseHeaderType>({
{"accept-patch", ResponseHeaderType::kAcceptPatch}, {"accept-patch", ResponseHeaderType::kAcceptPatch},
{"accept-ranges", ResponseHeaderType::kAcceptRanges}, {"accept-ranges", ResponseHeaderType::kAcceptRanges},
{"access-control-allow-credentials", {"access-control-allow-credentials",
...@@ -310,7 +299,8 @@ constexpr ResponseHeaderEntry kResponseHeaderEntries[] = { ...@@ -310,7 +299,8 @@ constexpr ResponseHeaderEntry kResponseHeaderEntries[] = {
{"server-timing", ResponseHeaderType::kServerTiming}, {"server-timing", ResponseHeaderType::kServerTiming},
{"set-cookie", ResponseHeaderType::kSetCookie}, {"set-cookie", ResponseHeaderType::kSetCookie},
{"sourcemap", ResponseHeaderType::kSourceMap}, {"sourcemap", ResponseHeaderType::kSourceMap},
{"strict-transport-security", ResponseHeaderType::kStrictTransportSecurity}, {"strict-transport-security",
ResponseHeaderType::kStrictTransportSecurity},
{"timing-allow-origin", ResponseHeaderType::kTimingAllowOrigin}, {"timing-allow-origin", ResponseHeaderType::kTimingAllowOrigin},
{"tk", ResponseHeaderType::kTk}, {"tk", ResponseHeaderType::kTk},
{"trailer", ResponseHeaderType::kTrailer}, {"trailer", ResponseHeaderType::kTrailer},
...@@ -324,29 +314,19 @@ constexpr ResponseHeaderEntry kResponseHeaderEntries[] = { ...@@ -324,29 +314,19 @@ constexpr ResponseHeaderEntry kResponseHeaderEntries[] = {
{"x-dns-prefetch-control", ResponseHeaderType::kXDNSPrefetchControl}, {"x-dns-prefetch-control", ResponseHeaderType::kXDNSPrefetchControl},
{"x-frame-options", ResponseHeaderType::kXFrameOptions}, {"x-frame-options", ResponseHeaderType::kXFrameOptions},
{"x-xss-protection", ResponseHeaderType::kXXSSProtection}, {"x-xss-protection", ResponseHeaderType::kXXSSProtection},
}; });
void RecordResponseHeader(base::StringPiece header, void RecordResponseHeader(base::StringPiece header,
void (*record_func)(ResponseHeaderType)) { 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)); DCHECK(IsStringLowerCaseASCII(header));
auto it = kHeaderMap->find(header); const auto* it = kResponseHeaderEntries.find(header);
ResponseHeaderType type = record_func(it != kResponseHeaderEntries.end() ? it->second
it != kHeaderMap->end() ? it->second : ResponseHeaderType::kOther; : ResponseHeaderType::kOther);
record_func(type);
} }
// All entries other than kOther and kNone are mapped. // All entries other than kOther and kNone are mapped.
static_assert(static_cast<size_t>(ResponseHeaderType::kMaxValue) - 1 == static_assert(static_cast<size_t>(ResponseHeaderType::kMaxValue) - 1 ==
base::size(kResponseHeaderEntries), kResponseHeaderEntries.size(),
"Invalid number of response header entries"); "Invalid number of response header entries");
static_assert(ValidateHeaderEntries(kResponseHeaderEntries), 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