20 #ifndef RIPPLE_SERVER_DOOR_H_INCLUDED
21 #define RIPPLE_SERVER_DOOR_H_INCLUDED
23 #include <ripple/basics/Log.h>
24 #include <ripple/basics/contract.h>
25 #include <ripple/server/impl/PlainHTTPPeer.h>
26 #include <ripple/server/impl/SSLHTTPPeer.h>
27 #include <ripple/server/impl/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>
46 template <
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_;
105 boost::asio::io_context& io_context,
129 template <
class ConstBufferSequence>
133 ConstBufferSequence
const& buffers,
141 template <
class Handler>
145 boost::asio::io_context& ioc,
152 , stream_(
std::move(stream))
153 , socket_(stream_.socket())
154 , remote_address_(remote_address)
160 template <
class Handler>
169 std::placeholders::_1));
172 template <
class Handler>
179 template <
class Handler>
183 boost::beast::multi_buffer buf(16);
185 boost::system::error_code ec;
186 bool const ssl = async_detect_ssl(stream_, buf, do_yield[ec]);
187 stream_.expires_never();
214 if (ec != boost::asio::error::operation_aborted)
216 JLOG(
j_.
trace()) <<
"Error detecting ssl: " << ec.message() <<
" from "
223 template <
class Handler>
226 boost::asio::io_context& io_context,
236 port_.protocol.count(
"https") > 0 ||
237 port_.protocol.count(
"wss") > 0 ||
port_.protocol.count(
"wss2") > 0 ||
238 port_.protocol.count(
"peer") > 0)
240 port_.protocol.count(
"http") > 0 ||
port_.protocol.count(
"ws") > 0 ||
241 port_.protocol.count(
"ws2"))
246 acceptor_.open(local_address.protocol(), ec);
250 <<
"' failed:" << ec.message();
251 Throw<std::exception>();
255 boost::asio::ip::tcp::acceptor::reuse_address(
true), ec);
258 JLOG(
j_.
error()) <<
"Option for port '" << port.
name
259 <<
"' failed:" << ec.message();
260 Throw<std::exception>();
267 <<
"' failed:" << ec.message();
268 Throw<std::exception>();
271 acceptor_.listen(boost::asio::socket_base::max_connections, ec);
274 JLOG(
j_.
error()) <<
"Listen on port '" << port.
name
275 <<
"' failed:" << ec.message();
276 Throw<std::exception>();
279 JLOG(
j_.
info()) <<
"Opened " << port;
282 template <
class Handler>
290 this->shared_from_this(),
291 std::placeholders::_1));
294 template <
class Handler>
298 if (!strand_.running_in_this_thread())
307 template <
class Handler>
308 template <
class ConstBufferSequence>
312 ConstBufferSequence
const& buffers,
340 template <
class Handler>
344 while (acceptor_.is_open())
350 acceptor_.async_accept(socket, remote_address, do_yield[ec]);
351 if (ec && ec != boost::asio::error::operation_aborted)
353 JLOG(j_.
error()) <<
"accept: " << ec.message();
355 if (ec == boost::asio::error::operation_aborted)
362 if (
auto sp = ios().
template emplace<Detector>(
371 else if (ssl_ || plain_)
375 boost::asio::null_buffers{},