Daniel Albuschat wrote:
I experience crashes for certain types of replies.
The "crash" you see is asio's buffer debug checking in action. For whatever reason, it thinks one of the strings referred to in a buffer is no longer valid. What is different about those "certain types of replies"?
What bothers me is the reply_.to_buffers() function. It looks like this:
std::vectorboost::asio::const_buffer reply::to_buffers() { std::vectorboost::asio::const_buffer buffers; buffers.push_back(status_strings::to_buffer(status)); for (std::size_t i = 0; i < headers.size(); ++i) { header& h = headers[i]; buffers.push_back(boost::asio::buffer(h.name)); buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator)); buffers.push_back(boost::asio::buffer(h.value)); buffers.push_back(boost::asio::buffer(misc_strings::crlf)); } buffers.push_back(boost::asio::buffer(misc_strings::crlf)); buffers.push_back(boost::asio::buffer(content)); return buffers; }
How can this even work? It adds temporaries (the misc_strings are const char[]s) to a const_buffer-vector and reads them later. Even the references to h.name, etc. seem invalid to me, since the io is asynchronous and there's no guarantee that they don't change.
The buffers in the vector refer directly to the strings contained within the reply object (in addition to the misc_strings, of course). The reply object must not be modified or destroyed for as long as the buffers returned by reply::to_buffers() are being used by an asynchronous operation. In the HTTP server example, the reply object is a data member of the connection class, so that it remains valid until the connection is closed.
IMHO the whole content needs to be COPIED to new buffers and then, after the async_write finished, deleted.
Am I missing something? Was the author of this example not aware of the const_buffer's ownership policy (i.e. it is *not* owner of the data)?
I pretty sure I was aware ;) However that's not to say there are no bugs in the HTTP server or buffer debug checking. Cheers, Chris