2 // Copyright (c) 2016-2017 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/core/string.hpp>
16 #include <unordered_map>
18 #include <boost/assert.hpp>
29 std::array<string_view, 352>;
34 operator()(string_view s) const
36 auto const n = s.size();
38 beast::detail::ascii_tolower(s[0]) *
39 beast::detail::ascii_tolower(s[n/2]) ^
40 beast::detail::ascii_tolower(s[n-1]); // hist[] = 331, 10, max_load_factor = 0.15f
46 // assumes inputs have equal length
50 string_view rhs) const
54 auto pend = lhs.end();
68 if( beast::detail::ascii_tolower(a) !=
69 beast::detail::ascii_tolower(b))
78 using map_type = std::unordered_map<
79 string_view, field, hash, iequal>;
82 std::vector<map_type> by_size_;
86 https://www.iana.org/assignments/message-headers/message-headers.xhtml
103 "Access-Control-Allow-Credentials",
104 "Access-Control-Allow-Headers",
105 "Access-Control-Allow-Methods",
106 "Access-Control-Allow-Origin",
107 "Access-Control-Max-Age",
108 "Access-Control-Request-Headers",
109 "Access-Control-Request-Method",
116 "Alternate-Recipient",
119 "Apply-To-Redirect-Ref",
125 "Authentication-Control",
126 "Authentication-Info",
127 "Authentication-Results",
149 "Content-Alternative",
151 "Content-Description",
152 "Content-Disposition",
157 "Content-Identifier",
164 "Content-Script-Type",
165 "Content-Style-Type",
166 "Content-Transfer-Encoding",
171 "Conversion-With-Loss",
188 "Discarded-X400-IPMS-Extensions",
189 "Discarded-X400-MTS-Extensions",
190 "Disclose-Recipients",
191 "Disposition-Notification-Options",
192 "Disposition-Notification-To",
195 "DL-Expansion-History",
198 "Downgraded-Disposition-Notification-To",
199 "Downgraded-Final-Recipient",
201 "Downgraded-In-Reply-To",
202 "Downgraded-Mail-From",
203 "Downgraded-Message-Id",
204 "Downgraded-Original-Recipient",
205 "Downgraded-Rcpt-To",
206 "Downgraded-References",
207 "Downgraded-Reply-To",
208 "Downgraded-Resent-Bcc",
209 "Downgraded-Resent-Cc",
210 "Downgraded-Resent-From",
211 "Downgraded-Resent-Reply-To",
212 "Downgraded-Resent-Sender",
213 "Downgraded-Resent-To",
214 "Downgraded-Return-Path",
230 "Generate-Delivery-Report",
240 "If-Schedule-Tag-Match",
241 "If-Unmodified-Since",
254 "Latest-Delivery-Time",
264 "List-Unsubscribe-Post",
275 "Method-Check-Expires",
277 "MMHS-Acp127-Message-Identifier",
278 "MMHS-Authorizing-Users",
279 "MMHS-Codress-Message-Indicator",
280 "MMHS-Copy-Precedence",
281 "MMHS-Exempted-Address",
282 "MMHS-Extended-Authorisation-Info",
283 "MMHS-Handling-Instructions",
284 "MMHS-Message-Instructions",
286 "MMHS-Originator-PLAD",
287 "MMHS-Originator-Reference",
288 "MMHS-Other-Recipients-Indicator-CC",
289 "MMHS-Other-Recipients-Indicator-To",
290 "MMHS-Primary-Precedence",
291 "MMHS-Subject-Indicator-Codes",
301 "Optional-WWW-Authenticate",
305 "Original-Encoded-Information-Types",
307 "Original-Message-ID",
308 "Original-Recipient",
311 "Originator-Return-Address",
322 "Preference-Applied",
323 "Prevent-NonDelivery-Report",
331 "Proxy-Authenticate",
332 "Proxy-Authentication-Info",
333 "Proxy-Authorization",
339 "Public-Key-Pins-Report-Only",
350 "Require-Recipient-Valid-Since",
366 "Sec-WebSocket-Accept",
367 "Sec-WebSocket-Extensions",
369 "Sec-WebSocket-Protocol",
370 "Sec-WebSocket-Version",
385 "Strict-Transport-Security",
391 "Surrogate-Capability",
421 "X-Device-Accept-Charset",
422 "X-Device-Accept-Encoding",
423 "X-Device-Accept-Language",
424 "X-Device-User-Agent",
429 "X-Riferimento-Message-ID",
432 "X-VerificaSicurezza",
433 "X400-Content-Identifier",
434 "X400-Content-Return",
436 "X400-MTS-Identifier",
444 // find the longest field length
445 std::size_t high = 0;
446 for(auto const& s : by_name_)
450 // skip field::unknown
451 by_size_.resize(high + 1);
452 for(auto& map : by_size_)
453 map.max_load_factor(.15f);
454 for(std::size_t i = 1;
455 i < by_name_.size(); ++i)
457 auto const& s = by_name_[i];
458 by_size_[s.size()].emplace(
459 s, static_cast<field>(i));
463 // This snippet calculates the performance
464 // of the hash function and map settings
466 std::vector<std::size_t> hist;
467 for(auto const& map : by_size_)
469 for(std::size_t i = 0; i < map.bucket_count(); ++i)
471 auto const n = map.bucket_size(i);
485 string_to_field(string_view s) const
487 if(s.size() >= by_size_.size())
488 return field::unknown;
489 auto const& map = by_size_[s.size()];
491 return field::unknown;
492 auto it = map.find(s);
494 return field::unknown;
502 using const_iterator =
503 array_type::const_iterator;
508 return by_name_.size();
514 return by_name_.begin();
520 return by_name_.end();
528 static field_table const tab;
532 template<class = void>
536 auto const& v = get_field_table();
537 BOOST_ASSERT(static_cast<unsigned>(f) < v.size());
538 return v.begin()[static_cast<unsigned>(f)];
547 return detail::to_string(f);
552 string_to_field(string_view s)
554 return detail::get_field_table().string_to_field(s);