| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 | //// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//// Official repository: https://github.com/boostorg/beast//#ifndef BOOST_BEAST_HTTP_IMPL_FIELD_IPP#define BOOST_BEAST_HTTP_IMPL_FIELD_IPP#include <boost/beast/http/field.hpp>#include <algorithm>#include <array>#include <cstring>#include <boost/assert.hpp>namespace boost {namespace beast {namespace http {namespace detail {struct field_table{    static    std::uint32_t    get_chars(        unsigned char const* p) noexcept    {        // VFALCO memcpy is endian-dependent        //std::memcpy(&v, p, 4);        // Compiler should be smart enough to        // optimize this down to one instruction.        return             p[0] |            (p[1] <<  8) |            (p[2] << 16) |            (p[3] << 24);    }    using array_type =        std::array<string_view, 353>;    // Strings are converted to lowercase    static    std::uint32_t    digest(string_view s)    {        std::uint32_t r = 0;        std::size_t n = s.size();        auto p = reinterpret_cast<            unsigned char const*>(s.data());        // consume N characters at a time        // VFALCO Can we do 8 on 64-bit systems?        while(n >= 4)        {            auto const v = get_chars(p);            r = (r * 5 + (                v | 0x20202020 )); // convert to lower            p += 4;            n -= 4;        }        // handle remaining characters        while( n > 0 )        {            r = r * 5 + ( *p | 0x20 );            ++p;            --n;        }        return r;    }    // This comparison is case-insensitive, and the    // strings must contain only valid http field characters.    static    bool    equals(string_view lhs, string_view rhs)    {        using Int = std::uint32_t; // VFALCO std::size_t?        auto n = lhs.size();        if(n != rhs.size())            return false;        auto p1 = reinterpret_cast<            unsigned char const*>(lhs.data());        auto p2 = reinterpret_cast<            unsigned char const*>(rhs.data());        auto constexpr S = sizeof(Int);        auto constexpr Mask = static_cast<Int>(            0xDFDFDFDFDFDFDFDF & ~Int{0});        for(; n >= S; p1 += S, p2 += S, n -= S)        {            Int const v1 = get_chars(p1);            Int const v2 = get_chars(p2);            if((v1 ^ v2) & Mask)                return false;        }        for(; n; ++p1, ++p2, --n)            if(( *p1 ^ *p2) & 0xDF)                return false;        return true;    }    array_type by_name_;    enum { N = 5155 };    unsigned char map_[ N ][ 2 ] = {};/*    From:        https://www.iana.org/assignments/message-headers/message-headers.xhtml*/    field_table()        : by_name_({{            "<unknown-field>",            "A-IM",            "Accept",            "Accept-Additions",            "Accept-Charset",            "Accept-Datetime",            "Accept-Encoding",            "Accept-Features",            "Accept-Language",            "Accept-Patch",            "Accept-Post",            "Accept-Ranges",            "Access-Control",            "Access-Control-Allow-Credentials",            "Access-Control-Allow-Headers",            "Access-Control-Allow-Methods",            "Access-Control-Allow-Origin",            "Access-Control-Expose-Headers",            "Access-Control-Max-Age",            "Access-Control-Request-Headers",            "Access-Control-Request-Method",            "Age",            "Allow",            "ALPN",            "Also-Control",            "Alt-Svc",            "Alt-Used",            "Alternate-Recipient",            "Alternates",            "Apparently-To",            "Apply-To-Redirect-Ref",            "Approved",            "Archive",            "Archived-At",            "Article-Names",            "Article-Updates",            "Authentication-Control",            "Authentication-Info",            "Authentication-Results",            "Authorization",            "Auto-Submitted",            "Autoforwarded",            "Autosubmitted",            "Base",            "Bcc",            "Body",            "C-Ext",            "C-Man",            "C-Opt",            "C-PEP",            "C-PEP-Info",            "Cache-Control",            "CalDAV-Timezones",            "Cancel-Key",            "Cancel-Lock",            "Cc",            "Close",            "Comments",            "Compliance",            "Connection",            "Content-Alternative",            "Content-Base",            "Content-Description",            "Content-Disposition",            "Content-Duration",            "Content-Encoding",            "Content-features",            "Content-ID",            "Content-Identifier",            "Content-Language",            "Content-Length",            "Content-Location",            "Content-MD5",            "Content-Range",            "Content-Return",            "Content-Script-Type",            "Content-Style-Type",            "Content-Transfer-Encoding",            "Content-Type",            "Content-Version",            "Control",            "Conversion",            "Conversion-With-Loss",            "Cookie",            "Cookie2",            "Cost",            "DASL",            "Date",            "Date-Received",            "DAV",            "Default-Style",            "Deferred-Delivery",            "Delivery-Date",            "Delta-Base",            "Depth",            "Derived-From",            "Destination",            "Differential-ID",            "Digest",            "Discarded-X400-IPMS-Extensions",            "Discarded-X400-MTS-Extensions",            "Disclose-Recipients",            "Disposition-Notification-Options",            "Disposition-Notification-To",            "Distribution",            "DKIM-Signature",            "DL-Expansion-History",            "Downgraded-Bcc",            "Downgraded-Cc",            "Downgraded-Disposition-Notification-To",            "Downgraded-Final-Recipient",            "Downgraded-From",            "Downgraded-In-Reply-To",            "Downgraded-Mail-From",            "Downgraded-Message-Id",            "Downgraded-Original-Recipient",            "Downgraded-Rcpt-To",            "Downgraded-References",            "Downgraded-Reply-To",            "Downgraded-Resent-Bcc",            "Downgraded-Resent-Cc",            "Downgraded-Resent-From",            "Downgraded-Resent-Reply-To",            "Downgraded-Resent-Sender",            "Downgraded-Resent-To",            "Downgraded-Return-Path",            "Downgraded-Sender",            "Downgraded-To",            "EDIINT-Features",            "Eesst-Version",            "Encoding",            "Encrypted",            "Errors-To",            "ETag",            "Expect",            "Expires",            "Expiry-Date",            "Ext",            "Followup-To",            "Forwarded",            "From",            "Generate-Delivery-Report",            "GetProfile",            "Hobareg",            "Host",            "HTTP2-Settings",            "If",            "If-Match",            "If-Modified-Since",            "If-None-Match",            "If-Range",            "If-Schedule-Tag-Match",            "If-Unmodified-Since",            "IM",            "Importance",            "In-Reply-To",            "Incomplete-Copy",            "Injection-Date",            "Injection-Info",            "Jabber-ID",            "Keep-Alive",            "Keywords",            "Label",            "Language",            "Last-Modified",            "Latest-Delivery-Time",            "Lines",            "Link",            "List-Archive",            "List-Help",            "List-ID",            "List-Owner",            "List-Post",            "List-Subscribe",            "List-Unsubscribe",            "List-Unsubscribe-Post",            "Location",            "Lock-Token",            "Man",            "Max-Forwards",            "Memento-Datetime",            "Message-Context",            "Message-ID",            "Message-Type",            "Meter",            "Method-Check",            "Method-Check-Expires",            "MIME-Version",            "MMHS-Acp127-Message-Identifier",            "MMHS-Authorizing-Users",            "MMHS-Codress-Message-Indicator",            "MMHS-Copy-Precedence",            "MMHS-Exempted-Address",            "MMHS-Extended-Authorisation-Info",            "MMHS-Handling-Instructions",            "MMHS-Message-Instructions",            "MMHS-Message-Type",            "MMHS-Originator-PLAD",            "MMHS-Originator-Reference",            "MMHS-Other-Recipients-Indicator-CC",            "MMHS-Other-Recipients-Indicator-To",            "MMHS-Primary-Precedence",            "MMHS-Subject-Indicator-Codes",            "MT-Priority",            "Negotiate",            "Newsgroups",            "NNTP-Posting-Date",            "NNTP-Posting-Host",            "Non-Compliance",            "Obsoletes",            "Opt",            "Optional",            "Optional-WWW-Authenticate",            "Ordering-Type",            "Organization",            "Origin",            "Original-Encoded-Information-Types",            "Original-From",            "Original-Message-ID",            "Original-Recipient",            "Original-Sender",            "Original-Subject",            "Originator-Return-Address",            "Overwrite",            "P3P",            "Path",            "PEP",            "Pep-Info",            "PICS-Label",            "Position",            "Posting-Version",            "Pragma",            "Prefer",            "Preference-Applied",            "Prevent-NonDelivery-Report",            "Priority",            "Privicon",            "ProfileObject",            "Protocol",            "Protocol-Info",            "Protocol-Query",            "Protocol-Request",            "Proxy-Authenticate",            "Proxy-Authentication-Info",            "Proxy-Authorization",            "Proxy-Connection",            "Proxy-Features",            "Proxy-Instruction",            "Public",            "Public-Key-Pins",            "Public-Key-Pins-Report-Only",            "Range",            "Received",            "Received-SPF",            "Redirect-Ref",            "References",            "Referer",            "Referer-Root",            "Relay-Version",            "Reply-By",            "Reply-To",            "Require-Recipient-Valid-Since",            "Resent-Bcc",            "Resent-Cc",            "Resent-Date",            "Resent-From",            "Resent-Message-ID",            "Resent-Reply-To",            "Resent-Sender",            "Resent-To",            "Resolution-Hint",            "Resolver-Location",            "Retry-After",            "Return-Path",            "Safe",            "Schedule-Reply",            "Schedule-Tag",            "Sec-WebSocket-Accept",            "Sec-WebSocket-Extensions",            "Sec-WebSocket-Key",            "Sec-WebSocket-Protocol",            "Sec-WebSocket-Version",            "Security-Scheme",            "See-Also",            "Sender",            "Sensitivity",            "Server",            "Set-Cookie",            "Set-Cookie2",            "SetProfile",            "SIO-Label",            "SIO-Label-History",            "SLUG",            "SoapAction",            "Solicitation",            "Status-URI",            "Strict-Transport-Security",            "Subject",            "SubOK",            "Subst",            "Summary",            "Supersedes",            "Surrogate-Capability",            "Surrogate-Control",            "TCN",            "TE",            "Timeout",            "Title",            "To",            "Topic",            "Trailer",            "Transfer-Encoding",            "TTL",            "UA-Color",            "UA-Media",            "UA-Pixels",            "UA-Resolution",            "UA-Windowpixels",            "Upgrade",            "Urgency",            "URI",            "User-Agent",            "Variant-Vary",            "Vary",            "VBR-Info",            "Version",            "Via",            "Want-Digest",            "Warning",            "WWW-Authenticate",            "X-Archived-At",            "X-Device-Accept",            "X-Device-Accept-Charset",            "X-Device-Accept-Encoding",            "X-Device-Accept-Language",            "X-Device-User-Agent",            "X-Frame-Options",            "X-Mittente",            "X-PGP-Sig",            "X-Ricevuta",            "X-Riferimento-Message-ID",            "X-TipoRicevuta",            "X-Trasporto",            "X-VerificaSicurezza",            "X400-Content-Identifier",            "X400-Content-Return",            "X400-Content-Type",            "X400-MTS-Identifier",            "X400-Originator",            "X400-Received",            "X400-Recipients",            "X400-Trace",            "Xref"        }})    {        for(std::size_t i = 1, n = 256; i < n; ++i)        {            auto sv = by_name_[ i ];            auto h = digest(sv);            auto j = h % N;            BOOST_ASSERT(map_[j][0] == 0);            map_[j][0] = static_cast<unsigned char>(i);        }        for(std::size_t i = 256, n = by_name_.size(); i < n; ++i)        {            auto sv = by_name_[i];            auto h = digest(sv);            auto j = h % N;            BOOST_ASSERT(map_[j][1] == 0);            map_[j][1] = static_cast<unsigned char>(i - 255);        }    }    field    string_to_field(string_view s) const    {        auto h = digest(s);        auto j = h % N;        int i = map_[j][0];        string_view s2 = by_name_[i];        if(i != 0 && equals(s, s2))            return static_cast<field>(i);        i = map_[j][1];        if(i == 0)            return field::unknown;        i += 255;        s2 = by_name_[i];        if(equals(s, s2))            return static_cast<field>(i);        return field::unknown;    }    //    // Deprecated    //    using const_iterator =    array_type::const_iterator;     std::size_t    size() const    {        return by_name_.size();    }    const_iterator    begin() const    {        return by_name_.begin();    }    const_iterator    end() const    {        return by_name_.end();    }};BOOST_BEAST_DECLfield_table const&get_field_table(){    static field_table const tab;    return tab;}BOOST_BEAST_DECLstring_viewto_string(field f){    auto const& v = get_field_table();    BOOST_ASSERT(static_cast<unsigned>(f) < v.size());    return v.begin()[static_cast<unsigned>(f)];}} // detailstring_viewto_string(field f){    return detail::to_string(f);}fieldstring_to_field(string_view s){    return detail::get_field_table().string_to_field(s);}} // http} // beast} // boost#endif
 |