update boost
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user