Refactor serialization algorithms:

serializer interface is changed to be buffer-only, no streams,
and placed in its own header file.

Operations on serializers are moved to free functions as part
of the HTTP write family of synchronous and asynchronous algorithms.
This commit is contained in:
Vinnie Falco
2017-05-28 19:35:20 -07:00
parent 407b0462d4
commit 34ea0b37c4
11 changed files with 1064 additions and 1217 deletions
+1
View File
@@ -52,6 +52,7 @@ unit-test http-tests :
http/message_parser.cpp
http/read.cpp
http/rfc7230.cpp
http/serializer.cpp
http/string_body.cpp
http/type_traits.cpp
http/write.cpp
+1
View File
@@ -22,6 +22,7 @@ add_executable (http-tests
message_parser.cpp
read.cpp
rfc7230.cpp
serializer.cpp
string_body.cpp
type_traits.cpp
write.cpp
+9 -9
View File
@@ -77,11 +77,11 @@ public:
req.body = "Hello, world!";
// send header
auto ws = make_serializer(req);
auto sr = make_serializer(req);
for(;;)
{
ws.async_write_some(stream, yield);
if(ws.is_header_done())
async_write_some(stream, sr, yield);
if(sr.is_header_done())
break;
}
@@ -92,8 +92,8 @@ public:
}
// send body
while(! ws.is_done())
ws.async_write_some(stream, yield);
while(! sr.is_done())
async_write_some(stream, sr, yield);
}
void
@@ -162,7 +162,7 @@ public:
m.target("/");
m.fields.insert("User-Agent", "test");
m.fields.insert("Content-Length", s.size());
auto ws = make_serializer(m);
auto sr = make_serializer(m);
error_code ec;
for(;;)
{
@@ -171,7 +171,7 @@ public:
m.body.second = s.size() > 3;
for(;;)
{
ws.write_some(p.client, ec);
write_some(p.client, sr, ec);
if(ec == error::need_more)
{
ec = {};
@@ -179,12 +179,12 @@ public:
}
if(! BEAST_EXPECTS(! ec, ec.message()))
return;
if(ws.is_done())
if(sr.is_done())
break;
}
s.erase(s.begin(), s.begin() +
boost::asio::buffer_size(*m.body.first));
if(ws.is_done())
if(sr.is_done())
break;
}
BEAST_EXPECT(p.server.str() ==
+9
View File
@@ -0,0 +1,9 @@
//
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Test that header file is self-contained.
#include <beast/http/serializer.hpp>
+26 -26
View File
@@ -765,15 +765,15 @@ public:
isRequest, Body, Fields> const& m, error_code& ec,
Decorator const& decorator = Decorator{})
{
auto ws = make_serializer(m, decorator);
auto sr = make_serializer(m, decorator);
for(;;)
{
stream.nwrite = 0;
ws.write_some(stream, ec);
write_some(stream, sr, ec);
if(ec)
return;
BEAST_EXPECT(stream.nwrite <= 1);
if(ws.is_done())
if(sr.is_done())
break;
}
}
@@ -787,15 +787,15 @@ public:
error_code& ec, yield_context yield,
Decorator const& decorator = Decorator{})
{
auto ws = make_serializer(m);
auto sr = make_serializer(m);
for(;;)
{
stream.nwrite = 0;
ws.async_write_some(stream, yield[ec]);
async_write_some(stream, sr, yield[ec]);
if(ec)
return;
BEAST_EXPECT(stream.nwrite <= 1);
if(ws.is_done())
if(sr.is_done())
break;
}
}
@@ -857,12 +857,12 @@ public:
{
auto m = m0;
error_code ec;
serializer<false, Body, fields> w{m};
w.split(true);
serializer<false, Body, fields> sr{m};
sr.split(true);
for(;;)
{
w.write_some(p.client);
if(w.is_header_done())
write_some(p.client, sr);
if(sr.is_header_done())
break;
}
BEAST_EXPECT(! m.body.read);
@@ -871,12 +871,12 @@ public:
{
auto m = m0;
error_code ec;
serializer<false, Body, fields> w{m};
w.split(true);
serializer<false, Body, fields> sr{m};
sr.split(true);
for(;;)
{
w.async_write_some(p.client, yield);
if(w.is_header_done())
async_write_some(p.client, sr, yield);
if(sr.is_header_done())
break;
}
BEAST_EXPECT(! m.body.read);
@@ -921,12 +921,12 @@ public:
auto m = m0;
error_code ec;
test::string_ostream so{get_io_service(), 3};
serializer<false, Body, fields> w{m};
w.split(true);
serializer<false, Body, fields> sr{m};
sr.split(true);
for(;;)
{
w.write_some(p.client);
if(w.is_header_done())
write_some(p.client, sr);
if(sr.is_header_done())
break;
}
BEAST_EXPECT(! m.body.read);
@@ -935,12 +935,12 @@ public:
{
auto m = m0;
error_code ec;
serializer<false, Body, fields> w{m};
w.split(true);
serializer<false, Body, fields> sr{m};
sr.split(true);
for(;;)
{
w.async_write_some(p.client, yield);
if(w.is_header_done())
async_write_some(p.client, sr, yield);
if(sr.is_header_done())
break;
}
BEAST_EXPECT(! m.body.read);
@@ -969,13 +969,13 @@ public:
m.body.first = boost::none;
m.body.second = true;
auto w = make_serializer(m);
auto sr = make_serializer(m);
// send the header first, so the
// other end gets it right away
for(;;)
{
w.write_some(output, ec);
write_some(output, sr, ec);
if(ec == error::need_more)
{
ec = {};
@@ -1008,7 +1008,7 @@ public:
// write to output
for(;;)
{
w.write_some(output, ec);
write_some(output, sr, ec);
if(ec == error::need_more)
{
ec = {};
@@ -1016,7 +1016,7 @@ public:
}
if(ec)
return;
if(w.is_done())
if(sr.is_done())
goto is_done;
}
b.consume(b.size());