Reusing an HTTP parser returns an error

This commit is contained in:
Vinnie Falco
2019-02-28 10:27:43 -08:00
parent 8eb15148d7
commit 00487f1de6
6 changed files with 45 additions and 1 deletions

View File

@ -2,6 +2,7 @@ Version 224:
* Remove extraneous error check in advanced-server-flex
* Advanced servers use HTTP parser interfaces for reading
* Reusing an HTTP parser returns an error
--------------------------------------------------------------------------------

View File

@ -353,6 +353,8 @@
* ([issue 1460]) Large WebSocket Upgrade response no longer overflows
* Reusing an HTTP parser returns an error
* Handler bind wrappers use the associated allocator
* `buffers_cat`

View File

@ -144,7 +144,16 @@ enum class error
bad_chunk_extension,
/// An obs-fold exceeded an internal limit.
bad_obs_fold
bad_obs_fold,
/** The parser is stale.
This happens when attempting to re-use a parser that has
already completed parsing a message. Programs must construct
a new parser for each message. This can be easily done by
storing the parser in an boost or std::optional container.
*/
stale_parser
};
} // http

View File

@ -55,6 +55,7 @@ public:
case error::bad_chunk: return "bad chunk";
case error::bad_chunk_extension: return "bad chunk extension";
case error::bad_obs_fold: return "bad obs-fold";
case error::stale_parser: return "stale parser";
default:
return "beast.http error";

View File

@ -61,6 +61,7 @@ class parser
message<isRequest, Body, basic_fields<Allocator>> m_;
typename Body::reader rd_;
bool rd_inited_ = false;
bool used_ = false;
std::function<void(
std::uint64_t,
@ -335,6 +336,20 @@ private:
error_code& ec,
std::true_type)
{
// If this assert goes off, it means you tried to re-use a
// parser after it was done reading a message. This is not
// allowed, you need to create a new parser for each message.
// The easiest way to do that is to store the parser in
// an optional object.
BOOST_ASSERT(! used_);
if(used_)
{
ec = error::stale_parser;
return;
}
used_ = true;
try
{
m_.target(target);
@ -378,6 +393,20 @@ private:
error_code& ec,
std::true_type)
{
// If this assert goes off, it means you tried to re-use a
// parser after it was done reading a message. This is not
// allowed, you need to create a new parser for each message.
// The easiest way to do that is to store the parser in
// an optional object.
BOOST_ASSERT(! used_);
if(used_)
{
ec = error::stale_parser;
return;
}
used_ = true;
m_.result(code);
m_.version(version);
try

View File

@ -65,6 +65,8 @@ public:
check("beast.http", error::bad_chunk);
check("beast.http", error::bad_chunk_extension);
check("beast.http", error::bad_obs_fold);
check("beast.http", error::stale_parser);
}
};