nghttpx: Rename ListenHandler as ConnectionHandler

This commit is contained in:
Tatsuhiro Tsujikawa 2015-01-08 21:48:39 +09:00
parent f570757701
commit 0173929538
6 changed files with 72 additions and 66 deletions

View File

@ -101,7 +101,7 @@ NGHTTPX_SRCS = \
shrpx_config.cc shrpx_config.h \ shrpx_config.cc shrpx_config.h \
shrpx_error.h \ shrpx_error.h \
shrpx_accept_handler.cc shrpx_accept_handler.h \ shrpx_accept_handler.cc shrpx_accept_handler.h \
shrpx_listen_handler.cc shrpx_listen_handler.h \ shrpx_connection_handler.cc shrpx_connection_handler.h \
shrpx_client_handler.cc shrpx_client_handler.h \ shrpx_client_handler.cc shrpx_client_handler.h \
shrpx_upstream.h \ shrpx_upstream.h \
shrpx_http2_upstream.cc shrpx_http2_upstream.h \ shrpx_http2_upstream.cc shrpx_http2_upstream.h \

View File

@ -54,7 +54,7 @@
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
#include "shrpx_config.h" #include "shrpx_config.h"
#include "shrpx_listen_handler.h" #include "shrpx_connection_handler.h"
#include "shrpx_ssl.h" #include "shrpx_ssl.h"
#include "shrpx_worker_config.h" #include "shrpx_worker_config.h"
#include "shrpx_worker.h" #include "shrpx_worker.h"
@ -139,7 +139,7 @@ int resolve_hostname(sockaddr_union *addr, size_t *addrlen,
} // namespace } // namespace
namespace { namespace {
std::unique_ptr<AcceptHandler> create_acceptor(ListenHandler *handler, std::unique_ptr<AcceptHandler> create_acceptor(ConnectionHandler *handler,
int family) { int family) {
{ {
auto envfd = auto envfd =
@ -294,7 +294,7 @@ void save_pid() {
namespace { namespace {
void reopen_log_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) { void reopen_log_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
auto listener_handler = static_cast<ListenHandler *>(w->data); auto conn_handler = static_cast<ConnectionHandler *>(w->data);
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LOG(INFO) << "Reopening log files: worker_info(" << worker_config << ")"; LOG(INFO) << "Reopening log files: worker_info(" << worker_config << ")";
@ -303,14 +303,14 @@ void reopen_log_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
(void)reopen_log_files(); (void)reopen_log_files();
if (get_config()->num_worker > 1) { if (get_config()->num_worker > 1) {
listener_handler->worker_reopen_log_files(); conn_handler->worker_reopen_log_files();
} }
} }
} // namespace } // namespace
namespace { namespace {
void exec_binary_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) { void exec_binary_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
auto listener_handler = static_cast<ListenHandler *>(w->data); auto conn_handler = static_cast<ConnectionHandler *>(w->data);
LOG(NOTICE) << "Executing new binary"; LOG(NOTICE) << "Executing new binary";
@ -349,14 +349,14 @@ void exec_binary_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
auto envp = util::make_unique<char *[]>(envlen + 3 + 1); auto envp = util::make_unique<char *[]>(envlen + 3 + 1);
size_t envidx = 0; size_t envidx = 0;
auto acceptor4 = listener_handler->get_acceptor4(); auto acceptor4 = conn_handler->get_acceptor4();
if (acceptor4) { if (acceptor4) {
std::string fd4 = ENV_LISTENER4_FD "="; std::string fd4 = ENV_LISTENER4_FD "=";
fd4 += util::utos(acceptor4->get_fd()); fd4 += util::utos(acceptor4->get_fd());
envp[envidx++] = strdup(fd4.c_str()); envp[envidx++] = strdup(fd4.c_str());
} }
auto acceptor6 = listener_handler->get_acceptor6(); auto acceptor6 = conn_handler->get_acceptor6();
if (acceptor6) { if (acceptor6) {
std::string fd6 = ENV_LISTENER6_FD "="; std::string fd6 = ENV_LISTENER6_FD "=";
fd6 += util::utos(acceptor6->get_fd()); fd6 += util::utos(acceptor6->get_fd());
@ -401,20 +401,20 @@ void exec_binary_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
namespace { namespace {
void graceful_shutdown_signal_cb(struct ev_loop *loop, ev_signal *w, void graceful_shutdown_signal_cb(struct ev_loop *loop, ev_signal *w,
int revents) { int revents) {
auto listener_handler = static_cast<ListenHandler *>(w->data); auto conn_handler = static_cast<ConnectionHandler *>(w->data);
LOG(NOTICE) << "Graceful shutdown signal received"; LOG(NOTICE) << "Graceful shutdown signal received";
worker_config->graceful_shutdown = true; worker_config->graceful_shutdown = true;
listener_handler->disable_acceptor(); conn_handler->disable_acceptor();
// After disabling accepting new connection, disptach incoming // After disabling accepting new connection, disptach incoming
// connection in backlog. // connection in backlog.
listener_handler->accept_pending_connection(); conn_handler->accept_pending_connection();
listener_handler->graceful_shutdown_worker(); conn_handler->graceful_shutdown_worker();
// We have accepted all pending connections. Shutdown main event // We have accepted all pending connections. Shutdown main event
// loop. // loop.
@ -424,8 +424,8 @@ void graceful_shutdown_signal_cb(struct ev_loop *loop, ev_signal *w,
namespace { namespace {
void refresh_cb(struct ev_loop *loop, ev_timer *w, int revents) { void refresh_cb(struct ev_loop *loop, ev_timer *w, int revents) {
auto listener_handler = static_cast<ListenHandler *>(w->data); auto conn_handler = static_cast<ConnectionHandler *>(w->data);
auto worker_stat = listener_handler->get_worker_stat(); auto worker_stat = conn_handler->get_worker_stat();
// In multi threaded mode (get_config()->num_worker > 1), we have to // In multi threaded mode (get_config()->num_worker > 1), we have to
// wait for event notification to workers to finish. // wait for event notification to workers to finish.
@ -438,7 +438,7 @@ void refresh_cb(struct ev_loop *loop, ev_timer *w, int revents) {
namespace { namespace {
void renew_ticket_key_cb(struct ev_loop *loop, ev_timer *w, int revents) { void renew_ticket_key_cb(struct ev_loop *loop, ev_timer *w, int revents) {
auto listener_handler = static_cast<ListenHandler *>(w->data); auto conn_handler = static_cast<ConnectionHandler *>(w->data);
const auto &old_ticket_keys = worker_config->ticket_keys; const auto &old_ticket_keys = worker_config->ticket_keys;
auto ticket_keys = std::make_shared<TicketKeys>(); auto ticket_keys = std::make_shared<TicketKeys>();
@ -475,7 +475,7 @@ void renew_ticket_key_cb(struct ev_loop *loop, ev_timer *w, int revents) {
worker_config->ticket_keys = ticket_keys; worker_config->ticket_keys = ticket_keys;
listener_handler->worker_renew_ticket_keys(ticket_keys); conn_handler->worker_renew_ticket_keys(ticket_keys);
} }
} // namespace } // namespace
@ -497,8 +497,8 @@ int event_loop() {
: nullptr; : nullptr;
} }
auto listener_handler = auto conn_handler =
util::make_unique<ListenHandler>(loop, sv_ssl_ctx, cl_ssl_ctx); util::make_unique<ConnectionHandler>(loop, sv_ssl_ctx, cl_ssl_ctx);
if (get_config()->daemon) { if (get_config()->daemon) {
if (daemon(0, 0) == -1) { if (daemon(0, 0) == -1) {
auto error = errno; auto error = errno;
@ -514,16 +514,16 @@ int event_loop() {
save_pid(); save_pid();
} }
auto acceptor6 = create_acceptor(listener_handler.get(), AF_INET6); auto acceptor6 = create_acceptor(conn_handler.get(), AF_INET6);
auto acceptor4 = create_acceptor(listener_handler.get(), AF_INET); auto acceptor4 = create_acceptor(conn_handler.get(), AF_INET);
if (!acceptor6 && !acceptor4) { if (!acceptor6 && !acceptor4) {
LOG(FATAL) << "Failed to listen on address " << get_config()->host.get() LOG(FATAL) << "Failed to listen on address " << get_config()->host.get()
<< ", port " << get_config()->port; << ", port " << get_config()->port;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
listener_handler->set_acceptor4(std::move(acceptor4)); conn_handler->set_acceptor4(std::move(acceptor4));
listener_handler->set_acceptor6(std::move(acceptor6)); conn_handler->set_acceptor6(std::move(acceptor6));
// ListenHandler loads private key, and we listen on a priveleged port. // ListenHandler loads private key, and we listen on a priveleged port.
// After that, we drop the root privileges if needed. // After that, we drop the root privileges if needed.
@ -533,7 +533,7 @@ int event_loop() {
if (sv_ssl_ctx && get_config()->auto_tls_ticket_key) { if (sv_ssl_ctx && get_config()->auto_tls_ticket_key) {
// Renew ticket key every 12hrs // Renew ticket key every 12hrs
ev_timer_init(&renew_ticket_key_timer, renew_ticket_key_cb, 0., 12 * 3600.); ev_timer_init(&renew_ticket_key_timer, renew_ticket_key_cb, 0., 12 * 3600.);
renew_ticket_key_timer.data = listener_handler.get(); renew_ticket_key_timer.data = conn_handler.get();
ev_timer_again(loop, &renew_ticket_key_timer); ev_timer_again(loop, &renew_ticket_key_timer);
// Generate first session ticket key before running workers. // Generate first session ticket key before running workers.
@ -554,11 +554,11 @@ int event_loop() {
#endif // !NOTHREADS #endif // !NOTHREADS
if (get_config()->num_worker > 1) { if (get_config()->num_worker > 1) {
listener_handler->create_worker_thread(get_config()->num_worker); conn_handler->create_worker_thread(get_config()->num_worker);
} else if (get_config()->downstream_proto == PROTO_HTTP2) { } else if (get_config()->downstream_proto == PROTO_HTTP2) {
listener_handler->create_http2_session(); conn_handler->create_http2_session();
} else { } else {
listener_handler->create_http1_connect_blocker(); conn_handler->create_http1_connect_blocker();
} }
#ifndef NOTHREADS #ifndef NOTHREADS
@ -570,23 +570,23 @@ int event_loop() {
ev_signal reopen_log_sig; ev_signal reopen_log_sig;
ev_signal_init(&reopen_log_sig, reopen_log_signal_cb, REOPEN_LOG_SIGNAL); ev_signal_init(&reopen_log_sig, reopen_log_signal_cb, REOPEN_LOG_SIGNAL);
reopen_log_sig.data = listener_handler.get(); reopen_log_sig.data = conn_handler.get();
ev_signal_start(loop, &reopen_log_sig); ev_signal_start(loop, &reopen_log_sig);
ev_signal exec_bin_sig; ev_signal exec_bin_sig;
ev_signal_init(&exec_bin_sig, exec_binary_signal_cb, EXEC_BINARY_SIGNAL); ev_signal_init(&exec_bin_sig, exec_binary_signal_cb, EXEC_BINARY_SIGNAL);
exec_bin_sig.data = listener_handler.get(); exec_bin_sig.data = conn_handler.get();
ev_signal_start(loop, &exec_bin_sig); ev_signal_start(loop, &exec_bin_sig);
ev_signal graceful_shutdown_sig; ev_signal graceful_shutdown_sig;
ev_signal_init(&graceful_shutdown_sig, graceful_shutdown_signal_cb, ev_signal_init(&graceful_shutdown_sig, graceful_shutdown_signal_cb,
GRACEFUL_SHUTDOWN_SIGNAL); GRACEFUL_SHUTDOWN_SIGNAL);
graceful_shutdown_sig.data = listener_handler.get(); graceful_shutdown_sig.data = conn_handler.get();
ev_signal_start(loop, &graceful_shutdown_sig); ev_signal_start(loop, &graceful_shutdown_sig);
ev_timer refresh_timer; ev_timer refresh_timer;
ev_timer_init(&refresh_timer, refresh_cb, 0., 1.); ev_timer_init(&refresh_timer, refresh_cb, 0., 1.);
refresh_timer.data = listener_handler.get(); refresh_timer.data = conn_handler.get();
ev_timer_again(loop, &refresh_timer); ev_timer_again(loop, &refresh_timer);
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
@ -595,7 +595,7 @@ int event_loop() {
ev_run(loop, 0); ev_run(loop, 0);
listener_handler->join_worker(); conn_handler->join_worker();
return 0; return 0;
} }

View File

@ -26,7 +26,7 @@
#include <unistd.h> #include <unistd.h>
#include "shrpx_listen_handler.h" #include "shrpx_connection_handler.h"
#include "shrpx_config.h" #include "shrpx_config.h"
#include "util.h" #include "util.h"
@ -41,7 +41,8 @@ void acceptcb(struct ev_loop *loop, ev_io *w, int revent) {
} }
} // namespace } // namespace
AcceptHandler::AcceptHandler(int fd, ListenHandler *h) : conn_hnr_(h), fd_(fd) { AcceptHandler::AcceptHandler(int fd, ConnectionHandler *h)
: conn_hnr_(h), fd_(fd) {
ev_io_init(&wev_, acceptcb, fd_, EV_READ); ev_io_init(&wev_, acceptcb, fd_, EV_READ);
wev_.data = this; wev_.data = this;
ev_io_start(conn_hnr_->get_loop(), &wev_); ev_io_start(conn_hnr_->get_loop(), &wev_);

View File

@ -31,11 +31,11 @@
namespace shrpx { namespace shrpx {
class ListenHandler; class ConnectionHandler;
class AcceptHandler { class AcceptHandler {
public: public:
AcceptHandler(int fd, ListenHandler *h); AcceptHandler(int fd, ConnectionHandler *h);
~AcceptHandler(); ~AcceptHandler();
void accept_connection(); void accept_connection();
void enable(); void enable();
@ -44,7 +44,7 @@ public:
private: private:
ev_io wev_; ev_io wev_;
ListenHandler *conn_hnr_; ConnectionHandler *conn_hnr_;
int fd_; int fd_;
}; };

View File

@ -22,7 +22,7 @@
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include "shrpx_listen_handler.h" #include "shrpx_connection_handler.h"
#include <unistd.h> #include <unistd.h>
@ -46,10 +46,10 @@ namespace shrpx {
namespace { namespace {
void acceptor_disable_cb(struct ev_loop *loop, ev_timer *w, int revent) { void acceptor_disable_cb(struct ev_loop *loop, ev_timer *w, int revent) {
auto h = static_cast<ListenHandler *>(w->data); auto h = static_cast<ConnectionHandler *>(w->data);
// If we are in graceful shutdown period, we must not enable // If we are in graceful shutdown period, we must not enable
// evlisteners again. // acceptors again.
if (worker_config->graceful_shutdown) { if (worker_config->graceful_shutdown) {
return; return;
} }
@ -58,8 +58,8 @@ void acceptor_disable_cb(struct ev_loop *loop, ev_timer *w, int revent) {
} }
} // namespace } // namespace
ListenHandler::ListenHandler(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, ConnectionHandler::ConnectionHandler(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx,
SSL_CTX *cl_ssl_ctx) SSL_CTX *cl_ssl_ctx)
: loop_(loop), sv_ssl_ctx_(sv_ssl_ctx), cl_ssl_ctx_(cl_ssl_ctx), : loop_(loop), sv_ssl_ctx_(sv_ssl_ctx), cl_ssl_ctx_(cl_ssl_ctx),
// rate_limit_group_(bufferevent_rate_limit_group_new( // rate_limit_group_(bufferevent_rate_limit_group_new(
// evbase, get_config()->worker_rate_limit_cfg)), // evbase, get_config()->worker_rate_limit_cfg)),
@ -69,12 +69,12 @@ ListenHandler::ListenHandler(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx,
disable_acceptor_timer_.data = this; disable_acceptor_timer_.data = this;
} }
ListenHandler::~ListenHandler() { ConnectionHandler::~ConnectionHandler() {
// bufferevent_rate_limit_group_free(rate_limit_group_); // bufferevent_rate_limit_group_free(rate_limit_group_);
ev_timer_stop(loop_, &disable_acceptor_timer_); ev_timer_stop(loop_, &disable_acceptor_timer_);
} }
void ListenHandler::worker_reopen_log_files() { void ConnectionHandler::worker_reopen_log_files() {
WorkerEvent wev; WorkerEvent wev;
memset(&wev, 0, sizeof(wev)); memset(&wev, 0, sizeof(wev));
@ -85,7 +85,7 @@ void ListenHandler::worker_reopen_log_files() {
} }
} }
void ListenHandler::worker_renew_ticket_keys( void ConnectionHandler::worker_renew_ticket_keys(
const std::shared_ptr<TicketKeys> &ticket_keys) { const std::shared_ptr<TicketKeys> &ticket_keys) {
WorkerEvent wev; WorkerEvent wev;
@ -98,7 +98,7 @@ void ListenHandler::worker_renew_ticket_keys(
} }
} }
void ListenHandler::create_worker_thread(size_t num) { void ConnectionHandler::create_worker_thread(size_t num) {
#ifndef NOTHREADS #ifndef NOTHREADS
assert(workers_.size() == 0); assert(workers_.size() == 0);
@ -113,7 +113,7 @@ void ListenHandler::create_worker_thread(size_t num) {
#endif // NOTHREADS #endif // NOTHREADS
} }
void ListenHandler::join_worker() { void ConnectionHandler::join_worker() {
#ifndef NOTHREADS #ifndef NOTHREADS
int n = 0; int n = 0;
@ -132,7 +132,7 @@ void ListenHandler::join_worker() {
#endif // NOTHREADS #endif // NOTHREADS
} }
void ListenHandler::graceful_shutdown_worker() { void ConnectionHandler::graceful_shutdown_worker() {
if (get_config()->num_worker == 1) { if (get_config()->num_worker == 1) {
return; return;
} }
@ -150,7 +150,7 @@ void ListenHandler::graceful_shutdown_worker() {
} }
} }
int ListenHandler::handle_connection(int fd, sockaddr *addr, int addrlen) { int ConnectionHandler::handle_connection(int fd, sockaddr *addr, int addrlen) {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
LLOG(INFO, this) << "Accepted connection. fd=" << fd; LLOG(INFO, this) << "Accepted connection. fd=" << fd;
} }
@ -198,35 +198,39 @@ int ListenHandler::handle_connection(int fd, sockaddr *addr, int addrlen) {
return 0; return 0;
} }
struct ev_loop *ListenHandler::get_loop() const { struct ev_loop *ConnectionHandler::get_loop() const {
return loop_; return loop_;
} }
void ListenHandler::create_http2_session() { void ConnectionHandler::create_http2_session() {
http2session_ = util::make_unique<Http2Session>(loop_, cl_ssl_ctx_); http2session_ = util::make_unique<Http2Session>(loop_, cl_ssl_ctx_);
} }
void ListenHandler::create_http1_connect_blocker() { void ConnectionHandler::create_http1_connect_blocker() {
http1_connect_blocker_ = util::make_unique<ConnectBlocker>(loop_); http1_connect_blocker_ = util::make_unique<ConnectBlocker>(loop_);
} }
const WorkerStat *ListenHandler::get_worker_stat() const { const WorkerStat *ConnectionHandler::get_worker_stat() const {
return worker_stat_.get(); return worker_stat_.get();
} }
void ListenHandler::set_acceptor4(std::unique_ptr<AcceptHandler> h) { void ConnectionHandler::set_acceptor4(std::unique_ptr<AcceptHandler> h) {
acceptor4_ = std::move(h); acceptor4_ = std::move(h);
} }
AcceptHandler *ListenHandler::get_acceptor4() const { return acceptor4_.get(); } AcceptHandler *ConnectionHandler::get_acceptor4() const {
return acceptor4_.get();
}
void ListenHandler::set_acceptor6(std::unique_ptr<AcceptHandler> h) { void ConnectionHandler::set_acceptor6(std::unique_ptr<AcceptHandler> h) {
acceptor6_ = std::move(h); acceptor6_ = std::move(h);
} }
AcceptHandler *ListenHandler::get_acceptor6() const { return acceptor6_.get(); } AcceptHandler *ConnectionHandler::get_acceptor6() const {
return acceptor6_.get();
}
void ListenHandler::enable_acceptor() { void ConnectionHandler::enable_acceptor() {
if (acceptor4_) { if (acceptor4_) {
acceptor4_->enable(); acceptor4_->enable();
} }
@ -236,7 +240,7 @@ void ListenHandler::enable_acceptor() {
} }
} }
void ListenHandler::disable_acceptor() { void ConnectionHandler::disable_acceptor() {
if (acceptor4_) { if (acceptor4_) {
acceptor4_->disable(); acceptor4_->disable();
} }
@ -246,7 +250,7 @@ void ListenHandler::disable_acceptor() {
} }
} }
void ListenHandler::disable_acceptor_temporary(ev_tstamp t) { void ConnectionHandler::disable_acceptor_temporary(ev_tstamp t) {
if (t == 0. || ev_is_active(&disable_acceptor_timer_)) { if (t == 0. || ev_is_active(&disable_acceptor_timer_)) {
return; return;
} }
@ -257,7 +261,7 @@ void ListenHandler::disable_acceptor_temporary(ev_tstamp t) {
ev_timer_start(loop_, &disable_acceptor_timer_); ev_timer_start(loop_, &disable_acceptor_timer_);
} }
void ListenHandler::accept_pending_connection() { void ConnectionHandler::accept_pending_connection() {
if (acceptor4_) { if (acceptor4_) {
acceptor4_->accept_connection(); acceptor4_->accept_connection();
} }

View File

@ -22,8 +22,8 @@
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef SHRPX_LISTEN_HANDLER_H #ifndef SHRPX_CONNECTION_HANDLER_H
#define SHRPX_LISTEN_HANDLER_H #define SHRPX_CONNECTION_HANDLER_H
#include "shrpx.h" #include "shrpx.h"
@ -49,10 +49,11 @@ struct WorkerStat;
struct TicketKeys; struct TicketKeys;
// TODO should be renamed as ConnectionHandler // TODO should be renamed as ConnectionHandler
class ListenHandler { class ConnectionHandler {
public: public:
ListenHandler(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx); ConnectionHandler(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx,
~ListenHandler(); SSL_CTX *cl_ssl_ctx);
~ConnectionHandler();
int handle_connection(int fd, sockaddr *addr, int addrlen); int handle_connection(int fd, sockaddr *addr, int addrlen);
void create_worker_thread(size_t num); void create_worker_thread(size_t num);
void worker_reopen_log_files(); void worker_reopen_log_files();
@ -94,4 +95,4 @@ private:
} // namespace shrpx } // namespace shrpx
#endif // SHRPX_LISTEN_HANDLER_H #endif // SHRPX_CONNECTION_HANDLER_H