Boost Beast HTTP
Asked Answered
G

1

7

I am working on a http parser, and it looks like boost.beast is a nice one. However, I still have some questions:

*** Assume HTTP Request POST data already received via boost.asio socket. Stored inside a std::string buffer.

  1. Is there any good sample on how to extract http header fields and its value (one-after-another)? I assume it will be an iterator method, but i tried several way and still won't work.

  2. How to extract the http body?

Thank you very much.

Gusella answered 23/5, 2018 at 3:33 Comment(0)
E
12

Starting from a simple example: https://www.boost.org/doc/libs/develop/libs/beast/example/http/client/sync/http_client_sync.cpp

    // Declare a container to hold the response
    http::response<http::dynamic_body> res;

    // Receive the HTTP response
    http::read(socket, buffer, res);

Extract The Headers

The response object already contains all the goods:

for(auto const& field : res)
    std::cout << field.name() << " = " << field.value() << "\n";

std::cout << "Server: " << res[http::field::server] << "\n";

You can also just stream the entire response object:

std::cout << res << std::endl;

Extract The Body

std::cout << "Body size is " << res.body().size() << "\n";

To actually use the "dynamic_body", use standard Asio buffer manipulation:

#include <boost/asio/buffers_iterator.hpp>
#include <boost/asio/buffers_iterator.hpp>

std::string body { boost::asio::buffers_begin(res.body().data()),
                   boost::asio::buffers_end(res.body().data()) };

std::cout << "Body: " << std::quoted(body) << "\n";

Alternatively, see beast::buffers_to_string

Obviously, things become more straight-forward when using a string_body:

std::cout << "Body: " << std::quoted(res.body()) << "\n";
Esemplastic answered 23/5, 2018 at 22:46 Comment(13)
I didn't know about std::quoted! An alternative for output is std::ostream& using std::cout << beast::buffers(res.body().data()) << "\n";. The function beast::buffers adapts a buffer sequence into something that works with operator<<.Darvon
@VinnieFalco Learning everyday here. I really like that you comment these things. Cheers!Esemplastic
Print just the headers: std::cout << res.base();Darvon
@VinnieFalco +1 In this case we were trying to specifically cater to the question "how to extract http header fields and its value (one-after-another)? "Esemplastic
Maybe basic_fields::value_type should have an operator<<. I'll open an issue. See: github.com/boostorg/beast/issues/1143Darvon
@VinnieFalco std::cout << res.base(); is not working in boost 1.70.0 version. I tried with beast::make_printable(res.base()), this is also not working. Please let me know your inputCirillo
It works fine, there's even a test for it: github.com/boostorg/beast/blob/… Does this test compile for you?Darvon
@VinnieFalco Thanks. I am still having some issue. Can you please advice, if I am doing something wrong? using BeastResponse = http::response<http::string_body>; ... BeastResponse mResponse; ... std::stringstream lHeaderStream; lHeaderStream << mResponse.base(); Error: /mnt/src/mobi-med-boost/cmake/../src/boost/beast/core/ostream.hpp:81:5: error: static assertion failed: The function buffers() is deprecated, use make_printable() instead, or define BOOST_BEAST_ALLOW_DEPRECATED to silence this error. static_assert(sizeof(T) == 0,Cirillo
‘void boost::beast::buffers(const T&) [with T = boost::beast::detail::buffers_ref<boost::beast::buffers_cat_view<boost::asio::const_buffer, boost::asio::const_buffer, boost::asio::const_buffer, boost::beast::http::basic_fields<std::allocator<char> >::writer::field_range, boost::beast::http::chunk_crlf> >]’: src/boost/beast/http/impl/write.hpp:906:25: required from ‘std::ostream& boost::beast::http::operator<<(std::ostream&, const boost::beast::http::header<true, Fields>&) [with Fields = boost::beast::http::basic_fields<std::allocator<char> >; std::ostream = std::basic_ostream<char>]'Cirillo
@VinnieFalco can you please help with code snippet? I am learning and unable to fixCirillo
@Cirillo 1.69.0, the error message with 1.70.0, the workaround with BOOST_BEAST_ALLOW_DEPRECATEDEsemplastic
@VinnieFalco AFAICT the fix using make_printable should replace buffers in e.g. L:906/916 (....?) of the library write.hpp implementation. That compiles as wellEsemplastic
Thanks @Esemplastic for the helpCirillo

© 2022 - 2024 — McMap. All rights reserved.