I have a http client that performs http::async_write() with a callback that performs http::async_read() on ssl::stream. All the async operations are wrapped in the same explicit strand.
The simplified code looks like this
http::async_write(
*tcp_session_->tcp_stream(), *request,
boost::asio::bind_executor(
tcp_session_strand_,
[request, this](
boost::system::error_code ec,
std::size_t /* bytes_transferred */) {
if (ec) {
return;
}
auto response_buffer =
std::make_shared<boost::beast::flat_buffer>();
auto response = std::make_shared<HttpResponse>();
http::async_read(
*tcp_session_->tcp_stream(), *response_buffer, *response,
boost::asio::bind_executor(
tcp_session_strand_,
[request, done, response_buffer, response](
boost::system::error_code ec,
std::size_t /*bytes_transferred*/) {
if (ec) {
// log error
return;
}
}));
}));
I call the async_write like this two times in a row. I don't wait for the first async_write handler completion before the second write is performed.
The behavior that I see is. The first async_write is completed, then the second async_write is completed, then the first async_read is invoked with the error: "Operation canceled". This reproduces quite consistently, so I assume ssl::stream does not support multiple pending http requests. Basically one has to wait for the response before sending next request.
Is my assumption correct? I read the documentation for ssl::stream but it does not say anything about that (only that async operations have to be serialized by strand).
Per Beast documentation for async_write: