New HTTP interfaces (API Change):

fix #123
fix #154
fix #265

This completely replaces the HTTP parser used to read and
parse incoming messages. The new version is faster than
the old one, and written in fewer lines. A summary of
changes:

* parse and async_parse renamed to read and async_read

* basic_parser is optimized for linear buffers,
  use flat_streambuf for the best performance with these
  functions:

  - http::read
  - http::read_some
  - http::async_read
  - http::async_read_some

* The overloads of read() and async_read() which take
  just a header have been removed, since they would
  throw away important parse metadata.

* The derived class callbacks for basic_parser have
  been streamlined. All strings passed to callbacks
  are presented in their entirety, instead of being
  provided in pieces.

These changes allow use-cases that were previously
difficult or impossible, such as:

- Efficient relaying

- Late body type commitment

- Expect: 100-continue handling
This commit is contained in:
Vinnie Falco
2017-07-20 08:12:15 -07:00
parent 34830a1780
commit e8be3fd7d3
74 changed files with 7106 additions and 5972 deletions
+109 -5
View File
@@ -13,9 +13,10 @@
#include <string>
#include <vector>
#include <beast/core/detail/empty_base_optimization.hpp>
namespace beast {
namespace http {
namespace test {
class rfc7230_test : public beast::unit_test::suite
{
@@ -135,9 +136,9 @@ public:
BEAST_EXPECTS(got == good, fmt(got));
};
/*
ext-list = *( "," OWS ) ext *( OWS "," [ OWS ext ] )
ext = token param-list
param-list = *( OWS ";" OWS param )
ext-basic_parsed_list = *( "," OWS ) ext *( OWS "," [ OWS ext ] )
ext = token param-basic_parsed_list
param-basic_parsed_list = *( OWS ";" OWS param )
param = token OWS "=" OWS ( token / quoted-string )
*/
cs(",", "");
@@ -237,17 +238,120 @@ public:
cs("x y", "x");
}
template<class Policy>
static
std::vector<std::string>
to_vector(boost::string_ref const& in)
{
std::vector<std::string> v;
detail::basic_parsed_list<Policy> list{in};
for(auto const& s :
detail::basic_parsed_list<Policy>{in})
v.emplace_back(s.data(), s.size());
return v;
}
template<class Policy>
void
validate(boost::string_ref const& in,
std::vector<std::string> const& v)
{
BEAST_EXPECT(to_vector<Policy>(in) == v);
}
template<class Policy>
void
good(boost::string_ref const& in)
{
BEAST_EXPECT(validate_list(
detail::basic_parsed_list<Policy>{in}));
}
template<class Policy>
void
good(boost::string_ref const& in,
std::vector<std::string> const& v)
{
BEAST_EXPECT(validate_list(
detail::basic_parsed_list<Policy>{in}));
validate<Policy>(in, v);
}
template<class Policy>
void
bad(boost::string_ref const& in)
{
BEAST_EXPECT(! validate_list(
detail::basic_parsed_list<Policy>{in}));
}
void
testOptTokenList()
{
/*
#token = [ ( "," / token ) *( OWS "," [ OWS token ] ) ]
*/
using type = detail::opt_token_list_policy;
good<type>("", {});
good<type>(" ", {});
good<type>("\t", {});
good<type>(" \t", {});
good<type>(",", {});
good<type>(",,", {});
good<type>(", ,", {});
good<type>(",\t,", {});
good<type>(", \t,", {});
good<type>(", \t, ", {});
good<type>(", \t,\t", {});
good<type>(", \t, \t", {});
good<type>("x", {"x"});
good<type>(" x", {"x"});
good<type>("x,,", {"x"});
good<type>("x, ,", {"x"});
good<type>("x,, ", {"x"});
good<type>("x,,,", {"x"});
good<type>("x,y", {"x","y"});
good<type>("x ,y", {"x","y"});
good<type>("x\t,y", {"x","y"});
good<type>("x \t,y", {"x","y"});
good<type>(" x,y", {"x","y"});
good<type>(" x,y ", {"x","y"});
good<type>(",x,y", {"x","y"});
good<type>("x,y,", {"x","y"});
good<type>(",,x,y", {"x","y"});
good<type>(",x,,y", {"x","y"});
good<type>(",x,y,", {"x","y"});
good<type>("x ,, y", {"x","y"});
good<type>("x , ,y", {"x","y"});
good<type>("x,y,z", {"x","y","z"});
bad<type>("(");
bad<type>("x(");
bad<type>("(x");
bad<type>(",(");
bad<type>("(,");
bad<type>("x,(");
bad<type>("(,x");
bad<type>("x y");
}
void
run()
{
testOptTokenList();
#if 0
testParamList();
testExtList();
testTokenList();
#endif
}
};
BEAST_DEFINE_TESTSUITE(rfc7230,http,beast);
} // test
} // http
} // beast