Tidy up chunk decorator (API Change):

* Rename to no_chunk_decorator
* Decorator no longer has to append "\r\n" to the returned string
This commit is contained in:
Vinnie Falco
2017-06-03 06:49:11 -07:00
parent 38e9b16f75
commit 2141fabcf9
9 changed files with 49 additions and 43 deletions

View File

@@ -1,3 +1,11 @@
Version 48
API Changes:
* Tidy up chunk decorator
--------------------------------------------------------------------------------
Version 47 Version 47
* Disable operator<< for buffer_body * Disable operator<< for buffer_body

View File

@@ -27,7 +27,7 @@ template<
bool isRequest, bool isRequest,
class Body, class Body,
class Fields, class Fields,
class Decorator = empty_decorator, class ChunkDecorator = no_chunk_decorator,
class Allocator = std::allocator<char> class Allocator = std::allocator<char>
> >
class serializer; class serializer;

View File

@@ -164,12 +164,11 @@ invoke the decorator with a buffer sequence of size zero. Or more
specifically, with an object of type specifically, with an object of type
[@http://www.boost.org/doc/html/boost_asio/reference/null_buffers.html `boost::asio::null_buffers`]. [@http://www.boost.org/doc/html/boost_asio/reference/null_buffers.html `boost::asio::null_buffers`].
For body chunks the string returned by the decorator must end in a For body chunks the string returned by the decorator must follow the
CRLF (`"\r\n"`) and follow the
[@https://tools.ietf.org/html/rfc7230#section-4.1.1 correct syntax] [@https://tools.ietf.org/html/rfc7230#section-4.1.1 correct syntax]
for the entire chunk extension. For the trailer, the returned string for the entire chunk extension. For the trailer, the returned string
should consist of zero or more lines ending in a CRLF and containing should consist of zero or more lines ending in a CRLF and containing
a field name/value pair in the format prescribed in __rfc7230__. It a field name/value pair in the format prescribed by __rfc7230__. It
is the responsibility of the decorator to manage returned string buffers. is the responsibility of the decorator to manage returned string buffers.
The implementation guarantees it will not reference previous strings The implementation guarantees it will not reference previous strings
after subsequent calls. after subsequent calls.
@@ -183,14 +182,14 @@ struct decorator
template<class ConstBufferSequence> template<class ConstBufferSequence>
string_view string_view
operator()(ConstBufferSequence const& buffer) const operator()(ConstBufferSequence const& buffers)
{ {
s = ";x=" + std::to_string(boost::asio::buffer_size(buffer)) + "\r\n"; s = ";x=" + std::to_string(boost::asio::buffer_size(buffers));
return s; return s;
} }
string_view string_view
operator()(boost::asio::null_buffers) const operator()(boost::asio::null_buffers)
{ {
return "Result: OK\r\n"; return "Result: OK\r\n";
} }

View File

@@ -35,12 +35,12 @@
<member><link linkend="beast.ref.http__buffer_body">buffer_body</link></member> <member><link linkend="beast.ref.http__buffer_body">buffer_body</link></member>
<member><link linkend="beast.ref.http__dynamic_body">dynamic_body</link></member> <member><link linkend="beast.ref.http__dynamic_body">dynamic_body</link></member>
<member><link linkend="beast.ref.http__empty_body">empty_body</link></member> <member><link linkend="beast.ref.http__empty_body">empty_body</link></member>
<member><link linkend="beast.ref.http__empty_decorator">empty_decorator</link></member>
<member><link linkend="beast.ref.http__fields">fields</link></member> <member><link linkend="beast.ref.http__fields">fields</link></member>
<member><link linkend="beast.ref.http__header">header</link></member> <member><link linkend="beast.ref.http__header">header</link></member>
<member><link linkend="beast.ref.http__header_parser">header_parser</link></member> <member><link linkend="beast.ref.http__header_parser">header_parser</link></member>
<member><link linkend="beast.ref.http__message">message</link></member> <member><link linkend="beast.ref.http__message">message</link></member>
<member><link linkend="beast.ref.http__message_parser">message_parser</link></member> <member><link linkend="beast.ref.http__message_parser">message_parser</link></member>
<member><link linkend="beast.ref.http__no_chunk_decorator">no_chunk_decorator</link></member>
<member><link linkend="beast.ref.http__request">request</link></member> <member><link linkend="beast.ref.http__request">request</link></member>
<member><link linkend="beast.ref.http__request_parser">request_parser</link></member> <member><link linkend="beast.ref.http__request_parser">request_parser</link></member>
<member><link linkend="beast.ref.http__response">response</link></member> <member><link linkend="beast.ref.http__response">response</link></member>

View File

@@ -134,14 +134,6 @@ chunk_crlf()
return {"\r\n", 2}; return {"\r\n", 2};
} }
/// Returns a buffer sequence holding a CRLF then final chunk
inline
boost::asio::const_buffers_1
chunk_crlf_final()
{
return {"\r\n0\r\n\r\n", 7};
}
/// Returns a buffer sequence holding a final chunk header /// Returns a buffer sequence holding a final chunk header
inline inline
boost::asio::const_buffers_1 boost::asio::const_buffers_1

View File

@@ -73,11 +73,11 @@ write_fields(std::ostream& os,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template<bool isRequest, class Body, class Fields, template<bool isRequest, class Body, class Fields,
class Decorator, class Allocator> class ChunkDecorator, class Allocator>
serializer<isRequest, Body, Fields, serializer<isRequest, Body, Fields,
Decorator, Allocator>:: ChunkDecorator, Allocator>::
serializer(message<isRequest, Body, Fields> const& m, serializer(message<isRequest, Body, Fields> const& m,
Decorator const& d, Allocator const& alloc) ChunkDecorator const& d, Allocator const& alloc)
: m_(m) : m_(m)
, d_(d) , d_(d)
, b_(1024, alloc) , b_(1024, alloc)
@@ -85,11 +85,11 @@ serializer(message<isRequest, Body, Fields> const& m,
} }
template<bool isRequest, class Body, class Fields, template<bool isRequest, class Body, class Fields,
class Decorator, class Allocator> class ChunkDecorator, class Allocator>
template<class Visit> template<class Visit>
void void
serializer<isRequest, Body, Fields, serializer<isRequest, Body, Fields,
Decorator, Allocator>:: ChunkDecorator, Allocator>::
get(error_code& ec, Visit&& visit) get(error_code& ec, Visit&& visit)
{ {
using boost::asio::buffer_size; using boost::asio::buffer_size;
@@ -207,6 +207,7 @@ get(error_code& ec, Visit&& visit)
sv.data(), sv.size()}; sv.data(), sv.size()};
}(), }(),
detail::chunk_crlf(),
result->first, result->first,
detail::chunk_crlf()}; detail::chunk_crlf()};
s_ = do_header_c; s_ = do_header_c;
@@ -251,6 +252,7 @@ get(error_code& ec, Visit&& visit)
sv.data(), sv.size()}; sv.data(), sv.size()};
}(), }(),
detail::chunk_crlf(),
result->first, result->first,
detail::chunk_crlf()}; detail::chunk_crlf()};
s_ = do_body_c + 2; s_ = do_body_c + 2;
@@ -296,10 +298,10 @@ get(error_code& ec, Visit&& visit)
} }
template<bool isRequest, class Body, class Fields, template<bool isRequest, class Body, class Fields,
class Decorator, class Allocator> class ChunkDecorator, class Allocator>
void void
serializer<isRequest, Body, Fields, serializer<isRequest, Body, Fields,
Decorator, Allocator>:: ChunkDecorator, Allocator>::
consume(std::size_t n) consume(std::size_t n)
{ {
using boost::asio::buffer_size; using boost::asio::buffer_size;

View File

@@ -356,12 +356,12 @@ class write_msg_op
{ {
Stream& s; Stream& s;
serializer<isRequest, Body, Fields, serializer<isRequest, Body, Fields,
empty_decorator, handler_alloc<char, Handler>> sr; no_chunk_decorator, handler_alloc<char, Handler>> sr;
data(Handler& h, Stream& s_, message< data(Handler& h, Stream& s_, message<
isRequest, Body, Fields> const& m_) isRequest, Body, Fields> const& m_)
: s(s_) : s(s_)
, sr(m_, empty_decorator{}, , sr(m_, no_chunk_decorator{},
handler_alloc<char, Handler>{h}) handler_alloc<char, Handler>{h})
{ {
} }

View File

@@ -37,13 +37,13 @@ namespace http {
@see @ref serializer @see @ref serializer
*/ */
struct empty_decorator struct no_chunk_decorator
{ {
template<class ConstBufferSequence> template<class ConstBufferSequence>
string_view string_view
operator()(ConstBufferSequence const&) const operator()(ConstBufferSequence const&) const
{ {
return {"\r\n"}; return {};
} }
string_view string_view
@@ -115,7 +115,7 @@ struct empty_decorator
@tparam Fields The type of fields in the message. @tparam Fields The type of fields in the message.
@tparam Decorator The type of chunk decorator to use. @tparam ChunkDecorator The type of chunk decorator to use.
@tparam Allocator The type of allocator to use. @tparam Allocator The type of allocator to use.
@@ -123,7 +123,7 @@ struct empty_decorator
*/ */
template< template<
bool isRequest, class Body, class Fields, bool isRequest, class Body, class Fields,
class Decorator = empty_decorator, class ChunkDecorator = no_chunk_decorator,
class Allocator = std::allocator<char> class Allocator = std::allocator<char>
> >
class serializer class serializer
@@ -172,13 +172,15 @@ class serializer
using ch0_t = consuming_buffers<buffers_view< using ch0_t = consuming_buffers<buffers_view<
typename buffer_type::const_buffers_type, // header typename buffer_type::const_buffers_type, // header
detail::chunk_header, // chunk-header detail::chunk_header, // chunk-header
boost::asio::const_buffers_1, // chunk-ext+\r\n boost::asio::const_buffers_1, // chunk-ext
boost::asio::const_buffers_1, // crlf
typename reader::const_buffers_type, // body typename reader::const_buffers_type, // body
boost::asio::const_buffers_1>>; // crlf boost::asio::const_buffers_1>>; // crlf
using ch1_t = consuming_buffers<buffers_view< using ch1_t = consuming_buffers<buffers_view<
detail::chunk_header, // chunk-header detail::chunk_header, // chunk-header
boost::asio::const_buffers_1, // chunk-ext+\r\n boost::asio::const_buffers_1, // chunk-ext
boost::asio::const_buffers_1, // crlf
typename reader::const_buffers_type, // body typename reader::const_buffers_type, // body
boost::asio::const_buffers_1>>; // crlf boost::asio::const_buffers_1>>; // crlf
@@ -188,7 +190,7 @@ class serializer
boost::asio::const_buffers_1>>; // crlf boost::asio::const_buffers_1>>; // crlf
message<isRequest, Body, Fields> const& m_; message<isRequest, Body, Fields> const& m_;
Decorator d_; ChunkDecorator d_;
boost::optional<reader> rd_; boost::optional<reader> rd_;
buffer_type b_; buffer_type b_;
boost::variant<boost::blank, boost::variant<boost::blank,
@@ -217,7 +219,7 @@ public:
*/ */
explicit explicit
serializer(message<isRequest, Body, Fields> const& msg, serializer(message<isRequest, Body, Fields> const& msg,
Decorator const& decorator = Decorator{}, ChunkDecorator const& decorator = ChunkDecorator{},
Allocator const& alloc = Allocator{}); Allocator const& alloc = Allocator{});
/** Returns `true` if we will pause after writing the complete header. /** Returns `true` if we will pause after writing the complete header.
@@ -335,18 +337,18 @@ public:
*/ */
template< template<
bool isRequest, class Body, class Fields, bool isRequest, class Body, class Fields,
class Decorator = empty_decorator, class ChunkDecorator = no_chunk_decorator,
class Allocator = std::allocator<char>> class Allocator = std::allocator<char>>
inline inline
serializer<isRequest, Body, Fields, serializer<isRequest, Body, Fields,
typename std::decay<Decorator>::type, typename std::decay<ChunkDecorator>::type,
typename std::decay<Allocator>::type> typename std::decay<Allocator>::type>
make_serializer(message<isRequest, Body, Fields> const& m, make_serializer(message<isRequest, Body, Fields> const& m,
Decorator const& decorator = Decorator{}, ChunkDecorator const& decorator = ChunkDecorator{},
Allocator const& allocator = Allocator{}) Allocator const& allocator = Allocator{})
{ {
return serializer<isRequest, Body, Fields, return serializer<isRequest, Body, Fields,
typename std::decay<Decorator>::type, typename std::decay<ChunkDecorator>::type,
typename std::decay<Allocator>::type>{ typename std::decay<Allocator>::type>{
m, decorator, allocator}; m, decorator, allocator};
} }

View File

@@ -759,7 +759,7 @@ public:
template<class Stream, template<class Stream,
bool isRequest, class Body, class Fields, bool isRequest, class Body, class Fields,
class Decorator = empty_decorator> class Decorator = no_chunk_decorator>
void void
do_write(Stream& stream, message< do_write(Stream& stream, message<
isRequest, Body, Fields> const& m, error_code& ec, isRequest, Body, Fields> const& m, error_code& ec,
@@ -780,7 +780,7 @@ public:
template<class Stream, template<class Stream,
bool isRequest, class Body, class Fields, bool isRequest, class Body, class Fields,
class Decorator = empty_decorator> class Decorator = no_chunk_decorator>
void void
do_async_write(Stream& stream, do_async_write(Stream& stream,
message<isRequest, Body, Fields> const& m, message<isRequest, Body, Fields> const& m,
@@ -802,17 +802,20 @@ public:
struct test_decorator struct test_decorator
{ {
std::string s;
template<class ConstBufferSequence> template<class ConstBufferSequence>
string_view string_view
operator()(ConstBufferSequence const&) const operator()(ConstBufferSequence const& buffers)
{ {
return {";x\r\n"}; s = ";x=" + std::to_string(boost::asio::buffer_size(buffers));
return s;
} }
string_view string_view
operator()(boost::asio::null_buffers) const operator()(boost::asio::null_buffers)
{ {
return {"F: v\r\n"}; return "Result: OK\r\n";
} }
}; };