Refactor HTTP serialization and parsing (API Change):

fix #404

Parsing and serialization interfaces have been fine tuned and unified.

For parsing these stream operations are defined:

* read
* read_header
* read_some
* async_read
* async_read_header
* async_read_some

For serialization these stream operations are defined:

* write
* write_header
* write_some
* async_write
* async_write_header
* async_write_some
This commit is contained in:
Vinnie Falco
2017-05-31 08:01:55 -07:00
parent 50cba32565
commit fe75a7ca2a
44 changed files with 3655 additions and 3250 deletions
+39 -35
View File
@@ -148,19 +148,18 @@ public:
return {s, N-1};
}
template<
bool isRequest, bool isDirect, class Derived>
template<bool isRequest, class Derived>
static
std::size_t
feed(boost::asio::const_buffer buffer,
basic_parser<isRequest, isDirect, Derived>& parser,
basic_parser<isRequest, Derived>& parser,
error_code& ec)
{
using boost::asio::const_buffers_1;
std::size_t used = 0;
for(;;)
{
auto const n = parser.write(
auto const n = parser.put(
const_buffers_1{buffer}, ec);
if(ec)
return 0;
@@ -168,7 +167,7 @@ public:
break;
buffer = buffer + n;
used += n;
if(parser.is_complete())
if(parser.is_done())
break;
if(buffer_size(buffer) == 0)
break;
@@ -177,11 +176,11 @@ public:
}
template<class ConstBufferSequence,
bool isRequest, bool isDirect, class Derived>
bool isRequest, class Derived>
static
std::size_t
feed(ConstBufferSequence const& buffers,
basic_parser<isRequest, isDirect, Derived>& parser,
basic_parser<isRequest, Derived>& parser,
error_code& ec)
{
using boost::asio::buffer_size;
@@ -191,14 +190,14 @@ public:
for(;;)
{
auto const n =
parser.write(cb, ec);
parser.put(cb, ec);
if(ec)
return 0;
if(n == 0)
break;
cb.consume(n);
used += n;
if(parser.is_complete())
if(parser.is_done())
break;
if(buffer_size(cb) == 0)
break;
@@ -206,12 +205,11 @@ public:
return used;
}
template<
bool isRequest, bool isDirect, class Derived>
template<bool isRequest, class Derived>
static
std::size_t
feed(boost::asio::const_buffers_1 buffers,
basic_parser<isRequest, isDirect, Derived>& parser,
basic_parser<isRequest, Derived>& parser,
error_code& ec)
{
return feed(*buffers.begin(), parser, ec);
@@ -225,7 +223,7 @@ public:
using boost::asio::buffer;
test_parser<isRequest> p;
if(skipBody)
p.skip_body();
p.skip(true);
error_code ec;
auto const n = feed(buffer(
s.data(), s.size()), p, ec);
@@ -233,8 +231,8 @@ public:
return;
if(! BEAST_EXPECT(n == s.size()))
return;
if(p.state() == parse_state::body_to_eof)
p.write_eof(ec);
if(p.need_eof())
p.put_eof(ec);
if(BEAST_EXPECTS(! ec, ec.message()))
pred(p);
}
@@ -257,18 +255,19 @@ public:
using boost::asio::buffer;
test_parser<isRequest> p;
if(skipBody)
p.skip_body();
p.skip(true);
error_code ec;
feed(buffer(
s.data(), s.size()), p, ec);
if(! ec && ev)
p.write_eof(ec);
p.put_eof(ec);
BEAST_EXPECTS(ec == ev, ec.message());
}
void
testFlatten()
{
#if 0
using boost::asio::buffer;
{
std::string const s =
@@ -289,7 +288,7 @@ public:
BEAST_EXPECTS(! ec, ec.message());
feed(buffer_cat(b1, b2), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
}
{
@@ -310,9 +309,10 @@ public:
ec = {};
feed(buffer_cat(b1, b2), p, ec);
BEAST_EXPECTS(! ec, ec.message());
p.write_eof(ec);
p.put_eof(ec);
}
}
#endif
}
// Check that all callbacks are invoked
@@ -331,7 +331,7 @@ public:
"*";
feed(buffer(s), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
BEAST_EXPECT(p.got_on_begin);
BEAST_EXPECT(p.got_on_field);
BEAST_EXPECT(p.got_on_header);
@@ -350,7 +350,7 @@ public:
"*";
feed(buffer(s), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
BEAST_EXPECT(p.got_on_begin);
BEAST_EXPECT(p.got_on_field);
BEAST_EXPECT(p.got_on_header);
@@ -747,6 +747,7 @@ public:
void testBody()
{
#if 0
using boost::asio::buffer;
good<true>(
"GET / HTTP/1.1\r\n"
@@ -774,7 +775,7 @@ public:
buf("67890")),
p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
// request without Content-Length or
@@ -787,7 +788,7 @@ public:
"\r\n"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
{
error_code ec;
@@ -797,7 +798,7 @@ public:
"\r\n"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
// response without Content-Length or
@@ -810,17 +811,17 @@ public:
"\r\n"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(! p.is_complete());
BEAST_EXPECT(! p.is_done());
BEAST_EXPECT(p.state() == parse_state::body_to_eof);
feed(buf(
"hello"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(! p.is_complete());
BEAST_EXPECT(! p.is_done());
BEAST_EXPECT(p.state() == parse_state::body_to_eof);
p.write_eof(ec);
p.put_eof(ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
// 304 "Not Modified" response does not require eof
@@ -832,7 +833,7 @@ public:
"\r\n"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
// Chunked response does not require eof
@@ -845,12 +846,12 @@ public:
"\r\n"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(! p.is_complete());
BEAST_EXPECT(! p.is_done());
feed(buf(
"0\r\n\r\n"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
// restart: 1.0 assumes Connection: close
@@ -862,7 +863,7 @@ public:
"\r\n"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
// restart: 1.1 assumes Connection: keep-alive
@@ -874,7 +875,7 @@ public:
"\r\n"
), p, ec);
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
}
bad<true>(
@@ -882,8 +883,10 @@ public:
"Content-Length: 1\r\n"
"\r\n",
error::partial_message);
#endif
}
#if 0
template<bool isRequest>
void
check_header(
@@ -898,6 +901,7 @@ public:
BEAST_EXPECT(! p.got_on_complete);
BEAST_EXPECT(p.state() != parse_state::header);
}
#endif
void
testSplit()
@@ -921,7 +925,7 @@ public:
BEAST_EXPECT(! p.got_on_chunk);
BEAST_EXPECT(! p.got_on_complete);
BEAST_EXPECT(p.state() != parse_state::header);
BEAST_EXPECT(! p.is_complete());
BEAST_EXPECT(! p.is_done());
BEAST_EXPECT(p.body.empty());
b.consume(n);
p.resume();
@@ -933,7 +937,7 @@ public:
BEAST_EXPECT(p.got_on_body);
BEAST_EXPECT(! p.got_on_chunk);
BEAST_EXPECT(p.got_on_complete);
BEAST_EXPECT(p.is_complete());
BEAST_EXPECT(p.is_done());
BEAST_EXPECT(p.body == "*****");
#endif
}