[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>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r35488 - in libmicrohttpd: . doc src/include src/microhttpd,
gnunet <=