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_DETAIL_RFC7230_IPP
0011 #define BOOST_BEAST_HTTP_DETAIL_RFC7230_IPP
0012 
0013 #include <boost/beast/core/string.hpp>
0014 #include <iterator>
0015 #include <utility>
0016 
0017 namespace boost {
0018 namespace beast {
0019 namespace http {
0020 namespace detail {
0021 
0022 bool
0023 is_digit(char c)
0024 {
0025     return c >= '0' && c <= '9';
0026 }
0027 
0028 char
0029 is_alpha(char c)
0030 {
0031     static char constexpr tab[] = {
0032         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 0
0033         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 16
0034         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 32
0035         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 48
0036         0, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 64
0037         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 0,  0, 0, 0, 0, // 80
0038         0, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 96
0039         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 0,  0, 0, 0, 0, // 112
0040         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 128
0041         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 144
0042         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 160
0043         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 176
0044         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 192
0045         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 208
0046         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 224
0047         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0  // 240
0048     };
0049     BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0050     return tab[static_cast<unsigned char>(c)];
0051 }
0052 
0053 char
0054 is_text(char c)
0055 {
0056     // TEXT = <any OCTET except CTLs, but including LWS>
0057     static char constexpr tab[] = {
0058         0, 0, 0, 0,  0, 0, 0, 0,  0, 1, 0, 0,  0, 0, 0, 0, // 0
0059         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 16
0060         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 32
0061         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 48
0062         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 64
0063         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 80
0064         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 96
0065         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 0, // 112
0066         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 128
0067         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 144
0068         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 160
0069         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 176
0070         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 192
0071         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 208
0072         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 224
0073         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1  // 240
0074     };
0075     BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0076     return tab[static_cast<unsigned char>(c)];
0077 }
0078 
0079 char
0080 is_token_char(char c)
0081 {
0082     /*
0083         tchar = "!" | "#" | "$" | "%" | "&" |
0084                 "'" | "*" | "+" | "-" | "." |
0085                 "^" | "_" | "`" | "|" | "~" |
0086                 DIGIT | ALPHA
0087     */
0088     static char constexpr tab[] = {
0089         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 0
0090         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 16
0091         0, 1, 0, 1,  1, 1, 1, 1,  0, 0, 1, 1,  0, 1, 1, 0, // 32
0092         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 0, 0,  0, 0, 0, 0, // 48
0093         0, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 64
0094         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 0,  0, 0, 1, 1, // 80
0095         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 96
0096         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 0,  1, 0, 1, 0, // 112
0097         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 128
0098         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 144
0099         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 160
0100         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 176
0101         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 192
0102         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 208
0103         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 224
0104         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0  // 240
0105     };
0106     BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0107     return tab[static_cast<unsigned char>(c)];
0108 }
0109 
0110 char
0111 is_qdchar(char c)
0112 {
0113     /*
0114         qdtext = HTAB / SP / "!" / %x23-5B ; '#'-'[' / %x5D-7E ; ']'-'~' / obs-text
0115     */
0116     static char constexpr tab[] = {
0117         0, 0, 0, 0,  0, 0, 0, 0,  0, 1, 0, 0,  0, 0, 0, 0, // 0
0118         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 16
0119         1, 1, 0, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 32
0120         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 48
0121         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 64
0122         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  0, 1, 1, 1, // 80
0123         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 96
0124         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 0, // 112
0125         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 128
0126         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 144
0127         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 160
0128         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 176
0129         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 192
0130         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 208
0131         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 224
0132         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1  // 240
0133     };
0134     BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0135     return tab[static_cast<unsigned char>(c)];
0136 }
0137 
0138 char
0139 is_qpchar(char c)
0140 {
0141     /*
0142         quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
0143         obs-text = %x80-FF
0144     */
0145     static char constexpr tab[] = {
0146         0, 0, 0, 0,  0, 0, 0, 0,  0, 1, 0, 0,  0, 0, 0, 0, // 0
0147         0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0, // 16
0148         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 32
0149         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 48
0150         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 64
0151         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 80
0152         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 96
0153         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 0, // 112
0154         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 128
0155         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 144
0156         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 160
0157         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 176
0158         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 192
0159         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 208
0160         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1, // 224
0161         1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1  // 240
0162     };
0163     BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0164     return tab[static_cast<unsigned char>(c)];
0165 }
0166 
0167 // converts to lower case,
0168 // returns 0 if not a valid text char
0169 //
0170 char
0171 to_value_char(char c)
0172 {
0173     // TEXT = <any OCTET except CTLs, but including LWS>
0174     static unsigned char constexpr tab[] = {
0175           0,   0,   0,   0,   0,   0,   0,   0,   0,   9,   0,   0,   0,   0,   0,   0, // 0
0176           0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, // 16
0177          32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47, // 32
0178          48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63, // 48
0179          64,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 64
0180         112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,  91,  92,  93,  94,  95, // 80
0181          96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 96
0182         112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,   0, // 112
0183         128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, // 128
0184         144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, // 144
0185         160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, // 160
0186         176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, // 176
0187         192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, // 192
0188         208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, // 208
0189         224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, // 224
0190         240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255  // 240
0191     };
0192     BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0193     return static_cast<char>(tab[static_cast<unsigned char>(c)]);
0194 }
0195 
0196 // VFALCO TODO Make this return unsigned?
0197 std::int8_t
0198 unhex(char c)
0199 {
0200     static signed char constexpr tab[] = {
0201         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0
0202         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16
0203         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32
0204          0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, // 48
0205         -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 64
0206         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80
0207         -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96
0208         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 112
0209         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128
0210         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144
0211         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160
0212         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176
0213         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192
0214         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208
0215         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224
0216         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  // 240
0217     };
0218     BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0219     return tab[static_cast<unsigned char>(c)];
0220 }
0221 
0222 template <class ForwardIt>
0223 void
0224 skip_ows(ForwardIt& it, ForwardIt end)
0225 {
0226     while(it != end)
0227     {
0228         if(*it != ' ' && *it != '\t')
0229             break;
0230         ++it;
0231     }
0232 }
0233 
0234 template <class ForwardIt>
0235 void
0236 skip_token(ForwardIt& it, ForwardIt last)
0237 {
0238     while(it != last && is_token_char(*it))
0239         ++it;
0240 }
0241 
0242 string_view
0243 trim(string_view s)
0244 {
0245     auto first = s.begin();
0246     auto last = s.end();
0247     skip_ows(first, last);
0248     while(first != last)
0249     {
0250         auto const c = *std::prev(last);
0251         if(c != ' ' && c != '\t')
0252             break;
0253         --last;
0254     }
0255     if(first == last)
0256         return {};
0257     return {&*first,
0258         static_cast<std::size_t>(last - first)};
0259 }
0260 
0261 
0262 BOOST_BEAST_DECL
0263 void
0264 param_iter::
0265 increment()
0266 {
0267 /*
0268     param-list      = *( OWS ";" OWS param )
0269     param           = token OWS [ "=" OWS ( token / quoted-string ) ]
0270     quoted-string   = DQUOTE *( qdtext / quoted-pair ) DQUOTE
0271     qdtext          = HTAB / SP / "!" / %x23-5B ; '#'-'[' / %x5D-7E ; ']'-'~' / obs-text
0272     quoted-pair     = "\" ( HTAB / SP / VCHAR / obs-text )
0273     obs-text        = %x80-FF
0274 */
0275     auto const err =
0276         [&]
0277         {
0278             it = first;
0279         };
0280     v.first = {};
0281     v.second = {};
0282     detail::skip_ows(it, last);
0283     first = it;
0284     if(it == last)
0285         return err();
0286     if(*it != ';')
0287         return err();
0288     ++it;
0289     detail::skip_ows(it, last);
0290     if(it == last)
0291         return err();
0292     // param
0293     if(! detail::is_token_char(*it))
0294         return err();
0295     auto const p0 = it;
0296     skip_token(++it, last);
0297     auto const p1 = it;
0298     v.first = { &*p0, static_cast<std::size_t>(p1 - p0) };
0299     detail::skip_ows(it, last);
0300     if(it == last)
0301         return;
0302     if(*it == ';')
0303         return;
0304     if(*it != '=')
0305         return err();
0306     ++it;
0307     detail::skip_ows(it, last);
0308     if(it == last)
0309         return;
0310     if(*it == '"')
0311     {
0312         // quoted-string
0313         auto const p2 = it;
0314         ++it;
0315         for(;;)
0316         {
0317             if(it == last)
0318                 return err();
0319             auto c = *it++;
0320             if(c == '"')
0321                 break;
0322             if(detail::is_qdchar(c))
0323                 continue;
0324             if(c != '\\')
0325                 return err();
0326             if(it == last)
0327                 return err();
0328             c = *it++;
0329             if(! detail::is_qpchar(c))
0330                 return err();
0331         }
0332         v.second = { &*p2, static_cast<std::size_t>(it - p2) };
0333     }
0334     else
0335     {
0336         // token
0337         if(! detail::is_token_char(*it))
0338             return err();
0339         auto const p2 = it;
0340         skip_token(++it, last);
0341         v.second = { &*p2, static_cast<std::size_t>(it - p2) };
0342     }
0343 }
0344 
0345 bool
0346 opt_token_list_policy::operator()(value_type& v,
0347     char const*& it, string_view s) const
0348 {
0349     v = {};
0350     auto need_comma = it != s.data();
0351     for(;;)
0352     {
0353         detail::skip_ows(it, (s.data() + s.size()));
0354         if(it == (s.data() + s.size()))
0355         {
0356             it = nullptr;
0357             return true;
0358         }
0359         auto const c = *it;
0360         if(detail::is_token_char(c))
0361         {
0362             if(need_comma)
0363                 return false;
0364             auto const p0 = it;
0365             for(;;)
0366             {
0367                 ++it;
0368                 if(it == (s.data() + s.size()))
0369                     break;
0370                 if(! detail::is_token_char(*it))
0371                     break;
0372             }
0373             v = string_view{p0,
0374                 static_cast<std::size_t>(it - p0)};
0375             return true;
0376         }
0377         if(c != ',')
0378             return false;
0379         need_comma = false;
0380         ++it;
0381     }
0382 }
0383 
0384 } // detail
0385 } // http
0386 } // beast
0387 } // boost
0388 
0389 #endif // BOOST_BEAST_HTTP_DETAIL_RFC7230_IPP
0390