20#ifndef RIPPLE_APP_MISC_DETAIL_WORKBASE_H_INCLUDED
21#define RIPPLE_APP_MISC_DETAIL_WORKBASE_H_INCLUDED
23#include <xrpld/app/misc/detail/Work.h>
24#include <xrpl/basics/random.h>
25#include <xrpl/protocol/BuildInfo.h>
27#include <boost/asio.hpp>
28#include <boost/beast/core/multi_buffer.hpp>
29#include <boost/beast/http/empty_body.hpp>
30#include <boost/beast/http/read.hpp>
31#include <boost/beast/http/write.hpp>
53 boost::beast::http::request<boost::beast::http::empty_body>;
59 boost::asio::io_service&
ios_;
74 boost::asio::io_service& ios,
83 return *
static_cast<Impl*
>(
this);
119 boost::asio::io_service& ios,
131 , lastEndpoint_{lastEndpoint}
132 , lastStatus_(lastStatus)
150 if (!strand_.running_in_this_thread())
154 resolver_.async_resolve(
159 impl().shared_from_this(),
160 std::placeholders::_1,
161 std::placeholders::_2)));
168 if (!strand_.running_in_this_thread())
170 return ios_.post(strand_.wrap(
185 cb_(ec, lastEndpoint_, std::move(res_));
205 results.begin(), results.end(), [&](
endpoint_type const& e) {
206 if (e == lastEndpoint_)
211 if (foundIt != results.end() && lastStatus_)
212 return lastEndpoint_;
213 else if (results.size() == 1)
214 return *results.begin();
215 else if (foundIt == results.end())
225 (results.size() > 2) ?
rand_int(results.size() - 2) : 0;
226 if (randIndex == foundIndex)
227 randIndex = results.size() - 1;
228 return *
std::next(results.begin(), randIndex);
231 socket_.async_connect(
235 impl().shared_from_this(),
236 std::placeholders::_1)));
243 req_.method(boost::beast::http::verb::get);
244 req_.target(path_.empty() ?
"/" : path_);
246 req_.set(
"Host", host_ +
":" + port_);
248 req_.prepare_payload();
249 boost::beast::http::async_write(
254 impl().shared_from_this(),
255 std::placeholders::_1)));
265 boost::beast::http::async_read(
271 impl().shared_from_this(),
272 std::placeholders::_1)));
283 XRPL_ASSERT(cb_,
"ripple::detail::WorkBase::onResponse : callback is set");
284 cb_(ec, lastEndpoint_, std::move(res_));
292 if (socket_.is_open())
295 socket_.shutdown(boost::asio::socket_base::shutdown_send, ec);
boost::asio::io_service & ios_
endpoint_type lastEndpoint_
boost::asio::ip::tcp::resolver::results_type results_type
boost::beast::http::request< boost::beast::http::empty_body > request_type
void onResolve(error_code const &ec, results_type results)
void onRequest(error_code const &ec)
boost::asio::ip::tcp::socket socket_type
boost::asio::io_service::strand strand_
void onResponse(error_code const &ec)
boost::asio::ip::tcp::endpoint endpoint_type
boost::asio::ip::tcp::resolver resolver_type
boost::system::error_code error_code
boost::beast::multi_buffer readBuf_
WorkBase(std::string const &host, std::string const &path, std::string const &port, boost::asio::io_service &ios, endpoint_type const &lastEndpoint, bool lastStatus, callback_type cb)
void fail(error_code const &ec)
std::string const & getFullVersionString()
Full server version string.
boost::beast::http::response< boost::beast::http::string_body > response_type
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::enable_if_t< std::is_integral< Integral >::value, Integral > rand_int()
std::error_code make_error_code(ripple::TokenCodecErrc e)