libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

commit 2b5a2a55cd26112dbdf3a3c395624909c1074591
parent 292efe4aab89dd1ed260350e6f6bab04d8469e36
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Fri, 30 May 2025 09:53:27 +0200

MHD_daemon_get_info_*(): added new information types, renumbered enum values

Diffstat:
Msrc/include/microhttpd2.h | 135++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/include/microhttpd2_main.h.in | 135++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/mhd2/daemon_get_info.c | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 303 insertions(+), 37 deletions(-)

diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h @@ -9295,6 +9295,38 @@ enum MHD_DaemonInfoFixedType { /** + * Get the type of system call used for sockets polling. + * The value #MHD_SPS_AUTO is never set in the returned data. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon + * does not use internal sockets polling. + * The result is placed in @a v_poll_syscall member. + */ + MHD_DAEMON_INFO_FIXED_POLL_SYSCALL = 41 + , + /** + * Get the file descriptor for the single FD that triggered when + * any MHD event happens. + * This FD can be watched as aggregate indicator for all MHD events. + * The provided socket must be used as 'read-only': only select() or similar + * functions should be used. Any modifications (changing socket attributes, + * calling accept(), closing it etc.) will lead to undefined behaviour. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD if the library + * does not support mode with agregate FD. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon + * is not configured to use this mode. + * The result is placed in @a v_aggreagate_fd member. + */ + MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD = 46 + , + /** + * Get the number of worker threads when used in MHD_WM_WORKER_THREADS mode. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon + * does not use worker threads mode. + * The result is placed in @a v_num_work_threads_uint member. + */ + MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS = 47 + , + /** * Get the port number of daemon's listen socket. * Note: if port '0' (auto port) was specified for #MHD_D_OPTION_BIND_PORT(), * returned value will be the real port number. @@ -9305,7 +9337,7 @@ enum MHD_DaemonInfoFixedType * If the function succeed, the returned port number is never zero. * The result is placed in @a v_bind_port_uint16 member. */ - MHD_DAEMON_INFO_FIXED_BIND_PORT = 1 + MHD_DAEMON_INFO_FIXED_BIND_PORT = 80 , /** * Get the file descriptor for the listening socket. @@ -9316,22 +9348,7 @@ enum MHD_DaemonInfoFixedType * does not have listening socket. * The result is placed in @a v_listen_socket member. */ - MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 2 - , - /** - * Get the file descriptor for the single FD that triggered when - * any MHD event happens. - * This FD can be watched as aggregate indicator for all MHD events. - * The provided socket must be used as 'read-only': only select() or similar - * functions should be used. Any modifications (changing socket attributes, - * calling accept(), closing it etc.) will lead to undefined behaviour. - * The function returns #MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD if the library - * does not support mode with agregate FD. - * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon - * is not configured to use this mode. - * The result is placed in @a v_aggreagate_fd member. - */ - MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD = 3 + MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 82 , /** * Get the TLS backend used by the daemon. @@ -9340,7 +9357,49 @@ enum MHD_DaemonInfoFixedType * If MHD built without TLS support then #MHD_TLS_BACKEND_NONE is always set. * The result is placed in @a v_tls_backend member. */ - MHD_DAEMON_INFO_FIXED_TLS_BACKEND = 100 + MHD_DAEMON_INFO_FIXED_TLS_BACKEND = 120 + , + /** + * Get the default inactivity timeout for connections. + * The result is placed in @a v_default_timeout_uint member. + */ + MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT = 160 + , + /** + * Get the limit of number of simutaneous network connections served by + * the daemon. + * The result is placed in @a v_global_connection_limit_uint member. + */ + MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT = 161 + , + /** + * Get the limit of number of simutaneous network connections served by + * the daemon for any single IP address. + * The result is placed in @a v_per_ip_limit_uint member. + */ + MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT = 162 + , + /** + * Get the setting for suppression of the 'Date:' header in replies. + * The result is placed in @a v_suppress_date_header_bool member. + */ + MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER = 240 + , + /** + * Get the size of buffer unsed per connection. + * The result is placed in @a v_conn_memory_limit_sizet member. + */ + MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT = 280 + , + /** + * Get the limit of maximum FD value for the daemon. + * The daemon rejects (closes) any sockets with FD equal or higher + * the resulting number. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon + * is built for W32. + * The result is placed in @a v_fd_number_limit_uint member. + */ + MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT = 283 , /* * Sentinel * */ @@ -9360,6 +9419,16 @@ enum MHD_DaemonInfoFixedType union MHD_DaemonInfoFixedData { /** + * The data for the #MHD_DAEMON_INFO_FIXED_POLL_SYSCALL query + */ + enum MHD_SockPollSyscall v_poll_syscall; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS query + */ + unsigned int v_num_work_threads_uint; + + /** * The data for the #MHD_DAEMON_INFO_FIXED_BIND_PORT query */ uint_least16_t v_bind_port_uint16; @@ -9380,6 +9449,36 @@ union MHD_DaemonInfoFixedData enum MHD_TlsBackend v_tls_backend; /** + * The data for the #MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT query + */ + unsigned int v_default_timeout_uint; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT query + */ + unsigned int v_global_connection_limit_uint; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT query + */ + unsigned int v_per_ip_limit_uint; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER query + */ + enum MHD_Bool v_suppress_date_header_bool; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT query + */ + size_t v_conn_memory_limit_sizet; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT query + */ + MHD_Socket v_fd_number_limit_socket; + + /** * Unused member. * Help enforcing future-proof alignment of the union. * Do not use. diff --git a/src/include/microhttpd2_main.h.in b/src/include/microhttpd2_main.h.in @@ -4578,6 +4578,38 @@ enum MHD_DaemonInfoFixedType { /** + * Get the type of system call used for sockets polling. + * The value #MHD_SPS_AUTO is never set in the returned data. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon + * does not use internal sockets polling. + * The result is placed in @a v_poll_syscall member. + */ + MHD_DAEMON_INFO_FIXED_POLL_SYSCALL = 41 + , + /** + * Get the file descriptor for the single FD that triggered when + * any MHD event happens. + * This FD can be watched as aggregate indicator for all MHD events. + * The provided socket must be used as 'read-only': only select() or similar + * functions should be used. Any modifications (changing socket attributes, + * calling accept(), closing it etc.) will lead to undefined behaviour. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD if the library + * does not support mode with agregate FD. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon + * is not configured to use this mode. + * The result is placed in @a v_aggreagate_fd member. + */ + MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD = 46 + , + /** + * Get the number of worker threads when used in MHD_WM_WORKER_THREADS mode. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon + * does not use worker threads mode. + * The result is placed in @a v_num_work_threads_uint member. + */ + MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS = 47 + , + /** * Get the port number of daemon's listen socket. * Note: if port '0' (auto port) was specified for #MHD_D_OPTION_BIND_PORT(), * returned value will be the real port number. @@ -4588,7 +4620,7 @@ enum MHD_DaemonInfoFixedType * If the function succeed, the returned port number is never zero. * The result is placed in @a v_bind_port_uint16 member. */ - MHD_DAEMON_INFO_FIXED_BIND_PORT = 1 + MHD_DAEMON_INFO_FIXED_BIND_PORT = 80 , /** * Get the file descriptor for the listening socket. @@ -4599,22 +4631,7 @@ enum MHD_DaemonInfoFixedType * does not have listening socket. * The result is placed in @a v_listen_socket member. */ - MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 2 - , - /** - * Get the file descriptor for the single FD that triggered when - * any MHD event happens. - * This FD can be watched as aggregate indicator for all MHD events. - * The provided socket must be used as 'read-only': only select() or similar - * functions should be used. Any modifications (changing socket attributes, - * calling accept(), closing it etc.) will lead to undefined behaviour. - * The function returns #MHD_SC_INFO_GET_TYPE_NOT_SUPP_BY_BUILD if the library - * does not support mode with agregate FD. - * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon - * is not configured to use this mode. - * The result is placed in @a v_aggreagate_fd member. - */ - MHD_DAEMON_INFO_FIXED_AGGREAGATE_FD = 3 + MHD_DAEMON_INFO_FIXED_LISTEN_SOCKET = 82 , /** * Get the TLS backend used by the daemon. @@ -4623,7 +4640,49 @@ enum MHD_DaemonInfoFixedType * If MHD built without TLS support then #MHD_TLS_BACKEND_NONE is always set. * The result is placed in @a v_tls_backend member. */ - MHD_DAEMON_INFO_FIXED_TLS_BACKEND = 100 + MHD_DAEMON_INFO_FIXED_TLS_BACKEND = 120 + , + /** + * Get the default inactivity timeout for connections. + * The result is placed in @a v_default_timeout_uint member. + */ + MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT = 160 + , + /** + * Get the limit of number of simutaneous network connections served by + * the daemon. + * The result is placed in @a v_global_connection_limit_uint member. + */ + MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT = 161 + , + /** + * Get the limit of number of simutaneous network connections served by + * the daemon for any single IP address. + * The result is placed in @a v_per_ip_limit_uint member. + */ + MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT = 162 + , + /** + * Get the setting for suppression of the 'Date:' header in replies. + * The result is placed in @a v_suppress_date_header_bool member. + */ + MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER = 240 + , + /** + * Get the size of buffer unsed per connection. + * The result is placed in @a v_conn_memory_limit_sizet member. + */ + MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT = 280 + , + /** + * Get the limit of maximum FD value for the daemon. + * The daemon rejects (closes) any sockets with FD equal or higher + * the resulting number. + * The function returns #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the daemon + * is built for W32. + * The result is placed in @a v_fd_number_limit_uint member. + */ + MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT = 283 , /* * Sentinel * */ @@ -4643,6 +4702,16 @@ enum MHD_DaemonInfoFixedType union MHD_DaemonInfoFixedData { /** + * The data for the #MHD_DAEMON_INFO_FIXED_POLL_SYSCALL query + */ + enum MHD_SockPollSyscall v_poll_syscall; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS query + */ + unsigned int v_num_work_threads_uint; + + /** * The data for the #MHD_DAEMON_INFO_FIXED_BIND_PORT query */ uint_least16_t v_bind_port_uint16; @@ -4663,6 +4732,36 @@ union MHD_DaemonInfoFixedData enum MHD_TlsBackend v_tls_backend; /** + * The data for the #MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT query + */ + unsigned int v_default_timeout_uint; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT query + */ + unsigned int v_global_connection_limit_uint; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT query + */ + unsigned int v_per_ip_limit_uint; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER query + */ + enum MHD_Bool v_suppress_date_header_bool; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT query + */ + size_t v_conn_memory_limit_sizet; + + /** + * The data for the #MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT query + */ + MHD_Socket v_fd_number_limit_socket; + + /** * Unused member. * Help enforcing future-proof alignment of the union. * Do not use. diff --git a/src/mhd2/daemon_get_info.c b/src/mhd2/daemon_get_info.c @@ -52,6 +52,7 @@ MHD_daemon_get_info_fixed_sz ( union MHD_DaemonInfoFixedData *MHD_RESTRICT output_buf, size_t output_buf_size) { + mhd_assert (! mhd_D_HAS_MASTER(daemon)); if (mhd_DAEMON_STATE_STARTED > daemon->state) return MHD_SC_TOO_EARLY; if (mhd_DAEMON_STATE_STARTED < daemon->state) @@ -59,6 +60,34 @@ MHD_daemon_get_info_fixed_sz ( switch (info_type) { + case MHD_DAEMON_INFO_FIXED_POLL_SYSCALL: + if (mhd_WM_INT_HAS_EXT_EVENTS(daemon->wmode_int)) + return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE; + if (sizeof(output_buf->v_poll_syscall) > output_buf_size) + return MHD_SC_INFO_GET_BUFF_TOO_SMALL; + output_buf->v_poll_syscall = + (enum MHD_SockPollSyscall) daemon->events.poll_type; + return MHD_SC_OK; + case MHD_DAEMON_INFO_FIXED_NUM_WORK_THREADS: +#ifdef MHD_SUPPORT_THREADS + if (! mhd_WM_INT_HAS_THREADS(daemon->wmode_int)) + return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE; + if (mhd_WM_INT_INTERNAL_EVENTS_THREAD_PER_CONNECTION == daemon->wmode_int) + return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE; + if (sizeof(output_buf->v_num_work_threads_uint) > output_buf_size) + return MHD_SC_INFO_GET_BUFF_TOO_SMALL; + if (mhd_DAEMON_TYPE_SINGLE == daemon->threading.d_type) + output_buf->v_num_work_threads_uint = 1; + else + { + mhd_assert (mhd_DAEMON_TYPE_MASTER_CONTROL_ONLY == \ + daemon->threading.d_type); + output_buf->v_num_work_threads_uint = daemon->threading.hier.pool.num; + } + return MHD_SC_OK; +#else /* ! MHD_SUPPORT_THREADS */ + return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE; +#endif /* ! MHD_SUPPORT_THREADS */ case MHD_DAEMON_INFO_FIXED_BIND_PORT: if ((MHD_INVALID_SOCKET == daemon->net.listen.fd) && ! daemon->net.listen.is_broken) @@ -136,7 +165,45 @@ MHD_daemon_get_info_fixed_sz ( #endif } return MHD_SC_OK; - break; + case MHD_DAEMON_INFO_FIXED_DEFAULT_TIMEOUT: + if (sizeof(output_buf->v_default_timeout_uint) > output_buf_size) + return MHD_SC_INFO_GET_BUFF_TOO_SMALL; + output_buf->v_default_timeout_uint = + (unsigned int) (daemon->conns.cfg.timeout_ms / 1000u); + mhd_assert (output_buf->v_default_timeout_uint * 1000u == \ + daemon->conns.cfg.timeout_ms); + return MHD_SC_OK; + case MHD_DAEMON_INFO_FIXED_GLOBAL_CONNECTION_LIMIT: + if (sizeof(output_buf->v_global_connection_limit_uint) > output_buf_size) + return MHD_SC_INFO_GET_BUFF_TOO_SMALL; + output_buf->v_global_connection_limit_uint = + daemon->conns.cfg.count_limit; + return MHD_SC_OK; + case MHD_DAEMON_INFO_FIXED_PER_IP_LIMIT: + if (sizeof(output_buf->v_per_ip_limit_uint) > output_buf_size) + return MHD_SC_INFO_GET_BUFF_TOO_SMALL; + output_buf->v_per_ip_limit_uint = daemon->conns.cfg.per_ip_limit; + return MHD_SC_OK; + case MHD_DAEMON_INFO_FIXED_SUPPRESS_DATE_HEADER: + if (sizeof(output_buf->v_suppress_date_header_bool) > output_buf_size) + return MHD_SC_INFO_GET_BUFF_TOO_SMALL; + output_buf->v_suppress_date_header_bool = + daemon->req_cfg.suppress_date ? MHD_YES : MHD_NO; + return MHD_SC_OK; + case MHD_DAEMON_INFO_FIXED_CONN_MEMORY_LIMIT: + if (sizeof(output_buf->v_conn_memory_limit_sizet) > output_buf_size) + return MHD_SC_INFO_GET_BUFF_TOO_SMALL; + output_buf->v_conn_memory_limit_sizet = daemon->conns.cfg.mem_pool_size; + return MHD_SC_OK; + case MHD_DAEMON_INFO_FIXED_FD_NUMBER_LIMIT: +#ifdef MHD_SOCKETS_KIND_POSIX + if (sizeof(output_buf->v_fd_number_limit_socket) > output_buf_size) + return MHD_SC_INFO_GET_BUFF_TOO_SMALL; + output_buf->v_fd_number_limit_socket = daemon->net.cfg.max_fd_num; + return MHD_SC_OK; +#else /* ! MHD_SOCKETS_KIND_POSIX */ + return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE; +#endif /* ! MHD_SOCKETS_KIND_POSIX */ case MHD_DAEMON_INFO_FIXED_SENTINEL: default: @@ -155,6 +222,7 @@ MHD_daemon_get_info_dynamic_sz ( union MHD_DaemonInfoDynamicData *MHD_RESTRICT output_buf, size_t output_buf_size) { + mhd_assert (! mhd_D_HAS_MASTER(daemon)); if (mhd_DAEMON_STATE_STARTED > daemon->state) return MHD_SC_TOO_EARLY; if (mhd_DAEMON_STATE_STARTED < daemon->state)