|
Boost : |
Subject: Re: [boost] [beast] Chunking example
From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2017-07-02 14:44:37
On Sun, Jul 2, 2017 at 7:34 AM, Bjorn Reese via Boost
<boost_at_[hidden]> wrote:
> So chunk-ext fields are not passed to the user unless they write a
> parser to extract them?
If you want the chunk extensions you have to subclass basic_parser
(not the same as writing a parser). Here's an example of what a
user-defined subclass could start with:
template<bool isRequest, class Body,
class Allocator = std::allocator<char>>
class parser
: public basic_parser<isRequest,
parser<isRequest, Body, Allocator>>
{
using base_type = basic_parser<isRequest,
parser<isRequest, Body, Allocator>>;
message<isRequest, Body, basic_fields<Allocator>> m_;
boost::optional<typename Body::writer> wr_;
public:
using value_type =
message<isRequest, Body, basic_fields<Allocator>>;
parser() = default;
parser(parser const&) = delete;
parser(parser&& other) = default;
parser& operator=(parser const&) = delete;
template<class... Args>
explicit
parser(Args&&... args)
: m_(std::forward<Args>(args))
{
}
value_type const&
get() const { return m_; }
value_type& get() { return m_; }
value_type release() { return std::move(m_); }
private:
friend class basic_parser<isRequest, parser>;
void
on_request(verb method, string_view method_str,
string_view target, int version, error_code& ec)
{
try
{
m_.target(target);
if(method != verb::unknown)
m_.method(method);
else
m_.method_string(method_str);
ec.assign(0, ec.category());
}
catch(std::bad_alloc const&)
{
ec = error::bad_alloc;
}
m_.version = version;
}
void
on_response(int code,
string_view reason,
int version, error_code& ec)
{
m_.result(code);
m_.version = version;
try
{
m_.reason(reason);
ec.assign(0, ec.category());
}
catch(std::bad_alloc const&)
{
ec = error::bad_alloc;
}
}
void
on_field(field name, string_view name_string,
string_view value, error_code& ec)
{
try
{
m_.insert(name, name_string, value);
ec.assign(0, ec.category());
}
catch(std::bad_alloc const&)
{
ec = error::bad_alloc;
}
}
void
on_header(error_code& ec)
{
ec.assign(0, ec.category());
}
void
on_body(boost::optional<
std::uint64_t> const& content_length,
error_code& ec)
{
wr_.emplace(m_, content_length, ec);
}
std::size_t
on_data(string_view s, error_code& ec)
{
return wr_->put(boost::asio::buffer(
s.data(), s.size()), ec);
}
void
on_chunk(std::uint64_t size,
string_view ext, error_code& ec)
{
ec.assign(0, ec.category());
}
void
on_complete(error_code& ec)
{
if(wr_)
wr_->finish(ec);
else
ec.assign(0, ec.category());
}
};
The function on_chunk() is called for each new chunk header, and gets
passed the size of the chunk as well as the extension.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk