]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/http/impl/field.ipp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / beast / http / impl / field.ipp
1 //
2 // Copyright (c) 2016-2019 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/http/field.hpp>
14 #include <boost/assert.hpp>
15 #include <algorithm>
16 #include <array>
17 #include <cstring>
18 #include <ostream>
19
20
21 namespace boost {
22 namespace beast {
23 namespace http {
24
25 namespace detail {
26
27 struct field_table
28 {
29 static
30 std::uint32_t
31 get_chars(
32 unsigned char const* p) noexcept
33 {
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.
38 return
39 p[0] |
40 (p[1] << 8) |
41 (p[2] << 16) |
42 (p[3] << 24);
43 }
44
45 using array_type =
46 std::array<string_view, 357>;
47
48 // Strings are converted to lowercase
49 static
50 std::uint32_t
51 digest(string_view s)
52 {
53 std::uint32_t r = 0;
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?
59 while(n >= 4)
60 {
61 auto const v = get_chars(p);
62 r = (r * 5 + (
63 v | 0x20202020 )); // convert to lower
64 p += 4;
65 n -= 4;
66 }
67 // handle remaining characters
68 while( n > 0 )
69 {
70 r = r * 5 + ( *p | 0x20 );
71 ++p;
72 --n;
73 }
74 return r;
75 }
76
77 // This comparison is case-insensitive, and the
78 // strings must contain only valid http field characters.
79 static
80 bool
81 equals(string_view lhs, string_view rhs)
82 {
83 using Int = std::uint32_t; // VFALCO std::size_t?
84 auto n = lhs.size();
85 if(n != rhs.size())
86 return false;
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)
95 {
96 Int const v1 = get_chars(p1);
97 Int const v2 = get_chars(p2);
98 if((v1 ^ v2) & Mask)
99 return false;
100 }
101 for(; n; ++p1, ++p2, --n)
102 if(( *p1 ^ *p2) & 0xDF)
103 return false;
104 return true;
105 }
106
107 array_type by_name_;
108
109 enum { N = 5155 };
110 unsigned char map_[ N ][ 2 ] = {};
111
112 /*
113 From:
114
115 https://www.iana.org/assignments/message-headers/message-headers.xhtml
116 */
117 field_table()
118 : by_name_({{
119 // string constants
120 "<unknown-field>",
121 "A-IM",
122 "Accept",
123 "Accept-Additions",
124 "Accept-Charset",
125 "Accept-Datetime",
126 "Accept-Encoding",
127 "Accept-Features",
128 "Accept-Language",
129 "Accept-Patch",
130 "Accept-Post",
131 "Accept-Ranges",
132 "Access-Control",
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",
141 "Age",
142 "Allow",
143 "ALPN",
144 "Also-Control",
145 "Alt-Svc",
146 "Alt-Used",
147 "Alternate-Recipient",
148 "Alternates",
149 "Apparently-To",
150 "Apply-To-Redirect-Ref",
151 "Approved",
152 "Archive",
153 "Archived-At",
154 "Article-Names",
155 "Article-Updates",
156 "Authentication-Control",
157 "Authentication-Info",
158 "Authentication-Results",
159 "Authorization",
160 "Auto-Submitted",
161 "Autoforwarded",
162 "Autosubmitted",
163 "Base",
164 "Bcc",
165 "Body",
166 "C-Ext",
167 "C-Man",
168 "C-Opt",
169 "C-PEP",
170 "C-PEP-Info",
171 "Cache-Control",
172 "CalDAV-Timezones",
173 "Cancel-Key",
174 "Cancel-Lock",
175 "Cc",
176 "Close",
177 "Comments",
178 "Compliance",
179 "Connection",
180 "Content-Alternative",
181 "Content-Base",
182 "Content-Description",
183 "Content-Disposition",
184 "Content-Duration",
185 "Content-Encoding",
186 "Content-features",
187 "Content-ID",
188 "Content-Identifier",
189 "Content-Language",
190 "Content-Length",
191 "Content-Location",
192 "Content-MD5",
193 "Content-Range",
194 "Content-Return",
195 "Content-Script-Type",
196 "Content-Style-Type",
197 "Content-Transfer-Encoding",
198 "Content-Type",
199 "Content-Version",
200 "Control",
201 "Conversion",
202 "Conversion-With-Loss",
203 "Cookie",
204 "Cookie2",
205 "Cost",
206 "DASL",
207 "Date",
208 "Date-Received",
209 "DAV",
210 "Default-Style",
211 "Deferred-Delivery",
212 "Delivery-Date",
213 "Delta-Base",
214 "Depth",
215 "Derived-From",
216 "Destination",
217 "Differential-ID",
218 "Digest",
219 "Discarded-X400-IPMS-Extensions",
220 "Discarded-X400-MTS-Extensions",
221 "Disclose-Recipients",
222 "Disposition-Notification-Options",
223 "Disposition-Notification-To",
224 "Distribution",
225 "DKIM-Signature",
226 "DL-Expansion-History",
227 "Downgraded-Bcc",
228 "Downgraded-Cc",
229 "Downgraded-Disposition-Notification-To",
230 "Downgraded-Final-Recipient",
231 "Downgraded-From",
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",
246 "Downgraded-Sender",
247 "Downgraded-To",
248 "EDIINT-Features",
249 "Eesst-Version",
250 "Encoding",
251 "Encrypted",
252 "Errors-To",
253 "ETag",
254 "Expect",
255 "Expires",
256 "Expiry-Date",
257 "Ext",
258 "Followup-To",
259 "Forwarded",
260 "From",
261 "Generate-Delivery-Report",
262 "GetProfile",
263 "Hobareg",
264 "Host",
265 "HTTP2-Settings",
266 "If",
267 "If-Match",
268 "If-Modified-Since",
269 "If-None-Match",
270 "If-Range",
271 "If-Schedule-Tag-Match",
272 "If-Unmodified-Since",
273 "IM",
274 "Importance",
275 "In-Reply-To",
276 "Incomplete-Copy",
277 "Injection-Date",
278 "Injection-Info",
279 "Jabber-ID",
280 "Keep-Alive",
281 "Keywords",
282 "Label",
283 "Language",
284 "Last-Modified",
285 "Latest-Delivery-Time",
286 "Lines",
287 "Link",
288 "List-Archive",
289 "List-Help",
290 "List-ID",
291 "List-Owner",
292 "List-Post",
293 "List-Subscribe",
294 "List-Unsubscribe",
295 "List-Unsubscribe-Post",
296 "Location",
297 "Lock-Token",
298 "Man",
299 "Max-Forwards",
300 "Memento-Datetime",
301 "Message-Context",
302 "Message-ID",
303 "Message-Type",
304 "Meter",
305 "Method-Check",
306 "Method-Check-Expires",
307 "MIME-Version",
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",
316 "MMHS-Message-Type",
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",
323 "MT-Priority",
324 "Negotiate",
325 "Newsgroups",
326 "NNTP-Posting-Date",
327 "NNTP-Posting-Host",
328 "Non-Compliance",
329 "Obsoletes",
330 "Opt",
331 "Optional",
332 "Optional-WWW-Authenticate",
333 "Ordering-Type",
334 "Organization",
335 "Origin",
336 "Original-Encoded-Information-Types",
337 "Original-From",
338 "Original-Message-ID",
339 "Original-Recipient",
340 "Original-Sender",
341 "Original-Subject",
342 "Originator-Return-Address",
343 "Overwrite",
344 "P3P",
345 "Path",
346 "PEP",
347 "Pep-Info",
348 "PICS-Label",
349 "Position",
350 "Posting-Version",
351 "Pragma",
352 "Prefer",
353 "Preference-Applied",
354 "Prevent-NonDelivery-Report",
355 "Priority",
356 "Privicon",
357 "ProfileObject",
358 "Protocol",
359 "Protocol-Info",
360 "Protocol-Query",
361 "Protocol-Request",
362 "Proxy-Authenticate",
363 "Proxy-Authentication-Info",
364 "Proxy-Authorization",
365 "Proxy-Connection",
366 "Proxy-Features",
367 "Proxy-Instruction",
368 "Public",
369 "Public-Key-Pins",
370 "Public-Key-Pins-Report-Only",
371 "Range",
372 "Received",
373 "Received-SPF",
374 "Redirect-Ref",
375 "References",
376 "Referer",
377 "Referer-Root",
378 "Relay-Version",
379 "Reply-By",
380 "Reply-To",
381 "Require-Recipient-Valid-Since",
382 "Resent-Bcc",
383 "Resent-Cc",
384 "Resent-Date",
385 "Resent-From",
386 "Resent-Message-ID",
387 "Resent-Reply-To",
388 "Resent-Sender",
389 "Resent-To",
390 "Resolution-Hint",
391 "Resolver-Location",
392 "Retry-After",
393 "Return-Path",
394 "Safe",
395 "Schedule-Reply",
396 "Schedule-Tag",
397 "Sec-Fetch-Dest",
398 "Sec-Fetch-Mode",
399 "Sec-Fetch-Site",
400 "Sec-Fetch-User",
401 "Sec-WebSocket-Accept",
402 "Sec-WebSocket-Extensions",
403 "Sec-WebSocket-Key",
404 "Sec-WebSocket-Protocol",
405 "Sec-WebSocket-Version",
406 "Security-Scheme",
407 "See-Also",
408 "Sender",
409 "Sensitivity",
410 "Server",
411 "Set-Cookie",
412 "Set-Cookie2",
413 "SetProfile",
414 "SIO-Label",
415 "SIO-Label-History",
416 "SLUG",
417 "SoapAction",
418 "Solicitation",
419 "Status-URI",
420 "Strict-Transport-Security",
421 "Subject",
422 "SubOK",
423 "Subst",
424 "Summary",
425 "Supersedes",
426 "Surrogate-Capability",
427 "Surrogate-Control",
428 "TCN",
429 "TE",
430 "Timeout",
431 "Title",
432 "To",
433 "Topic",
434 "Trailer",
435 "Transfer-Encoding",
436 "TTL",
437 "UA-Color",
438 "UA-Media",
439 "UA-Pixels",
440 "UA-Resolution",
441 "UA-Windowpixels",
442 "Upgrade",
443 "Urgency",
444 "URI",
445 "User-Agent",
446 "Variant-Vary",
447 "Vary",
448 "VBR-Info",
449 "Version",
450 "Via",
451 "Want-Digest",
452 "Warning",
453 "WWW-Authenticate",
454 "X-Archived-At",
455 "X-Device-Accept",
456 "X-Device-Accept-Charset",
457 "X-Device-Accept-Encoding",
458 "X-Device-Accept-Language",
459 "X-Device-User-Agent",
460 "X-Frame-Options",
461 "X-Mittente",
462 "X-PGP-Sig",
463 "X-Ricevuta",
464 "X-Riferimento-Message-ID",
465 "X-TipoRicevuta",
466 "X-Trasporto",
467 "X-VerificaSicurezza",
468 "X400-Content-Identifier",
469 "X400-Content-Return",
470 "X400-Content-Type",
471 "X400-MTS-Identifier",
472 "X400-Originator",
473 "X400-Received",
474 "X400-Recipients",
475 "X400-Trace",
476 "Xref"
477 }})
478 {
479 for(std::size_t i = 1, n = 256; i < n; ++i)
480 {
481 auto sv = by_name_[ i ];
482 auto h = digest(sv);
483 auto j = h % N;
484 BOOST_ASSERT(map_[j][0] == 0);
485 map_[j][0] = static_cast<unsigned char>(i);
486 }
487
488 for(std::size_t i = 256, n = by_name_.size(); i < n; ++i)
489 {
490 auto sv = by_name_[i];
491 auto h = digest(sv);
492 auto j = h % N;
493 BOOST_ASSERT(map_[j][1] == 0);
494 map_[j][1] = static_cast<unsigned char>(i - 255);
495 }
496 }
497
498 field
499 string_to_field(string_view s) const
500 {
501 auto h = digest(s);
502 auto j = h % N;
503 int i = map_[j][0];
504 string_view s2 = by_name_[i];
505 if(i != 0 && equals(s, s2))
506 return static_cast<field>(i);
507 i = map_[j][1];
508 if(i == 0)
509 return field::unknown;
510 i += 255;
511 s2 = by_name_[i];
512
513 if(equals(s, s2))
514 return static_cast<field>(i);
515 return field::unknown;
516 }
517
518 //
519 // Deprecated
520 //
521
522 using const_iterator =
523 array_type::const_iterator;
524
525 std::size_t
526 size() const
527 {
528 return by_name_.size();
529 }
530
531 const_iterator
532 begin() const
533 {
534 return by_name_.begin();
535 }
536
537 const_iterator
538 end() const
539 {
540 return by_name_.end();
541 }
542 };
543
544 BOOST_BEAST_DECL
545 field_table const&
546 get_field_table()
547 {
548 static field_table const tab;
549 return tab;
550 }
551
552 BOOST_BEAST_DECL
553 string_view
554 to_string(field f)
555 {
556 auto const& v = get_field_table();
557 BOOST_ASSERT(static_cast<unsigned>(f) < v.size());
558 return v.begin()[static_cast<unsigned>(f)];
559 }
560
561 } // detail
562
563 string_view
564 to_string(field f)
565 {
566 return detail::to_string(f);
567 }
568
569 field
570 string_to_field(string_view s)
571 {
572 return detail::get_field_table().string_to_field(s);
573 }
574
575 std::ostream&
576 operator<<(std::ostream& os, field f)
577 {
578 return os << to_string(f);
579 }
580
581 } // http
582 } // beast
583 } // boost
584
585 #endif