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.

Jimmy
  • 153
  • 1
  • 6

1 Answers1

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";
sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    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<<`. – Vinnie Falco May 25 '18 at 20:58
  • @VinnieFalco Learning everyday here. I really like that you comment these things. Cheers! – sehe May 25 '18 at 21:28
  • Print just the headers: `std::cout << res.base();` – Vinnie Falco May 26 '18 at 15:42
  • @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)? " – sehe May 26 '18 at 15:47
  • Maybe `basic_fields::value_type` should have an `operator<<`. I'll open an issue. See: https://github.com/boostorg/beast/issues/1143 – Vinnie Falco May 26 '18 at 16:01
  • @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 input – user2260304 Apr 24 '19 at 14:12
  • It works fine, there's even a test for it: https://github.com/boostorg/beast/blob/41040a21f0b0e12537beb1262c2d538a023efe65/test/beast/http/write.cpp#L612 Does this test compile for you? – Vinnie Falco Apr 24 '19 at 19:21
  • @VinnieFalco Thanks. I am still having some issue. Can you please advice, if I am doing something wrong? using BeastResponse = http::response; ... 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, – user2260304 Apr 26 '19 at 18:54
  • ‘void boost::beast::buffers(const T&) [with T = boost::beast::detail::buffers_ref >::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&) [with Fields = boost::beast::http::basic_fields >; std::ostream = std::basic_ostream]' – user2260304 Apr 26 '19 at 19:12
  • @VinnieFalco can you please help with code snippet? I am learning and unable to fix – user2260304 May 10 '19 at 18:45
  • @user2260304 [1.69.0](https://wandbox.org/permlink/O1zzfWMdVQUMEQN7), the error message with [1.70.0](https://wandbox.org/permlink/lC0j8jp9xTcXkubk), the workaround with [BOOST_BEAST_ALLOW_DEPRECATED](https://wandbox.org/permlink/ezLIEIjKrwePLOk8) – sehe May 10 '19 at 20:08
  • @VinnieFalco AFAICT the fix using `make_printable` should replace `buffers` in e.g. [L:906/916 (....?) of the library write.hpp implementation](https://github.com/boostorg/beast/blob/develop/include/boost/beast/http/impl/write.hpp). That compiles as well – sehe May 10 '19 at 20:09
  • Thanks @sehe for the help – user2260304 May 11 '19 at 18:14