2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_HTTP_IMPL_FIELD_IPP
11 #define BOOST_BEAST_HTTP_IMPL_FIELD_IPP
13 #include <boost/beast/http/field.hpp>
14 #include <boost/assert.hpp>
32 unsigned char const* p) noexcept
34 // VFALCO memcpy is endian-dependent
35 //std::memcpy(&v, p, 4);
36 // Compiler should be smart enough to
37 // optimize this down to one instruction.
46 std::array<string_view, 357>;
48 // Strings are converted to lowercase
54 std::size_t n = s.size();
55 auto p = reinterpret_cast<
56 unsigned char const*>(s.data());
57 // consume N characters at a time
58 // VFALCO Can we do 8 on 64-bit systems?
61 auto const v = get_chars(p);
63 v | 0x20202020 )); // convert to lower
67 // handle remaining characters
70 r = r * 5 + ( *p | 0x20 );
77 // This comparison is case-insensitive, and the
78 // strings must contain only valid http field characters.
81 equals(string_view lhs, string_view rhs)
83 using Int = std::uint32_t; // VFALCO std::size_t?
87 auto p1 = reinterpret_cast<
88 unsigned char const*>(lhs.data());
89 auto p2 = reinterpret_cast<
90 unsigned char const*>(rhs.data());
91 auto constexpr S = sizeof(Int);
92 auto constexpr Mask = static_cast<Int>(
93 0xDFDFDFDFDFDFDFDF & ~Int{0});
94 for(; n >= S; p1 += S, p2 += S, n -= S)
96 Int const v1 = get_chars(p1);
97 Int const v2 = get_chars(p2);
101 for(; n; ++p1, ++p2, --n)
102 if(( *p1 ^ *p2) & 0xDF)
110 unsigned char map_[ N ][ 2 ] = {};
115 https://www.iana.org/assignments/message-headers/message-headers.xhtml
133 "Access-Control-Allow-Credentials",
134 "Access-Control-Allow-Headers",
135 "Access-Control-Allow-Methods",
136 "Access-Control-Allow-Origin",
137 "Access-Control-Expose-Headers",
138 "Access-Control-Max-Age",
139 "Access-Control-Request-Headers",
140 "Access-Control-Request-Method",
147 "Alternate-Recipient",
150 "Apply-To-Redirect-Ref",
156 "Authentication-Control",
157 "Authentication-Info",
158 "Authentication-Results",
180 "Content-Alternative",
182 "Content-Description",
183 "Content-Disposition",
188 "Content-Identifier",
195 "Content-Script-Type",
196 "Content-Style-Type",
197 "Content-Transfer-Encoding",
202 "Conversion-With-Loss",
219 "Discarded-X400-IPMS-Extensions",
220 "Discarded-X400-MTS-Extensions",
221 "Disclose-Recipients",
222 "Disposition-Notification-Options",
223 "Disposition-Notification-To",
226 "DL-Expansion-History",
229 "Downgraded-Disposition-Notification-To",
230 "Downgraded-Final-Recipient",
232 "Downgraded-In-Reply-To",
233 "Downgraded-Mail-From",
234 "Downgraded-Message-Id",
235 "Downgraded-Original-Recipient",
236 "Downgraded-Rcpt-To",
237 "Downgraded-References",
238 "Downgraded-Reply-To",
239 "Downgraded-Resent-Bcc",
240 "Downgraded-Resent-Cc",
241 "Downgraded-Resent-From",
242 "Downgraded-Resent-Reply-To",
243 "Downgraded-Resent-Sender",
244 "Downgraded-Resent-To",
245 "Downgraded-Return-Path",
261 "Generate-Delivery-Report",
271 "If-Schedule-Tag-Match",
272 "If-Unmodified-Since",
285 "Latest-Delivery-Time",
295 "List-Unsubscribe-Post",
306 "Method-Check-Expires",
308 "MMHS-Acp127-Message-Identifier",
309 "MMHS-Authorizing-Users",
310 "MMHS-Codress-Message-Indicator",
311 "MMHS-Copy-Precedence",
312 "MMHS-Exempted-Address",
313 "MMHS-Extended-Authorisation-Info",
314 "MMHS-Handling-Instructions",
315 "MMHS-Message-Instructions",
317 "MMHS-Originator-PLAD",
318 "MMHS-Originator-Reference",
319 "MMHS-Other-Recipients-Indicator-CC",
320 "MMHS-Other-Recipients-Indicator-To",
321 "MMHS-Primary-Precedence",
322 "MMHS-Subject-Indicator-Codes",
332 "Optional-WWW-Authenticate",
336 "Original-Encoded-Information-Types",
338 "Original-Message-ID",
339 "Original-Recipient",
342 "Originator-Return-Address",
353 "Preference-Applied",
354 "Prevent-NonDelivery-Report",
362 "Proxy-Authenticate",
363 "Proxy-Authentication-Info",
364 "Proxy-Authorization",
370 "Public-Key-Pins-Report-Only",
381 "Require-Recipient-Valid-Since",
401 "Sec-WebSocket-Accept",
402 "Sec-WebSocket-Extensions",
404 "Sec-WebSocket-Protocol",
405 "Sec-WebSocket-Version",
420 "Strict-Transport-Security",
426 "Surrogate-Capability",
456 "X-Device-Accept-Charset",
457 "X-Device-Accept-Encoding",
458 "X-Device-Accept-Language",
459 "X-Device-User-Agent",
464 "X-Riferimento-Message-ID",
467 "X-VerificaSicurezza",
468 "X400-Content-Identifier",
469 "X400-Content-Return",
471 "X400-MTS-Identifier",
479 for(std::size_t i = 1, n = 256; i < n; ++i)
481 auto sv = by_name_[ i ];
484 BOOST_ASSERT(map_[j][0] == 0);
485 map_[j][0] = static_cast<unsigned char>(i);
488 for(std::size_t i = 256, n = by_name_.size(); i < n; ++i)
490 auto sv = by_name_[i];
493 BOOST_ASSERT(map_[j][1] == 0);
494 map_[j][1] = static_cast<unsigned char>(i - 255);
499 string_to_field(string_view s) const
504 string_view s2 = by_name_[i];
505 if(i != 0 && equals(s, s2))
506 return static_cast<field>(i);
509 return field::unknown;
514 return static_cast<field>(i);
515 return field::unknown;
522 using const_iterator =
523 array_type::const_iterator;
528 return by_name_.size();
534 return by_name_.begin();
540 return by_name_.end();
548 static field_table const tab;
556 auto const& v = get_field_table();
557 BOOST_ASSERT(static_cast<unsigned>(f) < v.size());
558 return v.begin()[static_cast<unsigned>(f)];
566 return detail::to_string(f);
570 string_to_field(string_view s)
572 return detail::get_field_table().string_to_field(s);
576 operator<<(std::ostream& os, field f)
578 return os << to_string(f);