Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:29

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
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         // VFALCO memcpy is endian-dependent
0036         //std::memcpy(&v, p, 4);
0037         // Compiler should be smart enough to
0038         // optimize this down to one instruction.
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     // Strings are converted to lowercase
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         // consume N characters at a time
0059         // VFALCO Can we do 8 on 64-bit systems?
0060         while(n >= 4)
0061         {
0062             auto const v = get_chars(p);
0063             r = (r * 5 + (
0064                 v | 0x20202020 )); // convert to lower
0065             p += 4;
0066             n -= 4;
0067         }
0068         // handle remaining characters
0069         while( n > 0 )
0070         {
0071             r = r * 5 + ( *p | 0x20 );
0072             ++p;
0073             --n;
0074         }
0075         return r;
0076     }
0077 
0078     // This comparison is case-insensitive, and the
0079     // strings must contain only valid http field characters.
0080     static
0081     bool
0082     equals(string_view lhs, string_view rhs)
0083     {
0084         using Int = std::uint32_t; // VFALCO std::size_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     From:
0115     
0116     https://www.iana.org/assignments/message-headers/message-headers.xhtml
0117 */
0118     field_table()
0119         : by_name_({{
0120 // string constants
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     // Deprecated
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 } // detail
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 } // http
0583 } // beast
0584 } // boost
0585 
0586 #endif