]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/http/impl/field.ipp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / http / impl / field.ipp
1 //
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
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)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_HTTP_IMPL_FIELD_IPP
11 #define BOOST_BEAST_HTTP_IMPL_FIELD_IPP
12
13 #include <boost/beast/core/string.hpp>
14 #include <algorithm>
15 #include <array>
16 #include <unordered_map>
17 #include <vector>
18 #include <boost/assert.hpp>
19
20 namespace boost {
21 namespace beast {
22 namespace http {
23
24 namespace detail {
25
26 struct field_table
27 {
28 using array_type =
29 std::array<string_view, 352>;
30
31 struct hash
32 {
33 std::size_t
34 operator()(string_view s) const
35 {
36 auto const n = s.size();
37 return
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
41 }
42 };
43
44 struct iequal
45 {
46 // assumes inputs have equal length
47 bool
48 operator()(
49 string_view lhs,
50 string_view rhs) const
51 {
52 auto p1 = lhs.data();
53 auto p2 = rhs.data();
54 auto pend = lhs.end();
55 char a, b;
56 while(p1 < pend)
57 {
58 a = *p1++;
59 b = *p2++;
60 if(a != b)
61 goto slow;
62 }
63 return true;
64
65 while(p1 < pend)
66 {
67 slow:
68 if( beast::detail::ascii_tolower(a) !=
69 beast::detail::ascii_tolower(b))
70 return false;
71 a = *p1++;
72 b = *p2++;
73 }
74 return true;
75 }
76 };
77
78 using map_type = std::unordered_map<
79 string_view, field, hash, iequal>;
80
81 array_type by_name_;
82 std::vector<map_type> by_size_;
83 /*
84 From:
85
86 https://www.iana.org/assignments/message-headers/message-headers.xhtml
87 */
88 field_table()
89 : by_name_({{
90 "<unknown-field>",
91 "A-IM",
92 "Accept",
93 "Accept-Additions",
94 "Accept-Charset",
95 "Accept-Datetime",
96 "Accept-Encoding",
97 "Accept-Features",
98 "Accept-Language",
99 "Accept-Patch",
100 "Accept-Post",
101 "Accept-Ranges",
102 "Access-Control",
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",
110 "Age",
111 "Allow",
112 "ALPN",
113 "Also-Control",
114 "Alt-Svc",
115 "Alt-Used",
116 "Alternate-Recipient",
117 "Alternates",
118 "Apparently-To",
119 "Apply-To-Redirect-Ref",
120 "Approved",
121 "Archive",
122 "Archived-At",
123 "Article-Names",
124 "Article-Updates",
125 "Authentication-Control",
126 "Authentication-Info",
127 "Authentication-Results",
128 "Authorization",
129 "Auto-Submitted",
130 "Autoforwarded",
131 "Autosubmitted",
132 "Base",
133 "Bcc",
134 "Body",
135 "C-Ext",
136 "C-Man",
137 "C-Opt",
138 "C-PEP",
139 "C-PEP-Info",
140 "Cache-Control",
141 "CalDAV-Timezones",
142 "Cancel-Key",
143 "Cancel-Lock",
144 "Cc",
145 "Close",
146 "Comments",
147 "Compliance",
148 "Connection",
149 "Content-Alternative",
150 "Content-Base",
151 "Content-Description",
152 "Content-Disposition",
153 "Content-Duration",
154 "Content-Encoding",
155 "Content-features",
156 "Content-ID",
157 "Content-Identifier",
158 "Content-Language",
159 "Content-Length",
160 "Content-Location",
161 "Content-MD5",
162 "Content-Range",
163 "Content-Return",
164 "Content-Script-Type",
165 "Content-Style-Type",
166 "Content-Transfer-Encoding",
167 "Content-Type",
168 "Content-Version",
169 "Control",
170 "Conversion",
171 "Conversion-With-Loss",
172 "Cookie",
173 "Cookie2",
174 "Cost",
175 "DASL",
176 "Date",
177 "Date-Received",
178 "DAV",
179 "Default-Style",
180 "Deferred-Delivery",
181 "Delivery-Date",
182 "Delta-Base",
183 "Depth",
184 "Derived-From",
185 "Destination",
186 "Differential-ID",
187 "Digest",
188 "Discarded-X400-IPMS-Extensions",
189 "Discarded-X400-MTS-Extensions",
190 "Disclose-Recipients",
191 "Disposition-Notification-Options",
192 "Disposition-Notification-To",
193 "Distribution",
194 "DKIM-Signature",
195 "DL-Expansion-History",
196 "Downgraded-Bcc",
197 "Downgraded-Cc",
198 "Downgraded-Disposition-Notification-To",
199 "Downgraded-Final-Recipient",
200 "Downgraded-From",
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",
215 "Downgraded-Sender",
216 "Downgraded-To",
217 "EDIINT-Features",
218 "Eesst-Version",
219 "Encoding",
220 "Encrypted",
221 "Errors-To",
222 "ETag",
223 "Expect",
224 "Expires",
225 "Expiry-Date",
226 "Ext",
227 "Followup-To",
228 "Forwarded",
229 "From",
230 "Generate-Delivery-Report",
231 "GetProfile",
232 "Hobareg",
233 "Host",
234 "HTTP2-Settings",
235 "If",
236 "If-Match",
237 "If-Modified-Since",
238 "If-None-Match",
239 "If-Range",
240 "If-Schedule-Tag-Match",
241 "If-Unmodified-Since",
242 "IM",
243 "Importance",
244 "In-Reply-To",
245 "Incomplete-Copy",
246 "Injection-Date",
247 "Injection-Info",
248 "Jabber-ID",
249 "Keep-Alive",
250 "Keywords",
251 "Label",
252 "Language",
253 "Last-Modified",
254 "Latest-Delivery-Time",
255 "Lines",
256 "Link",
257 "List-Archive",
258 "List-Help",
259 "List-ID",
260 "List-Owner",
261 "List-Post",
262 "List-Subscribe",
263 "List-Unsubscribe",
264 "List-Unsubscribe-Post",
265 "Location",
266 "Lock-Token",
267 "Man",
268 "Max-Forwards",
269 "Memento-Datetime",
270 "Message-Context",
271 "Message-ID",
272 "Message-Type",
273 "Meter",
274 "Method-Check",
275 "Method-Check-Expires",
276 "MIME-Version",
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",
285 "MMHS-Message-Type",
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",
292 "MT-Priority",
293 "Negotiate",
294 "Newsgroups",
295 "NNTP-Posting-Date",
296 "NNTP-Posting-Host",
297 "Non-Compliance",
298 "Obsoletes",
299 "Opt",
300 "Optional",
301 "Optional-WWW-Authenticate",
302 "Ordering-Type",
303 "Organization",
304 "Origin",
305 "Original-Encoded-Information-Types",
306 "Original-From",
307 "Original-Message-ID",
308 "Original-Recipient",
309 "Original-Sender",
310 "Original-Subject",
311 "Originator-Return-Address",
312 "Overwrite",
313 "P3P",
314 "Path",
315 "PEP",
316 "Pep-Info",
317 "PICS-Label",
318 "Position",
319 "Posting-Version",
320 "Pragma",
321 "Prefer",
322 "Preference-Applied",
323 "Prevent-NonDelivery-Report",
324 "Priority",
325 "Privicon",
326 "ProfileObject",
327 "Protocol",
328 "Protocol-Info",
329 "Protocol-Query",
330 "Protocol-Request",
331 "Proxy-Authenticate",
332 "Proxy-Authentication-Info",
333 "Proxy-Authorization",
334 "Proxy-Connection",
335 "Proxy-Features",
336 "Proxy-Instruction",
337 "Public",
338 "Public-Key-Pins",
339 "Public-Key-Pins-Report-Only",
340 "Range",
341 "Received",
342 "Received-SPF",
343 "Redirect-Ref",
344 "References",
345 "Referer",
346 "Referer-Root",
347 "Relay-Version",
348 "Reply-By",
349 "Reply-To",
350 "Require-Recipient-Valid-Since",
351 "Resent-Bcc",
352 "Resent-Cc",
353 "Resent-Date",
354 "Resent-From",
355 "Resent-Message-ID",
356 "Resent-Reply-To",
357 "Resent-Sender",
358 "Resent-To",
359 "Resolution-Hint",
360 "Resolver-Location",
361 "Retry-After",
362 "Return-Path",
363 "Safe",
364 "Schedule-Reply",
365 "Schedule-Tag",
366 "Sec-WebSocket-Accept",
367 "Sec-WebSocket-Extensions",
368 "Sec-WebSocket-Key",
369 "Sec-WebSocket-Protocol",
370 "Sec-WebSocket-Version",
371 "Security-Scheme",
372 "See-Also",
373 "Sender",
374 "Sensitivity",
375 "Server",
376 "Set-Cookie",
377 "Set-Cookie2",
378 "SetProfile",
379 "SIO-Label",
380 "SIO-Label-History",
381 "SLUG",
382 "SoapAction",
383 "Solicitation",
384 "Status-URI",
385 "Strict-Transport-Security",
386 "Subject",
387 "SubOK",
388 "Subst",
389 "Summary",
390 "Supersedes",
391 "Surrogate-Capability",
392 "Surrogate-Control",
393 "TCN",
394 "TE",
395 "Timeout",
396 "Title",
397 "To",
398 "Topic",
399 "Trailer",
400 "Transfer-Encoding",
401 "TTL",
402 "UA-Color",
403 "UA-Media",
404 "UA-Pixels",
405 "UA-Resolution",
406 "UA-Windowpixels",
407 "Upgrade",
408 "Urgency",
409 "URI",
410 "User-Agent",
411 "Variant-Vary",
412 "Vary",
413 "VBR-Info",
414 "Version",
415 "Via",
416 "Want-Digest",
417 "Warning",
418 "WWW-Authenticate",
419 "X-Archived-At",
420 "X-Device-Accept",
421 "X-Device-Accept-Charset",
422 "X-Device-Accept-Encoding",
423 "X-Device-Accept-Language",
424 "X-Device-User-Agent",
425 "X-Frame-Options",
426 "X-Mittente",
427 "X-PGP-Sig",
428 "X-Ricevuta",
429 "X-Riferimento-Message-ID",
430 "X-TipoRicevuta",
431 "X-Trasporto",
432 "X-VerificaSicurezza",
433 "X400-Content-Identifier",
434 "X400-Content-Return",
435 "X400-Content-Type",
436 "X400-MTS-Identifier",
437 "X400-Originator",
438 "X400-Received",
439 "X400-Recipients",
440 "X400-Trace",
441 "Xref"
442 }})
443 {
444 // find the longest field length
445 std::size_t high = 0;
446 for(auto const& s : by_name_)
447 if(high < s.size())
448 high = s.size();
449 // build by_size map
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)
456 {
457 auto const& s = by_name_[i];
458 by_size_[s.size()].emplace(
459 s, static_cast<field>(i));
460 }
461
462 #if 0
463 // This snippet calculates the performance
464 // of the hash function and map settings
465 {
466 std::vector<std::size_t> hist;
467 for(auto const& map : by_size_)
468 {
469 for(std::size_t i = 0; i < map.bucket_count(); ++i)
470 {
471 auto const n = map.bucket_size(i);
472 if(n > 0)
473 {
474 if(hist.size() < n)
475 hist.resize(n);
476 ++hist[n-1];
477 }
478 }
479 }
480 }
481 #endif
482 }
483
484 field
485 string_to_field(string_view s) const
486 {
487 if(s.size() >= by_size_.size())
488 return field::unknown;
489 auto const& map = by_size_[s.size()];
490 if(map.empty())
491 return field::unknown;
492 auto it = map.find(s);
493 if(it == map.end())
494 return field::unknown;
495 return it->second;
496 }
497
498 //
499 // Deprecated
500 //
501
502 using const_iterator =
503 array_type::const_iterator;
504
505 std::size_t
506 size() const
507 {
508 return by_name_.size();
509 }
510
511 const_iterator
512 begin() const
513 {
514 return by_name_.begin();
515 }
516
517 const_iterator
518 end() const
519 {
520 return by_name_.end();
521 }
522 };
523
524 inline
525 field_table const&
526 get_field_table()
527 {
528 static field_table const tab;
529 return tab;
530 }
531
532 template<class = void>
533 string_view
534 to_string(field f)
535 {
536 auto const& v = get_field_table();
537 BOOST_ASSERT(static_cast<unsigned>(f) < v.size());
538 return v.begin()[static_cast<unsigned>(f)];
539 }
540
541 } // detail
542
543 inline
544 string_view
545 to_string(field f)
546 {
547 return detail::to_string(f);
548 }
549
550 inline
551 field
552 string_to_field(string_view s)
553 {
554 return detail::get_field_table().string_to_field(s);
555 }
556
557 } // http
558 } // beast
559 } // boost
560
561 #endif