basic_parser returns error::header_limit ealier

This commit is contained in:
Mohammad Nejati
2024-08-19 14:35:48 +00:00
committed by Mohammad Nejati
parent a9c4a19f26
commit f181fbf6e4
3 changed files with 68 additions and 91 deletions

View File

@ -642,25 +642,30 @@ private:
error_code& ec);
void
maybe_need_more(
char const* p, std::size_t n,
error_code& ec);
void
parse_start_line(
inner_parse_start_line(
char const*& p, char const* last,
error_code& ec, std::true_type);
void
parse_start_line(
inner_parse_start_line(
char const*& p, char const* last,
error_code& ec, std::false_type);
void
parse_fields(
parse_start_line(
char const*& p, std::size_t n,
error_code& ec);
void
inner_parse_fields(
char const*& p, char const* last,
error_code& ec);
void
parse_fields(
char const*& p, std::size_t n,
error_code& ec);
void
finish_header(
error_code& ec, std::true_type);

View File

@ -111,65 +111,23 @@ loop:
BOOST_FALLTHROUGH;
case state::start_line:
{
maybe_need_more(p, n, ec);
parse_start_line(p, n, ec);
if(ec)
goto done;
parse_start_line(p, p + (std::min<std::size_t>)(
header_limit_, n), ec, is_request{});
if(ec)
{
if(ec == error::need_more)
{
if(n >= header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
goto done;
}
if(p + 3 <= p1)
skip_ = static_cast<
std::size_t>(p1 - p - 3);
}
goto done;
}
BOOST_ASSERT(! is_done());
n = static_cast<std::size_t>(p1 - p);
if(p >= p1)
{
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
goto done;
}
BOOST_FALLTHROUGH;
}
case state::fields:
maybe_need_more(p, n, ec);
parse_fields(p, n, ec);
if(ec)
goto done;
parse_fields(p, p + (std::min<std::size_t>)(
header_limit_, n), ec);
if(ec)
{
if(ec == error::need_more)
{
if(n >= header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
goto done;
}
if(p + 3 <= p1)
skip_ = static_cast<
std::size_t>(p1 - p - 3);
}
goto done;
}
finish_header(ec, is_request{});
if(ec)
goto done;
break;
case state::body0:
BOOST_ASSERT(! skip_);
this->on_body_init_impl(content_length(), ec);
if(ec)
goto done;
@ -177,14 +135,12 @@ loop:
BOOST_FALLTHROUGH;
case state::body:
BOOST_ASSERT(! skip_);
parse_body(p, n, ec);
if(ec)
goto done;
break;
case state::body_to_eof0:
BOOST_ASSERT(! skip_);
this->on_body_init_impl(content_length(), ec);
if(ec)
goto done;
@ -192,7 +148,6 @@ loop:
BOOST_FALLTHROUGH;
case state::body_to_eof:
BOOST_ASSERT(! skip_);
parse_body_to_eof(p, n, ec);
if(ec)
goto done;
@ -262,39 +217,7 @@ put_eof(error_code& ec)
template<bool isRequest>
void
basic_parser<isRequest>::
maybe_need_more(
char const* p, std::size_t n,
error_code& ec)
{
if(skip_ == 0)
return;
if( n > header_limit_)
n = header_limit_;
if(n < skip_ + 4)
{
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
auto const term =
find_eom(p + skip_, p + n);
if(! term)
{
skip_ = n - 3;
if(skip_ + 4 > header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
return;
}
BOOST_BEAST_ASSIGN_EC(ec, error::need_more);
return;
}
skip_ = 0;
}
template<bool isRequest>
void
basic_parser<isRequest>::
parse_start_line(
inner_parse_start_line(
char const*& in, char const* last,
error_code& ec, std::true_type)
{
@ -351,7 +274,7 @@ parse_start_line(
template<bool isRequest>
void
basic_parser<isRequest>::
parse_start_line(
inner_parse_start_line(
char const*& in, char const* last,
error_code& ec, std::false_type)
{
@ -409,7 +332,24 @@ parse_start_line(
template<bool isRequest>
void
basic_parser<isRequest>::
parse_fields(char const*& in,
parse_start_line(
char const*& in, std::size_t n, error_code& ec)
{
auto const p0 = in;
inner_parse_start_line(in, in + (std::min<std::size_t>)
(n, header_limit_), ec, is_request{});
if(ec == error::need_more && n >= header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
}
header_limit_ -= static_cast<std::uint32_t>(in - p0);
}
template<bool isRequest>
void
basic_parser<isRequest>::
inner_parse_fields(char const*& in,
char const* last, error_code& ec)
{
string_view name;
@ -447,6 +387,22 @@ parse_fields(char const*& in,
}
}
template<bool isRequest>
void
basic_parser<isRequest>::
parse_fields(char const*& in, std::size_t n, error_code& ec)
{
auto const p0 = in;
inner_parse_fields(in, in + (std::min<std::size_t>)
(n, header_limit_), ec);
if(ec == error::need_more && n >= header_limit_)
{
BOOST_BEAST_ASSIGN_EC(ec, error::header_limit);
}
header_limit_ -= static_cast<std::uint32_t>(in - p0);
}
template<bool isRequest>
void
basic_parser<isRequest>::
@ -736,7 +692,7 @@ parse_chunk_header(char const*& p0,
if(ec)
return;
p = eol;
parse_fields(p, eom, ec);
parse_fields(p, static_cast<std::size_t>(eom - p), ec);
if(ec)
return;
BOOST_ASSERT(p == eom);

View File

@ -843,6 +843,22 @@ public:
p.put(b.data(), ec);
BEAST_EXPECTS(ec == error::header_limit, ec.message());
}
{
multi_buffer b;
ostream(b) <<
"POST / HTTP/1.1\r\n";
error_code ec;
test_parser<true> p;
p.header_limit(18);
p.eager(true);
b.consume(p.put(b.data(), ec));
BEAST_EXPECTS(ec == error::need_more, ec.message());
ostream(b) <<
"field: value\r\n";
b.consume(p.put(b.data(), ec));
BEAST_EXPECT(! p.is_done());
BEAST_EXPECTS(ec == error::header_limit, ec.message());
}
{
multi_buffer b;
ostream(b) <<