File indexing completed on 2025-01-18 09:29:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_BEAST_HTTP_IMPL_FIELD_IPP
0011 #define BOOST_BEAST_HTTP_IMPL_FIELD_IPP
0012
0013 #include <boost/beast/http/field.hpp>
0014 #include <boost/assert.hpp>
0015 #include <algorithm>
0016 #include <array>
0017 #include <cstdint>
0018 #include <cstring>
0019 #include <ostream>
0020
0021
0022 namespace boost {
0023 namespace beast {
0024 namespace http {
0025
0026 namespace detail {
0027
0028 struct field_table
0029 {
0030 static
0031 std::uint32_t
0032 get_chars(
0033 unsigned char const* p) noexcept
0034 {
0035
0036
0037
0038
0039 return
0040 p[0] |
0041 (p[1] << 8) |
0042 (p[2] << 16) |
0043 (p[3] << 24);
0044 }
0045
0046 using array_type =
0047 std::array<string_view, 357>;
0048
0049
0050 static
0051 std::uint32_t
0052 digest(string_view s)
0053 {
0054 std::uint32_t r = 0;
0055 std::size_t n = s.size();
0056 auto p = reinterpret_cast<
0057 unsigned char const*>(s.data());
0058
0059
0060 while(n >= 4)
0061 {
0062 auto const v = get_chars(p);
0063 r = (r * 5 + (
0064 v | 0x20202020 ));
0065 p += 4;
0066 n -= 4;
0067 }
0068
0069 while( n > 0 )
0070 {
0071 r = r * 5 + ( *p | 0x20 );
0072 ++p;
0073 --n;
0074 }
0075 return r;
0076 }
0077
0078
0079
0080 static
0081 bool
0082 equals(string_view lhs, string_view rhs)
0083 {
0084 using Int = std::uint32_t;
0085 auto n = lhs.size();
0086 if(n != rhs.size())
0087 return false;
0088 auto p1 = reinterpret_cast<
0089 unsigned char const*>(lhs.data());
0090 auto p2 = reinterpret_cast<
0091 unsigned char const*>(rhs.data());
0092 auto constexpr S = sizeof(Int);
0093 auto constexpr Mask = static_cast<Int>(
0094 0xDFDFDFDFDFDFDFDF & ~Int{0});
0095 for(; n >= S; p1 += S, p2 += S, n -= S)
0096 {
0097 Int const v1 = get_chars(p1);
0098 Int const v2 = get_chars(p2);
0099 if((v1 ^ v2) & Mask)
0100 return false;
0101 }
0102 for(; n; ++p1, ++p2, --n)
0103 if(( *p1 ^ *p2) & 0xDF)
0104 return false;
0105 return true;
0106 }
0107
0108 array_type by_name_;
0109
0110 enum { N = 5155 };
0111 unsigned char map_[ N ][ 2 ] = {};
0112
0113
0114
0115
0116
0117
0118 field_table()
0119 : by_name_({{
0120
0121 "<unknown-field>",
0122 "A-IM",
0123 "Accept",
0124 "Accept-Additions",
0125 "Accept-Charset",
0126 "Accept-Datetime",
0127 "Accept-Encoding",
0128 "Accept-Features",
0129 "Accept-Language",
0130 "Accept-Patch",
0131 "Accept-Post",
0132 "Accept-Ranges",
0133 "Access-Control",
0134 "Access-Control-Allow-Credentials",
0135 "Access-Control-Allow-Headers",
0136 "Access-Control-Allow-Methods",
0137 "Access-Control-Allow-Origin",
0138 "Access-Control-Expose-Headers",
0139 "Access-Control-Max-Age",
0140 "Access-Control-Request-Headers",
0141 "Access-Control-Request-Method",
0142 "Age",
0143 "Allow",
0144 "ALPN",
0145 "Also-Control",
0146 "Alt-Svc",
0147 "Alt-Used",
0148 "Alternate-Recipient",
0149 "Alternates",
0150 "Apparently-To",
0151 "Apply-To-Redirect-Ref",
0152 "Approved",
0153 "Archive",
0154 "Archived-At",
0155 "Article-Names",
0156 "Article-Updates",
0157 "Authentication-Control",
0158 "Authentication-Info",
0159 "Authentication-Results",
0160 "Authorization",
0161 "Auto-Submitted",
0162 "Autoforwarded",
0163 "Autosubmitted",
0164 "Base",
0165 "Bcc",
0166 "Body",
0167 "C-Ext",
0168 "C-Man",
0169 "C-Opt",
0170 "C-PEP",
0171 "C-PEP-Info",
0172 "Cache-Control",
0173 "CalDAV-Timezones",
0174 "Cancel-Key",
0175 "Cancel-Lock",
0176 "Cc",
0177 "Close",
0178 "Comments",
0179 "Compliance",
0180 "Connection",
0181 "Content-Alternative",
0182 "Content-Base",
0183 "Content-Description",
0184 "Content-Disposition",
0185 "Content-Duration",
0186 "Content-Encoding",
0187 "Content-features",
0188 "Content-ID",
0189 "Content-Identifier",
0190 "Content-Language",
0191 "Content-Length",
0192 "Content-Location",
0193 "Content-MD5",
0194 "Content-Range",
0195 "Content-Return",
0196 "Content-Script-Type",
0197 "Content-Style-Type",
0198 "Content-Transfer-Encoding",
0199 "Content-Type",
0200 "Content-Version",
0201 "Control",
0202 "Conversion",
0203 "Conversion-With-Loss",
0204 "Cookie",
0205 "Cookie2",
0206 "Cost",
0207 "DASL",
0208 "Date",
0209 "Date-Received",
0210 "DAV",
0211 "Default-Style",
0212 "Deferred-Delivery",
0213 "Delivery-Date",
0214 "Delta-Base",
0215 "Depth",
0216 "Derived-From",
0217 "Destination",
0218 "Differential-ID",
0219 "Digest",
0220 "Discarded-X400-IPMS-Extensions",
0221 "Discarded-X400-MTS-Extensions",
0222 "Disclose-Recipients",
0223 "Disposition-Notification-Options",
0224 "Disposition-Notification-To",
0225 "Distribution",
0226 "DKIM-Signature",
0227 "DL-Expansion-History",
0228 "Downgraded-Bcc",
0229 "Downgraded-Cc",
0230 "Downgraded-Disposition-Notification-To",
0231 "Downgraded-Final-Recipient",
0232 "Downgraded-From",
0233 "Downgraded-In-Reply-To",
0234 "Downgraded-Mail-From",
0235 "Downgraded-Message-Id",
0236 "Downgraded-Original-Recipient",
0237 "Downgraded-Rcpt-To",
0238 "Downgraded-References",
0239 "Downgraded-Reply-To",
0240 "Downgraded-Resent-Bcc",
0241 "Downgraded-Resent-Cc",
0242 "Downgraded-Resent-From",
0243 "Downgraded-Resent-Reply-To",
0244 "Downgraded-Resent-Sender",
0245 "Downgraded-Resent-To",
0246 "Downgraded-Return-Path",
0247 "Downgraded-Sender",
0248 "Downgraded-To",
0249 "EDIINT-Features",
0250 "Eesst-Version",
0251 "Encoding",
0252 "Encrypted",
0253 "Errors-To",
0254 "ETag",
0255 "Expect",
0256 "Expires",
0257 "Expiry-Date",
0258 "Ext",
0259 "Followup-To",
0260 "Forwarded",
0261 "From",
0262 "Generate-Delivery-Report",
0263 "GetProfile",
0264 "Hobareg",
0265 "Host",
0266 "HTTP2-Settings",
0267 "If",
0268 "If-Match",
0269 "If-Modified-Since",
0270 "If-None-Match",
0271 "If-Range",
0272 "If-Schedule-Tag-Match",
0273 "If-Unmodified-Since",
0274 "IM",
0275 "Importance",
0276 "In-Reply-To",
0277 "Incomplete-Copy",
0278 "Injection-Date",
0279 "Injection-Info",
0280 "Jabber-ID",
0281 "Keep-Alive",
0282 "Keywords",
0283 "Label",
0284 "Language",
0285 "Last-Modified",
0286 "Latest-Delivery-Time",
0287 "Lines",
0288 "Link",
0289 "List-Archive",
0290 "List-Help",
0291 "List-ID",
0292 "List-Owner",
0293 "List-Post",
0294 "List-Subscribe",
0295 "List-Unsubscribe",
0296 "List-Unsubscribe-Post",
0297 "Location",
0298 "Lock-Token",
0299 "Man",
0300 "Max-Forwards",
0301 "Memento-Datetime",
0302 "Message-Context",
0303 "Message-ID",
0304 "Message-Type",
0305 "Meter",
0306 "Method-Check",
0307 "Method-Check-Expires",
0308 "MIME-Version",
0309 "MMHS-Acp127-Message-Identifier",
0310 "MMHS-Authorizing-Users",
0311 "MMHS-Codress-Message-Indicator",
0312 "MMHS-Copy-Precedence",
0313 "MMHS-Exempted-Address",
0314 "MMHS-Extended-Authorisation-Info",
0315 "MMHS-Handling-Instructions",
0316 "MMHS-Message-Instructions",
0317 "MMHS-Message-Type",
0318 "MMHS-Originator-PLAD",
0319 "MMHS-Originator-Reference",
0320 "MMHS-Other-Recipients-Indicator-CC",
0321 "MMHS-Other-Recipients-Indicator-To",
0322 "MMHS-Primary-Precedence",
0323 "MMHS-Subject-Indicator-Codes",
0324 "MT-Priority",
0325 "Negotiate",
0326 "Newsgroups",
0327 "NNTP-Posting-Date",
0328 "NNTP-Posting-Host",
0329 "Non-Compliance",
0330 "Obsoletes",
0331 "Opt",
0332 "Optional",
0333 "Optional-WWW-Authenticate",
0334 "Ordering-Type",
0335 "Organization",
0336 "Origin",
0337 "Original-Encoded-Information-Types",
0338 "Original-From",
0339 "Original-Message-ID",
0340 "Original-Recipient",
0341 "Original-Sender",
0342 "Original-Subject",
0343 "Originator-Return-Address",
0344 "Overwrite",
0345 "P3P",
0346 "Path",
0347 "PEP",
0348 "Pep-Info",
0349 "PICS-Label",
0350 "Position",
0351 "Posting-Version",
0352 "Pragma",
0353 "Prefer",
0354 "Preference-Applied",
0355 "Prevent-NonDelivery-Report",
0356 "Priority",
0357 "Privicon",
0358 "ProfileObject",
0359 "Protocol",
0360 "Protocol-Info",
0361 "Protocol-Query",
0362 "Protocol-Request",
0363 "Proxy-Authenticate",
0364 "Proxy-Authentication-Info",
0365 "Proxy-Authorization",
0366 "Proxy-Connection",
0367 "Proxy-Features",
0368 "Proxy-Instruction",
0369 "Public",
0370 "Public-Key-Pins",
0371 "Public-Key-Pins-Report-Only",
0372 "Range",
0373 "Received",
0374 "Received-SPF",
0375 "Redirect-Ref",
0376 "References",
0377 "Referer",
0378 "Referer-Root",
0379 "Relay-Version",
0380 "Reply-By",
0381 "Reply-To",
0382 "Require-Recipient-Valid-Since",
0383 "Resent-Bcc",
0384 "Resent-Cc",
0385 "Resent-Date",
0386 "Resent-From",
0387 "Resent-Message-ID",
0388 "Resent-Reply-To",
0389 "Resent-Sender",
0390 "Resent-To",
0391 "Resolution-Hint",
0392 "Resolver-Location",
0393 "Retry-After",
0394 "Return-Path",
0395 "Safe",
0396 "Schedule-Reply",
0397 "Schedule-Tag",
0398 "Sec-Fetch-Dest",
0399 "Sec-Fetch-Mode",
0400 "Sec-Fetch-Site",
0401 "Sec-Fetch-User",
0402 "Sec-WebSocket-Accept",
0403 "Sec-WebSocket-Extensions",
0404 "Sec-WebSocket-Key",
0405 "Sec-WebSocket-Protocol",
0406 "Sec-WebSocket-Version",
0407 "Security-Scheme",
0408 "See-Also",
0409 "Sender",
0410 "Sensitivity",
0411 "Server",
0412 "Set-Cookie",
0413 "Set-Cookie2",
0414 "SetProfile",
0415 "SIO-Label",
0416 "SIO-Label-History",
0417 "SLUG",
0418 "SoapAction",
0419 "Solicitation",
0420 "Status-URI",
0421 "Strict-Transport-Security",
0422 "Subject",
0423 "SubOK",
0424 "Subst",
0425 "Summary",
0426 "Supersedes",
0427 "Surrogate-Capability",
0428 "Surrogate-Control",
0429 "TCN",
0430 "TE",
0431 "Timeout",
0432 "Title",
0433 "To",
0434 "Topic",
0435 "Trailer",
0436 "Transfer-Encoding",
0437 "TTL",
0438 "UA-Color",
0439 "UA-Media",
0440 "UA-Pixels",
0441 "UA-Resolution",
0442 "UA-Windowpixels",
0443 "Upgrade",
0444 "Urgency",
0445 "URI",
0446 "User-Agent",
0447 "Variant-Vary",
0448 "Vary",
0449 "VBR-Info",
0450 "Version",
0451 "Via",
0452 "Want-Digest",
0453 "Warning",
0454 "WWW-Authenticate",
0455 "X-Archived-At",
0456 "X-Device-Accept",
0457 "X-Device-Accept-Charset",
0458 "X-Device-Accept-Encoding",
0459 "X-Device-Accept-Language",
0460 "X-Device-User-Agent",
0461 "X-Frame-Options",
0462 "X-Mittente",
0463 "X-PGP-Sig",
0464 "X-Ricevuta",
0465 "X-Riferimento-Message-ID",
0466 "X-TipoRicevuta",
0467 "X-Trasporto",
0468 "X-VerificaSicurezza",
0469 "X400-Content-Identifier",
0470 "X400-Content-Return",
0471 "X400-Content-Type",
0472 "X400-MTS-Identifier",
0473 "X400-Originator",
0474 "X400-Received",
0475 "X400-Recipients",
0476 "X400-Trace",
0477 "Xref"
0478 }})
0479 {
0480 for(std::size_t i = 1, n = 256; i < n; ++i)
0481 {
0482 auto sv = by_name_[ i ];
0483 auto h = digest(sv);
0484 auto j = h % N;
0485 BOOST_ASSERT(map_[j][0] == 0);
0486 map_[j][0] = static_cast<unsigned char>(i);
0487 }
0488
0489 for(std::size_t i = 256, n = by_name_.size(); i < n; ++i)
0490 {
0491 auto sv = by_name_[i];
0492 auto h = digest(sv);
0493 auto j = h % N;
0494 BOOST_ASSERT(map_[j][1] == 0);
0495 map_[j][1] = static_cast<unsigned char>(i - 255);
0496 }
0497 }
0498
0499 field
0500 string_to_field(string_view s) const
0501 {
0502 auto h = digest(s);
0503 auto j = h % N;
0504 int i = map_[j][0];
0505 string_view s2 = by_name_[i];
0506 if(i != 0 && equals(s, s2))
0507 return static_cast<field>(i);
0508 i = map_[j][1];
0509 if(i == 0)
0510 return field::unknown;
0511 i += 255;
0512 s2 = by_name_[i];
0513
0514 if(equals(s, s2))
0515 return static_cast<field>(i);
0516 return field::unknown;
0517 }
0518
0519
0520
0521
0522
0523 using const_iterator =
0524 array_type::const_iterator;
0525
0526 std::size_t
0527 size() const
0528 {
0529 return by_name_.size();
0530 }
0531
0532 const_iterator
0533 begin() const
0534 {
0535 return by_name_.begin();
0536 }
0537
0538 const_iterator
0539 end() const
0540 {
0541 return by_name_.end();
0542 }
0543 };
0544
0545 BOOST_BEAST_DECL
0546 field_table const&
0547 get_field_table()
0548 {
0549 static field_table const tab;
0550 return tab;
0551 }
0552
0553 BOOST_BEAST_DECL
0554 string_view
0555 to_string(field f)
0556 {
0557 auto const& v = get_field_table();
0558 BOOST_ASSERT(static_cast<unsigned>(f) < v.size());
0559 return v.begin()[static_cast<unsigned>(f)];
0560 }
0561
0562 }
0563
0564 string_view
0565 to_string(field f)
0566 {
0567 return detail::to_string(f);
0568 }
0569
0570 field
0571 string_to_field(string_view s)
0572 {
0573 return detail::get_field_table().string_to_field(s);
0574 }
0575
0576 std::ostream&
0577 operator<<(std::ostream& os, field f)
0578 {
0579 return os << to_string(f);
0580 }
0581
0582 }
0583 }
0584 }
0585
0586 #endif