boost::beast::http::async_read core dumped when reading chunked response
xiaoma565 opened this issue · 4 comments
in class ClientConnection
It has a variable "boost::beast::http::parser<false, boost::beast::http::empty_body> p_"
ClientConnection function "Start" call ClientConnection function "DoReadHeader"
In function "OnReadHeader"
I call "on_chunk_header" and "on_chunk_body"
And then running "boost::beast::http::async_read"
function "ParserChunkHeader" seem like
in "OnChunkBody", when p_ is done, close the socket, else keep reading
http::parser::on_chunk_header stores a reference to the provided callback object. Therefore, you need to extend the lifetime of the headerCB
and bodyCB
variables by making them members of your class.
The reason for storing references is that most std::function
implementations utilize small buffer optimization, meaning storing a reference won't require a memory allocation. A better alternative would be to accept std::function_ref
, but that's a C++26 feature.
http::parser::on_chunk_header stores a reference to the provided callback object. Therefore, you need to extend the lifetime of the
headerCB
andbodyCB
variables by making them members of your class.The reason for storing references is that most
std::function
implementations utilize small buffer optimization, meaning storing a reference won't require a memory allocation. A better alternative would be to acceptstd::function_ref
, but that's a C++26 feature.
thanks so much! It is helpful. But I have got another problem.
In my http server, I read a request and send some chunked messages. When I send the last chunk
boost::asio::async_write(stream_, http::make_chunk_last(), [this](boost::system::error_code ec, std::size_t bytes_transferred) {
do_read();
});
I call do_read to read a new reuqest.
void do_read()
{
req_ = {};
// Set the timeout.
stream_.expires_after(std::chrono::seconds(30));
// Read a request
http::async_read(stream_, buffer_, req_,
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
}
void on_read(beast::error_code ec, std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
// This means they closed the connection
if(ec == http::error::end_of_stream)
return do_close();
if(ec)
return fail(ec, "read");
handle_request(*doc_root_, std::move(req_));
send_chunked();
}
I did it with reference to this example: https://www.boost.org/doc/libs/1_85_0/libs/beast/example/http/server/async/http_server_async.cpp
But I got an error: free(): double free detected in tcache 2
boost::asio::async_write(stream_, http::make_chunk_last(), [this](boost::system::error_code ec, std::size_t bytes_transferred) {
do_read();
});
Here, you capture the this
pointer instead of a shared pointer to your object. You are probably facing a lifetime issue as a result.
boost::asio::async_write(stream_, http::make_chunk_last(), [this](boost::system::error_code ec, std::size_t bytes_transferred) { do_read(); });Here, you capture the
this
pointer instead of a shared pointer to your object. You are probably facing a lifetime issue as a result.
thanks bro!