commit 2207231ef2e361a4fa7c894348da6270c71df4bd
parent 0ca235616cb8f2ebfa7cebb7fabef1ff678a6377
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 16 Feb 2018 06:08:14 +0100
implement connection_finish_forward
Diffstat:
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;