30#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
31#include "mhd_threads.h"
40#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
48#ifdef MHD_USE_SYS_TSEARCH
56#ifdef MHD_HTTPS_REQUIRE_GCRYPT
61#if defined(_WIN32) && ! defined(__CYGWIN__)
62#ifndef WIN32_LEAN_AND_MEAN
63#define WIN32_LEAN_AND_MEAN 1
68#ifdef MHD_USE_POSIX_THREADS
77#ifdef MHD_POSIX_SOCKETS
78#define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4)
80#define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
86#define MHD_POOL_SIZE_DEFAULT (32 * 1024)
128_MHD_NORETURN
static void
137 _ (
"Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
167#if defined(MHD_WINSOCK_SOCKETS)
171static int mhd_winsock_inited_ = 0;
174#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
179#define MHD_check_global_init_() (void) 0
186#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
187#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
191MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
203#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
204#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
210#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
211#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
225MHD_default_logger_ (
void *cls,
229 vfprintf ((FILE *) cls, fm, ap);
231 fflush ((FILE *) cls);
292 struct in6_addr ipv6;
311#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
327#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
350 offsetof (
struct MHD_IPCount,
366 struct MHD_IPCount *key)
373 if (
sizeof (
struct sockaddr_in) == addrlen)
375 const struct sockaddr_in *addr4 = (
const struct sockaddr_in *) addr;
377 key->family = AF_INET;
378 memcpy (&key->addr.ipv4,
380 sizeof(addr4->sin_addr));
386 if (
sizeof (
struct sockaddr_in6) == addrlen)
388 const struct sockaddr_in6 *addr6 = (
const struct sockaddr_in6 *) addr;
390 key->family = AF_INET6;
391 memcpy (&key->addr.ipv6,
393 sizeof(addr6->sin6_addr));
416 const struct sockaddr *addr,
419 struct MHD_IPCount *key;
429 if (
NULL == (key = malloc (
sizeof(*key))))
450 _ (
"Failed to add IP connection count node.\n"));
460 key = (
struct MHD_IPCount *) node;
482 const struct sockaddr *addr,
485 struct MHD_IPCount search_key;
486 struct MHD_IPCount *found_key;
508 MHD_PANIC (
_ (
"Failed to find previously-added IP address.\n"));
510 found_key = (
struct MHD_IPCount *) *nodep;
512 if (0 == found_key->count)
514 MHD_PANIC (
_ (
"Previously-added IP address had counter of zero.\n"));
517 if (0 == --found_key->count)
537MHD_init_daemon_certificate (
struct MHD_Daemon *daemon)
543#if GNUTLS_VERSION_MAJOR >= 3
544 if (
NULL != daemon->cert_callback)
546 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
547 daemon->cert_callback);
550#if GNUTLS_VERSION_NUMBER >= 0x030603
551 else if (
NULL != daemon->cert_callback2)
553 gnutls_certificate_set_retrieve_function3 (daemon->x509_cred,
554 daemon->cert_callback2);
558 if (
NULL != daemon->https_mem_trust)
561 paramlen = strlen (daemon->https_mem_trust);
566 _ (
"Too long trust certificate.\n"));
570 cert.data = (
unsigned char *) daemon->https_mem_trust;
571 cert.size = (
unsigned int) paramlen;
572 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
574 GNUTLS_X509_FMT_PEM) < 0)
578 _ (
"Bad trust certificate format.\n"));
584 if (daemon->have_dhparams)
586 gnutls_certificate_set_dh_params (daemon->x509_cred,
587 daemon->https_mem_dhparams);
590 if ( (
NULL != daemon->https_mem_cert) &&
591 (
NULL != daemon->https_mem_key) )
596 param1len = strlen (daemon->https_mem_key);
597 param2len = strlen (daemon->https_mem_cert);
603 _ (
"Too long key or certificate.\n"));
607 key.data = (
unsigned char *) daemon->https_mem_key;
608 key.size = (
unsigned int) param1len;
609 cert.data = (
unsigned char *) daemon->https_mem_cert;
610 cert.size = (
unsigned int) param2len;
612 if (
NULL != daemon->https_key_password)
614#if GNUTLS_VERSION_NUMBER >= 0x030111
615 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
619 daemon->https_key_password,
624 _ (
"Failed to setup x509 certificate/key: pre 3.X.X version " \
625 "of GnuTLS does not support setting key password.\n"));
631 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
634 GNUTLS_X509_FMT_PEM);
638 _ (
"GnuTLS failed to setup x509 certificate/key: %s\n"),
639 gnutls_strerror (ret));
643#if GNUTLS_VERSION_MAJOR >= 3
644 if (
NULL != daemon->cert_callback)
647#if GNUTLS_VERSION_NUMBER >= 0x030603
648 else if (
NULL != daemon->cert_callback2)
653 _ (
"You need to specify a certificate and key location.\n"));
668 switch (daemon->cred_type)
670 case GNUTLS_CRD_CERTIFICATE:
672 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
673 return GNUTLS_E_MEMORY_ERROR;
674 return MHD_init_daemon_certificate (daemon);
677 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
678 return GNUTLS_E_MEMORY_ERROR;
683 _ (
"Error: invalid credentials type %d specified.\n"),
730 fd_set *write_fd_set,
731 fd_set *except_fd_set,
743#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
757urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
762 unsigned int fd_setsize)
764 const MHD_socket conn_sckt = urh->connection->socket_fd;
772 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
778 if ( (0 != urh->out_buffer_used) &&
787 ((0 != urh->in_buffer_size) ||
788 (0 != urh->out_buffer_size) ||
789 (0 != urh->out_buffer_used)))
797 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
803 if ( (0 != urh->in_buffer_used) &&
812 ((0 != urh->out_buffer_size) ||
813 (0 != urh->in_buffer_size) ||
814 (0 != urh->in_buffer_used)))
835urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
840 const MHD_socket conn_sckt = urh->connection->socket_fd;
851 if (FD_ISSET (conn_sckt, rs))
853 if (FD_ISSET (conn_sckt, ws))
855 if (FD_ISSET (conn_sckt, es))
860 if (FD_ISSET (mhd_sckt, rs))
862 if (FD_ISSET (mhd_sckt, ws))
864 if (FD_ISSET (mhd_sckt, es))
881urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
887 if (urh->in_buffer_used < urh->in_buffer_size)
888 p[0].events |= POLLIN;
889 if (0 != urh->out_buffer_used)
890 p[0].events |= POLLOUT;
895 ((0 != urh->in_buffer_size) ||
896 (0 != urh->out_buffer_size) ||
897 (0 != urh->out_buffer_used)))
898 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
900 if (urh->out_buffer_used < urh->out_buffer_size)
901 p[1].events |= POLLIN;
902 if (0 != urh->in_buffer_used)
903 p[1].events |= POLLOUT;
908 ((0 != urh->out_buffer_size) ||
909 (0 != urh->in_buffer_size) ||
910 (0 != urh->in_buffer_used)))
911 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
922urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
925 p[0].fd = urh->connection->socket_fd;
926 p[1].fd = urh->mhd.socket;
927 urh_update_pollfd (urh,
938urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
947 if (0 != (p[0].revents & POLLIN))
949 if (0 != (p[0].revents & POLLOUT))
951 if (0 != (p[0].revents & POLLHUP))
953 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
955 if (0 != (p[1].revents & POLLIN))
957 if (0 != (p[1].revents & POLLOUT))
959 if (0 != (p[1].revents & POLLHUP))
961 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
987 fd_set *write_fd_set,
988 fd_set *except_fd_set,
990 unsigned int fd_setsize)
1026#ifdef MHD_POSIX_SOCKETS
1039#ifdef MHD_POSIX_SOCKETS
1047 if ( (
NULL == except_fd_set) ||
1059#ifdef MHD_WINSOCK_SOCKETS
1072#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1074 struct MHD_UpgradeResponseHandle *urh;
1076 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
1089#if _MHD_DEBUG_CONNECT
1093 _ (
"Maximum socket in select set: %d\n"),
1137 fd_set *read_fd_set,
1138 fd_set *write_fd_set,
1139 fd_set *except_fd_set,
1141 unsigned int fd_setsize)
1145 if ( (
NULL == daemon) ||
1146 (
NULL == read_fd_set) ||
1147 (
NULL == write_fd_set) ||
1152 if (
NULL == except_fd_set)
1156 _ (
"MHD_get_fdset2() called with except_fd_set "
1157 "set to NULL. Such behavior is unsupported.\n"));
1160 except_fd_set = &es;
1208 bool states_info_processed =
false;
1218 (read_ready || (force_close && con->
sk_nonblck)) )
1225 states_info_processed =
true;
1236 states_info_processed =
true;
1246 if (! states_info_processed)
1303#ifdef UPGRADE_SUPPORT
1314 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1322 gnutls_bye (connection->tls_session,
1331 connection->urh =
NULL;
1339#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1349process_urh (
struct MHD_UpgradeResponseHandle *urh)
1362#ifdef MHD_USE_THREADS
1364 MHD_thread_ID_match_current_ (connection->
pid) );
1370 if (! urh->was_closed)
1374 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1377 urh->was_closed =
true;
1379 was_closed = urh->was_closed;
1384 if (0 < urh->in_buffer_used)
1388 _ (
"Failed to forward to application "
1390 " bytes of data received from remote side: application shut down socket.\n"),
1391 (uint64_t) urh->in_buffer_used);
1400 if (0 != urh->out_buffer_size)
1403 urh->in_buffer_used = 0;
1407 urh->in_buffer_size = 0;
1429 (urh->in_buffer_used < urh->in_buffer_size) )
1434 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1439 res = gnutls_record_recv (connection->tls_session,
1440 &urh->in_buffer[urh->in_buffer_used],
1444 if (GNUTLS_E_INTERRUPTED != res)
1447 if (GNUTLS_E_AGAIN != res)
1452 urh->in_buffer_size = 0;
1458 urh->in_buffer_used += res;
1459 if (0 < gnutls_record_check_pending (connection->tls_session))
1470 urh->in_buffer_size = 0;
1478 (urh->out_buffer_used < urh->out_buffer_size) )
1483 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1488 &urh->out_buffer[urh->out_buffer_used],
1507 urh->out_buffer_size = 0;
1513 urh->out_buffer_used += res;
1514 if (buf_size > (
size_t) res)
1524 urh->out_buffer_size = 0;
1532 (urh->out_buffer_used > 0) )
1537 data_size = urh->out_buffer_used;
1541 res = gnutls_record_send (connection->tls_session,
1546 if (GNUTLS_E_INTERRUPTED != res)
1549 if (GNUTLS_E_AGAIN != res)
1556 "Failed to forward to remote client "
1558 " bytes of data received from application: %s\n"),
1559 (uint64_t) urh->out_buffer_used,
1560 gnutls_strerror (res));
1563 urh->out_buffer_used = 0;
1565 urh->out_buffer_size = 0;
1572 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1573 if (0 != next_out_buffer_used)
1575 memmove (urh->out_buffer,
1576 &urh->out_buffer[res],
1577 next_out_buffer_used);
1578 if (data_size > (
size_t) res)
1581 urh->out_buffer_used = next_out_buffer_used;
1583 if ( (0 == urh->out_buffer_used) &&
1591 urh->out_buffer_size = 0;
1600 (urh->in_buffer_used > 0) )
1605 data_size = urh->in_buffer_used;
1626 "Failed to forward to application "
1628 " bytes of data received from remote side: %s\n"),
1629 (uint64_t) urh->in_buffer_used,
1633 urh->in_buffer_used = 0;
1635 urh->in_buffer_size = 0;
1643 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1644 if (0 != next_in_buffer_used)
1646 memmove (urh->in_buffer,
1647 &urh->in_buffer[res],
1648 next_in_buffer_used);
1649 if (data_size > (
size_t) res)
1652 urh->in_buffer_used = next_in_buffer_used;
1654 if ( (0 == urh->in_buffer_used) &&
1660 urh->in_buffer_size = 0;
1669 (urh->in_buffer_used < urh->in_buffer_size) &&
1674 ( (0 != urh->out_buffer_size) ||
1675 (0 != urh->out_buffer_used) ) )
1679 if (0 < urh->out_buffer_used)
1682 "Failed to forward to remote client "
1684 " bytes of data received from application: daemon shut down.\n"),
1685 (uint64_t) urh->out_buffer_used);
1688 urh->out_buffer_used = 0;
1692 urh->out_buffer_size = 0;
1700#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1701#ifdef UPGRADE_SUPPORT
1714 struct MHD_UpgradeResponseHandle *urh = con->urh;
1718 MHD_thread_ID_match_current_ (con->
pid) );
1725 while ( (0 != urh->in_buffer_size) ||
1726 (0 != urh->out_buffer_size) ||
1727 (0 != urh->in_buffer_used) ||
1728 (0 != urh->out_buffer_used) )
1742 result = urh_to_fdset (urh,
1752 _ (
"Error preparing select.\n"));
1759 struct timeval *tvp;
1762 (urh->in_buffer_used < urh->in_buffer_size)) ||
1787 _ (
"Error during select (%d): `%s'\n"),
1793 urh_from_fdset (urh,
1808 p[0].fd = urh->connection->socket_fd;
1809 p[1].fd = urh->mhd.socket;
1811 while ( (0 != urh->in_buffer_size) ||
1812 (0 != urh->out_buffer_size) ||
1813 (0 != urh->in_buffer_used) ||
1814 (0 != urh->out_buffer_used) )
1818 urh_update_pollfd (urh, p);
1821 (urh->in_buffer_used < urh->in_buffer_size)) ||
1827 if (MHD_sys_poll_ (p,
1837 _ (
"Error during poll: `%s'\n"),
1842 urh_from_pollfd (urh,
1874 uint64_t mseconds_left;
1879 if (timeout < since_actv)
1886 if (5000 >= jump_back)
1894 else if (since_actv == timeout)
1903 mseconds_left = timeout - since_actv;
1905 return mseconds_left;
1916static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1927 struct timeval *tvp;
1932#define EXTRA_SLOTS 1
1934#define EXTRA_SLOTS 0
1943 const bool use_poll = 0;
1945 bool was_suspended =
false;
1946 MHD_thread_init_ (&(con->
pid));
1951#ifdef UPGRADE_SUPPORT
1952 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1954 static const void *
const urh =
NULL;
1961 was_suspended =
true;
1970 #ifdef HAVE_MESSAGES
1972 _ (
"Failed to add FD to fd_set.\n"));
1988 _ (
"Error during select (%d): `%s'\n"),
1998 p[0].events = POLLIN;
1999 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
2001 if (0 > MHD_sys_poll_ (p,
2009 _ (
"Error during poll: `%s'\n"),
2016 MHD_itc_clear_ (daemon->
itc);
2025 was_suspended =
false;
2043 if ( (
NULL == tvp) &&
2046 const uint64_t mseconds_left = connection_get_wait (con);
2047#if (SIZEOF_UINT64_T - 2) >= SIZEOF_STRUCT_TIMEVAL_TV_SEC
2054 tv.tv_usec = (mseconds_left % 1000) * 1000;
2061 bool err_state =
false;
2095 if (MHD_ITC_IS_VALID_ (daemon->
itc) )
2108 _ (
"Failed to add FD to fd_set.\n"));
2126 _ (
"Error during select (%d): `%s'\n"),
2135 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2136 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
2138 MHD_itc_clear_ (daemon->
itc);
2161 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2164 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2167 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2175 if (MHD_ITC_IS_VALID_ (daemon->
itc))
2177 p[1].events |= POLLIN;
2178 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2183 if (MHD_sys_poll_ (p,
2189 (
NULL == tvp) ? -1 : (tv.tv_sec * 1000)) < 0)
2195 _ (
"Error during poll: `%s'\n"),
2203 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2204 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2205 MHD_itc_clear_ (daemon->
itc);
2209 (0 != (p[0].revents & POLLIN)),
2210 (0 != (p[0].revents & POLLOUT)),
2211 (0 != (p[0].revents & MHD_POLL_REVENTS_ERR_DISC)) ))
2215#ifdef UPGRADE_SUPPORT
2216 if (MHD_CONNECTION_UPGRADE == con->
state)
2228 thread_main_connection_upgrade (con);
2232 con->urh->clean_ready =
true;
2240 return (MHD_THRD_RTRN_TYPE_) 0;
2247 _ (
"Processing thread terminating. Closing connection.\n"));
2271 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2272 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2277 "Failed to signal thread termination via inter-thread communication channel.\n"));
2280 return (MHD_THRD_RTRN_TYPE_) 0;
2297#if defined(HTTPS_SUPPORT)
2298#if defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED) && \
2299 defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) && \
2300 ! defined(MHD_socket_nosignal_) && \
2301 (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL)
2307#define MHD_TLSLIB_NEED_PUSH_FUNC 1
2313#ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2319MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp,
2323#if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2343psk_gnutls_adapter (gnutls_session_t session,
2344 const char *username,
2345 gnutls_datum_t *key)
2349#if GNUTLS_VERSION_MAJOR >= 3
2351 size_t app_psk_size;
2354 connection = gnutls_session_get_ptr (session);
2355 if (
NULL == connection)
2359 MHD_PANIC (
_ (
"Internal server error. This should be impossible.\n"));
2363 daemon = connection->
daemon;
2364#if GNUTLS_VERSION_MAJOR >= 3
2365 if (
NULL == daemon->cred_callback)
2369 _ (
"PSK not supported by this server.\n"));
2373 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2379 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2384 "PSK authentication failed: gnutls_malloc failed to allocate memory.\n"));
2393 _ (
"PSK authentication failed: PSK too long.\n"));
2398 key->size = (
unsigned int) app_psk_size;
2405 (void) username; (void) key;
2408 _ (
"PSK not supported by this server.\n"));
2443 const struct sockaddr *
addr,
2447 bool sk_spipe_supprs,
2454#if _MHD_DEBUG_CONNECT
2456 _ (
"Accepted connection on socket %d.\n"),
2469 "Server reached connection limit. Closing inbound connection.\n"));
2487 _ (
"Connection rejected by application. Closing connection.\n"));
2505 _ (
"Error allocating memory: %s\n"),
2527 if (
NULL == (connection->
addr = malloc (addrlen)))
2532 _ (
"Error allocating memory: %s\n"),
2543 memcpy (connection->
addr,
2549 connection->
is_nonip = sk_is_nonip;
2564#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500)
2571 flags = GNUTLS_SERVER;
2572#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402)
2573 flags |= GNUTLS_NO_SIGNAL;
2575#if GNUTLS_VERSION_MAJOR >= 3
2576 flags |= GNUTLS_NONBLOCK;
2578#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603)
2580 flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2582#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605)
2584 flags |= GNUTLS_ENABLE_EARLY_DATA;
2588 if ((GNUTLS_E_SUCCESS != gnutls_init (&connection->tls_session, flags)) ||
2589 (GNUTLS_E_SUCCESS != gnutls_priority_set (connection->tls_session,
2590 daemon->priority_cache)))
2592 if (
NULL != connection->tls_session)
2593 gnutls_deinit (connection->tls_session);
2598 free (connection->
addr);
2602 _ (
"Failed to initialise TLS session.\n"));
2609#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030200)
2610 if (!
daemon->disable_alpn)
2612 gnutls_datum_t prts[2];
2613 const char prt1[] =
"http/1.1";
2614 const char prt2[] =
"http/1.0";
2616 prts[0].data = (
void *) prt1;
2618 prts[1].data = (
void *) prt2;
2620 if (GNUTLS_E_SUCCESS !=
2621 gnutls_alpn_set_protocols (connection->tls_session,
2623 sizeof(prts) /
sizeof(prts[0]),
2628 _ (
"Failed to set ALPN protocols.\n"));
2635 gnutls_session_set_ptr (connection->tls_session,
2637 switch (
daemon->cred_type)
2640 case GNUTLS_CRD_CERTIFICATE:
2641 gnutls_credentials_set (connection->tls_session,
2642 GNUTLS_CRD_CERTIFICATE,
2645 case GNUTLS_CRD_PSK:
2646 gnutls_credentials_set (connection->tls_session,
2649 gnutls_psk_set_server_credentials_function (
daemon->psk_cred,
2650 &psk_gnutls_adapter);
2656 "Failed to setup TLS credentials: unknown credential type %d.\n"),
2659 gnutls_deinit (connection->tls_session);
2664 free (connection->
addr);
2666 MHD_PANIC (
_ (
"Unknown credential type.\n"));
2672#if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64)
2673 gnutls_transport_set_int (connection->tls_session,
2674 (
int) (client_socket));
2676 gnutls_transport_set_ptr (connection->tls_session,
2677 (gnutls_transport_ptr_t) (intptr_t) (client_socket));
2679#ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2680 gnutls_transport_set_push_function (connection->tls_session,
2681 MHD_tls_push_func_);
2683 if (
daemon->https_mem_trust)
2684 gnutls_certificate_server_set_request (connection->tls_session,
2685 GNUTLS_CERT_REQUEST);
2691 free (connection->
addr);
2693 MHD_PANIC (
_ (
"TLS connection on non-TLS daemon.\n"));
2706#ifdef MHD_USE_THREADS
2725 if (
NULL != connection->tls_session)
2728 gnutls_deinit (connection->tls_session);
2735 free (connection->
addr);
2761#ifdef MHD_USE_THREADS
2765 MHD_thread_ID_match_current_ (
daemon->
pid) );
2777 _ (
"Error allocating memory: %s\n"),
2793 _ (
"Server reached connection limit. "
2794 "Closing inbound connection.\n"));
2819#ifdef MHD_USE_THREADS
2825 daemon->thread_stack_size,
2834 _ (
"Failed to create a new thread because it would "
2835 "have exceeded the system limit on the number of "
2836 "threads or no system resources available.\n"));
2840 _ (
"Failed to create a thread: %s\n"),
2852#ifdef MHD_USE_THREADS
2860 struct epoll_event event;
2862 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2863 event.data.ptr = connection;
2864 if (0 != epoll_ctl (daemon->epoll_fd,
2872 _ (
"Call to epoll_ctl failed: %s\n"),
2889 daemon->eready_tail,
2923 if (
NULL != connection->tls_session)
2924 gnutls_deinit (connection->tls_session);
2929 free (connection->
addr);
2973 const struct sockaddr *addr,
2977 bool sk_spipe_supprs,
2982#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2992 _ (
"New connection socket descriptor (%d) is not less " \
2993 "than FD_SETSIZE (%d).\n"),
2994 (
int) client_socket,
3009 _ (
"Epoll mode supports only non-blocking sockets\n"));
3025 if (
NULL == connection)
3028 if ((external_add) &&
3041 if ((MHD_ITC_IS_VALID_ (
daemon->
itc)) &&
3042 (! MHD_itc_activate_ (
daemon->
itc,
"n")))
3044 #ifdef HAVE_MESSAGES
3046 _ (
"Failed to signal new connection via inter-thread " \
3047 "communication channel.\n"));
3091 _ (
"Failed to start serving new connection.\n"));
3095 }
while (
NULL != local_tail);
3114#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3117 MHD_thread_ID_match_current_ (daemon->
pid) );
3124#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3154 daemon->eready_tail,
3156 connection->epoll_state &=
3161 if (0 != epoll_ctl (daemon->epoll_fd,
3165 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
3166 connection->epoll_state &=
3172#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3215#ifdef MHD_USE_THREADS
3218 MHD_thread_ID_match_current_ (daemon->
pid) );
3223 "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
3224#ifdef UPGRADE_SUPPORT
3225 if (
NULL != connection->urh)
3230 "Error: connection scheduled for \"upgrade\" cannot be suspended.\n"));
3254 "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
3255#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3260#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3263 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3264 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
3269 "Failed to signal resume via inter-thread communication channel.\n"));
3275#ifdef UPGRADE_SUPPORT
3284MHD_upgraded_connection_mark_app_closed_ (
struct MHD_Connection *connection)
3288#if defined(MHD_USE_THREADS)
3295 connection->urh->was_closed =
true;
3299 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3300 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
3304 _ (
"Failed to signal resume via " \
3305 "inter-thread communication channel.\n"));
3330#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3333 MHD_thread_ID_match_current_ (
daemon->
pid) );
3337#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3353#ifdef UPGRADE_SUPPORT
3354 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
3356 static const void *
const urh =
NULL;
3360#ifdef UPGRADE_SUPPORT
3361 || ( (
NULL != urh) &&
3362 ( (! urh->was_closed) ||
3363 (! urh->clean_ready) ) )
3397 MHD_PANIC (
"Resumed connection was already in EREADY set.\n");
3401 daemon->eready_tail,
3410#ifdef UPGRADE_SUPPORT
3435#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3438 if ( (used_thr_p_c) &&
3441 if (! MHD_itc_activate_ (daemon->
itc,
3447 "Failed to signal resume of connection via inter-thread communication channel.\n"));
3485 const struct sockaddr *addr,
3489 bool sk_spipe_supprs;
3501 _ (
"MHD_add_connection() has been called for daemon started"
3502 " without MHD_USE_ITC flag.\nDaemon will not process newly"
3503 " added connection until any activity occurs in already"
3504 " added sockets.\n"));
3512 _ (
"Failed to set nonblocking mode on new client socket: %s\n"),
3520#ifndef MHD_WINSOCK_SOCKETS
3521 sk_spipe_supprs =
false;
3523 sk_spipe_supprs =
true;
3525#if defined(MHD_socket_nosignal_)
3526 if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (client_socket))
3531 "Failed to suppress SIGPIPE on new client socket: %s\n"),
3549 sk_spipe_supprs =
true;
3557 _ (
"Failed to set noninheritable mode on new client socket.\n"));
3561#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3620 struct sockaddr_in6 addrstorage;
3622 struct sockaddr_in addrstorage;
3624 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3629 bool sk_spipe_supprs;
3632#ifdef MHD_USE_THREADS
3634 MHD_thread_ID_match_current_ (daemon->
pid) );
3637 addrlen =
sizeof (addrstorage);
3640 sizeof (addrstorage));
3651#ifndef MHD_WINSOCK_SOCKETS
3654 sk_spipe_supprs =
true;
3661#ifdef MHD_ACCEPT_INHERIT_NONBLOCK
3666#ifndef MHD_WINSOCK_SOCKETS
3667 sk_spipe_supprs =
false;
3669 sk_spipe_supprs =
true;
3687 _ (
"Error accepting connection: %s\n"),
3704 _ (
"Hit process or system resource limit at FIRST " \
3705 "connection. This is really bad as there is no sane " \
3706 "way to proceed. Will try busy waiting for system " \
3707 "resources to become magically available.\n"));
3712#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3716#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3721 _ (
"Hit process or system resource limit at %u " \
3722 "connections, temporarily suspending accept(). " \
3723 "Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3735 _ (
"Failed to set nonblocking mode on incoming connection " \
3749 _ (
"Failed to set noninheritable mode on incoming connection " \
3756#if defined(MHD_socket_nosignal_)
3757 if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s))
3761 _ (
"Failed to suppress SIGPIPE on incoming connection " \
3778 sk_spipe_supprs =
true;
3781#if _MHD_DEBUG_CONNECT
3783 _ (
"Accepted connection on socket %d\n"),
3812#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3814 MHD_thread_ID_match_current_ (
daemon->
pid) );
3823#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3827 (! MHD_join_thread_ (pos->
pid.handle)) )
3828 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
3830#ifdef UPGRADE_SUPPORT
3831 cleanup_upgraded_connection (pos);
3835 if (
NULL != pos->tls_session)
3836 gnutls_deinit (pos->tls_session);
3859 if ( (-1 !=
daemon->epoll_fd) &&
3868 if (0 != epoll_ctl (
daemon->epoll_fd,
3873 "Failed to remove FD from epoll set.\n"));
3891#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3897#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3939 uint64_t earliest_deadline;
3943#ifdef MHD_USE_THREADS
3945 MHD_thread_ID_match_current_ (
daemon->
pid) );
3952 _ (
"Illegal call to MHD_get_timeout.\n"));
3965#
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3976 earliest_tmot_conn =
NULL;
3977 earliest_deadline = 0;
3980 if ( (
NULL != pos) &&
3983 earliest_tmot_conn = pos;
3991 if ( (
NULL == earliest_tmot_conn) ||
3995 earliest_tmot_conn = pos;
4001 if (
NULL != earliest_tmot_conn)
4003 const uint64_t mssecond_left = connection_get_wait (earliest_tmot_conn);
4004#if SIZEOF_UINT64_T > SIZEOF_UNSIGNED_LONG_LONG
4009 *timeout = (
unsigned long long) mssecond_left;
4016#if defined(HAVE_POLL) || defined(EPOLL_SUPPORT)
4029 int32_t max_timeout)
4032 if (0 == max_timeout)
4036 return (INT_MAX <= max_timeout) ? INT_MAX : (int) max_timeout;
4038 if ( (0 > max_timeout) ||
4039 ((uint32_t) max_timeout > ulltimeout) )
4040 return (INT_MAX <= ulltimeout) ? INT_MAX : (int) ulltimeout;
4042 return (INT_MAX <= max_timeout) ? INT_MAX : (int) max_timeout;
4060 const fd_set *read_fd_set,
4061 const fd_set *write_fd_set,
4062 const fd_set *except_fd_set)
4067#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4068 struct MHD_UpgradeResponseHandle *urh;
4069 struct MHD_UpgradeResponseHandle *urhn;
4078 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
4079 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
4081 MHD_itc_clear_ (daemon->
itc);
4098 while (
NULL != (pos = prev))
4114#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4116 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
4120 urh_from_fdset (urh,
4127 if ( (0 == urh->in_buffer_size) &&
4128 (0 == urh->out_buffer_size) &&
4129 (0 == urh->in_buffer_used) &&
4130 (0 == urh->out_buffer_used) )
4133 urh->clean_ready =
true;
4172 const fd_set *read_fd_set,
4173 const fd_set *write_fd_set,
4174 const fd_set *except_fd_set)
4180 if ((
NULL == read_fd_set) || (
NULL == write_fd_set))
4182 if (
NULL == except_fd_set)
4186 _ (
"MHD_run_from_select() called with except_fd_set "
4187 "set to NULL. Such behavior is deprecated.\n"));
4190 except_fd_set = &es;
4235 struct timeval timeout;
4241 timeout.tv_usec = 0;
4267 _ (
"Could not obtain daemon fdsets.\n"));
4284 _ (
"Could not add listen socket to fdset.\n"));
4289 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
4297 retry_succeed =
false;
4298#if defined(MHD_WINSOCK_SOCKETS)
4311 retry_succeed =
true;
4315 if (! retry_succeed)
4319 _ (
"Could not add control inter-thread communication " \
4320 "channel FD to fdset.\n"));
4332 (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
4345 timeout.tv_usec = 0;
4357 if ( (0 < millisec) &&
4361 else if (0 < millisec)
4372 timeout.tv_usec = 0;
4377 timeout.tv_usec = (ltimeout % 1000) * 1000;
4395 _ (
"select failed: %s\n"),
4424 unsigned int num_connections;
4427#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4428 struct MHD_UpgradeResponseHandle *urh;
4429 struct MHD_UpgradeResponseHandle *urhn;
4437 num_connections = 0;
4440#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4441 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
4442 num_connections += 2;
4447 unsigned int poll_server;
4454 sizeof (
struct pollfd));
4459 _ (
"Error allocating memory: %s\n"),
4472 p[poll_server].fd = ls;
4473 p[poll_server].events = POLLIN;
4474 p[poll_server].revents = 0;
4475 poll_listen = (int) poll_server;
4479 if (MHD_ITC_IS_VALID_ (daemon->
itc))
4481 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
4482 p[poll_server].events = POLLIN;
4483 p[poll_server].revents = 0;
4484 poll_itc_idx = (int) poll_server;
4488 timeout = get_timeout_millisec_ (daemon, millisec);
4497 p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
4500 p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
4503 p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
4511#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4512 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
4514 urh_to_pollfd (urh, &(p[poll_server + i]));
4518 if (0 == poll_server + num_connections)
4523 if (MHD_sys_poll_ (p,
4524 poll_server + num_connections,
4535 _ (
"poll failed: %s\n"),
4545 if ( (-1 != poll_itc_idx) &&
4546 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4547 MHD_itc_clear_ (daemon->
itc);
4561 if ( (-1 != poll_listen) &&
4562 (0 != (p[poll_listen].revents & POLLIN)) )
4570 while (
NULL != (pos = prev))
4574 if (i >= num_connections)
4579 0 != (p[poll_server + i].revents & POLLIN),
4580 0 != (p[poll_server + i].revents & POLLOUT),
4581 0 != (p[poll_server + i].revents
4582 & MHD_POLL_REVENTS_ERR_DISC));
4585#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4586 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
4588 if (i >= num_connections)
4595 if ((p[poll_server + i].
fd != urh->connection->socket_fd) ||
4596 (p[poll_server + i + 1].fd != urh->mhd.socket))
4598 urh_from_pollfd (urh,
4599 &p[poll_server + i]);
4603 if ( (0 == urh->in_buffer_size) &&
4604 (0 == urh->out_buffer_size) &&
4605 (0 == urh->in_buffer_used) &&
4606 (0 == urh->out_buffer_used) )
4611 urh->clean_ready =
true;
4635MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
4640 unsigned int poll_count;
4655 p[poll_count].fd = ls;
4656 p[poll_count].events = POLLIN;
4657 p[poll_count].revents = 0;
4658 poll_listen = poll_count;
4661 if (MHD_ITC_IS_VALID_ (daemon->
itc))
4663 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
4664 p[poll_count].events = POLLIN;
4665 p[poll_count].revents = 0;
4666 poll_itc_idx = poll_count;
4677 if (0 == poll_count)
4679 if (MHD_sys_poll_ (p,
4689 _ (
"poll failed: %s\n"),
4694 if ( (-1 != poll_itc_idx) &&
4695 (0 != (p[poll_itc_idx].revents & POLLIN)) )
4696 MHD_itc_clear_ (daemon->
itc);
4706 if ( (-1 != poll_listen) &&
4707 (0 != (p[poll_listen].revents & POLLIN)) )
4731 return MHD_poll_all (daemon,
4732 may_block ? -1 : 0);
4733 return MHD_poll_listen_socket (daemon,
4753#define MAX_EVENTS 128
4756#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4766is_urh_ready (
struct MHD_UpgradeResponseHandle *
const urh)
4770 if ( (0 == urh->in_buffer_size) &&
4771 (0 == urh->out_buffer_size) &&
4772 (0 == urh->in_buffer_used) &&
4773 (0 == urh->out_buffer_used) )
4779 (urh->in_buffer_used < urh->in_buffer_size) )
4782 (urh->out_buffer_used < urh->out_buffer_size) )
4785 (urh->out_buffer_used > 0) )
4788 (urh->in_buffer_used > 0) )
4805 struct epoll_event events[MAX_EVENTS];
4807 struct MHD_UpgradeResponseHandle *pos;
4808 struct MHD_UpgradeResponseHandle *prev;
4810#ifdef MHD_USE_THREADS
4812 MHD_thread_ID_match_current_ (daemon->
pid) );
4815 num_events = MAX_EVENTS;
4816 while (0 != num_events)
4820 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4824 if (-1 == num_events)
4832 _ (
"Call to epoll_wait failed: %s\n"),
4837 for (i = 0; i < (
unsigned int) num_events; i++)
4839 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4840 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4841 bool new_err_state =
false;
4843 if (urh->clean_ready)
4847 if (0 != (events[i].events & EPOLLIN))
4851 if (0 != (events[i].events & EPOLLOUT))
4855 if (0 != (events[i].events & EPOLLHUP))
4861 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4866 new_err_state =
true;
4868 if (! urh->in_eready_list)
4870 if (new_err_state ||
4874 daemon->eready_urh_tail,
4876 urh->in_eready_list =
true;
4881 prev = daemon->eready_urh_tail;
4882 while (
NULL != (pos = prev))
4886 if (! is_urh_ready (pos))
4889 daemon->eready_urh_tail,
4891 pos->in_eready_list =
false;
4894 if ( (0 == pos->in_buffer_size) &&
4895 (0 == pos->out_buffer_size) &&
4896 (0 == pos->in_buffer_used) &&
4897 (0 == pos->out_buffer_used) )
4900 pos->clean_ready =
true;
4919static const char *
const epoll_itc_marker =
"itc_marker";
4935#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4936 static const char *
const upgrade_marker =
"upgrade_ptr";
4940 struct epoll_event events[MAX_EVENTS];
4941 struct epoll_event event;
4946#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4947 bool run_upgraded =
false;
4949 bool need_to_accept;
4951 if (-1 == daemon->epoll_fd)
4958 (! daemon->listen_socket_in_epoll) &&
4961 event.events = EPOLLIN;
4962 event.data.ptr = daemon;
4963 if (0 != epoll_ctl (daemon->epoll_fd,
4970 _ (
"Call to epoll_ctl failed: %s\n"),
4975 daemon->listen_socket_in_epoll =
true;
4978 (daemon->listen_socket_in_epoll) )
4980 if ( (0 != epoll_ctl (daemon->epoll_fd,
4986 MHD_PANIC (
"Failed to remove listen FD from epoll set.\n");
4987 daemon->listen_socket_in_epoll =
false;
4990#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4991 if ( ( (! daemon->upgrade_fd_in_epoll) &&
4992 (-1 != daemon->epoll_upgrade_fd) ) )
4994 event.events = EPOLLIN | EPOLLOUT;
4995 event.data.ptr = (
void *) upgrade_marker;
4996 if (0 != epoll_ctl (daemon->epoll_fd,
4998 daemon->epoll_upgrade_fd,
5003 _ (
"Call to epoll_ctl failed: %s\n"),
5008 daemon->upgrade_fd_in_epoll =
true;
5011 if ( (daemon->listen_socket_in_epoll) &&
5018 if (0 != epoll_ctl (daemon->epoll_fd,
5022 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set.\n"));
5023 daemon->listen_socket_in_epoll =
false;
5030 timeout_ms = get_timeout_millisec_ (daemon, millisec);
5037 need_to_accept =
false;
5042 num_events = MAX_EVENTS;
5043 while (MAX_EVENTS == num_events)
5046 num_events = epoll_wait (daemon->epoll_fd,
5050 if (-1 == num_events)
5057 _ (
"Call to epoll_wait failed: %s\n"),
5062 for (i = 0; i < (
unsigned int) num_events; i++)
5068#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5069 if (upgrade_marker == events[i].
data.ptr)
5073 run_upgraded =
true;
5077 if (epoll_itc_marker == events[i].
data.ptr)
5081 MHD_itc_clear_ (daemon->
itc);
5084 if (daemon == events[i].
data.ptr)
5088 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
5089 need_to_accept =
true;
5095 pos = events[i].data.ptr;
5097 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
5103 daemon->eready_tail,
5110 if (0 != (events[i].events & EPOLLIN))
5118 daemon->eready_tail,
5123 if (0 != (events[i].events & EPOLLOUT))
5130 daemon->eready_tail,
5145 unsigned int series_length = 0;
5152 (series_length < 10) &&
5167 while (
NULL != (pos = prev))
5177 while (
NULL != (pos = prev))
5185#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5186 if (run_upgraded || (
NULL != daemon->eready_urh_head))
5187 run_epoll_for_upgrade (daemon);
5191 prev = daemon->eready_tail;
5192 while (
NULL != (pos = prev))
5210 daemon->eready_tail,
5320 res = MHD_poll_all (daemon, millisec);
5327 res = MHD_epoll (daemon, millisec);
5353#ifdef MHD_USE_THREADS
5355 MHD_thread_ID_match_current_ (daemon->
pid) );
5365#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5385#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5391#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5399static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
5403#ifdef HAVE_PTHREAD_SIGMASK
5408 MHD_thread_init_ (&(daemon->
pid));
5409#ifdef HAVE_PTHREAD_SIGMASK
5410 if ((0 == sigemptyset (&s_mask)) &&
5411 (0 == sigaddset (&s_mask, SIGPIPE)))
5413 err = pthread_sigmask (SIG_BLOCK, &s_mask,
NULL);
5422 _ (
"Failed to block SIGPIPE on daemon thread: %s\n"),
5432 MHD_epoll (daemon, -1);
5446 return (MHD_THRD_RTRN_TYPE_) 0;
5544#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5558 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC.\n"));
5563#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5573 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
5577 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set.\n"));
5578 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
5586 "Failed to signal quiesce via inter-thread communication channel.\n"));
5593 (-1 != daemon->epoll_fd) &&
5594 (daemon->listen_socket_in_epoll) )
5596 if ( (0 != epoll_ctl (daemon->epoll_fd,
5602 MHD_PANIC (
"Failed to remove listen FD from epoll set.\n");
5603 daemon->listen_socket_in_epoll =
false;
5606 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
5607 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
5609 "failed to signal quiesce via inter-thread communication channel.\n"));
5637 const struct sockaddr **servaddr,
5651 const struct sockaddr **servaddr,
5657 va_start (ap, servaddr);
5676 const struct sockaddr **servaddr,
5685#if GNUTLS_VERSION_MAJOR >= 3
5686 gnutls_certificate_retrieve_function2 *pgcrf;
5688#if GNUTLS_VERSION_NUMBER >= 0x030603
5689 gnutls_certificate_retrieve_function3 *pgcrf2;
5715#if (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT
5720 _ (
"The specified connection timeout (%u) is too large. " \
5721 "Maximum allowed value (%" PRIu64 ") will be used " \
5748 *servaddr = va_arg (ap,
5749 const struct sockaddr *);
5762#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5771 "Warning: Zero size, specified for thread pool size, is ignored. "
5772 "Thread pool is not used.\n"));
5780 "Warning: \"1\", specified for thread pool size, is ignored. "
5781 "Thread pool is not used.\n"));
5785#if SIZEOF_UNSIGNED_INT >= (SIZEOF_SIZE_T - 2)
5794 _ (
"Specified thread pool size (%u) too big.\n"),
5806 _ (
"MHD_OPTION_THREAD_POOL_SIZE option is specified but "
5807 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5815 _ (
"Both MHD_OPTION_THREAD_POOL_SIZE option and "
5816 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5828 daemon->https_mem_key = pstr;
5833 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5841 daemon->https_key_password = pstr;
5846 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5854 daemon->https_mem_cert = pstr;
5859 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5867 daemon->https_mem_trust = pstr;
5872 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5877 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5885 gnutls_datum_t dhpar;
5888 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5892 _ (
"Error initializing DH parameters.\n"));
5896 dhpar.data = (
unsigned char *) pstr;
5897 pstr_len = strlen (pstr);
5902 _ (
"Diffie-Hellman parameters string too long.\n"));
5906 dhpar.size = (
unsigned int) pstr_len;
5907 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5909 GNUTLS_X509_FMT_PEM) < 0)
5913 _ (
"Bad Diffie-Hellman parameters format.\n"));
5915 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5918 daemon->have_dhparams =
true;
5924 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5934 gnutls_priority_deinit (daemon->priority_cache);
5935 init_res = gnutls_priority_init (&daemon->priority_cache,
5938 if (GNUTLS_E_SUCCESS != init_res)
5942 _ (
"Setting priorities to `%s' failed: %s\n"),
5944 gnutls_strerror (init_res));
5946 daemon->priority_cache =
NULL;
5954 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5959#if GNUTLS_VERSION_MAJOR < 3
5963 "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0.\n"));
5968 gnutls_certificate_retrieve_function2 *);
5970 daemon->cert_callback = pgcrf;
5975 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5981#if GNUTLS_VERSION_NUMBER < 0x030603
5985 "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3.\n"));
5989 pgcrf2 = va_arg (ap,
5990 gnutls_certificate_retrieve_function3 *);
5992 daemon->cert_callback2 = pgcrf2;
5997 "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
6005 daemon->digest_auth_rand_size = va_arg (ap,
6007 daemon->digest_auth_random = va_arg (ap,
6011 daemon->nonce_nc_size = va_arg (ap,
6020 _ (
"MHD_OPTION_LISTEN_SOCKET specified for daemon "
6021 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
6029#if defined(SO_DOMAIN) && defined(AF_UNIX)
6032 socklen_t len =
sizeof (af);
6052 daemon->custom_error_log = va_arg (ap,
6054 daemon->custom_error_log_cls = va_arg (ap,
6058 _ (
"MHD_OPTION_EXTERNAL_LOGGER is not the first option "
6059 "specified for the daemon. Some messages may be "
6060 "printed by the standard MHD logger.\n"));
6069#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6071 daemon->thread_stack_size = va_arg (ap,
6077 daemon->fastopen_queue_size = va_arg (ap,
6083 _ (
"TCP fastopen is not supported on this platform.\n"));
6089 unsigned int) ? 1 : -1;
6102 _ (
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
6103 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
6122 (
size_t) oa[i].
value,
6139 (
unsigned int) oa[i].
value,
6149 (gnutls_credentials_type_t) oa[i].
value,
6202 (
void *) oa[i].
value,
6212 (
size_t) oa[i].
value,
6231#if GNUTLS_VERSION_MAJOR >= 3
6232 daemon->cred_callback = va_arg (ap,
6234 daemon->cred_callback_cls = va_arg (ap,
6240 "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3.\n"),
6257 daemon->disable_alpn = (va_arg (ap,
6260 (void) va_arg (ap,
int);
6265 _ (
"MHD HTTPS option %d passed to MHD " \
6266 "but MHD_USE_TLS not set.\n"),
6279 "MHD HTTPS option %d passed to MHD compiled without HTTPS support.\n"),
6286 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?).\n"),
6303#ifndef HAVE_MESSAGES
6307#ifdef USE_EPOLL_CREATE1
6308 fd = epoll_create1 (EPOLL_CLOEXEC);
6310 fd = epoll_create (MAX_EVENTS);
6316 _ (
"Call to epoll_create1 failed: %s\n"),
6321#if ! defined(USE_EPOLL_CREATE1)
6326 _ (
"Failed to set noninheritable mode on epoll FD.\n"));
6343setup_epoll_to_listen (
struct MHD_Daemon *daemon)
6345 struct epoll_event event;
6352 MHD_ITC_IS_VALID_ (daemon->
itc) );
6353 daemon->epoll_fd = setup_epoll_fd (daemon);
6354 if (-1 == daemon->epoll_fd)
6356#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6359 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
6367 event.events = EPOLLIN;
6368 event.data.ptr = daemon;
6369 if (0 != epoll_ctl (daemon->epoll_fd,
6376 _ (
"Call to epoll_ctl failed: %s\n"),
6381 daemon->listen_socket_in_epoll =
true;
6384 if (MHD_ITC_IS_VALID_ (daemon->
itc))
6386 event.events = EPOLLIN;
6387 event.data.ptr = (
void *) epoll_itc_marker;
6388 if (0 != epoll_ctl (daemon->epoll_fd,
6390 MHD_itc_r_fd_ (daemon->
itc),
6395 _ (
"Call to epoll_ctl failed: %s\n"),
6441 struct sockaddr_in servaddr4;
6443 struct sockaddr_in6 servaddr6;
6445 const struct sockaddr *servaddr =
NULL;
6447#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6464#ifndef EPOLL_SUPPORT
6468#ifndef HTTPS_SUPPORT
6478#ifdef UPGRADE_SUPPORT
6514#if defined(EPOLL_SUPPORT)
6516#elif defined(HAVE_POLL)
6525#if defined(EPOLL_SUPPORT)
6536 daemon->epoll_fd = -1;
6537#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6538 daemon->epoll_upgrade_fd = -1;
6543 daemon->priority_cache =
NULL;
6546 gnutls_priority_init (&daemon->priority_cache,
6558 daemon->
port = port;
6569 MHD_itc_set_invalid_ (daemon->
itc);
6576 daemon->custom_error_log = &MHD_default_logger_;
6577 daemon->custom_error_log_cls = stderr;
6579#ifndef MHD_WINSOCK_SOCKETS
6596#ifdef HAVE_LISTEN_SHUTDOWN
6602 daemon->digest_auth_rand_size = 0;
6603 daemon->digest_auth_random =
NULL;
6604 daemon->nonce_nc_size = 4;
6609 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
6620 (
NULL != daemon->priority_cache) )
6621 gnutls_priority_deinit (daemon->priority_cache);
6633 "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
6634 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
6635 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
6647 _ (
"Using debug build of libmicrohttpd.\n") );
6652#
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6657 if (! MHD_itc_init_ (daemon->
itc))
6661 _ (
"Failed to create inter-thread communication channel: %s\n"),
6662 MHD_itc_last_strerror_ ());
6665 if (
NULL != daemon->priority_cache)
6666 gnutls_priority_deinit (daemon->priority_cache);
6678 "file descriptor for inter-thread communication channel exceeds maximum value.\n"));
6682 if (
NULL != daemon->priority_cache)
6683 gnutls_priority_deinit (daemon->priority_cache);
6691 if (daemon->nonce_nc_size > 0)
6693 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc)))
6694 /
sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
6698 _ (
"Specified value for NC_SIZE too large.\n"));
6702 gnutls_priority_deinit (daemon->priority_cache);
6707 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
6708 if (
NULL == daemon->nnc)
6712 _ (
"Failed to allocate memory for nonce-nc map: %s\n"),
6717 gnutls_priority_deinit (daemon->priority_cache);
6724#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6729 _ (
"MHD failed to initialize nonce-nc mutex.\n"));
6733 gnutls_priority_deinit (daemon->priority_cache);
6743#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6750 "MHD thread polling only works with MHD_USE_INTERNAL_POLLING_THREAD.\n"));
6762 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
6774 _ (
"Failed to create socket for listening: %s\n"),
6783#ifndef MHD_WINSOCK_SOCKETS
6788 if (0 > setsockopt (listen_fd,
6791 (
void *) &on,
sizeof (on)))
6795 _ (
"setsockopt failed: %s\n"),
6804#ifndef MHD_WINSOCK_SOCKETS
6807 if (0 > setsockopt (listen_fd,
6810 (
void *) &on,
sizeof (on)))
6814 _ (
"setsockopt failed: %s\n"),
6824#if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
6825 if (0 > setsockopt (listen_fd,
6827#ifndef MHD_WINSOCK_SOCKETS
6837 _ (
"setsockopt failed: %s\n"),
6848 "Cannot allow listening address reuse: SO_REUSEPORT not defined.\n"));
6861#if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
6862 (defined(__sun) && defined(SO_EXCLBIND))
6863 if (0 > setsockopt (listen_fd,
6865#ifdef SO_EXCLUSIVEADDRUSE
6866 SO_EXCLUSIVEADDRUSE,
6875 _ (
"setsockopt failed: %s\n"),
6880#elif defined(MHD_WINSOCK_SOCKETS)
6884 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined.\n"));
6893 addrlen =
sizeof (
struct sockaddr_in6);
6896 addrlen =
sizeof (
struct sockaddr_in);
6897 if (
NULL == servaddr)
6902#ifdef IN6ADDR_ANY_INIT
6903 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6907 sizeof (
struct sockaddr_in6));
6908 servaddr6.sin6_family = AF_INET6;
6909 servaddr6.sin6_port = htons (port);
6910#ifdef IN6ADDR_ANY_INIT
6911 servaddr6.sin6_addr = static_in6any;
6913#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
6914 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
6916 servaddr = (
struct sockaddr *) &servaddr6;
6923 sizeof (
struct sockaddr_in));
6924 servaddr4.sin_family = AF_INET;
6925 servaddr4.sin_port = htons (port);
6926 if (0 != INADDR_ANY)
6927 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6928#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
6929 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
6931 servaddr = (
struct sockaddr *) &servaddr4;
6945 if (0 > setsockopt (listen_fd,
6946 IPPROTO_IPV6, IPV6_V6ONLY,
6947 (
const void *) &v6_only,
6952 _ (
"setsockopt failed: %s\n"),
6959 if (-1 == bind (listen_fd, servaddr, addrlen))
6963 _ (
"Failed to bind to port %u: %s\n"),
6964 (
unsigned int) port,
6973 if (0 == daemon->fastopen_queue_size)
6974 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6975 if (0 != setsockopt (listen_fd,
6978 (
const void *) &daemon->fastopen_queue_size,
6979 sizeof (daemon->fastopen_queue_size)))
6983 _ (
"setsockopt failed: %s\n"),
6989 if (listen (listen_fd,
6994 _ (
"Failed to listen for connections: %s\n"),
7006#ifdef MHD_USE_GETSOCKNAME
7007 if ( (0 == daemon->
port) &&
7010 struct sockaddr_storage bindaddr;
7014 sizeof (
struct sockaddr_storage));
7015 addrlen =
sizeof (
struct sockaddr_storage);
7016#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
7017 bindaddr.ss_len = addrlen;
7019 if (0 != getsockname (listen_fd,
7020 (
struct sockaddr *) &bindaddr,
7025 _ (
"Failed to get listen port number: %s\n"),
7029#ifdef MHD_POSIX_SOCKETS
7030 else if (
sizeof (bindaddr) < addrlen)
7036 "Failed to get listen port number (`struct sockaddr_storage` too small!?).\n"));
7040 else if (0 == addrlen)
7050 switch (bindaddr.ss_family)
7054 struct sockaddr_in *s4 = (
struct sockaddr_in *) &bindaddr;
7056 daemon->
port = ntohs (s4->sin_port);
7062 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &bindaddr;
7064 daemon->
port = ntohs (s6->sin6_port);
7077 _ (
"Unknown address family!\n"));
7092 _ (
"Failed to set nonblocking mode on listening socket: %s\n"),
7096#
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7117 _ (
"Listen socket descriptor (%d) is not " \
7118 "less than FD_SETSIZE (%d).\n"),
7131#
if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7141 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
7145 if (
MHD_NO == setup_epoll_to_listen (daemon))
7150#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7155 _ (
"MHD failed to initialize IP connection limit mutex.\n"));
7165 _ (
"MHD failed to initialize IP connection limit mutex.\n"));
7167#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7179 (0 != MHD_TLS_init (daemon)) )
7183 _ (
"Failed to initialize TLS support.\n"));
7187#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7194#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7202#ifdef HAVE_LISTEN_SHUTDOWN
7204 (MHD_ITC_IS_VALID_ (daemon->
itc)) || \
7208 (MHD_ITC_IS_VALID_ (daemon->
itc)));
7216 _ (
"Failed to initialise mutex.\n"));
7227 "MHD-listen" :
"MHD-single",
7228 daemon->thread_stack_size,
7234 if (EAGAIN == errno)
7236 _ (
"Failed to create a new thread because it would have " \
7237 "exceeded the system limit on the number of threads or " \
7238 "no system resources available.\n"));
7242 _ (
"Failed to create listen thread: %s\n"),
7278 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
7285#if defined(DAUTH_SUPPORT) && defined(MHD_USE_THREADS)
7287 memset (&d->nnc_lock, -1,
sizeof(d->nnc_lock));
7291 #ifdef HAVE_MESSAGES
7293 _ (
"Failed to initialise mutex.\n"));
7299 if (! MHD_itc_init_ (d->
itc))
7304 "Failed to create worker inter-thread communication channel: %s\n"),
7305 MHD_itc_last_strerror_ () );
7317 "File descriptor for worker inter-thread communication channel exceeds maximum value.\n"));
7325 MHD_itc_set_invalid_ (d->
itc);
7327#ifdef HAVE_LISTEN_SHUTDOWN
7338 if (i < leftover_conns)
7342 (
MHD_NO == setup_epoll_to_listen (d)) )
7344 if (MHD_ITC_IS_VALID_ (d->
itc))
7355 _ (
"MHD failed to initialize cleanup connection mutex.\n"));
7357 if (MHD_ITC_IS_VALID_ (d->
itc))
7366 daemon->thread_stack_size,
7372 if (EAGAIN == errno)
7374 _ (
"Failed to create a new pool thread because it would " \
7375 "have exceeded the system limit on the number of " \
7376 "threads or no system resources available.\n"));
7380 _ (
"Failed to create pool thread: %s\n"),
7386 if (MHD_ITC_IS_VALID_ (d->
itc))
7400 _ (
"Failed to initialise mutex.\n"));
7409 daemon->https_key_password =
NULL;
7414#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7443#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7444 if (daemon->upgrade_fd_in_epoll)
7446 if (0 != epoll_ctl (daemon->epoll_fd,
7448 daemon->epoll_upgrade_fd,
7450 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
7451 daemon->upgrade_fd_in_epoll =
false;
7454 if (-1 != daemon->epoll_fd)
7455 close (daemon->epoll_fd);
7456#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7457 if (-1 != daemon->epoll_upgrade_fd)
7458 close (daemon->epoll_upgrade_fd);
7463#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7470 gnutls_priority_deinit (daemon->priority_cache);
7471 if (daemon->x509_cred)
7472 gnutls_certificate_free_credentials (daemon->x509_cred);
7473 if (daemon->psk_cred)
7474 gnutls_psk_free_server_credentials (daemon->psk_cred);
7477 if (MHD_ITC_IS_VALID_ (daemon->
itc))
7498#ifdef UPGRADE_SUPPORT
7501#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7502 struct MHD_UpgradeResponseHandle *urh;
7503 struct MHD_UpgradeResponseHandle *urhn;
7507#ifdef MHD_USE_THREADS
7510 MHD_thread_ID_match_current_ (daemon->
pid) );
7515#ifdef MHD_USE_THREADS
7524 new_connection_close_ (daemon, pos);
7528#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7531 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
7539 urh->clean_ready =
true;
7556#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7559#ifdef UPGRADE_SUPPORT
7565 while (
NULL != susp)
7567 if (
NULL == susp->urh)
7569 "MHD_stop_daemon() called while we have suspended connections.\n"));
7571 else if (used_tls &&
7573 (! susp->urh->clean_ready) )
7574 shutdown (susp->urh->app.socket,
7580 if (! susp->urh->was_closed)
7583 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
7585 susp->urh->was_closed =
true;
7602 "MHD_stop_daemon() called while we have suspended connections.\n"));
7603#if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
7604#ifdef MHD_USE_THREADS
7605 if (upg_allowed && used_tls && used_thr_p_c)
7623 if (! MHD_join_thread_ (pos->
pid.handle))
7624 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
7636#if MHD_WINSOCK_SOCKETS
7639 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
7641 "Failed to signal shutdown via inter-thread communication channel.\n"));
7645#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7655 if (! MHD_join_thread_ (pos->
pid.handle))
7656 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
7670#ifdef UPGRADE_SUPPORT
7686#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7689 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
7707#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7714 MHD_PANIC (
_ (
"MHD_stop_daemon() was called twice."));
7724#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7739 "Failed to signal shutdown via inter-thread communication channel.\n"));
7744#ifdef HAVE_LISTEN_SHUTDOWN
7747 (void) shutdown (
fd,
7759#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7767#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7777 "Failed to signal shutdown via inter-thread communication channel.\n"));
7781#ifdef HAVE_LISTEN_SHUTDOWN
7785 (void) shutdown (
fd,
7793 if (! MHD_join_thread_ (
daemon->
pid.handle))
7795 MHD_PANIC (
_ (
"Failed to join a thread.\n"));
7805#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7813#if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
7822 (-1 !=
daemon->epoll_fd) )
7824#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7826 (-1 !=
daemon->epoll_upgrade_fd) )
7831#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7845 if (
daemon->have_dhparams)
7847 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
7848 daemon->have_dhparams =
false;
7852 gnutls_priority_deinit (
daemon->priority_cache);
7854 gnutls_certificate_free_credentials (
daemon->x509_cred);
7856 gnutls_psk_free_server_credentials (
daemon->psk_cred);
7862#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7866#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7911#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7969#ifdef PACKAGE_VERSION
7970 return PACKAGE_VERSION;
7972 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
7975 int res = MHD_snprintf_ (ver,
7981 if ((0 >= res) || (
sizeof(ver) <= res))
8033#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
8039#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
8051#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
8069#ifdef HAVE_LISTEN_SHUTDOWN
8075#ifdef _MHD_ITC_SOCKETPAIR
8099#ifdef HAVE_POSTPROCESSOR
8105#if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
8111#if defined(HAVE_PREAD64) || defined(_WIN32)
8113#elif defined(HAVE_PREAD)
8114 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
8115#elif defined(HAVE_LSEEK64)
8118 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
8121#if defined(MHD_USE_THREAD_NAME_)
8127#if defined(UPGRADE_SUPPORT)
8133#if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
8139#ifdef MHD_USE_GETSOCKNAME
8145#if defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) || \
8146 ! defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED)
8152#ifdef _MHD_HAVE_SENDFILE
8158#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
8169#ifdef MHD_HTTPS_REQUIRE_GCRYPT
8170#if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
8171#if defined(MHD_USE_POSIX_THREADS)
8172GCRY_THREAD_OPTION_PTHREAD_IMPL;
8173#elif defined(MHD_W32_MUTEX_)
8176gcry_w32_mutex_init (
void **ppmtx)
8178 *ppmtx = malloc (
sizeof (MHD_mutex_));
8194gcry_w32_mutex_destroy (
void **ppmtx)
8203gcry_w32_mutex_lock (
void **ppmtx)
8210gcry_w32_mutex_unlock (
void **ppmtx)
8216static struct gcry_thread_cbs gcry_threads_w32 = {
8217 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
8218 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
8219 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
8233#if defined(MHD_WINSOCK_SOCKETS)
8240#if defined(MHD_WINSOCK_SOCKETS)
8241 if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
8242 MHD_PANIC (
_ (
"Failed to initialize winsock.\n"));
8243 mhd_winsock_inited_ = 1;
8244 if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion)))
8245 MHD_PANIC (
_ (
"Winsock version 2.2 is not available.\n"));
8248#ifdef MHD_HTTPS_REQUIRE_GCRYPT
8249#if GCRYPT_VERSION_NUMBER < 0x010600
8250#if defined(MHD_USE_POSIX_THREADS)
8251 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
8252 &gcry_threads_pthread))
8253 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt.\n"));
8254#elif defined(MHD_W32_MUTEX_)
8255 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
8257 MHD_PANIC (
_ (
"Failed to initialise multithreading in libgcrypt.\n"));
8259 gcry_check_version (
NULL);
8261 if (
NULL == gcry_check_version (
"1.6.0"))
8263 "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer.\n"));
8266 gnutls_global_init ();
8276 mhd_assert (
sizeof(tv.tv_sec) == SIZEOF_STRUCT_TIMEVAL_TV_SEC);
8279 mhd_assert (
sizeof(uint64_t) == SIZEOF_UINT64_T);
8287 gnutls_global_deinit ();
8289#if defined(MHD_WINSOCK_SOCKETS)
8290 if (mhd_winsock_inited_)
8297#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
void MHD_connection_handle_write(struct MHD_Connection *connection)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
enum MHD_Result MHD_connection_handle_idle(struct MHD_Connection *connection)
void MHD_connection_handle_read(struct MHD_Connection *connection, bool socket_error)
Methods for managing connections.
#define MHD_connection_finish_forward_(conn)
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
void MHD_set_https_callbacks(struct MHD_Connection *connection)
Methods for managing connections.
void MHD_update_last_activity_(struct MHD_Connection *connection)
void MHD_suspend_connection(struct MHD_Connection *connection)
static void close_all_connections(struct MHD_Daemon *daemon)
MHD_PanicCallback mhd_panic
static enum MHD_Result MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
void MHD_resume_connection(struct MHD_Connection *connection)
void internal_suspend_connection_(struct MHD_Connection *connection)
static enum MHD_Result parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
static enum MHD_Result call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
volatile int global_init_count
static enum MHD_Result MHD_poll(struct MHD_Daemon *daemon, int may_block)
void MHD_check_global_init_(void)
static void close_connection(struct MHD_Connection *pos)
static enum MHD_Result MHD_select(struct MHD_Daemon *daemon, int32_t millisec)
struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
static _MHD_NORETURN void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
static int MHD_ip_addr_compare(const void *a1, const void *a2)
static void new_connections_list_process_(struct MHD_Daemon *daemon)
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
static enum MHD_Result MHD_accept_connection(struct MHD_Daemon *daemon)
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
#define MHD_MAX_CONNECTIONS_DEFAULT
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
static enum MHD_Result new_connection_process_(struct MHD_Daemon *daemon, struct MHD_Connection *connection)
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
static enum MHD_Result MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
static enum MHD_Result parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
static struct MHD_Connection * new_connection_prepare_(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck, bool sk_spipe_supprs, enum MHD_tristate sk_is_nonip)
static enum MHD_Result resume_suspended_connections(struct MHD_Daemon *daemon)
#define MHD_POOL_SIZE_DEFAULT
static enum MHD_Result internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck, bool sk_spipe_supprs, enum MHD_tristate sk_is_nonip)
_MHD_EXTERN void MHD_free(void *ptr)
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, unsigned int fd_setsize)
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)
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...)
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
_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)
_MHD_EXTERN struct MHD_Daemon * MHD_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 enum MHD_Result MHD_run(struct MHD_Daemon *daemon)
_MHD_EXTERN enum MHD_Result MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
#define MHD_get_fdset(daemon, read_fd_set, write_fd_set, except_fd_set, max_fd)
_MHD_EXTERN enum MHD_Result MHD_run_wait(struct MHD_Daemon *daemon, int32_t millisec)
_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)
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
@ MHD_CONNECTION_NOTIFY_STARTED
@ MHD_CONNECTION_NOTIFY_CLOSED
@ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN
@ MHD_REQUEST_TERMINATED_COMPLETED_OK
@ MHD_REQUEST_TERMINATED_WITH_ERROR
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(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)
_MHD_EXTERN enum MHD_Result MHD_is_feature_supported(enum MHD_FEATURE feature)
_MHD_EXTERN uint32_t MHD_get_version_bin(void)
_MHD_EXTERN const char * MHD_get_version(void)
#define XDLL_insert(head, tail, element)
@ MHD_EPOLL_STATE_SUSPENDED
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
@ MHD_EPOLL_STATE_READ_READY
@ MHD_EPOLL_STATE_IN_EPOLL_SET
@ MHD_EPOLL_STATE_WRITE_READY
#define DLL_insert(head, tail, element)
#define EDLL_insert(head, tail, element)
#define EDLL_remove(head, tail, element)
#define XDLL_remove(head, tail, element)
#define DLL_remove(head, tail, element)
void MHD_pool_destroy(struct MemoryPool *pool)
struct MemoryPool * MHD_pool_create(size_t max)
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_strerror_(errnum)
#define MHD_ITC_IS_INVALID_(itc)
#define MHD_itc_destroy_chk_(itc)
#define TIMEVAL_TV_SEC_MAX
#define MHD_mutex_unlock_chk_(pmutex)
#define MHD_mutex_destroy_chk_(pmutex)
#define MHD_mutex_lock_chk_(pmutex)
void MHD_monotonic_sec_counter_finish(void)
void MHD_monotonic_sec_counter_init(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
int MHD_socket_noninheritable_(MHD_socket sock)
int MHD_socket_nonblocking_(MHD_socket sock)
MHD_socket MHD_socket_create_listen_(int pf)
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
#define MHD_SCKT_ERR_IS_(err, code)
#define MHD_socket_close_(fd)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
#define _MHD_SYS_DEFAULT_FD_SETSIZE
#define MHD_socket_strerr_(err)
#define MHD_socket_last_strerr_()
#define MHD_socket_get_error_()
#define MHD_socket_close_chk_(fd)
#define MHD_SCKT_ERR_IS_EINTR_(err)
#define MHD_socket_fset_error_(err)
#define MHD_SCKT_SEND_MAX_SIZE_
#define MHD_recv_(s, b, l)
#define MHD_send_(s, b, l)
#define MHD_SCKT_LAST_ERR_IS_(code)
#define MHD_SYS_select_(n, r, w, e, t)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
#define MHD_STATICSTR_LEN_(macro)
#define MHD_create_named_thread_(t, n, s, r, a)
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
void MHD_send_init_static_vars_(void)
Declarations of send() wrappers.
MHD internal shared structures.
@ MHD_CONNECTION_HEADERS_SENDING
@ MHD_CONNECTION_NORMAL_BODY_READY
@ MHD_CONNECTION_CHUNKED_BODY_READY
@ MHD_EVENT_LOOP_INFO_READ
@ MHD_EVENT_LOOP_INFO_WRITE
@ MHD_EVENT_LOOP_INFO_CLEANUP
@ MHD_EVENT_LOOP_INFO_BLOCK
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
#define MHD_TEST_ALLOW_SUSPEND_RESUME
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
void MHD_init_mem_pools_(void)
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
Header for platform missing functions.
Header for platform-independent inter-thread communication.
limits values definitions
#define MHD_mutex_destroy_(ignore)
#define MHD_mutex_unlock_(ignore)
#define MHD_mutex_lock_(ignore)
#define MHD_mutex_init_(ignore)
uint64_t MHD_monotonic_msec_counter(void)
internal monotonic clock functions implementations
#define SOCK_NONBLOCK_OR_ZERO
#define SOCK_NOSIGPIPE_OR_ZERO
#define SOCK_CLOEXEC_OR_ZERO
@ MHD_FEATURE_POSTPROCESSOR
@ MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET
@ MHD_FEATURE_AUTODETECT_BIND_PORT
@ MHD_FEATURE_HTTPS_CERT_CALLBACK
@ MHD_FEATURE_DIGEST_AUTH
@ MHD_FEATURE_THREAD_NAMES
@ MHD_FEATURE_HTTPS_KEY_PASSWORD
@ MHD_FEATURE_AUTOSUPPRESS_SIGPIPE
@ MHD_FEATURE_RESPONSES_SHARED_FD
@ MHD_FEATURE_TCP_FASTOPEN
@ MHD_FEATURE_HTTPS_CERT_CALLBACK2
@ MHD_OPTION_CONNECTION_MEMORY_INCREMENT
@ MHD_OPTION_HTTPS_CRED_TYPE
@ MHD_OPTION_URI_LOG_CALLBACK
@ MHD_OPTION_HTTPS_CERT_CALLBACK2
@ MHD_OPTION_SIGPIPE_HANDLED_BY_APP
@ MHD_OPTION_UNESCAPE_CALLBACK
@ MHD_OPTION_EXTERNAL_LOGGER
@ MHD_OPTION_LISTEN_BACKLOG_SIZE
@ MHD_OPTION_HTTPS_PRIORITIES
@ MHD_OPTION_HTTPS_MEM_DHPARAMS
@ MHD_OPTION_NOTIFY_CONNECTION
@ MHD_OPTION_LISTENING_ADDRESS_REUSE
@ MHD_OPTION_THREAD_POOL_SIZE
@ MHD_OPTION_CONNECTION_LIMIT
@ MHD_OPTION_PER_IP_CONNECTION_LIMIT
@ MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE
@ MHD_OPTION_HTTPS_MEM_CERT
@ MHD_OPTION_SERVER_INSANITY
@ MHD_OPTION_LISTEN_SOCKET
@ MHD_OPTION_HTTPS_MEM_KEY
@ MHD_OPTION_DIGEST_AUTH_RANDOM
@ MHD_OPTION_HTTPS_KEY_PASSWORD
@ MHD_OPTION_NONCE_NC_SIZE
@ MHD_OPTION_CONNECTION_MEMORY_LIMIT
@ MHD_OPTION_THREAD_STACK_SIZE
@ MHD_OPTION_STRICT_FOR_CLIENT
@ MHD_OPTION_CONNECTION_TIMEOUT
@ MHD_OPTION_GNUTLS_PSK_CRED_HANDLER
@ MHD_OPTION_HTTPS_MEM_TRUST
@ MHD_OPTION_HTTPS_CERT_CALLBACK
@ MHD_OPTION_NOTIFY_COMPLETED
enum MHD_Result(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
#define MHD_UNSIGNED_LONG_LONG
_MHD_EXTERN size_t MHD_http_unescape(char *val)
#define MHD_INVALID_SOCKET
enum MHD_Result(* MHD_AccessHandlerCallback)(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
@ MHD_DAEMON_INFO_MAC_KEY_SIZE
@ MHD_DAEMON_INFO_BIND_PORT
@ MHD_DAEMON_INFO_EPOLL_FD
@ MHD_DAEMON_INFO_KEY_SIZE
@ MHD_DAEMON_INFO_CURRENT_CONNECTIONS
@ MHD_DAEMON_INFO_LISTEN_FD
MHD_FLAG
Flags for the struct MHD_Daemon.
@ MHD_ALLOW_SUSPEND_RESUME
@ MHD_USE_THREAD_PER_CONNECTION
@ MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT
@ MHD_USE_INSECURE_TLS_EARLY_DATA
@ MHD_USE_NO_LISTEN_SOCKET
@ MHD_USE_PEDANTIC_CHECKS
@ MHD_USE_INTERNAL_POLLING_THREAD
Methods for managing response objects.
enum MHD_tristate sk_nodelay
struct MHD_Connection * prevX
enum MHD_ConnectionEventLoopInfo event_loop_info
enum MHD_tristate is_nonip
struct MHD_Response * response
struct MHD_Connection * next
struct sockaddr_storage addr
size_t read_buffer_offset
struct MHD_Connection * prev
MHD_thread_handle_ID_ pid
struct MHD_Connection * nextX
enum MHD_CONNECTION_STATE state
struct MHD_Daemon * daemon
uint64_t connection_timeout_ms
enum MHD_tristate sk_corked
MHD_NotifyConnectionCallback notify_connection
MHD_AccessHandlerCallback default_handler
LogCallback uri_log_callback
bool data_already_pending
MHD_mutex_ per_ip_connection_mutex
void * per_ip_connection_count
struct MHD_Connection * new_connections_tail
unsigned int connection_limit
void * unescape_callback_cls
MHD_mutex_ cleanup_connection_mutex
enum MHD_DisableSanityCheck insanity_level
struct MHD_Connection * connections_head
unsigned int listen_backlog_size
MHD_RequestCompletedCallback notify_completed
unsigned int worker_pool_size
int listening_address_reuse
uint64_t connection_timeout_ms
unsigned int per_ip_connection_limit
struct MHD_Connection * manual_timeout_tail
void * notify_connection_cls
UnescapeCallback unescape_callback
void * notify_completed_cls
struct MHD_Connection * cleanup_tail
struct MHD_Daemon * worker_pool
struct MHD_Connection * new_connections_head
MHD_thread_handle_ID_ pid
struct MHD_Connection * manual_timeout_head
enum MHD_tristate listen_is_unix
void * default_handler_cls
struct MHD_Connection * suspended_connections_tail
MHD_AcceptPolicyCallback apc
struct MHD_Connection * cleanup_head
struct MHD_Daemon * master
struct MHD_Connection * normal_timeout_head
struct MHD_Connection * normal_timeout_tail
void * uri_log_callback_cls
struct MHD_Connection * suspended_connections_head
struct MHD_Connection * connections_tail