C ++ Boost Beast пустое тело ответа - PullRequest
0 голосов
/ 17 декабря 2018

Я играю с частью Beast в Boost и пытаюсь создать простой http-клиент, который можно использовать для / GET содержимого из веб-ресурса (простые службы HTML или REST).).

Я использовал пример, который можно найти в github repo beast для http-клиента синхронизации, и переместил его в простой класс с именем http_client :
Заголовок:

#ifndef HTTP_CLIENT_HPP
#define HTTP_CLIENT_HPP

#include <string>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>

namespace playground
{
    namespace net
    {

        namespace beast = boost::beast;

        class http_client
        {
        public:
            beast::http::response<beast::http::string_body>
            get(std::string base_url,
                std::string path,
                std::string port = "80",
                unsigned short http_version = 11);
        };

    }
}

#endif

Реализация:

#include <iostream>
#include <string>
#include <cstdlib>
#include <stdexcept>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>

#include "http_client.hpp"

namespace playground
{
    namespace net
    {

        namespace beast = boost::beast;
        namespace asio = boost::asio;

        beast::http::response<beast::http::string_body> 
        http_client::get(std::string base_url,
                         std::string path,
                         std::string port,
                         unsigned short http_version)
        {
            std::cout << "HttpClient::getAsync()" << std::endl;
            beast::http::response <boost::beast::http::string_body> httpResponse;
            asio::io_context ioContext;
            asio::ip::tcp::resolver tcpResolver
            { ioContext };
            asio::ip::tcp::socket tcpSocket
            { ioContext };
            beast::http::request <beast::http::string_body> httpRequest(beast::http::verb::get, 
                                                                        path, 
                                                                        http_version);
            beast::error_code connectionError;
            beast::error_code readError;
            beast::flat_buffer responseBuffer;

            try
            {

                auto const ipAddresses = tcpResolver.resolve(base_url, port);

                asio::connect(tcpSocket,
                              ipAddresses.begin(),
                              ipAddresses.end());

                if (tcpSocket.is_open())
                {
                    httpRequest.set(beast::http::field::host, base_url);
                    httpRequest.set(beast::http::field::user_agent,
                                    "http_client");
                    httpRequest.set(beast::http::field::accept, "text/xml");

                    beast::http::write(tcpSocket, httpRequest);

                    beast::http::read(tcpSocket,
                                      responseBuffer,
                                      httpResponse,
                                      readError);

                    if (readError != beast::http::error::end_of_stream)
                    {
                        throw std::runtime_error(readError.message());
                    }

                    tcpSocket.shutdown(asio::ip::tcp::socket::shutdown_both,
                                       connectionError);

                    if (connectionError
                            && connectionError != beast::errc::not_connected)
                    {
                        throw beast::system_error(connectionError);
                    }
                }
                else
                {
                    throw std::runtime_error("Unable to open connection!");
                }

            }
            catch (std::exception const& ex)
            {
                throw;
            }
            return httpResponse;
        }

    }
}

Проблема в том, что данный string_body пуст, хотя http-код состояния равен 200.

Примерзвонок:

playground::net::http_client client;
std::string url("www.google.de");
auto response = client.get(url, "/", "443");

std::cout << "Response: " << response << std::endl;
std::cout << "Response body: " << response.body() << std::endl;

Чего-то не хватает в звонке?

...