libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 2207231ef2e361a4fa7c894348da6270c71df4bd
parent 0ca235616cb8f2ebfa7cebb7fabef1ff678a6377
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 16 Feb 2018 06:08:14 +0100

implement connection_finish_forward

Diffstat:
Msrc/include/microhttpd_tls.h | 6++++++
Msrc/lib/Makefile.am | 3+++
Msrc/lib/connection_add.c | 8+++-----
Asrc/lib/connection_finish_forward.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/lib/connection_finish_forward.h | 44++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/connection_update_last_activity.c | 4++--
Msrc/lib/daemon_epoll.c | 1+
Msrc/lib/daemon_poll.c | 4+++-
Msrc/lib/daemon_select.c | 1+
Msrc/lib/internal.h | 15++++++++-------
10 files changed, 165 insertions(+), 15 deletions(-)

diff --git a/src/include/microhttpd_tls.h b/src/include/microhttpd_tls.h @@ -90,6 +90,12 @@ struct MHD_TLS_Plugin (*setup_connection)(void *cls, ...); + + enum MHD_Bool + (*shutdown_connection) (void *cls, + struct MHD_TLS_ConnectionState *cs); + + void (*teardown_connection)(void *cls, struct MHD_TLS_ConnectionState *cs); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am @@ -59,8 +59,11 @@ libmicrohttpd_la_SOURCES = \ action_process_upload.c \ action_suspend.c \ connection_add.c connection_add.h \ + connection_close.c connection_close.h \ + connection_finish_forward.c connection_finish_forward.h \ connection_info.c \ connection_options.c \ + connection_update_last_activity.c connection_update_last_activity.h \ daemon_create.c \ daemon_destroy.c \ daemon_epoll.c daemon_epoll.h \ diff --git a/src/lib/connection_add.c b/src/lib/connection_add.c @@ -23,6 +23,7 @@ */ #include "internal.h" #include "connection_add.h" +#include "connection_update_last_activity.h" #include "daemon_ip_limit.h" #include "daemon_select.h" #include "daemon_poll.h" @@ -187,7 +188,7 @@ thread_main_handle_connection (void *data) if (was_suspended) { - MHD_update_last_activity_ (con); /* Reset timeout timer. */ + MHD_connection_update_last_activity_ (con); /* Reset timeout timer. */ /* Process response queued during suspend and update states. */ MHD_connection_handle_idle (con); was_suspended = false; @@ -394,14 +395,11 @@ thread_main_handle_connection (void *data) { /* Normal HTTP processing is finished, * notify application. */ - if ( (NULL != con->request.response->termination_cb) && - (con->request.client_aware) ) + if (NULL != con->request.response->termination_cb) con->request.response->termination_cb (con->request.response->termination_cb_cls, MHD_REQUEST_TERMINATED_COMPLETED_OK, con->request.client_context); - con->request.client_aware = false; - thread_main_connection_upgrade (con); /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ diff --git a/src/lib/connection_finish_forward.c b/src/lib/connection_finish_forward.c @@ -0,0 +1,94 @@ +/* + This file is part of libmicrohttpd + Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +/** + * @file lib/connection_finish_forward.c + * @brief complete upgrade socket forwarding operation in TLS mode + * @author Christian Grothoff + */ +#include "internal.h" +#include "connection_finish_forward.h" + + +#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) +/** + * Stop TLS forwarding on upgraded connection and + * reflect remote disconnect state to socketpair. + * @remark In thread-per-connection mode this function + * can be called from any thread, in other modes this + * function must be called only from thread that process + * daemon's select()/poll()/etc. + * + * @param connection the upgraded connection + */ +void +MHD_connection_finish_forward_ (struct MHD_Connection *connection) +{ + struct MHD_Daemon *daemon = connection->daemon; + struct MHD_UpgradeResponseHandle *urh = connection->request.urh; + + if (NULL == daemon->tls_api) + return; /* Nothing to do with non-TLS connection. */ + + if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_model) + DLL_remove (daemon->urh_head, + daemon->urh_tail, + urh); +#if EPOLL_SUPPORT + if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && + (0 != epoll_ctl (daemon->epoll_upgrade_fd, + EPOLL_CTL_DEL, + connection->socket_fd, + NULL)) ) + { + MHD_PANIC (_("Failed to remove FD from epoll set\n")); + } + if (urh->in_eready_list) + { + EDLL_remove (daemon->eready_urh_head, + daemon->eready_urh_tail, + urh); + urh->in_eready_list = false; + } +#endif /* EPOLL_SUPPORT */ + if (MHD_INVALID_SOCKET != urh->mhd.socket) + { +#if EPOLL_SUPPORT + if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && + (0 != epoll_ctl (daemon->epoll_upgrade_fd, + EPOLL_CTL_DEL, + urh->mhd.socket, + NULL)) ) + { + MHD_PANIC (_("Failed to remove FD from epoll set\n")); + } +#endif /* EPOLL_SUPPORT */ + /* Reflect remote disconnect to application by breaking + * socketpair connection. */ + shutdown (urh->mhd.socket, + SHUT_RDWR); + } + /* Socketpair sockets will remain open as they will be + * used with MHD_UPGRADE_ACTION_CLOSE. They will be + * closed by MHD_cleanup_upgraded_connection_() during + * connection's final cleanup. + */ +} +#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT*/ + +/* end of connection_finish_forward.c */ diff --git a/src/lib/connection_finish_forward.h b/src/lib/connection_finish_forward.h @@ -0,0 +1,44 @@ +/* + This file is part of libmicrohttpd + Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +/** + * @file lib/connection_finish_forward.h + * @brief complete upgrade socket forwarding operation in TLS mode + * @author Christian Grothoff + */ + +#ifndef CONNECTION_FINISH_FORWARD_H +#define CONNECTION_FINISH_FORWARD_H + + +/** + * Stop TLS forwarding on upgraded connection and + * reflect remote disconnect state to socketpair. + * + * @remark In thread-per-connection mode this function + * can be called from any thread, in other modes this + * function must be called only from thread that process + * daemon's select()/poll()/etc. + * + * @param connection the upgraded connection + */ +void +MHD_connection_finish_forward_ (struct MHD_Connection *connection) + MHD_NONNULL (1); + +#endif diff --git a/src/lib/connection_update_last_activity.c b/src/lib/connection_update_last_activity.c @@ -44,10 +44,10 @@ MHD_connection_update_last_activity_ (struct MHD_Connection *connection) return; /* no activity on suspended connections */ connection->last_activity = MHD_monotonic_sec_counter(); - if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) + if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model) return; /* each connection has personal timeout */ - if (connection->connection_timeout != daemon->connection_timeout) + if (connection->connection_timeout != daemon->connection_default_timeout) return; /* custom timeout, no need to move it in "normal" DLL */ MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); diff --git a/src/lib/daemon_epoll.c b/src/lib/daemon_epoll.c @@ -25,6 +25,7 @@ #include "internal.h" #include "daemon_epoll.h" #include "request_resume.h" +#include "connection_finish_forward.h" #ifdef EPOLL_SUPPORT diff --git a/src/lib/daemon_poll.c b/src/lib/daemon_poll.c @@ -24,6 +24,9 @@ #include "internal.h" #include "daemon_poll.h" #include "request_resume.h" +#include "connection_add.h" +#include "connection_finish_forward.h" + #ifdef HAVE_POLL @@ -463,7 +466,6 @@ void MHD_daemon_upgrade_connection_with_poll_ (struct MHD_Connection *con) { struct MHD_UpgradeResponseHandle *urh = con->request.urh; - struct MHD_Daemon *daemon = con->daemon; struct pollfd p[2]; memset (p, diff --git a/src/lib/daemon_select.c b/src/lib/daemon_select.c @@ -25,6 +25,7 @@ #include "internal.h" #include "daemon_select.h" #include "request_resume.h" +#include "connection_finish_forward.h" /** diff --git a/src/lib/internal.h b/src/lib/internal.h @@ -607,13 +607,6 @@ struct MHD_Request enum MHD_RequestEventLoopInfo event_loop_info; /** - * Did we ever call the "default_handler" on this request? (this - * flag will determine if we call the #MHD_OPTION_NOTIFY_COMPLETED - * handler when the request closes down). - */ - bool client_aware; - - /** * Are we currently inside the "idle" handler (to avoid recursively * invoking it). */ @@ -801,6 +794,14 @@ struct MHD_Connection bool suspended; /** + * Did we ever call the "default_handler" on this request? (this + * flag will determine if we call the + * #MHD_daemon_set_notify_connection() handler when the connection + * closes down). + */ + bool client_aware; + + /** * Are we ready to read from TLS for this connection? */ bool tls_read_ready;