update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -14,9 +14,9 @@
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/rfc7230.hpp>
#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/static_string.hpp>
#include <boost/beast/core/detail/clamp.hpp>
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/detail/string.hpp>
#include <boost/asio/buffer.hpp>
#include <algorithm>
#include <utility>
@@ -50,9 +50,7 @@ basic_parser<isRequest>::
content_length() const
{
BOOST_ASSERT(is_header_done());
if(! (f_ & flagContentLength))
return boost::none;
return len0_;
return content_length_unchecked();
}
template<bool isRequest>
@@ -84,7 +82,17 @@ basic_parser<isRequest>::
put(net::const_buffer buffer,
error_code& ec)
{
BOOST_ASSERT(state_ != state::complete);
// If this goes off you have tried to parse more data after the parser
// has completed. A common cause of this is re-using a parser, which is
// not supported. If you need to re-use a parser, consider storing it
// in an optional. Then reset() and emplace() prior to parsing each new
// message.
BOOST_ASSERT(!is_done());
if (is_done())
{
BOOST_BEAST_ASSIGN_EC(ec, error::stale_parser);
return 0;
}
auto p = static_cast<char const*>(buffer.data());
auto n = buffer.size();
auto const p0 = p;
@@ -96,7 +104,7 @@ loop:
case state::nothing_yet:
if(n == 0)
{
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return 0;
}
state_ = state::start_line;
@@ -115,7 +123,7 @@ loop:
{
if(n >= header_limit_)
{
ec = error::header_limit;
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
goto done;
}
if(p + 3 <= p1)
@@ -128,7 +136,7 @@ loop:
n = static_cast<std::size_t>(p1 - p);
if(p >= p1)
{
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
goto done;
}
BOOST_FALLTHROUGH;
@@ -146,7 +154,7 @@ loop:
{
if(n >= header_limit_)
{
ec = error::header_limit;
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
goto done;
}
if(p + 3 <= p1)
@@ -156,6 +164,8 @@ loop:
goto done;
}
finish_header(ec, is_request{});
if(ec)
goto done;
break;
case state::body0:
@@ -229,14 +239,14 @@ put_eof(error_code& ec)
if( state_ == state::start_line ||
state_ == state::fields)
{
ec = error::partial_message;
BOOST_BEAST_ASSIGN_EC(ec, error::partial_message);
return;
}
if(f_ & (flagContentLength | flagChunked))
{
if(state_ != state::complete)
{
ec = error::partial_message;
BOOST_BEAST_ASSIGN_EC(ec, error::partial_message);
return;
}
ec = {};
@@ -262,7 +272,7 @@ maybe_need_more(
n = header_limit_;
if(n < skip_ + 4)
{
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
auto const term =
@@ -272,10 +282,10 @@ maybe_need_more(
skip_ = n - 3;
if(skip_ + 4 > header_limit_)
{
ec = error::header_limit;
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
return;
}
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
skip_ = 0;
@@ -310,18 +320,18 @@ parse_start_line(
return;
if(version < 10 || version > 11)
{
ec = error::bad_version;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_version);
return;
}
if(p + 2 > last)
{
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
if(p[0] != '\r' || p[1] != '\n')
{
ec = error::bad_version;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_version);
return;
}
p += 2;
@@ -358,19 +368,19 @@ parse_start_line(
return;
if(version < 10 || version > 11)
{
ec = error::bad_version;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_version);
return;
}
// SP
if(p + 1 > last)
{
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
if(*p++ != ' ')
{
ec = error::bad_version;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_version);
return;
}
@@ -405,19 +415,21 @@ parse_fields(char const*& in,
string_view name;
string_view value;
// https://stackoverflow.com/questions/686217/maximum-on-http-header-values
static_string<max_obs_fold> buf;
beast::detail::char_buffer<max_obs_fold> buf;
auto p = in;
for(;;)
{
if(p + 2 > last)
{
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
if(p[0] == '\r')
{
if(p[1] != '\n')
ec = error::bad_line_ending;
{
BOOST_BEAST_ASSIGN_EC(ec, error::bad_line_ending);
}
in = p + 2;
return;
}
@@ -449,9 +461,10 @@ finish_header(error_code& ec, std::true_type)
}
else if(f_ & flagContentLength)
{
if(len_ > body_limit_)
if(body_limit_.has_value() &&
len_ > body_limit_)
{
ec = error::body_limit;
BOOST_BEAST_ASSIGN_EC(ec, error::body_limit);
return;
}
if(len_ > 0)
@@ -508,15 +521,17 @@ finish_header(error_code& ec, std::false_type)
}
else if(f_ & flagContentLength)
{
if(len_ > body_limit_)
{
ec = error::body_limit;
return;
}
if(len_ > 0)
{
f_ |= flagHasBody;
state_ = state::body0;
if(body_limit_.has_value() &&
len_ > body_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::body_limit);
return;
}
}
else
{
@@ -574,12 +589,15 @@ basic_parser<isRequest>::
parse_body_to_eof(char const*& p,
std::size_t n, error_code& ec)
{
if(n > body_limit_)
if(body_limit_.has_value())
{
ec = error::body_limit;
return;
if (n > *body_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::body_limit);
return;
}
*body_limit_ -= n;
}
body_limit_ = body_limit_ - n;
ec = {};
n = this->on_body_impl(string_view{p, n}, ec);
p += n;
@@ -615,7 +633,7 @@ parse_chunk_header(char const*& p0,
{
if(n < skip_ + 2)
{
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
if(f_ & flagExpectCRLF)
@@ -625,7 +643,7 @@ parse_chunk_header(char const*& p0,
// be parsed in one call instead of two.
if(! parse_crlf(p))
{
ec = error::bad_chunk;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_chunk);
return;
}
}
@@ -634,7 +652,7 @@ parse_chunk_header(char const*& p0,
return;
if(! eol)
{
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
skip_ = n - 1;
return;
}
@@ -644,24 +662,27 @@ parse_chunk_header(char const*& p0,
std::uint64_t size;
if(! parse_hex(p, size))
{
ec = error::bad_chunk;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_chunk);
return;
}
if(size != 0)
{
if(size > body_limit_)
if (body_limit_.has_value())
{
ec = error::body_limit;
return;
if (size > *body_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::body_limit);
return;
}
*body_limit_ -= size;
}
body_limit_ -= size;
auto const start = p;
parse_chunk_extensions(p, pend, ec);
if(ec)
return;
if(p != eol -2 )
{
ec = error::bad_chunk_extension;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_chunk_extension);
return;
}
auto const ext = make_string(start, p);
@@ -694,7 +715,7 @@ parse_chunk_header(char const*& p0,
{
BOOST_ASSERT(n >= 3);
skip_ = n - 3;
ec = error::need_more;
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
@@ -704,7 +725,7 @@ parse_chunk_header(char const*& p0,
return;
if(p != eol - 2)
{
ec = error::bad_chunk_extension;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_chunk_extension);
return;
}
auto const ext = make_string(start, p);
@@ -746,6 +767,7 @@ basic_parser<isRequest>::
do_field(field f,
string_view value, error_code& ec)
{
using namespace beast::detail::string_literals;
// Connection
if(f == field::connection ||
f == field::proxy_connection)
@@ -754,24 +776,24 @@ do_field(field f,
if(! validate_list(list))
{
// VFALCO Should this be a field specific error?
ec = error::bad_value;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_value);
return;
}
for(auto const& s : list)
{
if(iequals({"close", 5}, s))
if(beast::iequals("close"_sv, s))
{
f_ |= flagConnectionClose;
continue;
}
if(iequals({"keep-alive", 10}, s))
if(beast::iequals("keep-alive"_sv, s))
{
f_ |= flagConnectionKeepAlive;
continue;
}
if(iequals({"upgrade", 7}, s))
if(beast::iequals("upgrade"_sv, s))
{
f_ |= flagConnectionUpgrade;
continue;
@@ -784,31 +806,53 @@ do_field(field f,
// Content-Length
if(f == field::content_length)
{
if(f_ & flagContentLength)
auto bad_content_length = [&ec]
{
// duplicate
ec = error::bad_content_length;
return;
}
BOOST_BEAST_ASSIGN_EC(ec, error::bad_content_length);
};
auto multiple_content_length = [&ec]
{
BOOST_BEAST_ASSIGN_EC(ec, error::multiple_content_length);
};
// conflicting field
if(f_ & flagChunked)
return bad_content_length();
// Content-length may be a comma-separated list of integers
auto tokens_unprocessed = 1 +
std::count(value.begin(), value.end(), ',');
auto tokens = opt_token_list(value);
if (tokens.begin() == tokens.end() ||
!validate_list(tokens))
return bad_content_length();
auto existing = this->content_length_unchecked();
for (auto tok : tokens)
{
// conflicting field
ec = error::bad_content_length;
return;
std::uint64_t v;
if (!parse_dec(tok, v))
return bad_content_length();
--tokens_unprocessed;
if (existing.has_value())
{
if (v != *existing)
return multiple_content_length();
}
else
{
existing = v;
}
}
std::uint64_t v;
if(! parse_dec(
value.begin(), value.end(), v))
{
ec = error::bad_content_length;
return;
}
if (tokens_unprocessed)
return bad_content_length();
BOOST_ASSERT(existing.has_value());
ec = {};
len_ = v;
len0_ = v;
len_ = *existing;
len0_ = *existing;
f_ |= flagContentLength;
return;
}
@@ -819,23 +863,23 @@ do_field(field f,
if(f_ & flagChunked)
{
// duplicate
ec = error::bad_transfer_encoding;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_transfer_encoding);
return;
}
if(f_ & flagContentLength)
{
// conflicting field
ec = error::bad_transfer_encoding;
BOOST_BEAST_ASSIGN_EC(ec, error::bad_transfer_encoding);
return;
}
ec = {};
auto const v = token_list{value};
auto const p = std::find_if(v.begin(), v.end(),
[&](typename token_list::value_type const& s)
[&](string_view const& s)
{
return iequals({"chunked", 7}, s);
return beast::iequals("chunked"_sv, s);
});
if(p == v.end())
return;