<commit_before>#include "beast_request.hpp"
#include "beast_connection.hpp"
#include "http.hpp"

namespace msrv {

namespace {

class ResponseCoreSender : public boost::static_visitor<>
{
public:
    ResponseCoreSender(
        BeastConnection* connection,
        beast::http::request<beast::http::string_body>* request,
        ResponseCore* response)
        : connection_(connection),
          request_(request),
          response_(response) { }

    void send() const
    {
        boost::apply_visitor(*this, response_->body);
    }

    void operator()(bool) const
    {
        sendEmpty();
    }

    void operator()(std::string& str) const
    {
        if (str.empty())
        {
            sendEmpty();
            return;
        }

        auto resp = createResponse<beast::http::string_body>();
        resp->body() = std::move(str);
        doSend(std::move(resp));
    }

    void operator()(std::vector<uint8_t>& buffer) const
    {
        if (buffer.empty())
        {
            sendEmpty();
            return;
        }

        auto resp = createResponse<beast::http::vector_body<uint8_t>>();
        resp->body() = std::move(buffer);
        doSend(std::move(resp));
    }

    void operator()(ResponseCore::FileBody& fileResponse) const
    {
        if (fileResponse.size == 0)
        {
            sendEmpty();
            return;
        }

        auto resp = createResponse<beast::http::file_body>();

        beast::file file;
        file.native_handle(fileResponse.handle.release());

        boost::system::error_code error;
        resp->body().reset(std::move(file), error);

        doSend(std::move(resp));
    }

private:
    void sendEmpty() const
    {
        doSend(createResponse<beast::http::empty_body>());
    }

    template<typename Body>
    std::shared_ptr<beast::http::response<Body>> createResponse() const
    {
        auto status = beast::http::int_to_status(static_cast<unsigned>(response_->status));
        return std::make_shared<beast::http::response<Body>>(status, request_->version());
    }

    template<typename Response>
    void doSend(std::shared_ptr<Response> response) const
    {
        for (auto& header : response_->headers)
            response->set(header.first, header.second);

        response->keep_alive(request_->keep_alive());
        response->prepare_payload();
        connection_->sendResponse(std::move(response));
    }

    BeastConnection* connection_;
    beast::http::request<beast::http::string_body>* request_;
    ResponseCore* response_;
};

}

BeastRequest::BeastRequest(
    BeastConnection* connection,<commit_msg>beast_request: rearrange response creation logic<commit_after>#include "beast_request.hpp"
#include "beast_connection.hpp"
#include "http.hpp"

namespace msrv {

namespace {

class ResponseCoreSender : public boost::static_visitor<>
{
public:
    ResponseCoreSender(
        BeastConnection* connection,
        beast::http::request<beast::http::string_body>* request,
        ResponseCore* response)
        : connection_(connection),
          request_(request),
          response_(response) { }

    void send() const
    {
        boost::apply_visitor(*this, response_->body);
    }

    void operator()(bool) const
    {
        sendEmpty();
    }

    void operator()(std::string& str) const
    {
        if (str.empty())
        {
            sendEmpty();
            return;
        }

        auto resp = createResponse<beast::http::string_body>();
        resp->body() = std::move(str);
        doSend(std::move(resp));
    }

    void operator()(std::vector<uint8_t>& buffer) const
    {
        if (buffer.empty())
        {
            sendEmpty();
            return;
        }

        auto resp = createResponse<beast::http::vector_body<uint8_t>>();
        resp->body() = std::move(buffer);
        doSend(std::move(resp));
    }

    void operator()(ResponseCore::FileBody& fileResponse) const
    {
        if (fileResponse.size == 0)
        {
            sendEmpty();
            return;
        }

        auto resp = createResponse<beast::http::file_body>();

        beast::file file;
        file.native_handle(fileResponse.handle.release());

        boost::system::error_code error;
        resp->body().reset(std::move(file), error);

        doSend(std::move(resp));
    }

private:
    void sendEmpty() const
    {
        doSend(createResponse<beast::http::empty_body>());
    }

    template<typename Body>
    std::shared_ptr<beast::http::response<Body>> createResponse() const
    {
        using namespace beast::http;

        auto status = int_to_status(static_cast<unsigned>(response_->status));
        auto resp = std::make_shared<response<Body>>(status, request_->version());

        for (auto& header : response_->headers)
            resp->set(header.first, header.second);

        resp->keep_alive(request_->keep_alive());

        return resp;
    }

    template<typename Response>
    void doSend(std::shared_ptr<Response> response) const
    {
        response->prepare_payload();
        connection_->sendResponse(std::move(response));
    }

    BeastConnection* connection_;
    beast::http::request<beast::http::string_body>* request_;
    ResponseCore* response_;
};

}

BeastRequest::BeastRequest(
    BeastConnection* connection,
{'fraction_non_alphanumeric': 0.14013938594838954, 'fraction_numerical': 0.001130156338293464, 'mean_word_length': 2.6900625434329397, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4249974', 'n_tokens_mistral': 1548, 'n_tokens_neox': 1517, 'n_words': 251}