From b855c0abc7586103bef33e4e533a9f1ce8c7c3d4 Mon Sep 17 00:00:00 2001 From: garethsb-sony Date: Tue, 5 Dec 2017 12:01:29 +0000 Subject: [PATCH] Add http_listener configuration for the backlog, the maximum length of the queue of pending connections on the port. --- Release/include/cpprest/http_listener.h | 26 +++++++++++++++++++ .../src/http/listener/http_server_asio.cpp | 11 +++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Release/include/cpprest/http_listener.h b/Release/include/cpprest/http_listener.h index 3c154e49a6..d51e6e512f 100644 --- a/Release/include/cpprest/http_listener.h +++ b/Release/include/cpprest/http_listener.h @@ -46,6 +46,7 @@ class http_listener_config /// http_listener_config() : m_timeout(utility::seconds(120)) + , m_backlog(0) {} /// @@ -54,6 +55,7 @@ class http_listener_config /// http_listener_config to copy. http_listener_config(const http_listener_config &other) : m_timeout(other.m_timeout) + , m_backlog(other.m_backlog) #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) , m_ssl_context_callback(other.m_ssl_context_callback) #endif @@ -65,6 +67,7 @@ class http_listener_config /// http_listener_config to move from. http_listener_config(http_listener_config &&other) : m_timeout(std::move(other.m_timeout)) + , m_backlog(std::move(other.m_backlog)) #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) , m_ssl_context_callback(std::move(other.m_ssl_context_callback)) #endif @@ -79,6 +82,7 @@ class http_listener_config if(this != &rhs) { m_timeout = rhs.m_timeout; + m_backlog = rhs.m_backlog; #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) m_ssl_context_callback = rhs.m_ssl_context_callback; #endif @@ -95,6 +99,7 @@ class http_listener_config if(this != &rhs) { m_timeout = std::move(rhs.m_timeout); + m_backlog = std::move(rhs.m_backlog); #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) m_ssl_context_callback = std::move(rhs.m_ssl_context_callback); #endif @@ -120,6 +125,26 @@ class http_listener_config m_timeout = std::move(timeout); } + /// + /// Get the listen backlog + /// + /// The maximum length of the queue of pending connections, or zero for the implementation default. + /// The implementation may not honour this value. + int backlog() const + { + return m_backlog; + } + + /// + /// Set the listen backlog + /// + /// The maximum length of the queue of pending connections, or zero for the implementation default. + /// The implementation may not honour this value. + void set_backlog(int backlog) + { + m_backlog = backlog; + } + #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) /// /// Get the callback of ssl context @@ -143,6 +168,7 @@ class http_listener_config private: utility::seconds m_timeout; + int m_backlog; #if !defined(_WIN32) || defined(CPPREST_FORCE_HTTP_LISTENER_ASIO) std::function m_ssl_context_callback; #endif diff --git a/Release/src/http/listener/http_server_asio.cpp b/Release/src/http/listener/http_server_asio.cpp index 99351c13a0..7fe2a76938 100644 --- a/Release/src/http/listener/http_server_asio.cpp +++ b/Release/src/http/listener/http_server_asio.cpp @@ -122,6 +122,7 @@ namespace class hostport_listener { private: + int m_backlog; std::unique_ptr m_acceptor; std::map m_listeners; pplx::extensibility::reader_writer_lock_t m_listeners_lock; @@ -140,7 +141,8 @@ namespace public: hostport_listener(http_linux_server* server, const std::string& hostport, bool is_https, const http_listener_config& config) - : m_acceptor() + : m_backlog(config.backlog()) + , m_acceptor() , m_listeners() , m_listeners_lock() , m_connections_lock() @@ -482,8 +484,11 @@ void hostport_listener::start() tcp::endpoint endpoint = *resolver.resolve(query); - m_acceptor.reset(new tcp::acceptor(service, endpoint)); - m_acceptor->set_option(tcp::acceptor::reuse_address(true)); + m_acceptor.reset(new tcp::acceptor(service)); + m_acceptor->open(endpoint.protocol()); + m_acceptor->set_option(socket_base::reuse_address(true)); + m_acceptor->bind(endpoint); + m_acceptor->listen(0 != m_backlog ? m_backlog : socket_base::max_connections); auto socket = new ip::tcp::socket(service); m_acceptor->async_accept(*socket, [this, socket](const boost::system::error_code& ec)