rippled
Loading...
Searching...
No Matches
WorkBase.h
1#pragma once
2
3#include <xrpld/app/misc/detail/Work.h>
4
5#include <xrpl/basics/random.h>
6#include <xrpl/protocol/BuildInfo.h>
7
8#include <boost/asio.hpp>
9#include <boost/asio/strand.hpp>
10#include <boost/beast/core/multi_buffer.hpp>
11#include <boost/beast/http/empty_body.hpp>
12#include <boost/beast/http/read.hpp>
13#include <boost/beast/http/write.hpp>
14
15namespace xrpl {
16
17namespace detail {
18
19template <class Impl>
20class WorkBase : public Work
21{
22protected:
23 using error_code = boost::system::error_code;
24 using endpoint_type = boost::asio::ip::tcp::endpoint;
25
26public:
28
29protected:
30 using socket_type = boost::asio::ip::tcp::socket;
31 using resolver_type = boost::asio::ip::tcp::resolver;
32 using results_type = boost::asio::ip::tcp::resolver::results_type;
33 using request_type = boost::beast::http::request<boost::beast::http::empty_body>;
34
39 boost::asio::io_context& ios_;
40 boost::asio::strand<boost::asio::io_context::executor_type> strand_;
45 boost::beast::multi_buffer readBuf_;
48
49public:
51 std::string const& host,
52 std::string const& path,
53 std::string const& port,
54 boost::asio::io_context& ios,
55 endpoint_type const& lastEndpoint,
56 bool lastStatus,
57 callback_type cb);
59
60 Impl&
62 {
63 return *static_cast<Impl*>(this);
64 }
65
66 void
67 run() override;
68
69 void
70 cancel() override;
71
72 void
73 fail(error_code const& ec);
74
75 void
77
78 void
79 onConnect(error_code const& ec, endpoint_type const& endpoint);
80
81 void
83
84 void
86
87 void
89
90private:
91 void
93};
94
95//------------------------------------------------------------------------------
96
97template <class Impl>
99 std::string const& host,
100 std::string const& path,
101 std::string const& port,
102 boost::asio::io_context& ios,
103 endpoint_type const& lastEndpoint,
104 bool lastStatus,
105 callback_type cb)
106 : host_(host)
107 , path_(path)
108 , port_(port)
109 , cb_(std::move(cb))
110 , ios_(ios)
111 , strand_(boost::asio::make_strand(ios))
112 , resolver_(ios)
113 , socket_(ios)
114 , lastEndpoint_{lastEndpoint}
115 , lastStatus_(lastStatus)
116{
117}
118
119template <class Impl>
121{
122 if (cb_)
123 cb_(make_error_code(boost::system::errc::not_a_socket), lastEndpoint_, std::move(res_));
124 close();
125}
126
127template <class Impl>
128void
130{
131 if (!strand_.running_in_this_thread())
132 return boost::asio::post(
133 ios_, boost::asio::bind_executor(strand_, std::bind(&WorkBase::run, impl().shared_from_this())));
134
135 resolver_.async_resolve(
136 host_,
137 port_,
138 boost::asio::bind_executor(
139 strand_,
140 std::bind(&WorkBase::onResolve, impl().shared_from_this(), std::placeholders::_1, std::placeholders::_2)));
141}
142
143template <class Impl>
144void
146{
147 if (!strand_.running_in_this_thread())
148 {
149 return boost::asio::post(
150 ios_,
151
152 boost::asio::bind_executor(strand_, std::bind(&WorkBase::cancel, impl().shared_from_this())));
153 }
154
155 error_code ec;
156 resolver_.cancel();
157 socket_.cancel(ec);
158}
159
160template <class Impl>
161void
163{
164 if (cb_)
165 {
166 cb_(ec, lastEndpoint_, std::move(res_));
167 cb_ = nullptr;
168 }
169}
170
171template <class Impl>
172void
174{
175 if (ec)
176 return fail(ec);
177
178 boost::asio::async_connect(
179 socket_,
180 results,
181 boost::asio::bind_executor(
182 strand_,
183 std::bind(&WorkBase::onConnect, impl().shared_from_this(), std::placeholders::_1, std::placeholders::_2)));
184}
185
186template <class Impl>
187void
189{
190 lastEndpoint_ = endpoint;
191
192 if (ec)
193 return fail(ec);
194
195 impl().onConnect(ec);
196}
197
198template <class Impl>
199void
201{
202 req_.method(boost::beast::http::verb::get);
203 req_.target(path_.empty() ? "/" : path_);
204 req_.version(11);
205 req_.set("Host", host_ + ":" + port_);
206 req_.set("User-Agent", BuildInfo::getFullVersionString());
207 req_.prepare_payload();
208 boost::beast::http::async_write(
209 impl().stream(),
210 req_,
211 boost::asio::bind_executor(
212 strand_, std::bind(&WorkBase::onRequest, impl().shared_from_this(), std::placeholders::_1)));
213}
214
215template <class Impl>
216void
218{
219 if (ec)
220 return fail(ec);
221
222 boost::beast::http::async_read(
223 impl().stream(),
224 readBuf_,
225 res_,
226 boost::asio::bind_executor(
227 strand_, std::bind(&WorkBase::onResponse, impl().shared_from_this(), std::placeholders::_1)));
228}
229
230template <class Impl>
231void
233{
234 if (ec)
235 return fail(ec);
236
237 close();
238 XRPL_ASSERT(cb_, "xrpl::detail::WorkBase::onResponse : callback is set");
239 cb_(ec, lastEndpoint_, std::move(res_));
240 cb_ = nullptr;
241}
242
243template <class Impl>
244void
246{
247 if (socket_.is_open())
248 {
249 error_code ec;
250 socket_.shutdown(boost::asio::socket_base::shutdown_send, ec);
251 if (ec)
252 return;
253 socket_.close(ec);
254 }
255}
256
257} // namespace detail
258
259} // namespace xrpl
T bind(T... args)
void fail(error_code const &ec)
Definition WorkBase.h:162
void cancel() override
Definition WorkBase.h:145
endpoint_type lastEndpoint_
Definition WorkBase.h:46
boost::beast::http::request< boost::beast::http::empty_body > request_type
Definition WorkBase.h:33
request_type req_
Definition WorkBase.h:43
response_type res_
Definition WorkBase.h:44
void onResolve(error_code const &ec, results_type results)
Definition WorkBase.h:173
std::string port_
Definition WorkBase.h:37
socket_type socket_
Definition WorkBase.h:42
callback_type cb_
Definition WorkBase.h:38
std::string path_
Definition WorkBase.h:36
boost::asio::ip::tcp::endpoint endpoint_type
Definition WorkBase.h:24
boost::system::error_code error_code
Definition WorkBase.h:23
boost::asio::ip::tcp::resolver::results_type results_type
Definition WorkBase.h:32
void onRequest(error_code const &ec)
Definition WorkBase.h:217
boost::asio::ip::tcp::socket socket_type
Definition WorkBase.h:30
void onConnect(error_code const &ec, endpoint_type const &endpoint)
Definition WorkBase.h:188
boost::asio::strand< boost::asio::io_context::executor_type > strand_
Definition WorkBase.h:40
void onResponse(error_code const &ec)
Definition WorkBase.h:232
boost::beast::multi_buffer readBuf_
Definition WorkBase.h:45
WorkBase(std::string const &host, std::string const &path, std::string const &port, boost::asio::io_context &ios, endpoint_type const &lastEndpoint, bool lastStatus, callback_type cb)
Definition WorkBase.h:98
resolver_type resolver_
Definition WorkBase.h:41
boost::asio::io_context & ios_
Definition WorkBase.h:39
std::string host_
Definition WorkBase.h:35
void run() override
Definition WorkBase.h:129
boost::asio::ip::tcp::resolver resolver_type
Definition WorkBase.h:31
STL namespace.
std::string const & getFullVersionString()
Full server version string.
Definition BuildInfo.cpp:64
boost::beast::http::response< boost::beast::http::string_body > response_type
Definition Work.h:10
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::error_code make_error_code(xrpl::TokenCodecErrc e)