2

Reference: base basic_fields

base() : Returns the header portion of the message.
    
http::response<http::string_body> res_;
std::cout << "Type of res_.base() : " << typeid(res_.base()).name() << std::endl;
// Type of res_.base() : N5boost5beast4http6headerILb0ENS1_12basic_fieldsISaIcEEEEE

Question> I would like to know how to convert res_::base() to std::string. In other words, I need to find a way to convert http::basic_fields to std::string if my understanding is correct.

Thank you

q0987
  • 34,938
  • 69
  • 242
  • 387

2 Answers2

1

res has a begin() and end() so you can iterate res and print the fields by using name() and value()

http::response<http::string_body> res;
// some code
for (auto const &header : res)
  {
    std::cout << "name: " << header.name () << " value: " << header.value () << std::endl;
  }

example output:

name: Server value: nginx
name: Date value: Thu, 17 Mar 2022 15:57:46 GMT
name: Content-Type value: application/json
name: Transfer-Encoding value: chunked
name: Connection value: keep-alive
name: Access-Control-Allow-Origin value: null
name: Access-Control-Allow-Credentials value: true
name: Access-Control-Allow-Headers value: Origin, Content-Type, Accept, Authorization, X-Requested-With
name: Access-Control-Allow-Methods value: POST, GET, PUT, DELETE, OPTIONS
name: Strict-Transport-Security value: max-age=63072000; includeSubdomains; preload
name: <unknown-field> value: strict-origin
Koronis Neilos
  • 700
  • 2
  • 6
  • 20
  • 1
    `http::response` has both header and body. I would like to just get the header as a single `std::string`. For example, you can do this for getting the body as a std::string(i.e. std::string body_str = res_.body()) – q0987 Mar 17 '22 at 16:53
1

You can stream it, or let lexical_cast do that for you:

#include <boost/beast.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
namespace net = boost::asio;
namespace beast = boost::beast;
namespace http = beast::http;
using net::ip::tcp;

int main() {
    net::io_context io;
    tcp::socket conn(io);
    connect(conn, tcp::resolver{io}.resolve("httpbin.org", "http"));

    {
        http::request<http::empty_body> req{http::verb::get, "/get", 11};
        req.set(http::field::host, "httpbin.org");
        http::write(conn, req);
    }

    {
        http::response<http::string_body> resp;
        beast::flat_buffer buf;
        http::read(conn, buf, resp);

        std::string const strHeaders =
            boost::lexical_cast<std::string>(resp.base());

        std::cout << "Directly:   " << resp.base() << std::endl;
        std::cout << "strHeaders: " << strHeaders  << std::endl;
    }
}

Prints the same both ways:

Directly:   HTTP/1.1 200 OK
Date: Thu, 17 Mar 2022 22:19:17 GMT
Content-Type: application/json
Content-Length: 199
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true


strHeaders: HTTP/1.1 200 OK
Date: Thu, 17 Mar 2022 22:19:17 GMT
Content-Type: application/json
Content-Length: 199
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
sehe
  • 374,641
  • 47
  • 450
  • 633
  • May you please share with me how I could figure this out through reading the boost::beast documentation? I tried to look through the documentation but was not able to figure it out. – q0987 Mar 18 '22 at 01:56
  • 1
    It's not very easy, but also quite natural if you expect `operator<<`, which is [in the reference](https://www.boost.org/doc/libs/develop/libs/beast/doc/html/beast/quickref.html#:~:text=operator%3C%3C) it will be the [first overload listed](https://www.boost.org/doc/libs/develop/libs/beast/doc/html/beast/ref/boost__beast__http__operator_lt__lt_.html) – sehe Mar 18 '22 at 04:24