commit b7dd331e440f36db9c362731afed803148a08fe9
parent b14541751ff614f00867ceaf4c0fa21f7c484c58
Author: Christian Grothoff <christian@grothoff.org>
Date: Wed, 14 Feb 2018 05:35:48 +0100
more lib/ work
Diffstat:
8 files changed, 233 insertions(+), 64 deletions(-)
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
@@ -2608,7 +2608,14 @@ enum MHD_ConnectionInformationType
* Get connection timeout
* @ingroup request
*/
- MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT
+ MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT,
+
+ /**
+ * Check whether the connection is suspended.
+ * @ingroup request
+ */
+ MHD_CONNECTION_INFORMATION_CONNECTION_SUSPENDED
+
};
@@ -2654,7 +2661,7 @@ union MHD_ConnectionInformation
/**
* Address information for the client.
*/
- struct sockaddr *client_addr;
+ const struct sockaddr *client_addr;
/**
* Which daemon manages this connection (useful in case there are many
@@ -2663,10 +2670,16 @@ union MHD_ConnectionInformation
struct MHD_Daemon *daemon;
/**
- * Socket-specific client context. Points to the same address as
- * the "socket_context" of the #MHD_NotifyConnectionCallback.
+ * Pointer to connection-specific client context. Points to the
+ * same address as the "socket_context" of the
+ * #MHD_NotifyConnectionCallback.
+ */
+ void **socket_context;
+
+ /**
+ * Is this connection right now suspended?
*/
- void *socket_context;
+ enum MHD_Bool suspended;
};
@@ -2721,15 +2734,10 @@ union MHD_RequestInformation
struct MHD_Connection *connection;
/**
- * Socket-specific client context. Will also be given to
+ * Pointer to client context. Will also be given to
* the application in a #MHD_RequestTerminationCallback.
*/
- void *request_context;
-
- /**
- * The suspended status of a request.
- */
- enum MHD_Bool suspended;
+ void **request_context;
/**
* HTTP version requested by the client.
@@ -2762,11 +2770,11 @@ enum MHD_RequestInformationType
MHD_REQUEST_INFORMATION_CONNECTION,
/**
- * Check whether the connection is suspended.
- * @ingroup request
+ * Returns the client-specific pointer to a `void *` that
+ * is specific to this request.
*/
- MHD_REQUEST_INFORMATION_SUSPENDED,
-
+ MHD_REQUEST_INFORMATION_CLIENT_CONTEXT,
+
/**
* Return the HTTP version string given by the client.
* @ingroup request
@@ -2837,7 +2845,7 @@ enum MHD_DaemonInformationType
* Request the file descriptor for the listening socket.
* No extra arguments should be passed.
*/
- MHD_DAEMON_INFORMATION_LISTEN_FD,
+ MHD_DAEMON_INFORMATION_LISTEN_SOCKET,
/**
* Request the file descriptor for the external epoll.
@@ -2871,9 +2879,9 @@ union MHD_DaemonInformation
{
/**
- * Socket, returned for #MHD_DAEMON_INFORMATION_LISTEN_FD.
+ * Socket, returned for #MHD_DAEMON_INFORMATION_LISTEN_SOCKET.
*/
- MHD_socket listen_fd;
+ MHD_socket listen_socket;
/**
* Bind port number, returned for #MHD_DAEMON_INFORMATION_BIND_PORT.
diff --git a/src/include/microhttpd_tls.h b/src/include/microhttpd_tls.h
@@ -14,6 +14,12 @@
/**
+ * Data structure kept per TLS client by the plugin.
+ */
+struct MHD_TLS_ConnectionState;
+
+
+/**
* Callback functions to use for TLS operations.
*/
struct MHD_TLS_Plugin
@@ -70,7 +76,19 @@ struct MHD_TLS_Plugin
enum MHD_StatusCode
(*init_mem_trust)(void *cls,
const char *mem_trust);
-
+
+
+ /**
+ * Function called when we receive a connection and need
+ * to initialize our TLS state for it.
+ *
+ * @param cls the @e cls of this struct
+ * @param ... TBD
+ * @return NULL on error
+ */
+ struct MHD_TLS_ConnectionState *
+ (*setup_connection)(void *cls,
+ ...);
/**
* TODO: More functions here....
diff --git a/src/lib/connection_info.c b/src/lib/connection_info.c
@@ -46,7 +46,65 @@ MHD_connection_get_information_sz (struct MHD_Connection *connection,
union MHD_ConnectionInformation *return_value,
size_t return_value_size)
{
- return MHD_NO; /* FIXME: not yet implemented */
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
+ return MHD_NO
+
+ switch (info_type)
+ {
+#ifdef HTTPS_SUPPORT
+ case MHD_CONNECTION_INFORMATION_CIPHER_ALGO:
+ CHECK_SIZE (int);
+ if (NULL == connection->tls_cs)
+ return MHD_NO;
+ // return_value->cipher_algorithm
+ // = gnutls_cipher_get (connection->tls_session);
+ return MHD_NO; // FIXME: to be implemented
+ case MHD_CONNECTION_INFORMATION_PROTOCOL:
+ CHECK_SIZE (int);
+ if (NULL == connection->tls_cs)
+ return MHD_NO;
+ //return_value->protocol
+ // = gnutls_protocol_get_version (connection->tls_session);
+ return MHD_NO; // FIXME: to be implemented
+ case MHD_CONNECTION_INFORMATION_GNUTLS_SESSION:
+ CHECK_SIZE (void *);
+ if (NULL == connection->tls_cs)
+ return MHD_NO;
+ // return_value->tls_session = connection->tls_session;
+ return MHD_NO; // FIXME: to be implemented
+#endif /* HTTPS_SUPPORT */
+ case MHD_CONNECTION_INFORMATION_CLIENT_ADDRESS:
+ CHECK_SIZE (struct sockaddr *);
+ return_value->client_addr
+ = (const struct sockaddr *) &connection->addr;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_DAEMON:
+ CHECK_SIZE (struct MHD_Daemon *);
+ return_value->daemon = connection->daemon;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_CONNECTION_FD:
+ CHECK_SIZE (MHD_socket);
+ return_value->connect_fd = connection->socket_fd;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_SOCKET_CONTEXT:
+ CHECK_SIZE (void **);
+ return_value->socket_context = &connection->socket_context;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_CONNECTION_SUSPENDED:
+ CHECK_SIZE (enum MHD_Bool);
+ return_value->suspended
+ = connection->suspended ? MHD_YES : MHD_NO;
+ return MHD_YES;
+ case MHD_CONNECTION_INFORMATION_CONNECTION_TIMEOUT:
+ CHECK_SIZE (unsigned int);
+ return_value->connection_timeout
+ = (unsigned int) connection->connection_timeout;
+ return MHD_YES;
+ default:
+ return MHD_NO;
+ }
+
+#undef CHECK_SIZE
}
/* end of connection_info.c */
diff --git a/src/lib/daemon_info.c b/src/lib/daemon_info.c
@@ -46,50 +46,59 @@ MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
union MHD_DaemonInformation *return_value,
size_t return_value_size)
{
-#if OLD
- if (NULL == daemon)
- return NULL;
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
+ return MHD_NO
+
switch (info_type)
{
- case MHD_DAEMON_INFO_KEY_SIZE:
- return NULL; /* no longer supported */
- case MHD_DAEMON_INFO_MAC_KEY_SIZE:
- return NULL; /* no longer supported */
- case MHD_DAEMON_INFO_LISTEN_FD:
- return (const union MHD_DaemonInfo *) &daemon->listen_fd;
+ case MHD_DAEMON_INFORMATION_LISTEN_SOCKET:
+ CHECK_SIZE (MHD_socket);
+ return_value->listen_socket
+ = daemon->listen_socket;
+ return MHD_YES;
#ifdef EPOLL_SUPPORT
- case MHD_DAEMON_INFO_EPOLL_FD:
- return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
+ case MHD_DAEMON_INFORMATION_EPOLL_FD:
+ CHECK_SIZE (int);
+ // FIXME: maybe return MHD_NO if we are not using EPOLL?
+ return_value->epoll_fd = daemon->epoll_fd;
+ return MHD_YES;
#endif
- case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
- if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
+ case MHD_DAEMON_INFORMATION_CURRENT_CONNECTIONS:
+ CHECK_SIZE (unsigned int);
+ if (MHD_TM_EXTERNAL_EVENT_LOOP == daemon->threading_model)
{
- /* Assume that MHD_run() in not called in other thread
- * at the same time. */
+ /* Assumes that MHD_run() in not called in other thread
+ (of the application) at the same time. */
MHD_cleanup_connections (daemon);
+ return_value->num_connections
+ = daemon->connections;
}
else if (daemon->worker_pool)
{
unsigned int i;
/* Collect the connection information stored in the workers. */
- daemon->connections = 0;
- for (i = 0; i < daemon->worker_pool_size; i++)
+ return_value->num_connections = 0;
+ for (i = 0; i < daemon->worker_pool_size; i++)
{
/* FIXME: next line is thread-safe only if read is atomic. */
- daemon->connections += daemon->worker_pool[i].connections;
+ return_value->num_connections
+ += daemon->worker_pool[i].connections;
}
}
- return (const union MHD_DaemonInfo *) &daemon->connections;
- case MHD_DAEMON_INFO_FLAGS:
- return (const union MHD_DaemonInfo *) &daemon->options;
- case MHD_DAEMON_INFO_BIND_PORT:
- return (const union MHD_DaemonInfo *) &daemon->port;
+ else
+ return_value->num_connections
+ = daemon->connections;
+ return MHD_YES;
+ case MHD_DAEMON_INFORMATION_BIND_PORT:
+ CHECK_SIZE (uint16_t);
+ // FIXME: return MHD_NO if port is not known/UNIX?
+ return_value->port = daemon->listen_port;
+ return MHD_YES;
default:
- return NULL;
+ return MHD_NO;
}
-#else
- return MHD_NO;
-#endif
+
+#undef CHECK_SIZE
}
/* end of daemon_info.c */
diff --git a/src/lib/daemon_options.c b/src/lib/daemon_options.c
@@ -126,7 +126,7 @@ MHD_daemon_disallow_suspend_resume (struct MHD_Daemon *daemon)
void
MHD_daemon_disallow_upgrade (struct MHD_Daemon *daemon)
{
- daemon->disallow_upgrade;
+ daemon->disallow_upgrade = true;
}
@@ -165,6 +165,7 @@ MHD_daemon_tcp_fastopen (struct MHD_Daemon *daemon,
return MHD_NO;
#endif
}
+ return MHD_NO;
}
@@ -355,20 +356,20 @@ MHD_daemon_set_tls_backend (struct MHD_Daemon *daemon,
if (NULL ==
(daemon->tls_backend_lib = dlopen (filename,
RTLD_NOW | RTLD_LOCAL)))
- return MHD_SC_BACKEND_UNSUPPORTED; /* plugin not found */
+ return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* plugin not found */
if (NULL == (init = dlsym (daemon->tls_backend_lib,
"MHD_TLS_init_" MHD_TLS_ABI_VERSION_STR)))
{
dlclose (daemon->tls_backend_lib);
daemon->tls_backend_lib = NULL;
- return MHD_SC_BACKEND_UNSUPPORTED; /* possibly wrong version installed */
+ return MHD_SC_TLS_BACKEND_UNSUPPORTED; /* possibly wrong version installed */
}
if (NULL == (daemon->tls_api = init (ciphers)))
{
dlclose (daemon->tls_backend_lib);
daemon->tls_backend_lib = NULL;
- return MHD_SC_CIPHERS_INVALID; /* possibly wrong version installed */
+ return MHD_SC_TLS_CIPHERS_INVALID; /* possibly wrong version installed */
}
return MHD_SC_OK;
#endif
@@ -545,8 +546,8 @@ MHD_daemon_set_early_uri_logger (struct MHD_Daemon *daemon,
MHD_EarlyUriLogCallback cb,
void *cb_cls)
{
- daemon->early_uri_logger = cb;
- daemon->early_uri_logger_cls = cb_cls;
+ daemon->early_uri_logger_cb = cb;
+ daemon->early_uri_logger_cb_cls = cb_cls;
}
@@ -687,6 +688,9 @@ MHD_daemon_digest_auth_random (struct MHD_Daemon *daemon,
daemon->digest_auth_random_buf = buf;
daemon->digest_auth_random_buf_size = buf_size;
#else
+ (void) daemon;
+ (void) buf_size;
+ (void) buf;
MHD_PANIC ("digest authentication not supported by this build");
#endif
}
@@ -732,6 +736,8 @@ MHD_daemon_digest_auth_nc_length (struct MHD_Daemon *daemon,
daemon->digest_nc_length = nc_length;
return MHD_SC_OK;
#else
+ (void) daemon;
+ (void) nc_length;
return MHD_SC_DIGEST_AUTH_NOT_SUPPORTED_BY_BUILD;
#endif
}
diff --git a/src/lib/internal.c b/src/lib/internal.c
@@ -238,7 +238,7 @@ MHD_parse_arguments_ (struct MHD_Connection *connection,
break;
}
/* amper is non-NULL here */
- amper[0] = '\0';d
+ amper[0] = '\0';
amper++;
if ( (NULL == equals) ||
(equals >= amper) )
diff --git a/src/lib/internal.h b/src/lib/internal.h
@@ -454,7 +454,7 @@ struct MHD_Request
* HTTP version string (i.e. http/1.1). Allocated
* in pool.
*/
- char *version;
+ char *version_s;
/**
* Close connection after sending response?
@@ -493,7 +493,6 @@ struct MHD_Request
*/
char *colon;
-
/**
* Function used for reading HTTP request stream.
*/
@@ -515,11 +514,6 @@ struct MHD_Request
#endif /* UPGRADE_SUPPORT */
/**
- * Foreign address (of length @e addr_len).
- */
- struct sockaddr_storage addr;
-
- /**
* Thread handle for this connection (if we are using
* one thread per connection).
*/
@@ -741,7 +735,23 @@ struct MHD_Connection
* Reference to the MHD_Daemon struct.
*/
struct MHD_Daemon *daemon;
+
+ /**
+ * 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;
+#ifdef HTTPS_SUPPORT
+ /**
+ * State kept per TLS connection. Plugin-specific.
+ */
+ struct MHD_TLS_ConnectionState *tls_cs;
+#endif
+
/**
* Information about the current request we are processing
* on this connection.
@@ -749,6 +759,11 @@ struct MHD_Connection
struct MHD_Request request;
/**
+ * Foreign address (of length @e addr_len).
+ */
+ struct sockaddr_storage addr;
+
+ /**
* Length of the foreign address.
*/
socklen_t addr_len;
@@ -858,7 +873,7 @@ struct MHD_Daemon
/**
* Closure for @e early_uri_logger_cb.
*/
- void *early_uri_logger_cls;
+ void *early_uri_logger_cb_cls;
/**
* Function to call whenever a connection is started or
@@ -881,6 +896,17 @@ struct MHD_Daemon
* Closure for @e unescape_cb.
*/
void *unescape_cb_cls;
+
+ /**
+ * Pointer to master daemon (NULL if this is the master)
+ */
+ struct MHD_Daemon *master;
+
+ /**
+ * Worker daemons (one per thread)
+ */
+ struct MHD_Daemon *worker_pool;
+
#if HTTPS_SUPPORT
/**
@@ -1135,6 +1161,16 @@ struct MHD_Daemon
unsigned int ip_connection_limit;
/**
+ * Number of active parallel connections.
+ */
+ unsigned int connections;
+
+ /**
+ * Number of worker daemons
+ */
+ unsigned int worker_pool_size;
+
+ /**
* Default timeout in seconds for idle connections.
*/
time_t connection_default_timeout;
diff --git a/src/lib/request_info.c b/src/lib/request_info.c
@@ -46,7 +46,41 @@ MHD_request_get_information_sz (struct MHD_Request *request,
union MHD_RequestInformation *return_value,
size_t return_value_size)
{
- return MHD_NO; /* not implemented */
+#define CHECK_SIZE(type) if (sizeof(type) < return_value_size) \
+ return MHD_NO
+
+ switch (info_type)
+ {
+ case MHD_REQUEST_INFORMATION_CONNECTION:
+ CHECK_SIZE (struct MHD_Connection *);
+ return_value->connection = request->connection;
+ return MHD_YES;
+ case MHD_REQUEST_INFORMATION_CLIENT_CONTEXT:
+ CHECK_SIZE (void **);
+ return_value->request_context = &request->client_context;
+ return MHD_YES;
+ case MHD_REQUEST_INFORMATION_HTTP_VERSION:
+ CHECK_SIZE (const char *);
+ return_value->http_version = request->version_s;
+ return MHD_YES;
+ case MHD_REQUEST_INFORMATION_HTTP_METHOD:
+ CHECK_SIZE (const char *);
+ return_value->http_method = request->method_s;
+ return MHD_YES;
+ case MHD_REQUEST_INFORMATION_HEADER_SIZE:
+ CHECK_SIZE (size_t);
+ if ( (MHD_REQUEST_HEADERS_RECEIVED > request->state) ||
+ (MHD_REQUEST_CLOSED == request->state) ||
+ (MHD_REQUEST_IN_CLEANUP == request->state) )
+ return MHD_NO; /* invalid, too early! */
+ return_value->header_size = request->header_size;
+ return MHD_YES;
+
+ default:
+ return MHD_NO;
+ }
+
+#undef CHECK_SIZE
}