File indexing completed on 2025-01-18 09:29:29
0001
0002
0003
0004
0005
0006
0007
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,
0033 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0034 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0035 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0036 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0037 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0038 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0039 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0040 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0041 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0042 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0043 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0044 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0045 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0046 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0047 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
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
0057 static char constexpr tab[] = {
0058 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0059 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0060 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0061 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0062 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0063 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0064 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0065 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0066 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0067 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0068 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0069 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0070 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0071 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0072 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0073 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
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
0084
0085
0086
0087
0088 static char constexpr tab[] = {
0089 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,
0091 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
0092 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0093 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0094 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
0095 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0096 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
0097 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0098 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0099 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
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
0115
0116 static char constexpr tab[] = {
0117 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0119 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0120 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0121 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0122 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
0123 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0124 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0125 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0126 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0127 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0128 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0129 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0131 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0132 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
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
0143
0144
0145 static char constexpr tab[] = {
0146 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0148 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0149 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0150 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0151 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0152 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0153 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0154 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0155 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0156 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0157 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0158 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0159 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0160 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0161 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
0162 };
0163 BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0164 return tab[static_cast<unsigned char>(c)];
0165 }
0166
0167
0168
0169
0170 char
0171 to_value_char(char c)
0172 {
0173
0174 static unsigned char constexpr tab[] = {
0175 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0,
0176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0177 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
0178 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
0179 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
0180 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95,
0181 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
0182 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 0,
0183 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
0184 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
0185 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
0186 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
0187 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
0188 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
0189 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
0190 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
0191 };
0192 BOOST_STATIC_ASSERT(sizeof(tab) == 256);
0193 return static_cast<char>(tab[static_cast<unsigned char>(c)]);
0194 }
0195
0196
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,
0202 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0203 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0204 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
0205 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0206 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0207 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0208 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0209 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0210 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0211 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0212 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0213 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0214 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0215 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0216 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
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
0269
0270
0271
0272
0273
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
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
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
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 }
0385 }
0386 }
0387 }
0388
0389 #endif
0390