Skip to content
Merged

Work #236

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions include/boost/http_proto/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,12 @@ class parser
parse(
system::error_code& ec);

/** Return true if a body has been attached.
*/
BOOST_HTTP_PROTO_DECL
bool
is_body_set() const noexcept;

/** Attach an elastic buffer body.

This function attaches the specified elastic
Expand Down Expand Up @@ -634,10 +640,6 @@ class parser
detail::workspace&
ws() noexcept;

BOOST_HTTP_PROTO_DECL
bool
is_body_set() const noexcept;

BOOST_HTTP_PROTO_DECL
void
set_body_impl(buffers::any_dynamic_buffer&) noexcept;
Expand Down
87 changes: 87 additions & 0 deletions include/boost/http_proto/server/route_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,45 @@ struct BOOST_HTTP_PROTO_SYMBOL_VISIBLE
route_params&
set_body(std::string s);

/** Read the request body and receive a value.

This function reads the entire request body into the specified sink.
When the read operation completes, the given callback is invoked with
the result.

The @p callback parameter must be a function object with this
equivalent signature, where `T` is the type produced by the value sink:
@code
void ( T&& t );
@endcode

@par Example
@code
rp.read_body(
capy::string_body_sink(),
[]( std::string s )
{
// body read successfully
});
@endcode

If an error or an exception occurs during the read, it is propagated
through the router to the next error or exception handler.

@param sink The body sink to read into.
@param callback The function to call when the read completes.
@return The route result, which must be returned immediately
from the route handler.
*/
template<
class ValueSink,
class Callback>
auto
read_body(
ValueSink&& sink,
Callback&& callback) ->
route_result;

#ifdef BOOST_HTTP_PROTO_HAS_CORO

/** Spawn a coroutine for this route.
Expand Down Expand Up @@ -201,10 +240,58 @@ struct BOOST_HTTP_PROTO_SYMBOL_VISIBLE
virtual void do_post();

std::unique_ptr<task> task_;
std::function<void(void)> finish_;
};

//-----------------------------------------------

template<
class ValueSink,
class Callback>
auto
route_params::
read_body(
ValueSink&& sink,
Callback&& callback) ->
route_result
{
using T = typename std::decay<ValueSink>::type;

struct on_finish
{
T& sink;
resumer resume;
typename std::decay<Callback>::type cb;

on_finish(
T& sink_,
resumer resume_,
Callback&& cb_)
: sink(sink_)
, resume(resume_)
, cb(std::forward<Callback>(cb_))
{
}

void operator()()
{
resume(std::move(cb)(sink.release()));
}
};

return suspend(
[&](resumer resume)
{
finish_ = on_finish(
this->parser.set_body<T>(
std::forward<ValueSink>(sink)),
resume,
std::forward<Callback>(callback));
});
}

//-----------------------------------------------

template<class F>
auto
route_params::
Expand Down
14 changes: 7 additions & 7 deletions src/server/router_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const char*
route_cat_type::
name() const noexcept
{
return "boost.http";
return "boost.http.route";
}

std::string
Expand All @@ -40,12 +40,12 @@ message(
{
switch(static_cast<route>(code))
{
case route::close: return "route::close";
case route::complete: return "route::complete";
case route::suspend: return "route::suspend";
case route::next: return "route::next";
case route::next_route: return "route::next_route";
case route::send: return "route::send";
case route::close: return "close";
case route::complete: return "complete";
case route::suspend: return "suspend";
case route::next: return "next";
case route::next_route: return "next_route";
case route::send: return "send";
default:
return "?";
}
Expand Down
30 changes: 30 additions & 0 deletions test/unit/server/router_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,39 @@ namespace http_proto {

struct router_types_test
{
template<typename Error>
void
check(
char const* name,
Error ev)
{
auto const ec = make_error_code(ev);
BOOST_TEST(std::string(ec.category().name()) == name);
BOOST_TEST(! ec.message().empty());
BOOST_TEST(
std::addressof(ec.category()) ==
std::addressof(make_error_code(ev).category()));
BOOST_TEST(ec.category().equivalent(
static_cast<typename std::underlying_type<Error>::type>(ev),
ec.category().default_error_condition(
static_cast<typename std::underlying_type<Error>::type>(ev))));
BOOST_TEST(ec.category().equivalent(ec,
static_cast<typename std::underlying_type<Error>::type>(ev)));
}

void
run()
{
{
char const* const n = "boost.http.route";
check(n, route::close);
check(n, route::complete);
check(n, route::suspend);
check(n, route::next);
check(n, route::next_route);
check(n, route::send);
}

basic_router<route_params_base> r;
r.add(http_proto::method::post, "/",
[](route_params_base& rp) ->
Expand Down
Loading