c++boostboost-asioboost-beast

Correct way to convert http::response_parser<http::buffer_body> to http::response_parser<http::string_body>


I have a response parser of type http::response_parser<http::buffer_body>, which I need to convert to a parser of type http::response_parser<http::string_body>. I do the conversion after reading the headers via http::async_read_header.

At the time of conversion, http::response_parser<http::buffer_body> does not have a pointer to the buffer, since the buffer is not required to read the headers.

In code it looks like this

auto parser = std::make_shared<boost::beast::http::response_parser<boost::beast::http::buffer_body>>();

boost::beast::http::async_read_header(m_stream, m_buffer, *parser,
    [this, self, parser](const boost::system::error_code& ec, std::size_t bytes_transferred)
    {
        auto new_parser = std::make_shared<boost::beast::http::response_parser<boost::beast::http::string_body>>(std::move(*parser));
    });

My question is, is it safe to do such conversion while http::response_parser<http::buffer_body> doesn't have a buffer pointer?

The concern is that when creating a new parser, I think the converting constructor might try to access a buffer_body buffer that has not been set.

Should I set a valid buffer_body pointer before converting, or at least set the buffer size to 0?


Solution

  • In my comment here:

    Also, use this constructor to switch the body type on the fly (after parsing headers). See also https://live.boost.org/doc/libs/1_88_0/libs/beast/doc/html/beast/more_examples/change_body_type.html

    I linked both the constructor overload and the documentation article which contains a concrete example of when and how to use it.

    1. My question is, is it safe to do such conversion while http::response_parser<http::buffer_body> doesn't have a buffer pointer?

    The parser does not "have" a buffer to begin with.

    2. The concern is that when creating a new parser, I think the converting constructor might try to access a buffer_body buffer that has not been set.

    The constructor overload specifically, and by definition, does NOT assume a body:

    This constructs a new parser by move constructing the header from another parser with a different body type. The constructed-from parser must not have any parsed body octets or initialized BodyReader, otherwise an exception is generated.

    That's in the documentation of that overload.