Hi,

I am using libmicrohttpd in a multithreaded application in the
thread-per-connection mode. In order to maintain statistics and such on
the various clients, the application should be notified about
connections being started and stopped. Something like the
MHD_OPTION_NOTIFY_COMPLETED for requests, but then for connections. As
far as I could find libmicrohttpd does not (yet) provide that functionality.

Attached is a patch that does add this functionality by registering a
connection notification callback function: MHD_OPTION_NOTIFY_CONNECTION
(inspired by the MHD_OPTION_NOTIFY_COMPLETED option).

Could this be included in libmicrohttpd?

Cheers,
Robert

diff -u -r ../libmicrohttpd-0.9.39.org/src/include/microhttpd.h src/include/microhttpd.h
--- ../libmicrohttpd-0.9.39.org/src/include/microhttpd.h	2014-12-22 23:25:18.000000000 +0100
+++ src/include/microhttpd.h	2015-03-27 11:02:52.461304921 +0100
@@ -863,6 +863,18 @@
    * This option must be followed by a `unsigned int` argument.
    */
   MHD_OPTION_LISTENING_ADDRESS_REUSE = 25,
+
+  /**
+   * Register a function that should be called whenever a connection is
+   * started or closed.
+   *
+   * This option should be followed by TWO pointers.  First a pointer
+   * to a function of type #MHD_NotifyConnectionCallback and second a
+   * pointer to a closure to pass to the request completed callback.
+   * The second pointer maybe NULL.
+   */
+  MHD_OPTION_NOTIFY_CONNECTION = 26
+
 };
 
 
@@ -997,6 +1009,29 @@
 
 
 /**
+ * The `enum MHD_ConnectionNotificationCode` specifies types
+ * of connection notifications.
+ * @ingroup request
+ */
+enum MHD_ConnectionNotificationCode
+{
+
+  /**
+   * A new connection has been started.
+   * @ingroup request
+   */
+  MHD_CONNECTION_NOTIFY_STARTED = 0,
+
+  /**
+   * A connection is closed.
+   * @ingroup request
+   */
+  MHD_CONNECTION_NOTIFY_CLOSED = 1
+
+};
+
+
+/**
  * Information about a connection.
  */
 union MHD_ConnectionInfo
@@ -1234,6 +1269,21 @@
                                  void **con_cls,
                                  enum MHD_RequestTerminationCode toe);
 
+/**
+ * Signature of the callback used by MHD to notify the
+ * application about started/stopped connections
+ *
+ * @param cls client-defined closure
+ * @param connection connection handle
+ * @param toe reason for connection notification
+ * @see #MHD_OPTION_NOTIFY_CONNECTION
+ * @ingroup request
+ */
+typedef void
+  (*MHD_NotifyConnectionCallback) (void *cls,
+                                   struct MHD_Connection *connection,
+                                   enum MHD_ConnectionNotificationCode toe);
+
 
 /**
  * Iterator over key-value pairs.  This iterator
diff -u -r ../libmicrohttpd-0.9.39.org/src/microhttpd/daemon.c src/microhttpd/daemon.c
--- ../libmicrohttpd-0.9.39.org/src/microhttpd/daemon.c	2014-12-22 23:25:18.000000000 +0100
+++ src/microhttpd/daemon.c	2015-03-27 11:06:05.894678583 +0100
@@ -770,6 +770,11 @@
   struct pollfd p[1];
 #endif
 
+  if (con->daemon->notify_connection != NULL)
+    con->daemon->notify_connection (con->daemon->notify_connection_cls,
+                                    con,
+                                    MHD_CONNECTION_NOTIFY_STARTED);
+
   timeout = con->daemon->connection_timeout;
   while ( (MHD_YES != con->daemon->shutdown) &&
 	  (MHD_CONNECTION_CLOSED != con->state) )
@@ -932,6 +937,12 @@
       MHD_destroy_response (con->response);
       con->response = NULL;
     }
+
+  if (con->daemon->notify_connection != NULL)
+    con->daemon->notify_connection (con->daemon->notify_connection_cls,
+                                    con,
+                                    MHD_CONNECTION_NOTIFY_CLOSED);
+
   return (MHD_THRD_RTRN_TYPE_)0;
 }
 
@@ -2961,6 +2972,11 @@
             va_arg (ap, MHD_RequestCompletedCallback);
           daemon->notify_completed_cls = va_arg (ap, void *);
           break;
+        case MHD_OPTION_NOTIFY_CONNECTION:
+          daemon->notify_connection =
+            va_arg (ap, MHD_NotifyConnectionCallback);
+          daemon->notify_connection_cls = va_arg (ap, void *);
+          break;
         case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
           daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
           break;
@@ -3190,6 +3206,7 @@
 		  break;
 		  /* all options taking two pointers */
 		case MHD_OPTION_NOTIFY_COMPLETED:
+		case MHD_OPTION_NOTIFY_CONNECTION:
 		case MHD_OPTION_URI_LOG_CALLBACK:
 		case MHD_OPTION_EXTERNAL_LOGGER:
 		case MHD_OPTION_UNESCAPE_CALLBACK:
diff -u -r ../libmicrohttpd-0.9.39.org/src/microhttpd/internal.h src/microhttpd/internal.h
--- ../libmicrohttpd-0.9.39.org/src/microhttpd/internal.h	2014-12-22 13:01:24.000000000 +0100
+++ src/microhttpd/internal.h	2015-03-27 11:01:31.154307185 +0100
@@ -1000,6 +1000,17 @@
   void *notify_completed_cls;
 
   /**
+   * Function to call when we are starting/stopping
+   * a connection.  May be NULL.
+   */
+  MHD_NotifyConnectionCallback notify_connection;
+
+  /**
+   * Closure argument to notify_connection.
+   */
+  void *notify_connection_cls;
+
+  /**
    * Function to call with the full URI at the
    * beginning of request processing.  May be NULL.
    * <p>

Reply via email to