20#ifndef RIPPLE_SERVER_DOOR_H_INCLUDED
21#define RIPPLE_SERVER_DOOR_H_INCLUDED
23#include <xrpl/basics/Log.h>
24#include <xrpl/basics/contract.h>
25#include <xrpl/server/detail/PlainHTTPPeer.h>
26#include <xrpl/server/detail/SSLHTTPPeer.h>
27#include <xrpl/server/detail/io_list.h>
28#include <boost/asio/basic_waitable_timer.hpp>
29#include <boost/asio/buffer.hpp>
30#include <boost/asio/io_context.hpp>
31#include <boost/asio/ip/tcp.hpp>
32#include <boost/asio/spawn.hpp>
33#include <boost/beast/core/detect_ssl.hpp>
34#include <boost/beast/core/multi_buffer.hpp>
35#include <boost/beast/core/tcp_stream.hpp>
36#include <boost/container/flat_map.hpp>
46template <
class Handler>
52 using timer_type = boost::asio::basic_waitable_timer<clock_type>;
68 boost::asio::io_context&
ioc_;
79 boost::asio::io_context& ioc,
96 boost::asio::io_context&
ioc_;
108 boost::asio::io_context& io_context,
132 template <
class ConstBufferSequence>
136 ConstBufferSequence
const& buffers,
144template <
class Handler>
148 boost::asio::io_context& ioc,
155 , stream_(
std::move(stream))
156 , socket_(stream_.socket())
157 , remote_address_(remote_address)
163template <
class Handler>
172 std::placeholders::_1));
175template <
class Handler>
182template <
class Handler>
186 boost::beast::multi_buffer buf(16);
188 boost::system::error_code ec;
189 bool const ssl = async_detect_ssl(stream_, buf, do_yield[ec]);
190 stream_.expires_never();
217 if (ec != boost::asio::error::operation_aborted)
219 JLOG(
j_.
trace()) <<
"Error detecting ssl: " << ec.message() <<
" from "
226template <
class Handler>
238 ss <<
"Can't close acceptor: " <<
port_.
name <<
", "
241 Throw<std::runtime_error>(ss.
str());
247 acceptor_.open(local_address.protocol(), ec);
251 <<
"' failed:" << ec.message();
252 Throw<std::exception>();
256 boost::asio::ip::tcp::acceptor::reuse_address(
true), ec);
260 <<
"' failed:" << ec.message();
261 Throw<std::exception>();
268 <<
"' failed:" << ec.message();
269 Throw<std::exception>();
272 acceptor_.listen(boost::asio::socket_base::max_connections, ec);
276 <<
"' failed:" << ec.message();
277 Throw<std::exception>();
283template <
class Handler>
286 boost::asio::io_context& io_context,
306template <
class Handler>
314 this->shared_from_this(),
315 std::placeholders::_1));
318template <
class Handler>
322 if (!strand_.running_in_this_thread())
331template <
class Handler>
332template <
class ConstBufferSequence>
336 ConstBufferSequence
const& buffers,
364template <
class Handler>
368 while (acceptor_.is_open())
374 acceptor_.async_accept(socket, remote_address, do_yield[ec]);
377 if (ec == boost::asio::error::operation_aborted)
379 JLOG(j_.
error()) <<
"accept: " << ec.message();
380 if (ec == boost::asio::error::no_descriptors)
382 JLOG(j_.
info()) <<
"re-opening acceptor";
390 if (
auto sp = ios().
template emplace<Detector>(
399 else if (ssl_ || plain_)
403 boost::asio::null_buffers{},
A generic endpoint for log messages.
Stream trace() const
Severity stream access functions.
endpoint_type remote_address_
void do_detect(yield_context yield)
boost::asio::io_context & ioc_
boost::asio::io_context::strand strand_
Detector(Port const &port, Handler &handler, boost::asio::io_context &ioc, stream_type &&stream, endpoint_type remote_address, beast::Journal j)
void do_accept(yield_context yield)
void create(bool ssl, ConstBufferSequence const &buffers, stream_type &&stream, endpoint_type remote_address)
protocol_type::endpoint endpoint_type
boost::asio::io_context & ioc_
Door(Handler &handler, boost::asio::io_context &io_context, Port const &port, beast::Journal j)
boost::beast::tcp_stream stream_type
boost::asio::basic_waitable_timer< clock_type > timer_type
protocol_type::acceptor acceptor_type
boost::asio::io_context::strand strand_
boost::system::error_code error_code
boost::asio::ip::tcp protocol_type
boost::asio::yield_context yield_context
void close() override
Close the Door listening socket and connections.
endpoint_type get_endpoint() const
boost::asio::ip::tcp::socket socket_type
io_list & ios()
Return the io_list associated with the work.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
boost::beast::ssl_stream< socket_type > stream_type
T shared_from_this(T... args)
Configuration information for a Server listening port.
boost::asio::ip::address ip