浏览代码

implement connection_finish_forward

Christian Grothoff 8 年之前
父节点
当前提交
2207231ef2

+ 6 - 0
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);

+ 3 - 0
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 \

+ 3 - 5
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(). */
 

+ 94 - 0
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 */

+ 44 - 0
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

+ 2 - 2
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);

+ 1 - 0
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
 

+ 3 - 1
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,

+ 1 - 0
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"
 
 
 /**

+ 8 - 7
src/lib/internal.h

@@ -606,13 +606,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).
@@ -800,6 +793,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?
    */