forked from boostorg/beast
Fix HTTP split parse edge case:
fix #257 This fixes a problem when doing split parsing (header then body). The problem arises when the first buffer passed to the header parser contains exactly the full header and nothing more. The symptom is that when parsing the body, the parse will erroneously be considered complete.
This commit is contained in:
+69
-59
@@ -25,64 +25,8 @@ class parser_v1_test
|
||||
, public test::enable_yield_to
|
||||
{
|
||||
public:
|
||||
void testRegressions()
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
|
||||
// consecutive empty header values
|
||||
{
|
||||
error_code ec;
|
||||
parser_v1<true, string_body, fields> p;
|
||||
std::string const s =
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"X1:\r\n"
|
||||
"X2:\r\n"
|
||||
"X3:x\r\n"
|
||||
"\r\n";
|
||||
p.write(buffer(s), ec);
|
||||
if(! BEAST_EXPECTS(! ec, ec.message()))
|
||||
return;
|
||||
BEAST_EXPECT(p.complete());
|
||||
auto const msg = p.release();
|
||||
BEAST_EXPECT(msg.fields.exists("X1"));
|
||||
BEAST_EXPECT(msg.fields["X1"] == "");
|
||||
BEAST_EXPECT(msg.fields.exists("X2"));
|
||||
BEAST_EXPECT(msg.fields["X2"] == "");
|
||||
BEAST_EXPECT(msg.fields.exists("X3"));
|
||||
BEAST_EXPECT(msg.fields["X3"] == "x");
|
||||
}
|
||||
}
|
||||
|
||||
void testWithBody()
|
||||
{
|
||||
test::string_istream ss{ios_,
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"User-Agent: test\r\n"
|
||||
"Content-Length: 1\r\n"
|
||||
"\r\n"
|
||||
"*"};
|
||||
streambuf rb;
|
||||
header_parser_v1<true, fields> p0;
|
||||
parse(ss, rb, p0);
|
||||
request_header const& reqh = p0.get();
|
||||
BEAST_EXPECT(reqh.method == "GET");
|
||||
BEAST_EXPECT(reqh.url == "/");
|
||||
BEAST_EXPECT(reqh.version == 11);
|
||||
BEAST_EXPECT(reqh.fields["User-Agent"] == "test");
|
||||
BEAST_EXPECT(reqh.fields["Content-Length"] == "1");
|
||||
parser_v1<true, string_body, fields> p =
|
||||
with_body<string_body>(p0);
|
||||
BEAST_EXPECT(p.get().method == "GET");
|
||||
BEAST_EXPECT(p.get().url == "/");
|
||||
BEAST_EXPECT(p.get().version == 11);
|
||||
BEAST_EXPECT(p.get().fields["User-Agent"] == "test");
|
||||
BEAST_EXPECT(p.get().fields["Content-Length"] == "1");
|
||||
parse(ss, rb, p);
|
||||
request<string_body, fields> req = p.release();
|
||||
BEAST_EXPECT(req.body == "*");
|
||||
}
|
||||
|
||||
void run() override
|
||||
void
|
||||
testParse()
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
{
|
||||
@@ -138,9 +82,75 @@ public:
|
||||
BEAST_EXPECT(! ec);
|
||||
BEAST_EXPECT(p.complete());
|
||||
}
|
||||
}
|
||||
|
||||
testRegressions();
|
||||
void
|
||||
testWithBody()
|
||||
{
|
||||
std::string const raw =
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"User-Agent: test\r\n"
|
||||
"Content-Length: 1\r\n"
|
||||
"\r\n"
|
||||
"*";
|
||||
test::string_istream ss{
|
||||
ios_, raw, raw.size() - 1};
|
||||
|
||||
streambuf rb;
|
||||
header_parser_v1<true, fields> p0;
|
||||
parse(ss, rb, p0);
|
||||
request_header const& reqh = p0.get();
|
||||
BEAST_EXPECT(reqh.method == "GET");
|
||||
BEAST_EXPECT(reqh.url == "/");
|
||||
BEAST_EXPECT(reqh.version == 11);
|
||||
BEAST_EXPECT(reqh.fields["User-Agent"] == "test");
|
||||
BEAST_EXPECT(reqh.fields["Content-Length"] == "1");
|
||||
parser_v1<true, string_body, fields> p =
|
||||
with_body<string_body>(p0);
|
||||
BEAST_EXPECT(p.get().method == "GET");
|
||||
BEAST_EXPECT(p.get().url == "/");
|
||||
BEAST_EXPECT(p.get().version == 11);
|
||||
BEAST_EXPECT(p.get().fields["User-Agent"] == "test");
|
||||
BEAST_EXPECT(p.get().fields["Content-Length"] == "1");
|
||||
parse(ss, rb, p);
|
||||
request<string_body, fields> req = p.release();
|
||||
BEAST_EXPECT(req.body == "*");
|
||||
}
|
||||
|
||||
void
|
||||
testRegressions()
|
||||
{
|
||||
using boost::asio::buffer;
|
||||
|
||||
// consecutive empty header values
|
||||
{
|
||||
error_code ec;
|
||||
parser_v1<true, string_body, fields> p;
|
||||
std::string const s =
|
||||
"GET / HTTP/1.1\r\n"
|
||||
"X1:\r\n"
|
||||
"X2:\r\n"
|
||||
"X3:x\r\n"
|
||||
"\r\n";
|
||||
p.write(buffer(s), ec);
|
||||
if(! BEAST_EXPECTS(! ec, ec.message()))
|
||||
return;
|
||||
BEAST_EXPECT(p.complete());
|
||||
auto const msg = p.release();
|
||||
BEAST_EXPECT(msg.fields.exists("X1"));
|
||||
BEAST_EXPECT(msg.fields["X1"] == "");
|
||||
BEAST_EXPECT(msg.fields.exists("X2"));
|
||||
BEAST_EXPECT(msg.fields["X2"] == "");
|
||||
BEAST_EXPECT(msg.fields.exists("X3"));
|
||||
BEAST_EXPECT(msg.fields["X3"] == "x");
|
||||
}
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testParse();
|
||||
testWithBody();
|
||||
testRegressions();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user