libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit bca7a709f8129e856d9175ea1081abc0feec883c
parent b926a975e6633e9d4d1c2ec21f459e55a5ceb5de
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 15 Feb 2018 03:30:41 +0100

add a few more missing fundamental API functions

Diffstat:
Msrc/include/microhttpd2.h | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/Makefile.am | 5+++++
Asrc/lib/daemon_add_connection.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/daemon_create.c | 3+++
Asrc/lib/daemon_get_fdset.c | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/lib/daemon_get_timeout.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/daemon_quiesce.c | 3++-
Asrc/lib/daemon_run.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/lib/daemon_run_from_select.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/daemon_start.c | 5++---
Msrc/lib/internal.c | 3+--
Msrc/lib/memorypool.c | 12++++++------
12 files changed, 557 insertions(+), 12 deletions(-)

diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h @@ -1197,6 +1197,209 @@ _MHD_EXTERN void MHD_daemon_destroy (struct MHD_Daemon *daemon); +/** + * Add another client connection to the set of connections managed by + * MHD. This API is usually not needed (since MHD will accept inbound + * connections on the server socket). Use this API in special cases, + * for example if your HTTP server is behind NAT and needs to connect + * out to the HTTP client, or if you are building a proxy. + * + * If you use this API in conjunction with a internal select or a + * thread pool, you must set the option #MHD_USE_ITC to ensure that + * the freshly added connection is immediately processed by MHD. + * + * The given client socket will be managed (and closed!) by MHD after + * this call and must no longer be used directly by the application + * afterwards. + * + * @param daemon daemon that manages the connection + * @param client_socket socket to manage (MHD will expect + * to receive an HTTP request from this socket next). + * @param addr IP address of the client + * @param addrlen number of bytes in @a addr + * @return #MHD_SC_OK on success + * The socket will be closed in any case; `errno` is + * set to indicate further details about the error. + * @ingroup specialized + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_add_connection (struct MHD_Daemon *daemon, + MHD_socket client_socket, + const struct sockaddr *addr, + socklen_t addrlen); + + +/** + * Obtain the `select()` sets for this daemon. Daemon's FDs will be + * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO + * for each fd_set before calling this function. FD_SETSIZE is assumed + * to be platform's default. + * + * This function should only be called in when MHD is configured to + * use external select with 'select()' or with 'epoll'. In the latter + * case, it will only add the single 'epoll()' file descriptor used by + * MHD to the sets. It's necessary to use #MHD_get_timeout() in + * combination with this function. + * + * This function must be called only for daemon started without + * #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @return #MHD_SC_OK on success, otherwise error code + * @ingroup event + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_get_fdset (struct MHD_Daemon *daemon, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *except_fd_set, + MHD_socket *max_fd); + + +/** + * Obtain the `select()` sets for this daemon. Daemon's FDs will be + * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO + * for each fd_set before calling this function. + * + * Passing custom FD_SETSIZE as @a fd_setsize allow usage of + * larger/smaller than platform's default fd_sets. + * + * This function should only be called in when MHD is configured to + * use external select with 'select()' or with 'epoll'. In the latter + * case, it will only add the single 'epoll' file descriptor used by + * MHD to the sets. It's necessary to use #MHD_get_timeout() in + * combination with this function. + * + * This function must be called only for daemon started + * without #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @param fd_setsize value of FD_SETSIZE + * @return #MHD_SC_OK on success, otherwise error code + * @ingroup event + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *except_fd_set, + MHD_socket *max_fd, + unsigned int fd_setsize); + + +/** + * Obtain the `select()` sets for this daemon. Daemon's FDs will be + * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO + * for each fd_set before calling this function. Size of fd_set is + * determined by current value of FD_SETSIZE. It's necessary to use + * #MHD_get_timeout() in combination with this function. + * + * This function could be called only for daemon started + * without #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @return #MHD_YES on success, #MHD_NO if this + * daemon was not started with the right + * options for this call or any FD didn't + * fit fd_set. + * @ingroup event + */ +#define MHD_daemon_get_fdset(daemon,read_fd_set,write_fd_set,except_fd_set,max_fd) \ + MHD_get_fdset2((daemon),(read_fd_set),(write_fd_set),(except_fd_set),(max_fd),FD_SETSIZE) + + +/** + * Obtain timeout value for polling function for this daemon. + * This function set value to amount of milliseconds for which polling + * function (`select()` or `poll()`) should at most block, not the + * timeout value set for connections. + * It is important to always use this function, even if connection + * timeout is not set, as in some cases MHD may already have more + * data to process on next turn (data pending in TLS buffers, + * connections are already ready with epoll etc.) and returned timeout + * will be zero. + * + * @param daemon daemon to query for timeout + * @param timeout set to the timeout (in milliseconds) + * @return #MHD_SC_OK on success, #MHD_SC_NO_TIMEOUT if timeouts are + * not used (or no connections exist that would + * necessitate the use of a timeout right now), otherwise + * an error code + * @ingroup event + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_get_timeout (struct MHD_Daemon *daemon, + MHD_UNSIGNED_LONG_LONG *timeout); + + +/** + * Run webserver operations (without blocking unless in client + * callbacks). This method should be called by clients in combination + * with #MHD_get_fdset if the client-controlled select method is used + * and #MHD_get_timeout(). + * + * This function is a convenience method, which is useful if the + * fd_sets from #MHD_get_fdset were not directly passed to `select()`; + * with this function, MHD will internally do the appropriate `select()` + * call itself again. While it is always safe to call #MHD_run (if + * #MHD_USE_INTERNAL_POLLING_THREAD is not set), you should call + * #MHD_run_from_select if performance is important (as it saves an + * expensive call to `select()`). + * + * @param daemon daemon to run + * @return #MHD_SC_OK on success + * @ingroup event + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_run (struct MHD_Daemon *daemon); + + +/** + * Run webserver operations. This method should be called by clients + * in combination with #MHD_get_fdset and #MHD_get_timeout() if the + * client-controlled select method is used. + * + * You can use this function instead of #MHD_run if you called + * `select()` on the result from #MHD_get_fdset. File descriptors in + * the sets that are not controlled by MHD will be ignored. Calling + * this function instead of #MHD_run is more efficient as MHD will not + * have to call `select()` again to determine which operations are + * ready. + * + * This function cannot be used with daemon started with + * #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to run select loop for + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @return #MHD_SC_OK on success + * @ingroup event + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_run_from_select (struct MHD_Daemon *daemon, + const fd_set *read_fd_set, + const fd_set *write_fd_set, + const fd_set *except_fd_set); + + + + /* ********************* daemon options ************** */ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am @@ -60,10 +60,15 @@ libmicrohttpd_la_SOURCES = \ action_suspend.c \ connection_info.c \ connection_options.c \ + daemon_add_connection.c \ daemon_create.c \ daemon_destroy.c \ + daemon_get_fdset.c \ + daemon_get_timeout.c \ daemon_info.c \ daemon_options.c \ + daemon_run.c \ + daemon_run_from_select.c \ daemon_start.c \ daemon_quiesce.c \ init.c init.h \ diff --git a/src/lib/daemon_add_connection.c b/src/lib/daemon_add_connection.c @@ -0,0 +1,63 @@ +/* + 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/daemon_add_connection.c + * @brief main functions to add a connection to be managed by a daemon + * @author Christian Grothoff + */ +#include "internal.h" + + +/** + * Add another client connection to the set of connections managed by + * MHD. This API is usually not needed (since MHD will accept inbound + * connections on the server socket). Use this API in special cases, + * for example if your HTTP server is behind NAT and needs to connect + * out to the HTTP client, or if you are building a proxy. + * + * If you use this API in conjunction with a internal select or a + * thread pool, you must set the option + * #MHD_USE_ITC to ensure that the freshly added + * connection is immediately processed by MHD. + * + * The given client socket will be managed (and closed!) by MHD after + * this call and must no longer be used directly by the application + * afterwards. + * + * @param daemon daemon that manages the connection + * @param client_socket socket to manage (MHD will expect + * to receive an HTTP request from this socket next). + * @param addr IP address of the client + * @param addrlen number of bytes in @a addr + * @return #MHD_SC_OK on success + * The socket will be closed in any case; `errno` is + * set to indicate further details about the error. + * @ingroup specialized + */ +_MHD_EXTERN enum MHD_StatusCode +MHD_daemon_add_connection (struct MHD_Daemon *daemon, + MHD_socket client_socket, + const struct sockaddr *addr, + socklen_t addrlen) +{ + return -1; +} + +/* end of daemon_add_connection.c */ diff --git a/src/lib/daemon_create.c b/src/lib/daemon_create.c @@ -135,3 +135,6 @@ MHD_daemon_create (MHD_RequestCallback cb, #endif return daemon; } + + +/* end of daemon_create.c */ diff --git a/src/lib/daemon_get_fdset.c b/src/lib/daemon_get_fdset.c @@ -0,0 +1,107 @@ +/* + 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/daemon_get_fdset.c + * @brief function to get select() fdset of a daemon + * @author Christian Grothoff + */ +#include "internal.h" + +/** + * We defined a macro with the same name as a function we + * are implementing here. Need to undef the macro to avoid + * causing a conflict. + */ +#undef MHD_daemon_get_fdset + +/** + * Obtain the `select()` sets for this daemon. Daemon's FDs will be + * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO + * for each fd_set before calling this function. FD_SETSIZE is assumed + * to be platform's default. + * + * This function should only be called in when MHD is configured to + * use external select with 'select()' or with 'epoll'. In the latter + * case, it will only add the single 'epoll()' file descriptor used by + * MHD to the sets. It's necessary to use #MHD_get_timeout() in + * combination with this function. + * + * This function must be called only for daemon started without + * #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @return #MHD_SC_OK on success, otherwise error code + * @ingroup event + */ +enum MHD_StatusCode +MHD_daemon_get_fdset (struct MHD_Daemon *daemon, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *except_fd_set, + MHD_socket *max_fd) +{ + return -1; +} + + +/** + * Obtain the `select()` sets for this daemon. Daemon's FDs will be + * added to fd_sets. To get only daemon FDs in fd_sets, call FD_ZERO + * for each fd_set before calling this function. + * + * Passing custom FD_SETSIZE as @a fd_setsize allow usage of + * larger/smaller than platform's default fd_sets. + * + * This function should only be called in when MHD is configured to + * use external select with 'select()' or with 'epoll'. In the latter + * case, it will only add the single 'epoll' file descriptor used by + * MHD to the sets. It's necessary to use #MHD_get_timeout() in + * combination with this function. + * + * This function must be called only for daemon started + * without #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to get sets from + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @param max_fd increased to largest FD added (if larger + * than existing value); can be NULL + * @param fd_setsize value of FD_SETSIZE + * @return #MHD_SC_OK on success, otherwise error code + * @ingroup event + */ +enum MHD_StatusCode +MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *except_fd_set, + MHD_socket *max_fd, + unsigned int fd_setsize) +{ + return -1; +} + +/* end of daemon_get_fdset.c */ diff --git a/src/lib/daemon_get_timeout.c b/src/lib/daemon_get_timeout.c @@ -0,0 +1,54 @@ +/* + 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/daemon_get_timeout.c + * @brief function to obtain timeout for event loop + * @author Christian Grothoff + */ +#include "internal.h" + + +/** + * Obtain timeout value for polling function for this daemon. + * This function set value to amount of milliseconds for which polling + * function (`select()` or `poll()`) should at most block, not the + * timeout value set for connections. + * It is important to always use this function, even if connection + * timeout is not set, as in some cases MHD may already have more + * data to process on next turn (data pending in TLS buffers, + * connections are already ready with epoll etc.) and returned timeout + * will be zero. + * + * @param daemon daemon to query for timeout + * @param timeout set to the timeout (in milliseconds) + * @return #MHD_SC_OK on success, #MHD_SC_NO_TIMEOUT if timeouts are + * not used (or no connections exist that would + * necessitate the use of a timeout right now), otherwise + * an error code + * @ingroup event + */ +enum MHD_StatusCode +MHD_daemon_get_timeout (struct MHD_Daemon *daemon, + MHD_UNSIGNED_LONG_LONG *timeout) +{ + return -1; +} + +/* end of daemon_get_timeout.c */ diff --git a/src/lib/daemon_quiesce.c b/src/lib/daemon_quiesce.c @@ -18,7 +18,7 @@ */ /** - * @file lib/daemon.c + * @file lib/daemon_quiesce.c * @brief main functions to quiesce a daemon * @author Christian Grothoff */ @@ -124,4 +124,5 @@ MHD_daemon_quiesce (struct MHD_Daemon *daemon) return listen_socket; } +/* end of daemon_quiesce.c */ diff --git a/src/lib/daemon_run.c b/src/lib/daemon_run.c @@ -0,0 +1,52 @@ +/* + 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/daemon_run.c + * @brief generic function to run event loop of a daemon + * @author Christian Grothoff + */ +#include "internal.h" + + +/** + * Run webserver operations (without blocking unless in client + * callbacks). This method should be called by clients in combination + * with #MHD_get_fdset if the client-controlled select method is used + * and #MHD_get_timeout(). + * + * This function is a convenience method, which is useful if the + * fd_sets from #MHD_get_fdset were not directly passed to `select()`; + * with this function, MHD will internally do the appropriate `select()` + * call itself again. While it is always safe to call #MHD_run (if + * #MHD_USE_INTERNAL_POLLING_THREAD is not set), you should call + * #MHD_run_from_select if performance is important (as it saves an + * expensive call to `select()`). + * + * @param daemon daemon to run + * @return #MHD_SC_OK on success + * @ingroup event + */ +enum MHD_StatusCode +MHD_daemon_run (struct MHD_Daemon *daemon) +{ + return -1; +} + +/* end of daemon_run.c */ diff --git a/src/lib/daemon_run_from_select.c b/src/lib/daemon_run_from_select.c @@ -0,0 +1,59 @@ +/* + 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/daemon_run_from_select.c + * @brief functions to run select-based event loop + * @author Christian Grothoff + */ +#include "internal.h" + + +/** + * Run webserver operations. This method should be called by clients + * in combination with #MHD_get_fdset and #MHD_get_timeout() if the + * client-controlled select method is used. + * + * You can use this function instead of #MHD_run if you called + * `select()` on the result from #MHD_get_fdset. File descriptors in + * the sets that are not controlled by MHD will be ignored. Calling + * this function instead of #MHD_run is more efficient as MHD will not + * have to call `select()` again to determine which operations are + * ready. + * + * This function cannot be used with daemon started with + * #MHD_USE_INTERNAL_POLLING_THREAD flag. + * + * @param daemon daemon to run select loop for + * @param read_fd_set read set + * @param write_fd_set write set + * @param except_fd_set except set + * @return #MHD_SC_OK on success + * @ingroup event + */ +enum MHD_StatusCode +MHD_daemon_run_from_select (struct MHD_Daemon *daemon, + const fd_set *read_fd_set, + const fd_set *write_fd_set, + const fd_set *except_fd_set) +{ + return -1; +} + +/* end of daemon_run_from_select.c */ diff --git a/src/lib/daemon_start.c b/src/lib/daemon_start.c @@ -18,7 +18,7 @@ */ /** - * @file lib/daemon.c + * @file lib/daemon_start.c * @brief functions to start a daemon * @author Christian Grothoff */ @@ -958,5 +958,4 @@ MHD_daemon_start (struct MHD_Daemon *daemon) } - -/* end of daemon.c */ +/* end of daemon_start.c */ diff --git a/src/lib/internal.c b/src/lib/internal.c @@ -1,6 +1,6 @@ /* This file is part of libmicrohttpd - Copyright (C) 2007 Daniel Pittman and Christian Grothoff + 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 @@ -23,7 +23,6 @@ * @author Daniel Pittman * @author Christian Grothoff */ - #include "internal.h" #include "mhd_str.h" diff --git a/src/lib/memorypool.c b/src/lib/memorypool.c @@ -1,6 +1,6 @@ /* This file is part of libmicrohttpd - Copyright (C) 2007, 2009, 2010 Daniel Pittman and Christian Grothoff + Copyright (C) 2007, 2009, 2010, 2018 Christian Grothoff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -71,9 +71,9 @@ struct MemoryPool size_t end; /** - * #MHD_NO if pool was malloc'ed, #MHD_YES if mmapped (VirtualAlloc'ed for W32). + * false if pool was malloc'ed, true if mmapped (VirtualAlloc'ed for W32). */ - int is_mmap; + bool is_mmap; }; @@ -135,11 +135,11 @@ MHD_pool_create (size_t max) free (pool); return NULL; } - pool->is_mmap = MHD_NO; + pool->is_mmap = false; } else { - pool->is_mmap = MHD_YES; + pool->is_mmap = true; } pool->pos = 0; pool->end = max; @@ -158,7 +158,7 @@ MHD_pool_destroy (struct MemoryPool *pool) { if (NULL == pool) return; - if (MHD_NO == pool->is_mmap) + if (! pool->is_mmap) free (pool->memory); else #if defined(MAP_ANONYMOUS) && !defined(_WIN32)