40template <
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();
99namespace acceptor_details
110template<
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 >
161template <
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,
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.
Helper type for controlling the lifetime of the connection.
An interface of acceptor to be used by connection count limiters.
Context for accepting http connections.
void open()
Start listen on port specified in ctor.
asio_ns::ip::tcp::acceptor m_acceptor
void close_impl()
Close opened acceptor.
void accept_connection_for_socket_with_index(std::size_t i)
Performs actual actions for accepting a new connection.
::restinio::connection_count_limits::impl::acceptor_callback_iface_t * self_as_acceptor_callback() noexcept
Helper for suppressing warnings of using this in initilizer list.
typename Traits::strand_t strand_t
std::shared_ptr< connection_factory_t > connection_factory_shared_ptr_t
const asio_ns::ip::tcp m_protocol
connection_factory_shared_ptr_t m_connection_factory
Factory for creating connections.
typename connection_count_limit_types< Traits >::limiter_t connection_count_limiter_t
connection_count_limiter_t m_connection_count_limiter
Actual limiter of active parallel connections.
strand_t m_open_close_operations_executor
void do_accept_current_connection(stream_socket_t incoming_socket, endpoint_t remote_endpoint)
void accept_next(std::size_t i) noexcept
Set a callback for a new connection.
void schedule_next_accept_attempt(std::size_t index) noexcept
typename Traits::stream_socket_t stream_socket_t
typename connection_count_limit_types< Traits >::lifetime_monitor_t connection_lifetime_monitor_t
const std::uint16_t m_port
Server endpoint.
void accept_current_connection(std::size_t i, const std::error_code &ec) noexcept
Accept current connection.
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.
void close()
Close listener if any.
void call_accept_now(std::size_t index) noexcept
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.
acceptor_post_bind_hook_t m_acceptor_post_bind_hook
A hook to be called just after a successful call to bind for acceptor.
const restinio::details::address_variant_t m_address
typename Traits::logger_t logger_t
default_asio_executor m_executor
Asio executor.
const bool m_separate_accept_and_create_connect
Do separate an accept operation and connection instantiation.
auto & get_executor() noexcept
Get executor for acceptor.
acceptor_t(Settings &settings, asio_ns::io_context &io_context, connection_factory_shared_ptr_t connection_factory, logger_t &logger)
auto concurrent_accept_sockets_count() const noexcept
The number of sockets that can be used for cuncurrent accept operations.
Socket & socket(std::size_t idx)
Get the reference to socket.
std::vector< Socket > m_sockets
A temporary socket for receiving new connections.
socket_supplier_t(Settings &settings, asio_ns::io_context &io_context)
Socket move_socket(std::size_t idx)
Extract the socket via move.
asio_ns::io_context & m_io_context
io_context for sockets to run on.
An information about new incoming connection to be passed to IP-blocker object.
#define RESTINIO_NODISCARD
Stuff related to limits of active parallel connections.
A special wrapper around fmtlib include files.
restinio::utils::tagged_scalar_t< std::size_t, max_active_accepts_tag > max_active_accepts_t
A kind of strict typedef for maximum count of active accepts.
restinio::utils::tagged_scalar_t< std::size_t, max_parallel_connections_tag > max_parallel_connections_t
A kind of strict typedef for maximum count of active connections.
inspection_result_t
Enumeration of result of inspecting new incoming connection.
@ deny
New connection is disabled and should be closed.
@ allow
New connection is allowed to be processed further.
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...
void log_error_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
void log_trace_noexcept(Logger &&logger, Message_Builder &&builder) noexcept
Value_Type from_string(string_view_t s)
Get a value from string.
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.
asio_ns::executor default_asio_executor
asio_ns::ip::tcp::endpoint endpoint_t
An alias for endpoint type from Asio.
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
restinio::ip_blocker::inspection_result_t inspect_incoming(Socket &) const noexcept
ip_blocker_holder_t(const Settings &)
A class for holding actual IP-blocker.
restinio::ip_blocker::inspection_result_t inspect_incoming(Socket &socket) const noexcept
std::shared_ptr< Ip_Blocker > m_ip_blocker
ip_blocker_holder_t(const Settings &settings)
The default no-op IP-blocker.
Utilities for suppressing exceptions from some code block.