Go to the documentation of this file.
40 template <
typename Socket >
44 template <
typename Settings >
49 asio_ns::io_context & io_context )
52 m_sockets.reserve( settings.concurrent_accepts_count() );
56 settings.concurrent_accepts_count(),
58 return Socket{m_io_context};
61 assert(
m_sockets.size() == settings.concurrent_accepts_count() );
70 return m_sockets.at( idx );
87 return m_sockets.size();
99 namespace acceptor_details
110 template<
typename Ip_Blocker >
115 template<
typename Settings >
117 const Settings & settings )
118 : m_ip_blocker{ settings.ip_blocker() }
121 template<
typename Socket >
125 return m_ip_blocker->inspect(
127 socket.lowest_layer().remote_endpoint()
143 template<
typename Settings >
146 template<
typename Socket >
161 template <
typename Traits >
163 :
public std::enable_shared_from_this< acceptor_t< Traits > >
169 typename Traits::ip_blocker_t >;
179 std::shared_ptr< connection_factory_t >;
185 template <
typename Settings >
189 asio_ns::io_context & io_context,
195 , ip_blocker_base_t{ settings }
196 , m_port{ settings.port() }
197 , m_protocol{ settings.protocol() }
198 , m_address{ settings.address() }
199 , m_acceptor_options_setter{ settings.acceptor_options_setter() }
200 , m_acceptor{ io_context }
201 , m_acceptor_post_bind_hook{ settings.giveaway_acceptor_post_bind_hook() }
202 , m_executor{ io_context.get_executor() }
203 , m_open_close_operations_executor{ io_context.get_executor() }
204 , m_separate_accept_and_create_connect{ settings.separate_accept_and_create_connect() }
205 , m_connection_factory{
std::move( connection_factory ) }
207 , m_connection_count_limiter{
208 self_as_acceptor_callback(),
210 settings.max_parallel_connections()
213 settings.concurrent_accepts_count()
222 if( m_acceptor.is_open() )
224 const auto ep = m_acceptor.local_endpoint();
226 return fmt::format(
"server already started on {}",
ep );
231 asio_ns::ip::tcp::endpoint
ep{ m_protocol, m_port };
233 const auto actual_address = try_extract_actual_address_from_variant(
236 ep.address( *actual_address );
241 return fmt::format(
"starting server on {}",
ep );
244 m_acceptor.open(
ep.protocol() );
250 (*m_acceptor_options_setter)( options );
253 m_acceptor.bind(
ep );
255 m_acceptor_post_bind_hook( m_acceptor );
259 ep = m_acceptor.local_endpoint();
262 m_acceptor.listen( asio_ns::socket_base::max_connections );
265 for( std::size_t i = 0; i< this->concurrent_accept_sockets_count(); ++i )
268 return fmt::format(
"init accept #{}", i );
275 return fmt::format(
"server started on {}",
ep );
278 catch(
const std::exception & ex )
281 if( m_acceptor.is_open() )
284 m_logger.error( [&]() ->
auto {
285 return fmt::format(
"failed to start server on {}: {}",
298 if( m_acceptor.is_open() )
305 return fmt::format(
"server already closed" );
314 return m_open_close_operations_executor;
328 m_acceptor.async_accept(
329 this->socket( index ).lowest_layer(),
330 asio_ns::bind_executor(
332 [index, ctx = this->shared_from_this()]
333 (
const auto & ec ) noexcept
337 ctx->accept_current_connection( index, ec );
349 asio_ns::bind_executor(
351 [index, ctx = this->shared_from_this()]() noexcept
353 ctx->accept_next( index );
383 m_connection_count_limiter.accept_next( i );
395 const std::error_code & ec ) noexcept
401 "accept_current_connection",
403 accept_connection_for_socket_with_index( i );
412 "failed to accept connection on socket #{}: {}",
435 auto incoming_socket = this->move_socket( i );
437 auto remote_endpoint =
438 incoming_socket.lowest_layer().remote_endpoint();
442 "accept connection from {} on socket #{}",
443 remote_endpoint, i );
448 const auto inspection_result = this->inspect_incoming(
451 switch( inspection_result )
457 "accepted connection from {} on socket #{} denied by"
459 remote_endpoint, i );
466 do_accept_current_connection(
478 auto create_and_init_connection =
480 factory = m_connection_factory,
483 &m_connection_count_limiter
491 "do_accept_current_connection.create_and_init_connection",
497 auto conn = factory->create_new_connection(
507 if( m_separate_accept_and_create_connect )
511 std::move( create_and_init_connection ) );
515 create_and_init_connection();
523 const auto ep = m_acceptor.local_endpoint();
529 return fmt::format(
"closing server on {}",
ep );
535 return fmt::format(
"server closed on {}",
ep );
592 if(
auto * str_v = get_if<std::string>( &from ) )
594 auto str_addr = *str_v;
595 if( str_addr ==
"localhost" )
596 str_addr =
"127.0.0.1";
597 else if( str_addr ==
"ip6-localhost" )
602 else if(
auto * addr_v = get_if<asio_ns::ip::address>( &from ) )
An adapter for setting acceptor options before running server.
std::unique_ptr< acceptor_options_setter_t > m_acceptor_options_setter
Server port listener and connection receiver routine.
auto & get_open_close_operations_executor() noexcept
Get an executor for close operation.
#define RESTINIO_NODISCARD
typename connection_count_limit_types< Traits >::limiter_t connection_count_limiter_t
inspection_result_t
Enumeration of result of inspecting new incoming connection.
constexpr inspection_result_t deny() noexcept
Shorthand for inspection_result_t::deny.
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
Helper type for controlling the lifetime of the connection.
static RESTINIO_NODISCARD optional_t< asio_ns::ip::address > try_extract_actual_address_from_variant(const restinio::details::address_variant_t &from)
Helper for extraction of an actual IP-address from an instance of address_variant.
typename Traits::strand_t strand_t
default_asio_executor m_executor
Asio executor.
asio_ns::ip::tcp::acceptor m_acceptor
A class for holding actual IP-blocker.
asio_ns::io_context & m_io_context
io_context for sockets to run on.
std::shared_ptr< Ip_Blocker > m_ip_blocker
Context for accepting http connections.
void call_accept_now(std::size_t index) noexcept
const std::uint16_t m_port
Server endpoint.
auto concurrent_accept_sockets_count() const noexcept
The number of sockets that can be used for cuncurrent accept operations.
typename Traits::logger_t logger_t
Stuff related to limits of active parallel connections.
typename std::conditional< Traits::use_connection_count_limiter, connection_count_limits::connection_count_limiter_t< typename Traits::strand_t >, connection_count_limits::noop_connection_count_limiter_t >::type limiter_t
void log_error_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
ip_blocker_holder_t(const Settings &)
asio_ns::executor default_asio_executor
Socket move_socket(std::size_t idx)
Extract the socket via move.
Helper template for defining tagged scalar types.
void do_accept_current_connection(stream_socket_t incoming_socket, endpoint_t remote_endpoint)
std::shared_ptr< connection_factory_t > connection_factory_shared_ptr_t
An interface of acceptor to be used by connection count limiters.
void log_trace_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
typename connection_count_limit_types< Traits >::lifetime_monitor_t connection_lifetime_monitor_t
restinio::ip_blocker::inspection_result_t inspect_incoming(Socket &socket) const noexcept
void suppress_exceptions(Logger &&logger, const char *block_description, Lambda &&lambda) noexcept
Helper function for execution a block of code with suppression of any exceptions raised inside that b...
std::vector< Socket > m_sockets
A temporary socket for receiving new connections.
A special wrapper around fmtlib include files.
const restinio::details::address_variant_t m_address
@ deny
New connection is disabled and should be closed.
std::function< void(asio_ns::ip::tcp::acceptor &) > acceptor_post_bind_hook_t
A type of callback to be called after a successful invocation of bind() function for the acceptor.
Utilities for suppressing exceptions from some code block.
strand_t m_open_close_operations_executor
void accept_connection_for_socket_with_index(std::size_t i)
Performs actual actions for accepting a new connection.
socket_supplier_t(Settings &settings, asio_ns::io_context &io_context)
ip_blocker_holder_t(const Settings &settings)
void accept_next(std::size_t i) noexcept
Set a callback for a new connection.
Socket & socket(std::size_t idx)
Get the reference to socket.
void open()
Start listen on port specified in ctor.
restinio::ip_blocker::inspection_result_t inspect_incoming(Socket &) const noexcept
auto & get_executor() noexcept
Get executor for acceptor.
const bool m_separate_accept_and_create_connect
Do separate an accept operation and connection instantiation.
typename Traits::stream_socket_t stream_socket_t
connection_factory_shared_ptr_t m_connection_factory
Factory for creating connections.
acceptor_post_bind_hook_t m_acceptor_post_bind_hook
A hook to be called just after a successful call to bind for acceptor.
An information about new incoming connection to be passed to IP-blocker object.
connection_count_limiter_t m_connection_count_limiter
Actual limiter of active parallel connections.
The default no-op IP-blocker.
void close()
Close listener if any.
Value_Type from_string(string_view_t s)
Get a value from string.
::restinio::connection_count_limits::impl::acceptor_callback_iface_t * self_as_acceptor_callback() noexcept
Helper for suppressing warnings of using this in initilizer list.
void close_impl()
Close opened acceptor.
void accept_current_connection(std::size_t i, const std::error_code &ec) noexcept
Accept current connection.
const asio_ns::ip::tcp m_protocol
acceptor_t(Settings &settings, asio_ns::io_context &io_context, connection_factory_shared_ptr_t connection_factory, logger_t &logger)
void schedule_next_accept_attempt(std::size_t index) noexcept