With cpp-netlib, asynchronous reads have to be done as follows. req.body doesn't get loaded with the data read from the asynchronous. So have to have your own holder for data.
struct connection_handler : boost::enable_shared_from_this<connection_handler>
{
std::string body;
boost::condition_variable cond;
boost::mutex mtx;
size_t read_sofar;
connection_handler(const server::request& req, const server::connection_ptr& conn) :
conn(conn),
body("")
{
}
~connection_handler()
{
}
void operator()(const server::request& req, const server::connection_ptr& conn)
{
size_t cl = 0;
auto const& hs = req.headers;
for (auto it = hs.begin(); it != hs.end(); ++it)
{
if (boost::to_lower_copy(it->name)=="content-length")
{
cl = boost::lexical_cast<size_t>(it->value);
break;
}
}
read_sofar = 0;
while (read_sofar < cl)
{
boost::unique_lock<boost::mutex> lock(mtx);
read_chunk(cl - read_sofar, conn);
LogTrace(("gonna wait"));
cond.wait(lock);
LogTrace(("wokeup"));
}
}
void read_chunk(size_t left2read, server::connection_ptr conn)
{
LogTrace(("left2read: %ld", left2read));
conn->read(
boost::bind(
&connection_handler::handle_post_read,
connection_handler::shared_from_this(),
_1, _2, _3, conn, left2read
)
);
}
void handle_post_read(server::connection::input_range range,
boost::system::error_code error,
size_t size,
server::connection_ptr conn,
size_t left2read)
{
if (!error)
{
LogTrace(("readSize: %ld", size));
body.append(boost::begin(range), size);
size_t left = left2read - size;
read_sofar += size;
if (left > 0)
{
read_chunk(left, conn);
}
else
{
cond.notify_one();
}
}
LogTrace((error.message()));
}
};
Also you may want to change BOOST_NETWORK_HTTP_SERVER_CONNECTION_BUFFER_SIZE
defined in boost/network/protocol/http/serversync_connection.hpp
to a higher value so that you can avoid multiple context switches. It is not configurable at present.