GNU libmicrohttpd 1.0.0
Loading...
Searching...
No Matches
daemon.c File Reference

A minimal-HTTP server library. More...

#include "platform.h"
#include "internal.h"
#include "response.h"
#include "connection.h"
#include "memorypool.h"
#include "mhd_limits.h"
#include "autoinit_funcs.h"
#include "mhd_mono_clock.h"
#include "mhd_sockets.h"
#include "mhd_itc.h"
#include "mhd_compat.h"
#include "mhd_send.h"
#include "mhd_align.h"
#include "mhd_str.h"
#include "tsearch.h"
Include dependency graph for daemon.c:

Go to the source code of this file.

Macros

#define MHD_MAX_CONNECTIONS_DEFAULT   (FD_SETSIZE - 3 - 1 - MHD_ITC_NUM_FDS_)
 
#define MHD_POOL_SIZE_DEFAULT   (32 * 1024)
 

Typedefs

typedef void(* VfprintfFunctionPointerType) (void *cls, const char *format, va_list va)
 

Functions

void MHD_init (void)
 
void MHD_fini (void)
 
static void close_all_connections (struct MHD_Daemon *daemon)
 
void MHD_check_global_init_ (void)
 
_MHD_EXTERN void MHD_free (void *ptr)
 
static void MHD_ip_count_lock (struct MHD_Daemon *daemon)
 
static void MHD_ip_count_unlock (struct MHD_Daemon *daemon)
 
static int MHD_ip_addr_compare (const void *a1, const void *a2)
 
static enum MHD_Result MHD_ip_addr_to_key (const struct sockaddr_storage *addr, socklen_t addrlen, struct MHD_IPCount *key)
 
static enum MHD_Result MHD_ip_limit_add (struct MHD_Daemon *daemon, const struct sockaddr_storage *addr, socklen_t addrlen)
 
static void MHD_ip_limit_del (struct MHD_Daemon *daemon, const struct sockaddr_storage *addr, socklen_t addrlen)
 
_MHD_EXTERN enum MHD_Result MHD_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)
 
static enum MHD_Result internal_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, int fd_setsize)
 
_MHD_EXTERN enum MHD_Result MHD_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)
 
static enum MHD_Result call_handlers (struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
 
static void MHD_cleanup_connections (struct MHD_Daemon *daemon)
 
static struct MHD_Connectionnew_connection_prepare_ (struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr_storage *addr, socklen_t addrlen, bool external_add, bool non_blck, bool sk_spipe_supprs, enum MHD_tristate sk_is_nonip)
 
static enum MHD_Result new_connection_process_ (struct MHD_Daemon *daemon, struct MHD_Connection *connection)
 
static enum MHD_Result internal_add_connection (struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr_storage *addr, socklen_t addrlen, bool external_add, bool non_blck, bool sk_spipe_supprs, enum MHD_tristate sk_is_nonip)
 
static void new_connections_list_process_ (struct MHD_Daemon *daemon)
 
void internal_suspend_connection_ (struct MHD_Connection *connection)
 
_MHD_EXTERN void MHD_suspend_connection (struct MHD_Connection *connection)
 
_MHD_EXTERN void MHD_resume_connection (struct MHD_Connection *connection)
 
static enum MHD_Result resume_suspended_connections (struct MHD_Daemon *daemon)
 
_MHD_EXTERN enum MHD_Result MHD_add_connection (struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
 
static enum MHD_Result MHD_accept_connection (struct MHD_Daemon *daemon)
 
_MHD_EXTERN enum MHD_Result MHD_get_timeout (struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
 
_MHD_EXTERN enum MHD_Result MHD_get_timeout64 (struct MHD_Daemon *daemon, uint64_t *timeout)
 
static enum MHD_Result internal_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, int fd_setsize)
 
_MHD_EXTERN enum MHD_Result MHD_run_from_select2 (struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set, unsigned int fd_setsize)
 
_MHD_EXTERN enum MHD_Result MHD_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)
 
static enum MHD_Result MHD_select (struct MHD_Daemon *daemon, int32_t millisec)
 
_MHD_EXTERN enum MHD_Result MHD_run (struct MHD_Daemon *daemon)
 
_MHD_EXTERN enum MHD_Result MHD_run_wait (struct MHD_Daemon *daemon, int32_t millisec)
 
static void close_connection (struct MHD_Connection *pos)
 
static size_t unescape_wrapper (void *cls, struct MHD_Connection *connection, char *val)
 
_MHD_EXTERN struct MHD_DaemonMHD_start_daemon (unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...)
 
_MHD_EXTERN MHD_socket MHD_quiesce_daemon (struct MHD_Daemon *daemon)
 
static enum MHD_Result parse_options_va (struct MHD_Daemon *daemon, struct MHD_InterimParams_ *params, va_list ap)
 
static enum MHD_Result parse_options (struct MHD_Daemon *daemon, struct MHD_InterimParams_ *params,...)
 
static bool process_interim_params (struct MHD_Daemon *d, const struct sockaddr **ppsockaddr, socklen_t *psockaddr_len, struct MHD_InterimParams_ *params)
 
_MHD_EXTERN struct MHD_DaemonMHD_start_daemon_va (unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls, va_list ap)
 
_MHD_EXTERN void MHD_stop_daemon (struct MHD_Daemon *daemon)
 
_MHD_EXTERN const union MHD_DaemonInfoMHD_get_daemon_info (struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
 
_MHD_EXTERN const char * MHD_get_version (void)
 
_MHD_EXTERN uint32_t MHD_get_version_bin (void)
 
_MHD_EXTERN enum MHD_Result MHD_is_feature_supported (enum MHD_FEATURE feature)
 

Variables

volatile int global_init_count = 0
 

Detailed Description

A minimal-HTTP server library.

Author
Daniel Pittman
Christian Grothoff
Karlson2k (Evgeny Grin)

Definition in file daemon.c.

Macro Definition Documentation

◆ MHD_MAX_CONNECTIONS_DEFAULT

#define MHD_MAX_CONNECTIONS_DEFAULT   (FD_SETSIZE - 3 - 1 - MHD_ITC_NUM_FDS_)

Default connection limit.

Definition at line 80 of file daemon.c.

Referenced by MHD_start_daemon_va().

◆ MHD_POOL_SIZE_DEFAULT

#define MHD_POOL_SIZE_DEFAULT   (32 * 1024)

Default memory allowed per connection.

Definition at line 88 of file daemon.c.

Referenced by MHD_start_daemon_va().

Typedef Documentation

◆ VfprintfFunctionPointerType

typedef void(* VfprintfFunctionPointerType) (void *cls, const char *format, va_list va)

Signature of the MHD custom logger function.

Parameters
clsclosure
formatformat string
vaarguments to the format string (fprintf-style)

Definition at line 6277 of file daemon.c.

Function Documentation

◆ call_handlers()

static enum MHD_Result call_handlers ( struct MHD_Connection * con,
bool read_ready,
bool write_ready,
bool force_close )
static

Call the handlers for a connection in the appropriate order based on the readiness as detected by the event loop.

Parameters
conconnection to handle
read_readyset if the socket is ready for reading
write_readyset if the socket is ready for writing
force_closeset if a hard error was detected on the socket; if this information is not available, simply pass MHD_NO
Returns
MHD_YES to continue normally, MHD_NO if a serious error was encountered and the connection is to be closed.

Definition at line 1293 of file daemon.c.

References MHD_Connection::daemon, MHD_Daemon::data_already_pending, MHD_Connection::event_loop_info, mhd_assert, MHD_CONNECTION_CHUNKED_BODY_READY, MHD_connection_close_(), MHD_CONNECTION_CLOSED, MHD_connection_handle_idle(), MHD_connection_handle_read(), MHD_connection_handle_write(), MHD_CONNECTION_HEADERS_SENDING, MHD_CONNECTION_INIT, MHD_CONNECTION_NORMAL_BODY_READY, MHD_D_IS_USING_THREAD_PER_CONN_, MHD_EVENT_LOOP_INFO_PROCESS, MHD_EVENT_LOOP_INFO_READ, MHD_EVENT_LOOP_INFO_WRITE, MHD_REQUEST_TERMINATED_WITH_ERROR, MHD_thread_handle_ID_is_current_thread_, MHD_thread_handle_ID_is_valid_ID_, MHD_USE_SELECT_INTERNALLY, MHD_YES, MHD_Daemon::options, MHD_Connection::sk_nonblck, MHD_Connection::state, and MHD_Connection::tls_read_ready.

Referenced by internal_run_from_select().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ close_all_connections()

◆ close_connection()

◆ internal_add_connection()

static enum MHD_Result internal_add_connection ( struct MHD_Daemon * daemon,
MHD_socket client_socket,
const struct sockaddr_storage * addr,
socklen_t addrlen,
bool external_add,
bool non_blck,
bool sk_spipe_supprs,
enum MHD_tristate sk_is_nonip )
static

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.

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.

Parameters
daemondaemon that manages the connection
client_socketsocket to manage (MHD will expect to receive an HTTP request from this socket next).
addrIP address of the client
addrlennumber of bytes in addr
external_addperform additional operations needed due to the application calling us directly
non_blckindicate that socket in non-blocking mode
sk_spipe_supprsindicate that the client_socket has set SIGPIPE suppression
sk_is_nonip_MHD_YES if this is not a TCP/IP socket
Returns
MHD_YES on success, MHD_NO if this daemon could not handle the connection (i.e. malloc failed, etc). The socket will be closed in any case; 'errno' is set to indicate further details about the error.

Definition at line 3085 of file daemon.c.

References _, MHD_Connection::addr, MHD_Connection::daemon, DLL_insert, MHD_Daemon::have_new, MHD_Daemon::itc, mhd_assert, MHD_D_DOES_SCKT_FIT_FDSET_, MHD_D_GET_FD_SETSIZE_, MHD_D_IS_THREAD_SAFE_, MHD_D_IS_USING_EPOLL_, MHD_D_IS_USING_SELECT_, MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_NO, MHD_socket_close_chk_, MHD_YES, new_connection_prepare_(), new_connection_process_(), MHD_Daemon::new_connections_head, MHD_Daemon::new_connections_tail, NULL, and MHD_Daemon::worker_pool.

Referenced by MHD_accept_connection(), and MHD_add_connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ internal_suspend_connection_()

◆ MHD_accept_connection()

static enum MHD_Result MHD_accept_connection ( struct MHD_Daemon * daemon)
static

Accept an incoming connection and create the MHD_Connection object for it. This function also enforces policy by way of checking with the accept policy callback.

Remarks
To be called only from thread that process daemon's select()/poll()/etc.
Parameters
daemonhandle with the listen socket
Returns
MHD_YES on success (connections denied by policy or due to 'out of memory' and similar errors) are still considered successful as far as MHD_accept_connection() is concerned); a return code of MHD_NO only refers to the actual accept() system call.

Definition at line 3805 of file daemon.c.

References _, _MHD_NO, _MHD_YES, MHD_Daemon::at_limit, MHD_Daemon::cleanup_connection_mutex, MHD_Daemon::connections, fd, internal_add_connection(), MHD_Daemon::listen_fd, MHD_Daemon::listen_is_unix, MHD_Daemon::listen_nonblk, mhd_assert, MHD_D_IS_USING_THREADS_, MHD_INVALID_SOCKET, MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_NO, MHD_SCKT_EINVAL_, MHD_SCKT_ERR_IS_, MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_, MHD_SCKT_ERR_IS_EAGAIN_, MHD_SCKT_ERR_IS_LOW_RESOURCES_, MHD_socket_close_, MHD_socket_get_error_, MHD_socket_last_strerr_, MHD_socket_nonblocking_(), MHD_socket_noninheritable_(), MHD_socket_strerr_, MHD_thread_handle_ID_is_current_thread_, MHD_YES, NULL, MHD_Daemon::sigpipe_blocked, SOCK_CLOEXEC_OR_ZERO, SOCK_NONBLOCK_OR_ZERO, SOCK_NOSIGPIPE_OR_ZERO, MHD_Daemon::was_quiesced, and MHD_Daemon::worker_pool.

Referenced by internal_run_from_select().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_check_global_init_()

void MHD_check_global_init_ ( void )

Check whether global initialisation was performed and call initialiser if necessary.

Definition at line 161 of file daemon.c.

References global_init_count, MHD_init(), MHD_mutex_lock_chk_, and MHD_mutex_unlock_chk_.

Referenced by MHD_start_daemon_va().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_cleanup_connections()

static void MHD_cleanup_connections ( struct MHD_Daemon * daemon)
static

Free resources associated with all closed connections. (destroy responses, free buffers, etc.). All closed connections are kept in the "cleanup" doubly-linked list.

Parameters
daemondaemon to clean up

Free resources associated with all closed connections. (destroy responses, free buffers, etc.). All closed connections are kept in the "cleanup" doubly-linked list.

Remarks
To be called only from thread that process daemon's select()/poll()/etc.
Parameters
daemondaemon to clean up

Definition at line 4044 of file daemon.c.

References _, MHD_Connection::addr, MHD_Connection::addr_len, MHD_Daemon::at_limit, MHD_Daemon::cleanup_connection_mutex, MHD_Daemon::cleanup_head, MHD_Daemon::cleanup_tail, MHD_Daemon::connections, MHD_Connection::daemon, DLL_remove, EDLL_remove, mhd_assert, MHD_CONNECTION_NOTIFY_CLOSED, MHD_D_IS_USING_EPOLL_, MHD_D_IS_USING_THREAD_PER_CONN_, MHD_D_IS_USING_THREADS_, MHD_destroy_response(), MHD_EPOLL_STATE_IN_EPOLL_SET, MHD_EPOLL_STATE_IN_EREADY_EDLL, MHD_INVALID_SOCKET, MHD_ip_limit_del(), MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_PANIC, MHD_pool_destroy(), MHD_socket_close_chk_, MHD_thread_handle_ID_is_current_thread_, MHD_thread_handle_ID_join_thread_, MHD_Daemon::notify_connection, MHD_Daemon::notify_connection_cls, NULL, MHD_Connection::pool, MHD_Reply::response, MHD_Connection::rp, MHD_Connection::socket_context, MHD_Connection::socket_fd, MHD_Connection::thread_joined, and MHD_Daemon::worker_pool.

Referenced by close_all_connections(), internal_run_from_select(), MHD_add_connection(), MHD_get_daemon_info(), MHD_run_from_select2(), and MHD_run_wait().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_fini()

void MHD_fini ( void )

Global deinitialisation function.

Definition at line 9897 of file daemon.c.

References MHD_monotonic_sec_counter_finish().

Here is the call graph for this function:

◆ MHD_init()

void MHD_init ( void )

Global initialisation function.

Initialize do setup work.

Definition at line 9844 of file daemon.c.

References _, mhd_assert, MHD_init_mem_pools_(), MHD_monotonic_sec_counter_init(), MHD_PANIC, MHD_send_init_static_vars_(), MHD_set_panic_func(), and NULL.

Referenced by MHD_check_global_init_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_ip_addr_compare()

static int MHD_ip_addr_compare ( const void * a1,
const void * a2 )
static

Tree comparison function for IP addresses (supplied to tsearch() family). We compare everything in the struct up through the beginning of the 'count' field.

Parameters
a1first address to compare
a2second address to compare
Returns
-1, 0 or 1 depending on result of compare

Definition at line 297 of file daemon.c.

Referenced by MHD_ip_limit_add(), and MHD_ip_limit_del().

Here is the caller graph for this function:

◆ MHD_ip_addr_to_key()

static enum MHD_Result MHD_ip_addr_to_key ( const struct sockaddr_storage * addr,
socklen_t addrlen,
struct MHD_IPCount * key )
static

Parse address and initialize key using the address.

Parameters
addraddress to parse
addrlennumber of bytes in addr
keywhere to store the parsed address
Returns
MHD_YES on success and MHD_NO otherwise (e.g., invalid address type)

Definition at line 316 of file daemon.c.

References MHD_NO, MHD_YES, and NULL.

Referenced by MHD_ip_limit_add(), and MHD_ip_limit_del().

Here is the caller graph for this function:

◆ MHD_ip_count_lock()

static void MHD_ip_count_lock ( struct MHD_Daemon * daemon)
static

Lock shared structure for IP connection counts and connection DLLs.

Parameters
daemonhandle to daemon where lock is

Definition at line 259 of file daemon.c.

References MHD_Daemon::master, mhd_assert, MHD_mutex_lock_chk_, NULL, and MHD_Daemon::per_ip_connection_mutex.

Referenced by MHD_ip_limit_add(), and MHD_ip_limit_del().

Here is the caller graph for this function:

◆ MHD_ip_count_unlock()

static void MHD_ip_count_unlock ( struct MHD_Daemon * daemon)
static

Unlock shared structure for IP connection counts and connection DLLs.

Parameters
daemonhandle to daemon where lock is

Definition at line 276 of file daemon.c.

References MHD_Daemon::master, mhd_assert, MHD_mutex_unlock_chk_, NULL, and MHD_Daemon::per_ip_connection_mutex.

Referenced by MHD_ip_limit_add(), and MHD_ip_limit_del().

Here is the caller graph for this function:

◆ MHD_ip_limit_add()

static enum MHD_Result MHD_ip_limit_add ( struct MHD_Daemon * daemon,
const struct sockaddr_storage * addr,
socklen_t addrlen )
static

Check if IP address is over its limit in terms of the number of allowed concurrent connections. If the IP is still allowed, increments the connection counter.

Parameters
daemonhandle to daemon where connection counts are tracked
addraddress to add (or increment counter)
addrlennumber of bytes in addr
Returns
Return MHD_YES if IP below limit, MHD_NO if IP has surpassed limit. Also returns MHD_NO if fails to allocate memory.

Definition at line 369 of file daemon.c.

References _, MHD_get_master(), MHD_ip_addr_compare(), MHD_ip_addr_to_key(), MHD_ip_count_lock(), MHD_ip_count_unlock(), MHD_NO, MHD_YES, NULL, MHD_Daemon::per_ip_connection_count, MHD_Daemon::per_ip_connection_limit, and tsearch().

Referenced by new_connection_prepare_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_ip_limit_del()

static void MHD_ip_limit_del ( struct MHD_Daemon * daemon,
const struct sockaddr_storage * addr,
socklen_t addrlen )
static

Decrement connection count for IP address, removing from table count reaches 0.

Parameters
daemonhandle to daemon where connection counts are tracked
addraddress to remove (or decrement counter)
addrlennumber of bytes in addr

Definition at line 437 of file daemon.c.

References _, MHD_get_master(), MHD_ip_addr_compare(), MHD_ip_addr_to_key(), MHD_ip_count_lock(), MHD_ip_count_unlock(), MHD_NO, MHD_PANIC, NULL, MHD_Daemon::per_ip_connection_count, MHD_Daemon::per_ip_connection_limit, tdelete(), and tfind().

Referenced by MHD_cleanup_connections(), new_connection_prepare_(), and new_connection_process_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_resume_connection()

_MHD_EXTERN void MHD_resume_connection ( struct MHD_Connection * connection)

Resume handling of network data for suspended connection. It is safe to resume a suspended connection at any time. Calling this function on a connection that was not previously suspended will result in undefined behavior.

If you are using this function in "external" sockets polling mode, you must make sure to run MHD_run() and MHD_get_timeout() afterwards (before again calling MHD_get_fdset()), as otherwise the change may not be reflected in the set returned by MHD_get_fdset() and you may end up with a connection that is stuck until the next network activity.

Parameters
connectionthe connection to resume

Definition at line 3365 of file daemon.c.

References _, MHD_Daemon::cleanup_connection_mutex, MHD_Connection::daemon, MHD_Daemon::itc, mhd_assert, MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_PANIC, MHD_TEST_ALLOW_SUSPEND_RESUME, NULL, MHD_Daemon::options, MHD_Connection::resuming, MHD_Daemon::resuming, and MHD_Daemon::worker_pool.

Referenced by close_all_connections(), and internal_run_from_select().

Here is the caller graph for this function:

◆ MHD_select()

static enum MHD_Result MHD_select ( struct MHD_Daemon * daemon,
int32_t millisec )
static

Main internal select() call. Will compute select sets, call select() and then internal_run_from_select with the result.

Parameters
daemondaemon to run select() loop for
millisecthe maximum time in milliseconds to wait for events, set to '0' for non-blocking processing, set to '-1' to wait indefinitely.
Returns
MHD_NO on serious errors, MHD_YES on success

Definition at line 4795 of file daemon.c.

References _, MHD_Daemon::at_limit, MHD_Daemon::connection_limit, MHD_Daemon::connections, internal_get_fdset2(), internal_run_from_select(), MHD_Daemon::itc, MHD_Daemon::listen_fd, MHD_add_to_fd_set_(), MHD_D_IS_USING_THREAD_PER_CONN_, MHD_get_timeout64(), MHD_INVALID_SOCKET, MHD_NO, MHD_SCKT_ERR_IS_EINTR_, MHD_socket_get_error_, MHD_socket_strerr_, MHD_SYS_select_, MHD_TEST_ALLOW_SUSPEND_RESUME, MHD_YES, NULL, MHD_Daemon::options, resume_suspended_connections(), MHD_Daemon::shutdown, TIMEVAL_TV_SEC_MAX, and MHD_Daemon::was_quiesced.

Referenced by MHD_run_wait().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MHD_suspend_connection()

_MHD_EXTERN void MHD_suspend_connection ( struct MHD_Connection * connection)

Suspend handling of network data for a given connection. This can be used to dequeue a connection from MHD's event loop (not applicable to thread-per-connection!) for a while.

If you use this API in conjunction with an "internal" socket polling, you must set the option MHD_USE_ITC to ensure that a resumed connection is immediately processed by MHD.

Suspended connections continue to count against the total number of connections allowed (per daemon, as well as per IP, if such limits are set). Suspended connections will NOT time out; timeouts will restart when the connection handling is resumed. While a connection is suspended, MHD will not detect disconnects by the client.

The only safe way to call this function is to call it from the MHD_AccessHandlerCallback or MHD_ContentReaderCallback.

Finally, it is an API violation to call MHD_stop_daemon while having suspended connections (this will at least create memory and socket leaks or lead to undefined behavior). You must explicitly resume all connections before stopping the daemon.

Parameters
connectionthe connection to suspend
See also
MHD_AccessHandlerCallback

Definition at line 3322 of file daemon.c.

References _, MHD_Connection::daemon, internal_suspend_connection_(), mhd_assert, MHD_D_IS_USING_THREAD_PER_CONN_, MHD_D_IS_USING_THREADS_, MHD_PANIC, MHD_TEST_ALLOW_SUSPEND_RESUME, MHD_thread_handle_ID_is_current_thread_, NULL, and MHD_Daemon::options.

Here is the call graph for this function:

◆ new_connection_prepare_()

static struct MHD_Connection * new_connection_prepare_ ( struct MHD_Daemon * daemon,
MHD_socket client_socket,
const struct sockaddr_storage * addr,
socklen_t addrlen,
bool external_add,
bool non_blck,
bool sk_spipe_supprs,
enum MHD_tristate sk_is_nonip )
static

Do basic preparation work on the new incoming connection.

This function do all preparation that is possible outside main daemon thread.

Remarks
Could be called from any thread.
Parameters
daemondaemon that manages the connection
client_socketsocket to manage (MHD will expect to receive an HTTP request from this socket next).
addrIP address of the client
addrlennumber of bytes in addr
external_addindicate that socket has been added externally
non_blckindicate that socket in non-blocking mode
sk_spipe_supprsindicate that the client_socket has set SIGPIPE suppression
sk_is_nonip_MHD_YES if this is not a TCP/IP socket
Returns
pointer to the connection on success, NULL if this daemon could not handle the connection (i.e. malloc failed, etc). The socket will be closed in case of error; 'errno' is set to indicate further details about the error.

Definition at line 2535 of file daemon.c.

References _, _MHD_DROP_CONST, _MHD_OFF, _MHD_UNKNOWN, MHD_Connection::addr, MHD_Connection::addr_len, MHD_Daemon::apc, MHD_Daemon::apc_cls, MHD_Daemon::connection_limit, MHD_Connection::connection_timeout_ms, MHD_Daemon::connection_timeout_ms, MHD_Daemon::connections, MHD_Connection::daemon, MHD_Connection::event_loop_info, MHD_Connection::is_nonip, MHD_Connection::last_activity, MHD_calloc_(), MHD_EVENT_LOOP_INFO_READ, MHD_ip_limit_add(), MHD_ip_limit_del(), MHD_monotonic_msec_counter(), MHD_NO, MHD_PANIC, MHD_set_http_callbacks_(), MHD_set_https_callbacks(), MHD_socket_close_chk_, MHD_STATICSTR_LEN_, MHD_strerror_, MHD_thread_handle_ID_set_invalid_, MHD_TLS_CONN_INIT, MHD_USE_INSECURE_TLS_EARLY_DATA, MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT, MHD_USE_TLS, NULL, MHD_Daemon::options, MHD_Connection::sk_corked, MHD_Connection::sk_nodelay, MHD_Connection::sk_nonblck, MHD_Connection::sk_spipe_suppress, and MHD_Connection::socket_fd.

Referenced by internal_add_connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_connection_process_()

static enum MHD_Result new_connection_process_ ( struct MHD_Daemon * daemon,
struct MHD_Connection * connection )
static

Finally insert the new connection to the list of connections served by the daemon and start processing.

Remarks
To be called only from thread that process daemon's select()/poll()/etc.
Parameters
daemondaemon that manages the connection
connectionthe newly created connection
Returns
MHD_YES on success, MHD_NO on error

Definition at line 2862 of file daemon.c.

References _, MHD_Connection::addr, MHD_Connection::addr_len, MHD_Daemon::cleanup_connection_mutex, MHD_Daemon::connection_limit, MHD_Daemon::connections, MHD_Daemon::connections_head, MHD_Daemon::connections_tail, MHD_Connection::daemon, DLL_insert, DLL_remove, EDLL_insert, mhd_assert, MHD_CONNECTION_NOTIFY_CLOSED, MHD_CONNECTION_NOTIFY_STARTED, MHD_connection_set_initial_state_(), MHD_create_named_thread_, MHD_D_IS_USING_EPOLL_, MHD_D_IS_USING_THREAD_PER_CONN_, MHD_D_IS_USING_THREADS_, MHD_EPOLL_STATE_IN_EPOLL_SET, MHD_EPOLL_STATE_IN_EREADY_EDLL, MHD_EPOLL_STATE_READ_READY, MHD_EPOLL_STATE_WRITE_READY, MHD_ip_limit_del(), MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_NO, MHD_pool_create(), MHD_pool_destroy(), MHD_socket_close_chk_, MHD_socket_last_strerr_, MHD_strerror_, MHD_thread_handle_ID_is_current_thread_, MHD_USE_TURBO, MHD_YES, MHD_Daemon::normal_timeout_head, MHD_Daemon::normal_timeout_tail, MHD_Daemon::notify_connection, MHD_Daemon::notify_connection_cls, NULL, MHD_Daemon::options, MHD_Connection::pool, MHD_Daemon::pool_size, MHD_Connection::socket_context, MHD_Connection::socket_fd, thread_main_handle_connection(), MHD_Daemon::worker_pool, XDLL_insert, and XDLL_remove.

Referenced by internal_add_connection(), and new_connections_list_process_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_connections_list_process_()

static void new_connections_list_process_ ( struct MHD_Daemon * daemon)
static

< Currently processed connection

Definition at line 3172 of file daemon.c.

References _, MHD_Connection::daemon, DLL_remove, MHD_Daemon::have_new, mhd_assert, MHD_D_IS_THREAD_SAFE_, MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_NO, new_connection_process_(), MHD_Daemon::new_connections_head, MHD_Daemon::new_connections_tail, and NULL.

Referenced by internal_run_from_select().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_options()

static enum MHD_Result parse_options ( struct MHD_Daemon * daemon,
struct MHD_InterimParams_ * params,
... )
static

Parse a list of options given as varargs.

Parameters
daemonthe daemon to initialize
servaddrwhere to store the server's listen address
paramsthe interim parameters to be assigned to
...the options
Returns
MHD_YES on success, MHD_NO on error

Definition at line 6308 of file daemon.c.

References parse_options_va().

Referenced by parse_options_va().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_options_va()

static enum MHD_Result parse_options_va ( struct MHD_Daemon * daemon,
struct MHD_InterimParams_ * params,
va_list ap )
static

Parse a list of options given as varargs.

Parameters
daemonthe daemon to initialize
servaddrwhere to store the server's listen address
paramsthe interim parameters to be assigned to
apthe options
Returns
MHD_YES on success, MHD_NO on error

Parse a list of options given as varargs.

Parameters
[in,out]daemonthe daemon to initialize
[out]paramsthe interim parameters to be assigned to
apthe options
Returns
MHD_YES on success, MHD_NO on error

Definition at line 6600 of file daemon.c.

References _, _MHD_DROP_CONST, MHD_Daemon::client_discipline, MHD_Daemon::connection_limit, MHD_Daemon::connection_timeout_ms, MHD_Daemon::insanity_level, MHD_Daemon::listen_backlog_size, MHD_Daemon::listening_address_reuse, MHD_D_IS_USING_THREAD_PER_CONN_, MHD_D_IS_USING_THREADS_, MHD_DAUTH_BIND_NONCE_URI, MHD_DAUTH_BIND_NONCE_URI_PARAMS, MHD_NO, MHD_OPTION_APP_FD_SETSIZE, MHD_OPTION_ARRAY, MHD_OPTION_CLIENT_DISCIPLINE_LVL, MHD_OPTION_CONNECTION_LIMIT, MHD_OPTION_CONNECTION_MEMORY_INCREMENT, MHD_OPTION_CONNECTION_MEMORY_LIMIT, MHD_OPTION_CONNECTION_TIMEOUT, MHD_OPTION_DIGEST_AUTH_DEFAULT_MAX_NC, MHD_OPTION_DIGEST_AUTH_DEFAULT_NONCE_TIMEOUT, MHD_OPTION_DIGEST_AUTH_NONCE_BIND_TYPE, MHD_OPTION_DIGEST_AUTH_RANDOM, MHD_OPTION_DIGEST_AUTH_RANDOM_COPY, MHD_OPTION_END, MHD_OPTION_EXTERNAL_LOGGER, MHD_OPTION_GNUTLS_PSK_CRED_HANDLER, MHD_OPTION_HTTPS_CERT_CALLBACK, MHD_OPTION_HTTPS_CERT_CALLBACK2, MHD_OPTION_HTTPS_CRED_TYPE, MHD_OPTION_HTTPS_KEY_PASSWORD, MHD_OPTION_HTTPS_MEM_CERT, MHD_OPTION_HTTPS_MEM_DHPARAMS, MHD_OPTION_HTTPS_MEM_KEY, MHD_OPTION_HTTPS_MEM_TRUST, MHD_OPTION_HTTPS_PRIORITIES, MHD_OPTION_HTTPS_PRIORITIES_APPEND, MHD_OPTION_LISTEN_BACKLOG_SIZE, MHD_OPTION_LISTEN_SOCKET, MHD_OPTION_LISTENING_ADDRESS_REUSE, MHD_OPTION_NONCE_NC_SIZE, MHD_OPTION_NOTIFY_COMPLETED, MHD_OPTION_NOTIFY_CONNECTION, MHD_OPTION_PER_IP_CONNECTION_LIMIT, MHD_OPTION_SERVER_INSANITY, MHD_OPTION_SIGPIPE_HANDLED_BY_APP, MHD_OPTION_SOCK_ADDR, MHD_OPTION_SOCK_ADDR_LEN, MHD_OPTION_STRICT_FOR_CLIENT, MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE, MHD_OPTION_THREAD_POOL_SIZE, MHD_OPTION_THREAD_STACK_SIZE, MHD_OPTION_TLS_NO_ALPN, MHD_OPTION_UNESCAPE_CALLBACK, MHD_OPTION_URI_LOG_CALLBACK, MHD_USE_PEDANTIC_CHECKS, MHD_USE_TLS, MHD_YES, MHD_Daemon::notify_completed, MHD_Daemon::notify_completed_cls, MHD_Daemon::notify_connection, MHD_Daemon::notify_connection_cls, NULL, MHD_OptionItem::option, MHD_Daemon::options, parse_options(), MHD_Daemon::per_ip_connection_limit, MHD_Daemon::pool_increment, MHD_Daemon::pool_size, PRIu64, MHD_OptionItem::ptr_value, MHD_Daemon::sigpipe_blocked, SIZE_MAX, UINT64_MAX, UINT_MAX, MHD_Daemon::unescape_callback, MHD_Daemon::unescape_callback_cls, MHD_Daemon::uri_log_callback, MHD_Daemon::uri_log_callback_cls, MHD_OptionItem::value, and MHD_Daemon::worker_pool_size.

Referenced by MHD_start_daemon_va(), and parse_options().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_interim_params()

static bool process_interim_params ( struct MHD_Daemon * d,
const struct sockaddr ** ppsockaddr,
socklen_t * psockaddr_len,
struct MHD_InterimParams_ * params )
static

Apply interim parameters

Parameters
[in,out]dthe daemon to use
[out]ppsockaddrthe pointer to store the pointer to 'struct sockaddr' if provided by application
[out]psockaddr_lenthe size memory area pointed by 'struct sockaddr' if provided by application
[in,out]paramsthe interim parameters to process
Returns
true in case of success, false in case of critical error (the daemon must be closed).

Definition at line 7486 of file daemon.c.

References _, _MHD_UNKNOWN, MHD_Daemon::listen_fd, MHD_Daemon::listen_is_unix, mhd_assert, MHD_D_IS_USING_POLL_, MHD_D_IS_USING_THREADS_, MHD_INVALID_SOCKET, MHD_socket_close_, MHD_USE_NO_LISTEN_SOCKET, NULL, MHD_Daemon::options, and MHD_Daemon::port.

Referenced by MHD_start_daemon_va().

Here is the caller graph for this function:

◆ resume_suspended_connections()

static enum MHD_Result resume_suspended_connections ( struct MHD_Daemon * daemon)
static

Run through the suspended connections and move any that are no longer suspended back to the active state.

Remarks
To be called only from thread that process daemon's select()/poll()/etc.
Parameters
daemondaemon context
Returns
MHD_YES if a connection was actually resumed

Definition at line 3443 of file daemon.c.

References _, MHD_Daemon::cleanup_connection_mutex, MHD_Daemon::cleanup_head, MHD_Daemon::cleanup_tail, MHD_Request::client_aware, MHD_Request::client_context, MHD_Connection::connection_timeout_ms, MHD_Daemon::connection_timeout_ms, MHD_Daemon::connections_head, MHD_Daemon::connections_tail, MHD_Connection::daemon, MHD_Daemon::data_already_pending, DLL_insert, DLL_remove, EDLL_insert, MHD_Daemon::itc, MHD_Connection::last_activity, MHD_Daemon::manual_timeout_head, MHD_Daemon::manual_timeout_tail, MHD_ALLOW_UPGRADE, mhd_assert, MHD_D_IS_USING_EPOLL_, MHD_D_IS_USING_THREAD_PER_CONN_, MHD_D_IS_USING_THREADS_, MHD_EPOLL_STATE_IN_EREADY_EDLL, MHD_EPOLL_STATE_READ_READY, MHD_EPOLL_STATE_SUSPENDED, MHD_EPOLL_STATE_WRITE_READY, MHD_monotonic_msec_counter(), MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_NO, MHD_PANIC, MHD_REQUEST_TERMINATED_COMPLETED_OK, MHD_thread_handle_ID_is_current_thread_, MHD_USE_THREAD_PER_CONNECTION, MHD_YES, MHD_Daemon::normal_timeout_head, MHD_Daemon::normal_timeout_tail, MHD_Daemon::notify_completed, MHD_Daemon::notify_completed_cls, NULL, MHD_Daemon::options, MHD_Connection::prev, MHD_Connection::resuming, MHD_Daemon::resuming, MHD_Connection::rq, MHD_Daemon::shutdown, MHD_Connection::suspended, MHD_Daemon::suspended_connections_head, MHD_Daemon::suspended_connections_tail, MHD_Daemon::worker_pool, and XDLL_insert.

Referenced by close_all_connections(), MHD_run_from_select2(), and MHD_select().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unescape_wrapper()

static size_t unescape_wrapper ( void * cls,
struct MHD_Connection * connection,
char * val )
static

Process escape sequences ('HH') Updates val in place; the result cannot be larger than the input. The result must also still be 0-terminated.

Parameters
clsclosure (use NULL)
connectionhandle to connection, not used
valvalue to unescape (modified in the process)
Returns
length of the resulting val (strlen(val) maybe shorter afterwards due to elimination of escape sequences)

Definition at line 6058 of file daemon.c.

References _, MHD_Daemon::client_discipline, MHD_Connection::daemon, MHD_str_pct_decode_in_place_lenient_(), and MHD_str_pct_decode_in_place_strict_().

Referenced by MHD_start_daemon_va().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ global_init_count

volatile int global_init_count = 0

Track global initialisation

Definition at line 144 of file daemon.c.

Referenced by MHD_check_global_init_().