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