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 std::function<void(error_code const&, endpoint_type const&, response_type&&)>;
29
30protected:
31 using socket_type = boost::asio::ip::tcp::socket;
32 using resolver_type = boost::asio::ip::tcp::resolver;
33 using results_type = boost::asio::ip::tcp::resolver::results_type;
34 using request_type = boost::beast::http::request<boost::beast::http::empty_body>;
35
40 boost::asio::io_context& ios_;
41 boost::asio::strand<boost::asio::io_context::executor_type> strand_;
46 boost::beast::multi_buffer readBuf_;
49
50public:
52 std::string const& host,
53 std::string const& path,
54 std::string const& port,
55 boost::asio::io_context& ios,
56 endpoint_type const& lastEndpoint,
57 bool lastStatus,
58 callback_type cb);
60
61 Impl&
63 {
64 return *static_cast<Impl*>(this);
65 }
66
67 void
68 run() override;
69
70 void
71 cancel() override;
72
73 void
74 fail(error_code const& ec);
75
76 void
78
79 void
80 onConnect(error_code const& ec, endpoint_type const& endpoint);
81
82 void
84
85 void
87
88 void
90
91private:
92 void
94};
95
96//------------------------------------------------------------------------------
97
98template <class Impl>
100 std::string const& host,
101 std::string const& path,
102 std::string const& port,
103 boost::asio::io_context& ios,
104 endpoint_type const& lastEndpoint,
105 bool lastStatus,
106 callback_type cb)
107 : host_(host)
108 , path_(path)
109 , port_(port)
110 , cb_(std::move(cb))
111 , ios_(ios)
112 , strand_(boost::asio::make_strand(ios))
113 , resolver_(ios)
114 , socket_(ios)
115 , lastEndpoint_{lastEndpoint}
116 , lastStatus_(lastStatus)
117{
118}
119
120template <class Impl>
122{
123 if (cb_)
124 cb_(make_error_code(boost::system::errc::not_a_socket), lastEndpoint_, std::move(res_));
125 close();
126}
127
128template <class Impl>
129void
131{
132 if (!strand_.running_in_this_thread())
133 return boost::asio::post(
134 ios_,
135 boost::asio::bind_executor(
136 strand_, std::bind(&WorkBase::run, impl().shared_from_this())));
137
138 resolver_.async_resolve(
139 host_,
140 port_,
141 boost::asio::bind_executor(
142 strand_,
143 std::bind(
145 impl().shared_from_this(),
146 std::placeholders::_1,
147 std::placeholders::_2)));
148}
149
150template <class Impl>
151void
153{
154 if (!strand_.running_in_this_thread())
155 {
156 return boost::asio::post(
157 ios_,
158
159 boost::asio::bind_executor(
160 strand_, std::bind(&WorkBase::cancel, impl().shared_from_this())));
161 }
162
163 error_code ec;
164 resolver_.cancel();
165 socket_.cancel(ec);
166}
167
168template <class Impl>
169void
171{
172 if (cb_)
173 {
174 cb_(ec, lastEndpoint_, std::move(res_));
175 cb_ = nullptr;
176 }
177}
178
179template <class Impl>
180void
182{
183 if (ec)
184 return fail(ec);
185
186 boost::asio::async_connect(
187 socket_,
188 results,
189 boost::asio::bind_executor(
190 strand_,
191 std::bind(
193 impl().shared_from_this(),
194 std::placeholders::_1,
195 std::placeholders::_2)));
196}
197
198template <class Impl>
199void
201{
202 lastEndpoint_ = endpoint;
203
204 if (ec)
205 return fail(ec);
206
207 impl().onConnect(ec);
208}
209
210template <class Impl>
211void
213{
214 req_.method(boost::beast::http::verb::get);
215 req_.target(path_.empty() ? "/" : path_);
216 req_.version(11);
217 req_.set("Host", host_ + ":" + port_);
218 req_.set("User-Agent", BuildInfo::getFullVersionString());
219 req_.prepare_payload();
220 boost::beast::http::async_write(
221 impl().stream(),
222 req_,
223 boost::asio::bind_executor(
224 strand_,
225 std::bind(&WorkBase::onRequest, impl().shared_from_this(), std::placeholders::_1)));
226}
227
228template <class Impl>
229void
231{
232 if (ec)
233 return fail(ec);
234
235 boost::beast::http::async_read(
236 impl().stream(),
237 readBuf_,
238 res_,
239 boost::asio::bind_executor(
240 strand_,
241 std::bind(&WorkBase::onResponse, impl().shared_from_this(), std::placeholders::_1)));
242}
243
244template <class Impl>
245void
247{
248 if (ec)
249 return fail(ec);
250
251 close();
252 XRPL_ASSERT(cb_, "xrpl::detail::WorkBase::onResponse : callback is set");
253 cb_(ec, lastEndpoint_, std::move(res_));
254 cb_ = nullptr;
255}
256
257template <class Impl>
258void
260{
261 if (socket_.is_open())
262 {
263 error_code ec;
264 socket_.shutdown(boost::asio::socket_base::shutdown_send, ec);
265 if (ec)
266 return;
267 socket_.close(ec);
268 }
269}
270
271} // namespace detail
272
273} // namespace xrpl
T bind(T... args)
void fail(error_code const &ec)
Definition WorkBase.h:170
void cancel() override
Definition WorkBase.h:152
endpoint_type lastEndpoint_
Definition WorkBase.h:47
boost::beast::http::request< boost::beast::http::empty_body > request_type
Definition WorkBase.h:34
request_type req_
Definition WorkBase.h:44
response_type res_
Definition WorkBase.h:45
void onResolve(error_code const &ec, results_type results)
Definition WorkBase.h:181
std::string port_
Definition WorkBase.h:38
socket_type socket_
Definition WorkBase.h:43
callback_type cb_
Definition WorkBase.h:39
std::string path_
Definition WorkBase.h:37
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:33
void onRequest(error_code const &ec)
Definition WorkBase.h:230
boost::asio::ip::tcp::socket socket_type
Definition WorkBase.h:31
void onConnect(error_code const &ec, endpoint_type const &endpoint)
Definition WorkBase.h:200
boost::asio::strand< boost::asio::io_context::executor_type > strand_
Definition WorkBase.h:41
void onResponse(error_code const &ec)
Definition WorkBase.h:246
boost::beast::multi_buffer readBuf_
Definition WorkBase.h:46
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:99
resolver_type resolver_
Definition WorkBase.h:42
boost::asio::io_context & ios_
Definition WorkBase.h:40
std::string host_
Definition WorkBase.h:36
void run() override
Definition WorkBase.h:130
boost::asio::ip::tcp::resolver resolver_type
Definition WorkBase.h:32
STL namespace.
std::string const & getFullVersionString()
Full server version string.
Definition BuildInfo.cpp:82
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)