gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r35488 - in libmicrohttpd: . doc src/include src/microhttpd


From: gnunet
Subject: [GNUnet-SVN] r35488 - in libmicrohttpd: . doc src/include src/microhttpd
Date: Tue, 31 Mar 2015 10:38:33 +0200

Author: grothoff
Date: 2015-03-31 10:38:33 +0200 (Tue, 31 Mar 2015)
New Revision: 35488

Modified:
   libmicrohttpd/AUTHORS
   libmicrohttpd/ChangeLog
   libmicrohttpd/doc/libmicrohttpd.texi
   libmicrohttpd/src/include/microhttpd.h
   libmicrohttpd/src/microhttpd/connection.c
   libmicrohttpd/src/microhttpd/daemon.c
   libmicrohttpd/src/microhttpd/internal.h
Log:
Robert Gronenberg wrote:


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?

=>

The patch was only working for multithreaded apps, so I adjusted it
to cover other threading models, fixed a merge issue and added the
ability to associate a void* with the callbacks (and obtain it via
MHD connection info).  And I updated the manual & ChangeLog. Now
I think it can be included ;-).



Modified: libmicrohttpd/AUTHORS
===================================================================
--- libmicrohttpd/AUTHORS       2015-03-30 19:46:35 UTC (rev 35487)
+++ libmicrohttpd/AUTHORS       2015-03-31 08:38:33 UTC (rev 35488)
@@ -51,6 +51,7 @@
 Sree Harsha Totakura <address@hidden>
 Hani Benhabiles <address@hidden>
 Guy Martin <address@hidden>
+Robert Groenenberg <address@hidden>
 
 
 Documentation contributions also came from:

Modified: libmicrohttpd/ChangeLog
===================================================================
--- libmicrohttpd/ChangeLog     2015-03-30 19:46:35 UTC (rev 35487)
+++ libmicrohttpd/ChangeLog     2015-03-31 08:38:33 UTC (rev 35488)
@@ -1,3 +1,12 @@
+Tue Mar 31 10:28:26 CEST 2015
+       Adding MHD_OPTION_NOTIFY_CONNECTION,
+       MHD_CONNECTION_NOTIFY_STARTED,
+       MHD_CONNECTION_NOTIFY_CLOSED and
+       MHD_CONNECTION_INFO_SOCKET_CONTEXT to allow
+       applications to trigger operations when TCP
+       connections start or end, instead of just
+       exposing HTTP requests starting and ending. -RG/CG
+
 Thu Feb 26 09:55:43 CET 2015
        Fixing bug that prevented MHD_OPTION_HTTPS_MEM_DHPARAMS
        from working within a MHD_OPTION_ARRAY. -DD

Modified: libmicrohttpd/doc/libmicrohttpd.texi
===================================================================
--- libmicrohttpd/doc/libmicrohttpd.texi        2015-03-30 19:46:35 UTC (rev 
35487)
+++ libmicrohttpd/doc/libmicrohttpd.texi        2015-03-31 08:38:33 UTC (rev 
35488)
@@ -631,7 +631,26 @@
 and second a pointer to a closure to pass to the request completed
 callback.  The second pointer maybe @code{NULL}.
 
address@hidden MHD_OPTION_NOTIFY_CONNECTION
+Register a function that should be called when the TCP connection to a
+client is opened or closed.  Note that
address@hidden and the @code{con_cls} argument to
+the @code{MHD_AccessHandlerCallback} are per HTTP request (and there
+can be multiple HTTP requests per TCP connection).  The registered
+callback is called twice per TCP connection, with
address@hidden and
address@hidden respectively.  An additional
+argument can be used to store TCP connection specific information,
+which can be retrieved using @code{MHD_CONNECTION_INFO_SOCKET_CONTEXT}
+during the lifetime of the TCP connection.  The respective location is
+not the same as the HTTP-request-specific @code{con_cls} from the
address@hidden
 
+This option should be followed by @strong{TWO} pointers.  First a
+pointer to a function of type @code{MHD_NotifyConnectionCallback()}
+and second a pointer to a closure to pass to the request completed
+callback.  The second pointer maybe @code{NULL}.
+
 @item MHD_OPTION_PER_IP_CONNECTION_LIMIT
 Limit on the number of (concurrent) connections made to the
 server from the same IP address.  Can be used to prevent one
@@ -2579,6 +2598,14 @@
 callbacks are invoked in between, those might be used to set different
 values for TCP-CORK and TCP-NODELAY in the meantime.
 
address@hidden MHD_CONNECTION_INFO_SOCKET_CONTEXT
+Returns the client-specific pointer to a @code{void *} that was
+(possibly) set during a @code{MHD_NotifyConnectionCallback} when the
+socket was first accepted.  Note that this is NOT the same as the
address@hidden argument of the @code{MHD_AccessHandlerCallback}.  The
address@hidden is fresh for each HTTP request, while the
address@hidden is fresh for each socket.
+
 @end table
 @end deftp
 

Modified: libmicrohttpd/src/include/microhttpd.h
===================================================================
--- libmicrohttpd/src/include/microhttpd.h      2015-03-30 19:46:35 UTC (rev 
35487)
+++ libmicrohttpd/src/include/microhttpd.h      2015-03-31 08:38:33 UTC (rev 
35488)
@@ -130,7 +130,7 @@
  * Current version of the library.
  * 0x01093001 = 1.9.30-1.
  */
-#define MHD_VERSION 0x00093903
+#define MHD_VERSION 0x00093904
 
 /**
  * MHD-internal return code for "YES".
@@ -871,7 +871,19 @@
    * `const char *` argument.
    * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY.
    */
-  MHD_OPTION_HTTPS_KEY_PASSWORD = 26
+  MHD_OPTION_HTTPS_KEY_PASSWORD = 26,
+
+  /**
+   * 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 = 27
+
 };
 
 
@@ -1006,6 +1018,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
@@ -1046,6 +1081,12 @@
    * daemons running).
    */
   struct MHD_Daemon *daemon;
+
+  /**
+   * Socket-specific client context.  Points to the same address as
+   * the "socket_context" of the #MHD_NotifyConnectionCallback.
+   */
+  void **socket_context;
 };
 
 
@@ -1104,8 +1145,18 @@
    * No extra arguments should be passed.
    * @ingroup request
    */
-  MHD_CONNECTION_INFO_CONNECTION_FD
+  MHD_CONNECTION_INFO_CONNECTION_FD,
 
+  /**
+   * Returns the client-specific pointer to a `void *` that was (possibly)
+   * set during a #MHD_NotifyConnectionCallback when the socket was
+   * first accepted.  Note that this is NOT the same as the "con_cls"
+   * argument of the #MHD_AccessHandlerCallback.  The "con_cls" is
+   * fresh for each HTTP request, while the "socket_context" is fresh
+   * for each socket.
+   */
+  MHD_CONNECTION_INFO_SOCKET_CONTEXT
+
 };
 
 
@@ -1243,7 +1294,32 @@
                                  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 socket_context socket-specific pointer where the
+ *                       client can associate some state specific
+ *                       to the TCP connection; note that this is
+ *                       different from the "con_cls" which is per
+ *                       HTTP request.  The client can initialize
+ *                       during #MHD_CONNECTION_NOTIFY_STARTED and
+ *                       cleanup during #MHD_CONNECTION_NOTIFY_CLOSED
+ *                       and access in the meantime using
+ *                       #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
+ * @param toe reason for connection notification
+ * @see #MHD_OPTION_NOTIFY_CONNECTION
+ * @ingroup request
+ */
+typedef void
+(*MHD_NotifyConnectionCallback) (void *cls,
+                                 struct MHD_Connection *connection,
+                                 void **socket_context,
+                                 enum MHD_ConnectionNotificationCode toe);
 
+
 /**
  * Iterator over key-value pairs.  This iterator
  * can be used to iterate over all of the cookies,

Modified: libmicrohttpd/src/microhttpd/connection.c
===================================================================
--- libmicrohttpd/src/microhttpd/connection.c   2015-03-30 19:46:35 UTC (rev 
35487)
+++ libmicrohttpd/src/microhttpd/connection.c   2015-03-31 08:38:33 UTC (rev 
35488)
@@ -1,6 +1,6 @@
 /*
     This file is part of libmicrohttpd
-     Copyright (C) 2007-2013 Daniel Pittman and Christian Grothoff
+     Copyright (C) 2007-2015 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

Modified: libmicrohttpd/src/microhttpd/daemon.c
===================================================================
--- libmicrohttpd/src/microhttpd/daemon.c       2015-03-30 19:46:35 UTC (rev 
35487)
+++ libmicrohttpd/src/microhttpd/daemon.c       2015-03-31 08:38:33 UTC (rev 
35488)
@@ -796,6 +796,7 @@
   struct pollfd p[1];
 #endif
 
+
   timeout = con->daemon->connection_timeout;
   while ( (MHD_YES != con->daemon->shutdown) &&
          (MHD_CONNECTION_CLOSED != con->state) )
@@ -958,6 +959,13 @@
       MHD_destroy_response (con->response);
       con->response = NULL;
     }
+
+  if (NULL != con->daemon->notify_connection)
+    con->daemon->notify_connection (con->daemon->notify_connection_cls,
+                                    con,
+                                    &con->socket_context,
+                                    MHD_CONNECTION_NOTIFY_CLOSED);
+
   return (MHD_THRD_RTRN_TYPE_)0;
 }
 
@@ -1301,7 +1309,9 @@
       errno = eno;
       return MHD_NO;
     }
-  memset (connection, 0, sizeof (struct MHD_Connection));
+  memset (connection,
+          0,
+          sizeof (struct MHD_Connection));
   connection->pool = MHD_pool_create (daemon->pool_size);
   if (NULL == connection->pool)
     {
@@ -1445,11 +1455,19 @@
        (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
     MHD_PANIC ("Failed to release cleanup mutex\n");
 
+  if (NULL != daemon->notify_connection)
+    daemon->notify_connection (daemon->notify_connection_cls,
+                               connection,
+                               &connection->socket_context,
+                               MHD_CONNECTION_NOTIFY_STARTED);
+
   /* attempt to create handler thread */
   if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
     {
-      res_thread_create = create_thread (&connection->pid, daemon,
-                                        &MHD_handle_connection, connection);
+      res_thread_create = create_thread (&connection->pid,
+                                         daemon,
+                                        &MHD_handle_connection,
+                                         connection);
       if (0 != res_thread_create)
         {
          eno = errno;
@@ -1508,6 +1526,11 @@
   daemon->connections++;
   return MHD_YES;
  cleanup:
+  if (NULL != daemon->notify_connection)
+    daemon->notify_connection (daemon->notify_connection_cls,
+                               connection,
+                               &connection->socket_context,
+                               MHD_CONNECTION_NOTIFY_CLOSED);
   if (0 != MHD_socket_close_ (client_socket))
     MHD_PANIC ("close failed\n");
   MHD_ip_limit_del (daemon, addr, addrlen);
@@ -1921,12 +1944,15 @@
        }
       MHD_pool_destroy (pos->pool);
 #if HTTPS_SUPPORT
-      if (pos->tls_session != NULL)
+      if (NULL != pos->tls_session)
        gnutls_deinit (pos->tls_session);
 #endif
-      MHD_ip_limit_del (daemon,
-                       (struct sockaddr *) pos->addr,
-                       pos->addr_len);
+      if (NULL != daemon->notify_connection)
+        daemon->notify_connection (daemon->notify_connection_cls,
+                                   pos,
+                                   &pos->socket_context,
+                                   MHD_CONNECTION_NOTIFY_CLOSED);
+      MHD_ip_limit_del (daemon, pos->addr, pos->addr_len);
 #if EPOLL_SUPPORT
       if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
        {
@@ -2993,6 +3019,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;
@@ -3234,6 +3265,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:

Modified: libmicrohttpd/src/microhttpd/internal.h
===================================================================
--- libmicrohttpd/src/microhttpd/internal.h     2015-03-30 19:46:35 UTC (rev 
35487)
+++ libmicrohttpd/src/microhttpd/internal.h     2015-03-31 08:38:33 UTC (rev 
35488)
@@ -1,6 +1,6 @@
 /*
   This file is part of libmicrohttpd
-  Copyright (C) 2007-2013 Daniel Pittman and Christian Grothoff
+  Copyright (C) 2007-2015 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
@@ -487,8 +487,10 @@
  * @param max_bytes maximum number of bytes to receive
  * @return number of bytes written to write_to
  */
-typedef ssize_t (*ReceiveCallback) (struct MHD_Connection * conn,
-                                    void *write_to, size_t max_bytes);
+typedef ssize_t
+(*ReceiveCallback) (struct MHD_Connection *conn,
+                    void *write_to,
+                    size_t max_bytes);
 
 
 /**
@@ -499,8 +501,10 @@
  * @param max_bytes maximum number of bytes to transmit
  * @return number of bytes transmitted
  */
-typedef ssize_t (*TransmitCallback) (struct MHD_Connection * conn,
-                                     const void *write_to, size_t max_bytes);
+typedef ssize_t
+(*TransmitCallback) (struct MHD_Connection *conn,
+                     const void *write_to,
+                     size_t max_bytes);
 
 
 /**
@@ -578,14 +582,23 @@
   struct MemoryPool *pool;
 
   /**
-   * We allow the main application to associate some
-   * pointer with the connection.  Here is where we
-   * store it.  (MHD does not know or care what it
-   * is).
+   * We allow the main application to associate some pointer with the
+   * HTTP request, which is passed to each #MHD_AccessHandlerCallback
+   * and some other API calls.  Here is where we store it.  (MHD does
+   * not know or care what it is).
    */
   void *client_context;
 
   /**
+   * We allow the main application to associate some pointer with the
+   * TCP connection (which may span multiple HTTP requests).  Here is
+   * where we store it.  (MHD does not know or care what it is).
+   * The location is given to the #MHD_NotifyConnectionCallback and
+   * also accessible via #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
+   */
+  void *socket_context;
+
+  /**
    * Request method.  Should be GET/POST/etc.  Allocated
    * in pool.
    */
@@ -606,7 +619,7 @@
   /**
    * Buffer for reading requests.   Allocated
    * in pool.  Actually one byte larger than
-   * read_buffer_size (if non-NULL) to allow for
+   * @e read_buffer_size (if non-NULL) to allow for
    * 0-termination.
    */
   char *read_buffer;
@@ -620,7 +633,8 @@
   /**
    * Last incomplete header line during parsing of headers.
    * Allocated in pool.  Only valid if state is
-   * either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED.
+   * either #MHD_CONNECTION_HEADER_PART_RECEIVED or
+   * #MHD_CONNECTION_FOOTER_PART_RECEIVED.
    */
   char *last;
 
@@ -628,12 +642,13 @@
    * Position after the colon on the last incomplete header
    * line during parsing of headers.
    * Allocated in pool.  Only valid if state is
-   * either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED.
+   * either #MHD_CONNECTION_HEADER_PART_RECEIVED or
+   * #MHD_CONNECTION_FOOTER_PART_RECEIVED.
    */
   char *colon;
 
   /**
-   * Foreign address (of length addr_len).  MALLOCED (not
+   * Foreign address (of length @e addr_len).  MALLOCED (not
    * in pool!).
    */
   struct sockaddr *addr;
@@ -676,7 +691,7 @@
 
   /**
    * How many more bytes of the body do we expect
-   * to read? MHD_SIZE_UNKNOWN for unknown.
+   * to read? #MHD_SIZE_UNKNOWN for unknown.
    */
   uint64_t remaining_upload_size;
 
@@ -800,17 +815,17 @@
   /**
    * Handler used for processing read connection operations
    */
-  int (*read_handler) (struct MHD_Connection * connection);
+  int (*read_handler) (struct MHD_Connection *connection);
 
   /**
    * Handler used for processing write connection operations
    */
-  int (*write_handler) (struct MHD_Connection * connection);
+  int (*write_handler) (struct MHD_Connection *connection);
 
   /**
    * Handler used for processing idle connection operations
    */
-  int (*idle_handler) (struct MHD_Connection * connection);
+  int (*idle_handler) (struct MHD_Connection *connection);
 
   /**
    * Function used for reading HTTP request stream.
@@ -864,9 +879,10 @@
  * @param con connection handle
  * @return new closure
  */
-typedef void * (*LogCallback)(void * cls,
-                             const char * uri,
-                             struct MHD_Connection *con);
+typedef void *
+(*LogCallback)(void * cls,
+               const char * uri,
+               struct MHD_Connection *con);
 
 /**
  * Signature of function called to unescape URIs.  See also
@@ -877,9 +893,10 @@
  * @param uri 0-terminated string to unescape (should be updated)
  * @return length of the resulting string
  */
-typedef size_t (*UnescapeCallback)(void *cls,
-                                  struct MHD_Connection *conn,
-                                  char *uri);
+typedef size_t
+(*UnescapeCallback)(void *cls,
+                    struct MHD_Connection *conn,
+                    char *uri);
 
 
 /**
@@ -1000,6 +1017,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

[Prev in Thread] Current Thread [Next in Thread]