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>
29#include <boost/asio/basic_waitable_timer.hpp>
30#include <boost/asio/buffer.hpp>
31#include <boost/asio/io_context.hpp>
32#include <boost/asio/ip/tcp.hpp>
33#include <boost/asio/spawn.hpp>
34#include <boost/beast/core/detect_ssl.hpp>
35#include <boost/beast/core/multi_buffer.hpp>
36#include <boost/beast/core/tcp_stream.hpp>
37#include <boost/container/flat_map.hpp>
48template <
class Handler>
54 using timer_type = boost::asio::basic_waitable_timer<clock_type>;
70 boost::asio::io_context&
ioc_;
81 boost::asio::io_context& ioc,
98 boost::asio::io_context&
ioc_;
110 boost::asio::io_context& io_context,
134 template <
class ConstBufferSequence>
138 ConstBufferSequence
const& buffers,
146template <
class Handler>
150 boost::asio::io_context& ioc,
157 , stream_(
std::move(stream))
158 , socket_(stream_.socket())
159 , remote_address_(remote_address)
165template <
class Handler>
174 std::placeholders::_1));
177template <
class Handler>
184template <
class Handler>
188 boost::beast::multi_buffer buf(16);
190 boost::system::error_code ec;
191 bool const ssl = async_detect_ssl(stream_, buf, do_yield[ec]);
192 stream_.expires_never();
219 if (ec != boost::asio::error::operation_aborted)
221 JLOG(
j_.
trace()) <<
"Error detecting ssl: " << ec.message() <<
" from "
228template <
class Handler>
240 ss <<
"Can't close acceptor: " <<
port_.
name <<
", "
243 Throw<std::runtime_error>(ss.
str());
249 acceptor_.open(local_address.protocol(), ec);
253 <<
"' failed:" << ec.message();
254 Throw<std::exception>();
258 boost::asio::ip::tcp::acceptor::reuse_address(
true), ec);
262 <<
"' failed:" << ec.message();
263 Throw<std::exception>();
270 <<
"' failed:" << ec.message();
271 Throw<std::exception>();
274 acceptor_.listen(boost::asio::socket_base::max_connections, ec);
278 <<
"' failed:" << ec.message();
279 Throw<std::exception>();
285template <
class Handler>
288 boost::asio::io_context& io_context,
308template <
class Handler>
316 this->shared_from_this(),
317 std::placeholders::_1));
320template <
class Handler>
324 if (!strand_.running_in_this_thread())
333template <
class Handler>
334template <
class ConstBufferSequence>
338 ConstBufferSequence
const& buffers,
366template <
class Handler>
370 while (acceptor_.is_open())
376 acceptor_.async_accept(socket, remote_address, do_yield[ec]);
379 if (ec == boost::asio::error::operation_aborted)
381 JLOG(j_.
error()) <<
"accept: " << ec.message();
382 if (ec == boost::asio::error::no_descriptors)
384 JLOG(j_.
info()) <<
"re-opening acceptor";
392 if (
auto sp = ios().
template emplace<Detector>(
401 else if (ssl_ || plain_)
405 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