Is that possible to construct a boost::beast::http::message
(specifically I have to construct a boost::beast::http::response<bb_http::string_body>
) from std::string
, std::string_view
or other raw buffer?
Maybe there is some kind of parser? From what I see in Boost.Beast samples, we can either:
boost::beast::read*
functions. In that case the first argument should be a SyncReadStream
, which has to comply with contracts of SyncReadStream
from boost/beast/core/type_traits.hpp
:struct is_sync_read_stream<T, detail::void_t<decltype(
std::declval<std::size_t&>() = std::declval<T>().read_some(
std::declval<detail::MutableBufferSequence>()),
std::declval<std::size_t&>() = std::declval<T>().read_some(
std::declval<detail::MutableBufferSequence>(),
std::declval<boost::system::error_code&>()),
(void)0)>> : std::true_type {};
http::request<http::string_body> req{http::verb::get, target, version};
You can manually invoke the parser, e.g. with this simple skeleton function:
http::response<http::string_body> do_parse(std::string_view input)
{
beast::error_code ec;
http::response_parser<http::string_body> p;
// read headers
auto buf = boost::asio::buffer(sample);
auto n = p.put(buf, ec);
assert(p.is_header_done());
// read body
if (!ec) {
buf += n;
n = p.put(buf, ec);
p.put_eof(ec);
}
if (ec)
throw boost::system::system_error(ec);
assert(p.is_done());
return p.release();
}
This assumes that input is a sinlge complete request.
#include <boost/beast.hpp>
#include <boost/beast/http.hpp>
#include <string_view>
#include <iostream>
#include <iomanip>
namespace beast = boost::beast;
namespace http = beast::http;
http::response<http::string_body> do_parse(std::string_view input)
{
beast::error_code ec;
http::response_parser<http::string_body> p;
// read headers
auto buf = boost::asio::buffer(input);
auto n = p.put(buf, ec);
assert(p.is_header_done());
// read body
if (!ec) {
buf += n;
n = p.put(buf, ec);
p.put_eof(ec);
}
if (ec)
throw boost::system::system_error(ec);
assert(p.is_done());
return p.release();
}
int main() {
auto res = do_parse(
"HTTP/1.1 200 OK\r\n"
"Date: Sun, 10 Oct 2010 23:26:07 GMT\r\n"
"Server: Apache/2.2.8 (Ubuntu) mod_ssl/2.2.8 OpenSSL/0.9.8g\r\n"
"Last-Modified: Sun, 26 Sep 2010 22:04:35 GMT\r\n"
"ETag: 45b6-834-49130cc1182c0\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 12\r\n"
"Connection: close\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"Hello world!");
std::cout << res << '\n';
std::cout << "====== body:\n" << std::quoted(res.body()) << "\n";
}
Prints
HTTP/1.1 200 OK
Date: Sun, 10 Oct 2010 23:26:07 GMT
Server: Apache/2.2.8 (Ubuntu) mod_ssl/2.2.8 OpenSSL/0.9.8g
Last-Modified: Sun, 26 Sep 2010 22:04:35 GMT
ETag: 45b6-834-49130cc1182c0
Accept-Ranges: bytes
Content-Length: 12
Connection: close
Content-Type: text/html
Hello world!
====== body:
"Hello world!"