12#include <userver/utils/small_string_fwd.hpp>
13#include <userver/utils/string_literal.hpp>
14#include <userver/utils/trivial_map.hpp>
16USERVER_NAMESPACE_BEGIN
22inline constexpr std::size_t kTypicalHeadersSize = 1024;
23using HeadersString =
utils::SmallString<kTypicalHeadersSize>;
32struct UnsafeConstexprHasher
final {
33 constexpr std::size_t operator()(std::string_view str)
const noexcept {
34 constexpr std::uint64_t mul = (0xc6a4a793UL << 32UL) + 0x5bd1e995UL;
36 std::uint64_t hash = seed_ ^ (str.size() * mul);
37 while (str.size() >= 8) {
38 const std::uint64_t data = ShiftMix(Load8(str.data()) * mul) * mul;
45 const std::uint64_t data = LoadN(str.data(), str.size());
50 hash = ShiftMix(hash) * mul;
51 hash = ShiftMix(hash);
56 static constexpr inline std::uint64_t ShiftMix(std::uint64_t v)
noexcept {
return v ^ (v >> 47); }
58 static constexpr inline std::uint64_t Load8(
const char* data)
noexcept {
return LoadN(data, 8); }
60 static constexpr inline std::uint64_t LoadN(
const char* data, std::size_t n)
noexcept {
67 constexpr std::uint64_t kDeliberatelyBrokenLowercaseMask = 0x2020202020202020UL;
69 std::uint64_t result = kDeliberatelyBrokenLowercaseMask >> (8 * (8 - n));
70 for (std::size_t i = 0; i < n; ++i) {
71 const std::uint8_t c = data[i];
72 result |=
static_cast<std::uint64_t>(c) << (8 * i);
84 std::uint64_t seed_{54999};
88inline constexpr utils::TrivialBiMap kKnownHeadersLowercaseMap = [](
auto selector) {
90 .Case(
"content-type", std::int8_t{1})
91 .Case(
"content-encoding", 2)
92 .Case(
"content-length", 3)
93 .Case(
"transfer-encoding", 4)
96 .Case(
"accept-encoding", 7)
97 .Case(
"accept-language", 8)
98 .Case(
"x-yataxi-api-key", 9)
99 .Case(
"user-agent", 10)
100 .Case(
"x-request-application", 11)
103 .Case(
"access-control-allow-headers", 14)
106 .Case(
"set-cookie", 17)
107 .Case(
"connection", 18)
109 .Case(
"x-yarequestid", 20)
110 .Case(
"x-yatraceid", 21)
111 .Case(
"x-yaspanid", 22)
112 .Case(
"x-requestid", 23)
113 .Case(
"x-backend-server", 24)
114 .Case(
"x-taxi-envoyproxy-dstvhost", 25)
116 .Case(
"x-yataxi-allow-auth-request", 27)
117 .Case(
"x-yataxi-allow-auth-response", 28)
118 .Case(
"x-yataxi-server-hostname", 29)
119 .Case(
"x-yataxi-client-timeoutms", 30)
120 .Case(
"x-yataxi-deadline-expired", 31)
121 .Case(
"x-yataxi-ratelimited-by", 32)
122 .Case(
"x-yataxi-ratelimit-reason", 33)
123 .Case(
"x-b3-traceid", 34)
124 .Case(
"x-b3-spanid", 35)
125 .Case(
"x-b3-sampled", 36)
126 .Case(
"x-b3-parentspanid", 37)
127 .Case(
"traceparent", 38)
128 .Case(
"tracestate", 39)
129 .Case(
"http2-settings", 40)
132 .Case(
"x-request-deadline", 43);
137inline constexpr std::int8_t kNoHeaderIndexLookup = -1;
138inline constexpr std::int8_t kNoHeaderIndexInsertion = -2;
139static_assert(kNoHeaderIndexLookup != kNoHeaderIndexInsertion);
140static_assert(kNoHeaderIndexLookup != 0 && kNoHeaderIndexInsertion != 0);
143constexpr std::int8_t GetHeaderIndexForLookup(std::string_view key) {
145 return opt.value_or(kNoHeaderIndexLookup);
151inline std::int8_t GetHeaderIndexForInsertion(std::string_view key) {
153 return opt.value_or(kNoHeaderIndexInsertion);
173class PredefinedHeader
final {
177 hash_{impl::UnsafeConstexprHasher{}(name)},
178 header_index_{impl::GetHeaderIndexForLookup(name)}
185 constexpr operator std::string_view()
const {
return name_; }
187 explicit operator std::string()
const {
return std::string{name_}; }
197 const std::size_t hash_;
205 const std::int8_t header_index_;
213struct fmt::formatter<USERVER_NAMESPACE::http::
headers::PredefinedHeader> : fmt::formatter<std::string_view> {
214 template <
typename FormatContext>
215 auto format(
const USERVER_NAMESPACE::http::
headers::PredefinedHeader& value, FormatContext& ctx)
const
216 ->
decltype(ctx.out()) {
217 return fmt::format_to(ctx.out(),
"{}", std::string_view{value});