50 #ifdef MHD_HTTPS_REQUIRE_GRYPT 55 #if defined(_WIN32) && ! defined(__CYGWIN__) 56 #ifndef WIN32_LEAN_AND_MEAN 57 #define WIN32_LEAN_AND_MEAN 1 65 #ifdef MHD_POSIX_SOCKETS 66 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4) 68 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2) 74 #define MHD_POOL_SIZE_DEFAULT (32 * 1024) 80 #define DEBUG_CLOSE MHD_NO 86 #define DEBUG_CONNECT MHD_NO 136 _(
"Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
166 #if defined(_WIN32) && ! defined(__CYGWIN__) 170 static int mhd_winsock_inited_ = 0;
173 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED 178 #define MHD_check_global_init_() (void)0 184 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 188 MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_);
197 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 202 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 247 struct in6_addr ipv6;
297 offsetof (
struct MHD_IPCount,
313 struct MHD_IPCount *key)
320 if (
sizeof (
struct sockaddr_in) == addrlen)
322 const struct sockaddr_in *addr4 = (
const struct sockaddr_in*) addr;
324 key->family = AF_INET;
325 memcpy (&key->addr.ipv4,
327 sizeof(addr4->sin_addr));
333 if (
sizeof (
struct sockaddr_in6) == addrlen)
335 const struct sockaddr_in6 *addr6 = (
const struct sockaddr_in6*) addr;
337 key->family = AF_INET6;
338 memcpy (&key->addr.ipv6,
340 sizeof(addr6->sin6_addr));
363 const struct sockaddr *addr,
366 struct MHD_IPCount *key;
376 if (
NULL == (key = malloc (
sizeof(*key))))
397 _(
"Failed to add IP connection count node\n"));
407 key = (
struct MHD_IPCount *) node;
429 const struct sockaddr *addr,
432 struct MHD_IPCount search_key;
433 struct MHD_IPCount *found_key;
455 MHD_PANIC (
_(
"Failed to find previously-added IP address\n"));
457 found_key = (
struct MHD_IPCount *) *nodep;
459 if (0 == found_key->count)
461 MHD_PANIC (
_(
"Previously-added IP address had counter of zero\n"));
464 if (0 == --found_key->count)
484 MHD_init_daemon_certificate (
struct MHD_Daemon *daemon)
490 #if GNUTLS_VERSION_MAJOR >= 3 491 if (
NULL != daemon->cert_callback)
493 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
494 daemon->cert_callback);
497 if (
NULL != daemon->https_mem_trust)
499 cert.data = (
unsigned char *) daemon->https_mem_trust;
500 cert.size = strlen (daemon->https_mem_trust);
501 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
503 GNUTLS_X509_FMT_PEM) < 0)
507 "Bad trust certificate format\n");
513 if (daemon->have_dhparams)
515 gnutls_certificate_set_dh_params (daemon->x509_cred,
516 daemon->https_mem_dhparams);
519 if ( (
NULL != daemon->https_mem_cert) &&
520 (
NULL != daemon->https_mem_key) )
522 key.data = (
unsigned char *) daemon->https_mem_key;
523 key.size = strlen (daemon->https_mem_key);
524 cert.data = (
unsigned char *) daemon->https_mem_cert;
525 cert.size = strlen (daemon->https_mem_cert);
527 if (
NULL != daemon->https_key_password) {
528 #if GNUTLS_VERSION_NUMBER >= 0x030111 529 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
533 daemon->https_key_password,
538 _(
"Failed to setup x509 certificate/key: pre 3.X.X version " \
539 "of GnuTLS does not support setting key password"));
545 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
548 GNUTLS_X509_FMT_PEM);
552 "GnuTLS failed to setup x509 certificate/key: %s\n",
553 gnutls_strerror (ret));
557 #if GNUTLS_VERSION_MAJOR >= 3 558 if (
NULL != daemon->cert_callback)
563 "You need to specify a certificate and key location\n");
577 switch (daemon->cred_type)
579 case GNUTLS_CRD_CERTIFICATE:
581 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
582 return GNUTLS_E_MEMORY_ERROR;
583 return MHD_init_daemon_certificate (daemon);
586 gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
587 return GNUTLS_E_MEMORY_ERROR;
592 _(
"Error: invalid credentials type %d specified.\n"),
635 fd_set *write_fd_set,
636 fd_set *except_fd_set,
648 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 662 urh_to_fdset (
struct MHD_UpgradeResponseHandle *urh,
667 unsigned int fd_setsize)
669 const MHD_socket conn_sckt = urh->connection->socket_fd;
677 if ( (urh->in_buffer_used < urh->in_buffer_size) &&
683 if ( (0 != urh->out_buffer_used) &&
692 ((0 != urh->in_buffer_size) ||
693 (0 != urh->out_buffer_size) ||
694 (0 != urh->out_buffer_used)))
702 if ( (urh->out_buffer_used < urh->out_buffer_size) &&
708 if ( (0 != urh->in_buffer_used) &&
717 ((0 != urh->out_buffer_size) ||
718 (0 != urh->in_buffer_size) ||
719 (0 != urh->in_buffer_used)))
740 urh_from_fdset (
struct MHD_UpgradeResponseHandle *urh,
745 const MHD_socket conn_sckt = urh->connection->socket_fd;
754 if (FD_ISSET (conn_sckt, rs))
756 if (FD_ISSET (conn_sckt, ws))
758 if (FD_ISSET (conn_sckt, es))
763 if (FD_ISSET (mhd_sckt, rs))
765 if (FD_ISSET (mhd_sckt, ws))
767 if (FD_ISSET (mhd_sckt, es))
783 urh_update_pollfd (
struct MHD_UpgradeResponseHandle *urh,
789 if (urh->in_buffer_used < urh->in_buffer_size)
790 p[0].events |= POLLIN;
791 if (0 != urh->out_buffer_used)
792 p[0].events |= POLLOUT;
797 ((0 != urh->in_buffer_size) ||
798 (0 != urh->out_buffer_size) ||
799 (0 != urh->out_buffer_used)))
800 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
802 if (urh->out_buffer_used < urh->out_buffer_size)
803 p[1].events |= POLLIN;
804 if (0 != urh->in_buffer_used)
805 p[1].events |= POLLOUT;
810 ((0 != urh->out_buffer_size) ||
811 (0 != urh->in_buffer_size) ||
812 (0 != urh->in_buffer_used)))
813 p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
824 urh_to_pollfd (
struct MHD_UpgradeResponseHandle *urh,
827 p[0].fd = urh->connection->socket_fd;
828 p[1].fd = urh->mhd.socket;
829 urh_update_pollfd (urh,
840 urh_from_pollfd (
struct MHD_UpgradeResponseHandle *urh,
847 if (0 != (p[0].revents & POLLIN))
849 if (0 != (p[0].revents & POLLOUT))
851 if (0 != (p[0].revents & POLLHUP))
853 if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
855 if (0 != (p[1].revents & POLLIN))
857 if (0 != (p[1].revents & POLLOUT))
859 if (0 != (p[1].revents & POLLHUP))
861 if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
885 fd_set *write_fd_set,
886 fd_set *except_fd_set,
888 unsigned int fd_setsize)
924 #ifdef MHD_POSIX_SOCKETS 937 #ifdef MHD_POSIX_SOCKETS 945 if ( (
NULL == except_fd_set) ||
957 #ifdef MHD_WINSOCK_SOCKETS 970 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 972 struct MHD_UpgradeResponseHandle *urh;
974 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
991 _(
"Maximum socket in select set: %d\n"),
1033 fd_set *read_fd_set,
1034 fd_set *write_fd_set,
1035 fd_set *except_fd_set,
1037 unsigned int fd_setsize)
1041 if ( (
NULL == daemon) ||
1042 (
NULL == read_fd_set) ||
1043 (
NULL == write_fd_set) ||
1048 if (
NULL == except_fd_set)
1050 #ifdef HAVE_MESSAGES 1052 _(
"MHD_get_fdset2() called with except_fd_set " 1053 "set to NULL. Such behavior is unsupported.\n"));
1056 except_fd_set = &es;
1059 #ifdef EPOLL_SUPPORT 1104 bool states_info_processed =
false;
1108 #ifdef HTTPS_SUPPORT 1119 states_info_processed =
true;
1128 states_info_processed =
true;
1138 if (!states_info_processed)
1185 #ifdef HTTPS_SUPPORT 1195 #ifdef UPGRADE_SUPPORT 1206 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1210 #ifdef HTTPS_SUPPORT 1214 gnutls_bye (connection->tls_session,
1223 connection->urh =
NULL;
1229 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1239 process_urh (
struct MHD_UpgradeResponseHandle *urh)
1254 #ifdef HAVE_MESSAGES 1255 if (! urh->was_closed)
1258 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1261 urh->was_closed =
true;
1263 was_closed = urh->was_closed;
1268 if (0 < urh->in_buffer_used)
1270 #ifdef HAVE_MESSAGES 1273 " bytes of data received from remote side: application shut down socket\n"),
1283 if (0 != urh->out_buffer_size)
1286 urh->in_buffer_used = 0;
1290 urh->in_buffer_size = 0;
1313 (urh->in_buffer_used < urh->in_buffer_size) )
1318 buf_size = urh->in_buffer_size - urh->in_buffer_used;
1319 if (buf_size > SSIZE_MAX)
1320 buf_size = SSIZE_MAX;
1323 res = gnutls_record_recv (connection->tls_session,
1324 &urh->in_buffer[urh->in_buffer_used],
1328 if (GNUTLS_E_INTERRUPTED != res)
1331 if (GNUTLS_E_AGAIN != res)
1336 urh->in_buffer_size = 0;
1342 urh->in_buffer_used += res;
1343 if (buf_size > (
size_t)res)
1345 else if (0 < gnutls_record_check_pending (connection->tls_session))
1354 urh->in_buffer_size = 0;
1362 (urh->out_buffer_used < urh->out_buffer_size) )
1367 buf_size = urh->out_buffer_size - urh->out_buffer_used;
1372 &urh->out_buffer[urh->out_buffer_used],
1391 urh->out_buffer_size = 0;
1397 urh->out_buffer_used += res;
1398 if (buf_size > (
size_t)res)
1408 urh->out_buffer_size = 0;
1416 (urh->out_buffer_used > 0) )
1421 data_size = urh->out_buffer_used;
1422 if (data_size > SSIZE_MAX)
1423 data_size = SSIZE_MAX;
1425 res = gnutls_record_send (connection->tls_session,
1430 if (GNUTLS_E_INTERRUPTED != res)
1433 if (GNUTLS_E_INTERRUPTED != res)
1437 #ifdef HAVE_MESSAGES 1440 " bytes of data received from application: %s\n"),
1442 gnutls_strerror(res));
1445 urh->out_buffer_used = 0;
1447 urh->out_buffer_size = 0;
1454 const size_t next_out_buffer_used = urh->out_buffer_used - res;
1455 if (0 != next_out_buffer_used)
1457 memmove (urh->out_buffer,
1458 &urh->out_buffer[res],
1459 next_out_buffer_used);
1460 if (data_size > (
size_t)res)
1463 urh->out_buffer_used = next_out_buffer_used;
1465 if ( (0 == urh->out_buffer_used) &&
1473 urh->out_buffer_size = 0;
1482 (urh->in_buffer_used > 0) )
1487 data_size = urh->in_buffer_used;
1505 #ifdef HAVE_MESSAGES 1508 " bytes of data received from remote side: %s\n"),
1513 urh->in_buffer_used = 0;
1515 urh->in_buffer_size = 0;
1523 const size_t next_in_buffer_used = urh->in_buffer_used - res;
1524 if (0 != next_in_buffer_used)
1526 memmove (urh->in_buffer,
1527 &urh->in_buffer[res],
1528 next_in_buffer_used);
1529 if (data_size > (
size_t)res)
1532 urh->in_buffer_used = next_in_buffer_used;
1534 if ( (0 == urh->in_buffer_used) &&
1540 urh->in_buffer_size = 0;
1549 (urh->in_buffer_used < urh->in_buffer_size) &&
1554 ( (0 != urh->out_buffer_size) ||
1555 (0 != urh->out_buffer_used) ) )
1558 #ifdef HAVE_MESSAGES 1559 if (0 < urh->out_buffer_used)
1562 " bytes of data received from application: daemon shut down\n"),
1566 urh->out_buffer_used = 0;
1570 urh->out_buffer_size = 0;
1577 #ifdef UPGRADE_SUPPORT 1589 #ifdef HTTPS_SUPPORT 1590 struct MHD_UpgradeResponseHandle *urh = con->urh;
1599 while ( (0 != urh->in_buffer_size) ||
1600 (0 != urh->out_buffer_size) ||
1601 (0 != urh->in_buffer_used) ||
1602 (0 != urh->out_buffer_used) )
1616 result = urh_to_fdset (urh,
1624 #ifdef HAVE_MESSAGES 1626 _(
"Error preparing select\n"));
1633 struct timeval* tvp;
1636 (urh->in_buffer_used < urh->in_buffer_size))
1658 #ifdef HAVE_MESSAGES 1660 _(
"Error during select (%d): `%s'\n"),
1666 urh_from_fdset (urh,
1681 p[0].fd = urh->connection->socket_fd;
1682 p[1].fd = urh->mhd.socket;
1684 while ( (0 != urh->in_buffer_size) ||
1685 (0 != urh->out_buffer_size) ||
1686 (0 != urh->in_buffer_used) ||
1687 (0 != urh->out_buffer_used) )
1691 urh_update_pollfd(urh, p);
1694 (urh->in_buffer_used < urh->in_buffer_size))
1699 if (MHD_sys_poll_ (p,
1707 #ifdef HAVE_MESSAGES 1709 _(
"Error during poll: `%s'\n"),
1714 urh_from_pollfd (urh,
1738 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1749 struct timeval *tvp;
1755 #define EXTRA_SLOTS 1 1757 #define EXTRA_SLOTS 0 1766 const bool use_poll = 0;
1768 bool was_suspended =
false;
1769 MHD_thread_init_(&(con->
pid));
1775 #ifdef UPGRADE_SUPPORT 1776 struct MHD_UpgradeResponseHandle *
const urh = con->urh;
1778 static const void *
const urh =
NULL;
1785 was_suspended =
true;
1794 #ifdef HAVE_MESSAGES 1796 _(
"Failed to add FD to fd_set\n"));
1810 #ifdef HAVE_MESSAGES 1812 _(
"Error during select (%d): `%s'\n"),
1822 p[0].events = POLLIN;
1823 p[0].fd = MHD_itc_r_fd_ (daemon->
itc);
1825 if (0 > MHD_sys_poll_ (p,
1831 #ifdef HAVE_MESSAGES 1833 _(
"Error during poll: `%s'\n"),
1840 MHD_itc_clear_ (daemon->
itc);
1849 was_suspended =
false;
1855 #ifdef HTTPS_SUPPORT
1867 if ( (
NULL == tvp) &&
1875 const time_t seconds_left = timeout - (now - con->
last_activity);
1876 #if !defined(_WIN32) || defined(__CYGWIN__) 1877 tv.tv_sec = seconds_left;
1891 bool err_state =
false;
1925 if (MHD_ITC_IS_VALID_(daemon->
itc) )
1936 #ifdef HAVE_MESSAGES 1938 _(
"Failed to add FD to fd_set\n"));
1954 #ifdef HAVE_MESSAGES 1956 _(
"Error during select (%d): `%s'\n"),
1965 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
1966 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
1968 MHD_itc_clear_ (daemon->
itc);
1991 p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
1994 p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
1997 p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2005 if (MHD_ITC_IS_VALID_(daemon->
itc))
2007 p[1].events |= POLLIN;
2008 p[1].fd = MHD_itc_r_fd_ (daemon->
itc);
2013 if (MHD_sys_poll_ (p,
2019 (
NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2023 #ifdef HAVE_MESSAGES 2025 _(
"Error during poll: `%s'\n"),
2033 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2034 (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2035 MHD_itc_clear_ (daemon->
itc);
2039 0 != (p[0].revents & POLLIN),
2040 0 != (p[0].revents & POLLOUT),
2041 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2045 #ifdef UPGRADE_SUPPORT 2046 if (MHD_CONNECTION_UPGRADE == con->
state)
2058 thread_main_connection_upgrade (con);
2062 con->urh->clean_ready =
true;
2070 return (MHD_THRD_RTRN_TYPE_) 0;
2075 #ifdef HAVE_MESSAGES 2077 _(
"Processing thread terminating. Closing connection\n"));
2101 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2102 (! MHD_itc_activate_ (daemon->
itc,
"t")) )
2104 #ifdef HAVE_MESSAGES 2106 _(
"Failed to signal thread termination via inter-thread communication channel."));
2109 return (MHD_THRD_RTRN_TYPE_) 0;
2123 #if defined(HTTPS_SUPPORT) 2124 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \ 2125 (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL) 2131 #define MHD_TLSLIB_NEED_PUSH_FUNC 1 2134 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2140 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2144 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) 2162 psk_gnutls_adapter (gnutls_session_t session,
2163 const char *username,
2164 gnutls_datum_t *key)
2169 size_t app_psk_size;
2171 connection = gnutls_session_get_ptr (session);
2172 if (
NULL == connection)
2174 #ifdef HAVE_MESSAGES 2176 MHD_PANIC (
_(
"Internal server error. This should be impossible.\n"));
2180 daemon = connection->
daemon;
2181 #if GNUTLS_VERSION_MAJOR >= 3 2182 if (
NULL == daemon->cred_callback)
2184 #ifdef HAVE_MESSAGES 2186 _(
"PSK not supported by this server.\n"));
2190 if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2196 if (
NULL == (key->data = gnutls_malloc (app_psk_size)))
2198 #ifdef HAVE_MESSAGES 2200 _(
"PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2205 key->size = app_psk_size;
2212 #ifdef HAVE_MESSAGES 2214 _(
"PSK not supported by this server.\n"));
2250 const struct sockaddr *addr,
2290 #ifdef HAVE_MESSAGES 2292 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2293 (
int) client_socket,
2303 #ifdef MHD_socket_nosignal_ 2304 if (! MHD_socket_nosignal_ (client_socket))
2306 #ifdef HAVE_MESSAGES 2308 _(
"Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2311 #ifndef MSG_NOSIGNAL 2322 #ifdef HAVE_MESSAGES 2325 _(
"Accepted connection on socket %d\n"),
2335 #ifdef HAVE_MESSAGES 2337 _(
"Server reached connection limit. Closing inbound connection.\n"));
2353 #ifdef HAVE_MESSAGES 2355 _(
"Connection rejected by application. Closing connection.\n"));
2371 #ifdef HAVE_MESSAGES 2373 "Error allocating memory: %s\n",
2386 #ifdef HAVE_MESSAGES 2388 _(
"Error allocating memory: %s\n"),
2403 if (
NULL == (connection->
addr = malloc (addrlen)))
2406 #ifdef HAVE_MESSAGES 2408 _(
"Error allocating memory: %s\n"),
2420 memcpy (connection->
addr,
2426 connection->
daemon = daemon;
2436 #ifdef HTTPS_SUPPORT 2439 gnutls_init (&connection->tls_session,
2441 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402)
2444 #
if GNUTLS_VERSION_MAJOR >= 3
2448 gnutls_priority_set (connection->tls_session,
2449 daemon->priority_cache);
2450 gnutls_session_set_ptr (connection->tls_session,
2452 switch (daemon->cred_type)
2455 case GNUTLS_CRD_CERTIFICATE:
2456 gnutls_credentials_set (connection->tls_session,
2457 GNUTLS_CRD_CERTIFICATE,
2460 case GNUTLS_CRD_PSK:
2461 gnutls_credentials_set (connection->tls_session,
2464 gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2465 &psk_gnutls_adapter);
2468 #ifdef HAVE_MESSAGES 2469 MHD_DLOG (connection->
daemon,
2470 _(
"Failed to setup TLS credentials: unknown credential type %d\n"),
2477 free (connection->
addr);
2485 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) 2486 gnutls_transport_set_int (connection->tls_session,
2487 (
int)(client_socket));
2489 gnutls_transport_set_ptr (connection->tls_session,
2490 (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2492 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC 2493 gnutls_transport_set_push_function (connection->tls_session,
2494 MHD_tls_push_func_);
2496 if (daemon->https_mem_trust)
2497 gnutls_certificate_server_set_request (connection->tls_session,
2498 GNUTLS_CERT_REQUEST);
2511 #ifdef HAVE_MESSAGES 2513 _(
"Server reached connection limit. Closing inbound connection.\n"));
2548 #ifdef HAVE_MESSAGES 2550 "Failed to create a thread: %s\n",
2557 connection->
pid = daemon->
pid;
2558 #ifdef EPOLL_SUPPORT 2563 struct epoll_event event;
2565 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2566 event.data.ptr = connection;
2567 if (0 != epoll_ctl (daemon->epoll_fd,
2573 #ifdef HAVE_MESSAGES 2575 _(
"Call to epoll_ctl failed: %s\n"),
2587 daemon->eready_tail,
2595 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2596 (! MHD_itc_activate_ (daemon->
itc,
"n")) )
2598 #ifdef HAVE_MESSAGES 2600 _(
"Failed to signal new connection via inter-thread communication channel."));
2610 #ifdef HTTPS_SUPPORT 2611 if (
NULL != connection->tls_session)
2612 gnutls_deinit (connection->tls_session);
2630 free (connection->
addr);
2681 #ifdef EPOLL_SUPPORT 2687 daemon->eready_tail,
2693 if (0 != epoll_ctl (daemon->epoll_fd,
2697 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
2744 MHD_PANIC (
_(
"Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2745 #ifdef UPGRADE_SUPPORT 2746 if (
NULL != connection->urh)
2748 #ifdef HAVE_MESSAGES 2750 _(
"Error: connection scheduled for \"upgrade\" cannot be suspended"));
2773 MHD_PANIC (
_(
"Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2778 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
2779 (! MHD_itc_activate_ (daemon->
itc,
"r")) )
2781 #ifdef HAVE_MESSAGES 2783 _(
"Failed to signal resume via inter-thread communication channel."));
2821 #ifdef UPGRADE_SUPPORT 2822 struct MHD_UpgradeResponseHandle *
const urh = pos->urh;
2824 static const void *
const urh =
NULL;
2828 #ifdef UPGRADE_SUPPORT
2829 || ( (
NULL != urh) &&
2830 ( (! urh->was_closed) ||
2831 (! urh->clean_ready) ) )
2861 #ifdef EPOLL_SUPPORT 2865 MHD_PANIC (
"Resumed connection was already in EREADY set\n");
2869 daemon->eready_tail,
2877 #ifdef UPGRADE_SUPPORT 2903 if ( (used_thr_p_c) &&
2906 if (! MHD_itc_activate_(daemon->
itc,
2909 #ifdef HAVE_MESSAGES 2911 _(
"Failed to signal resume of connection via inter-thread communication channel."));
2949 const struct sockaddr *addr,
2955 #ifdef HAVE_MESSAGES 2957 _(
"Failed to set nonblocking mode on new client socket: %s\n"),
2968 #ifdef HAVE_MESSAGES 2970 _(
"Failed to set noninheritable mode on new client socket.\n"));
3000 struct sockaddr_in6 addrstorage;
3002 struct sockaddr_in addrstorage;
3004 struct sockaddr *addr = (
struct sockaddr *) &addrstorage;
3010 addrlen =
sizeof (addrstorage);
3013 sizeof (addrstorage));
3040 #ifdef HAVE_MESSAGES 3043 _(
"Error accepting connection: %s\n"),
3055 #ifdef HAVE_MESSAGES 3060 _(
"Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n"));
3068 #ifdef HAVE_MESSAGES 3070 _(
"Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3077 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) 3080 #ifdef HAVE_MESSAGES 3082 _(
"Failed to set nonblocking mode on incoming connection socket: %s\n"),
3089 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) 3092 #ifdef HAVE_MESSAGES 3094 _(
"Failed to set noninheritable mode on incoming connection socket.\n"));
3098 #ifdef HAVE_MESSAGES 3101 _(
"Accepted connection on socket %d\n"),
3139 (! MHD_join_thread_ (pos->
pid.handle)) )
3141 #ifdef UPGRADE_SUPPORT 3142 cleanup_upgraded_connection (pos);
3145 #ifdef HTTPS_SUPPORT 3146 if (
NULL != pos->tls_session)
3147 gnutls_deinit (pos->tls_session);
3159 #ifdef EPOLL_SUPPORT 3169 if ( (-1 !=
daemon->epoll_fd) &&
3178 if (0 != epoll_ctl (
daemon->epoll_fd,
3182 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
3230 time_t earliest_deadline;
3237 #ifdef HAVE_MESSAGES 3239 _(
"Illegal call to MHD_get_timeout\n"));
3251 #ifdef EPOLL_SUPPORT 3254 #
if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3265 have_timeout =
false;
3266 earliest_deadline = 0;
3271 if ( (! have_timeout) ||
3274 have_timeout =
true;
3279 if ( (
NULL != pos) &&
3282 if ( (! have_timeout) ||
3285 have_timeout =
true;
3291 if (earliest_deadline < now)
3295 const time_t second_left = earliest_deadline - now;
3297 if (((
unsigned long long)second_left) >
ULLONG_MAX / 1000)
3300 *timeout = 1000LLU * (
unsigned long long) second_left;
3318 const fd_set *read_fd_set,
3319 const fd_set *write_fd_set,
3320 const fd_set *except_fd_set)
3325 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3326 struct MHD_UpgradeResponseHandle *urh;
3327 struct MHD_UpgradeResponseHandle *urhn;
3336 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3337 (FD_ISSET (MHD_itc_r_fd_ (daemon->
itc),
3339 MHD_itc_clear_ (daemon->
itc);
3352 while (
NULL != (pos = prev))
3368 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3370 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3374 urh_from_fdset (urh,
3381 if ( (0 == urh->in_buffer_size) &&
3382 (0 == urh->out_buffer_size) &&
3383 (0 == urh->in_buffer_used) &&
3384 (0 == urh->out_buffer_used) )
3387 urh->clean_ready =
true;
3422 const fd_set *read_fd_set,
3423 const fd_set *write_fd_set,
3424 const fd_set *except_fd_set)
3430 if (
NULL == read_fd_set ||
NULL == write_fd_set)
3432 if (
NULL == except_fd_set)
3434 #ifdef HAVE_MESSAGES 3436 _(
"MHD_run_from_select() called with except_fd_set " 3437 "set to NULL. Such behavior is deprecated.\n"));
3440 except_fd_set = &es;
3444 #ifdef EPOLL_SUPPORT 3445 int ret = MHD_epoll (daemon,
3483 struct timeval timeout;
3490 timeout.tv_usec = 0;
3514 #ifdef HAVE_MESSAGES 3516 _(
"Could not obtain daemon fdsets"));
3531 #ifdef HAVE_MESSAGES 3533 _(
"Could not add listen socket to fdset"));
3538 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3544 #if defined(MHD_WINSOCK_SOCKETS) 3559 #ifdef HAVE_MESSAGES 3561 _(
"Could not add control inter-thread communication channel FD to fdset"));
3564 #if defined(MHD_WINSOCK_SOCKETS) 3576 (MHD_ITC_IS_VALID_(daemon->
itc)) &&
3588 timeout.tv_usec = 0;
3596 timeout.tv_usec = (ltimeout % 1000) * 1000;
3615 #ifdef HAVE_MESSAGES 3617 _(
"select failed: %s\n"),
3644 unsigned int num_connections;
3647 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3648 struct MHD_UpgradeResponseHandle *urh;
3649 struct MHD_UpgradeResponseHandle *urhn;
3657 num_connections = 0;
3660 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3661 for (urh = daemon->urh_head;
NULL != urh; urh = urh->next)
3662 num_connections += 2;
3668 unsigned int poll_server;
3675 sizeof (
struct pollfd));
3678 #ifdef HAVE_MESSAGES 3680 _(
"Error allocating memory: %s\n"),
3693 p[poll_server].fd = ls;
3694 p[poll_server].events = POLLIN;
3695 p[poll_server].revents = 0;
3696 poll_listen = (int) poll_server;
3700 if (MHD_ITC_IS_VALID_(daemon->
itc))
3702 p[poll_server].fd = MHD_itc_r_fd_ (daemon->
itc);
3703 p[poll_server].events = POLLIN;
3704 p[poll_server].revents = 0;
3705 poll_itc_idx = (int) poll_server;
3715 timeout = (ltimeout > INT_MAX) ? INT_MAX : (
int) ltimeout;
3724 p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3727 p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3730 p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3738 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3739 for (urh = daemon->urh_tail;
NULL != urh; urh = urh->prev)
3741 urh_to_pollfd(urh, &(p[poll_server+i]));
3745 if (0 == poll_server + num_connections)
3750 if (MHD_sys_poll_(p,
3751 poll_server + num_connections,
3760 #ifdef HAVE_MESSAGES 3762 _(
"poll failed: %s\n"),
3775 if ( (-1 != poll_itc_idx) &&
3776 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3777 MHD_itc_clear_ (daemon->
itc);
3787 while (
NULL != (pos = prev))
3791 if (i >= num_connections)
3796 0 != (p[poll_server+i].revents & POLLIN),
3797 0 != (p[poll_server+i].revents & POLLOUT),
3798 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3801 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3802 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
3804 if (i >= num_connections)
3811 if ((p[poll_server+i].
fd != urh->connection->socket_fd) ||
3812 (p[poll_server+i+1].fd != urh->mhd.socket))
3814 urh_from_pollfd (urh,
3819 if ( (0 == urh->in_buffer_size) &&
3820 (0 == urh->out_buffer_size) &&
3821 (0 == urh->in_buffer_used) &&
3822 (0 == urh->out_buffer_used) )
3827 urh->clean_ready =
true;
3837 if ( (-1 != poll_listen) &&
3838 (0 != (p[poll_listen].revents & POLLIN)) )
3855 MHD_poll_listen_socket (
struct MHD_Daemon *daemon,
3860 unsigned int poll_count;
3875 p[poll_count].fd = ls;
3876 p[poll_count].events = POLLIN;
3877 p[poll_count].revents = 0;
3878 poll_listen = poll_count;
3881 if (MHD_ITC_IS_VALID_(daemon->
itc))
3883 p[poll_count].fd = MHD_itc_r_fd_ (daemon->
itc);
3884 p[poll_count].events = POLLIN;
3885 p[poll_count].revents = 0;
3886 poll_itc_idx = poll_count;
3897 if (0 == poll_count)
3899 if (MHD_sys_poll_(p,
3907 #ifdef HAVE_MESSAGES 3909 _(
"poll failed: %s\n"),
3914 if ( (-1 != poll_itc_idx) &&
3915 (0 != (p[poll_itc_idx].revents & POLLIN)) )
3916 MHD_itc_clear_ (daemon->
itc);
3921 if ( (-1 != poll_listen) &&
3922 (0 != (p[poll_listen].revents & POLLIN)) )
3944 return MHD_poll_all (daemon,
3946 return MHD_poll_listen_socket (daemon,
3956 #ifdef EPOLL_SUPPORT 3966 #define MAX_EVENTS 128 3969 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 3979 is_urh_ready(
struct MHD_UpgradeResponseHandle *
const urh)
3981 const struct MHD_Connection *
const connection = urh->connection;
3983 if ( (0 == urh->in_buffer_size) &&
3984 (0 == urh->out_buffer_size) &&
3985 (0 == urh->in_buffer_used) &&
3986 (0 == urh->out_buffer_used) )
3992 (urh->in_buffer_used < urh->in_buffer_size) )
3995 (urh->out_buffer_used < urh->out_buffer_size) )
3998 (urh->out_buffer_used > 0) )
4001 (urh->in_buffer_used > 0) )
4018 struct epoll_event events[MAX_EVENTS];
4020 struct MHD_UpgradeResponseHandle * pos;
4021 struct MHD_UpgradeResponseHandle * prev;
4023 num_events = MAX_EVENTS;
4024 while (MAX_EVENTS == num_events)
4028 num_events = epoll_wait (daemon->epoll_upgrade_fd,
4032 if (-1 == num_events)
4037 #ifdef HAVE_MESSAGES 4039 _(
"Call to epoll_wait failed: %s\n"),
4044 for (i = 0; i < (
unsigned int) num_events; i++)
4046 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
4047 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
4048 bool new_err_state =
false;
4050 if (urh->clean_ready)
4054 if (0 != (events[i].events & EPOLLIN))
4056 if (0 != (events[i].events & EPOLLOUT))
4058 if (0 != (events[i].events & EPOLLHUP))
4062 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4068 new_err_state =
true;
4071 if (! urh->in_eready_list)
4073 if (new_err_state ||
4077 daemon->eready_urh_tail,
4079 urh->in_eready_list =
true;
4084 prev = daemon->eready_urh_tail;
4085 while (
NULL != (pos = prev))
4089 if (! is_urh_ready(pos))
4092 daemon->eready_urh_tail,
4094 pos->in_eready_list =
false;
4097 if ( (0 == pos->in_buffer_size) &&
4098 (0 == pos->out_buffer_size) &&
4099 (0 == pos->in_buffer_used) &&
4100 (0 == pos->out_buffer_used) )
4103 pos->clean_ready =
true;
4120 static const char *
const epoll_itc_marker =
"itc_marker";
4135 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4136 static const char *
const upgrade_marker =
"upgrade_ptr";
4140 struct epoll_event events[MAX_EVENTS];
4141 struct epoll_event event;
4147 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4148 int run_upgraded =
MHD_NO;
4151 if (-1 == daemon->epoll_fd)
4158 (! daemon->listen_socket_in_epoll) &&
4161 event.events = EPOLLIN;
4162 event.data.ptr = daemon;
4163 if (0 != epoll_ctl (daemon->epoll_fd,
4168 #ifdef HAVE_MESSAGES 4170 _(
"Call to epoll_ctl failed: %s\n"),
4175 daemon->listen_socket_in_epoll =
true;
4178 (daemon->listen_socket_in_epoll) )
4180 if ( (0 != epoll_ctl (daemon->epoll_fd,
4186 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4187 daemon->listen_socket_in_epoll =
false;
4190 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4191 if ( (! daemon->upgrade_fd_in_epoll) &&
4192 (-1 != daemon->epoll_upgrade_fd) )
4194 event.events = EPOLLIN | EPOLLOUT;
4195 event.data.ptr = (
void *) upgrade_marker;
4196 if (0 != epoll_ctl (daemon->epoll_fd,
4198 daemon->epoll_upgrade_fd,
4201 #ifdef HAVE_MESSAGES 4203 _(
"Call to epoll_ctl failed: %s\n"),
4208 daemon->upgrade_fd_in_epoll =
true;
4211 if ( (daemon->listen_socket_in_epoll) &&
4218 if (0 != epoll_ctl (daemon->epoll_fd,
4222 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4223 daemon->listen_socket_in_epoll =
false;
4236 timeout_ms = INT_MAX;
4238 timeout_ms = (int) timeout_ll;
4255 num_events = MAX_EVENTS;
4256 while (MAX_EVENTS == num_events)
4259 num_events = epoll_wait (daemon->epoll_fd,
4263 if (-1 == num_events)
4268 #ifdef HAVE_MESSAGES 4270 _(
"Call to epoll_wait failed: %s\n"),
4275 for (i=0;i<(
unsigned int) num_events;i++)
4281 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4282 if (upgrade_marker == events[i].
data.ptr)
4290 if (epoll_itc_marker == events[i].
data.ptr)
4294 MHD_itc_clear_ (daemon->
itc);
4297 if (daemon == events[i].
data.ptr)
4301 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4303 unsigned int series_length = 0;
4309 (series_length < 10) &&
4319 pos = events[i].data.ptr;
4321 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4327 daemon->eready_tail,
4334 if (0 != (events[i].events & EPOLLIN))
4342 daemon->eready_tail,
4347 if (0 != (events[i].events & EPOLLOUT))
4354 daemon->eready_tail,
4363 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 4365 run_epoll_for_upgrade (daemon);
4369 prev = daemon->eready_tail;
4370 while (
NULL != (pos = prev))
4387 daemon->eready_tail,
4403 while (
NULL != (pos = prev))
4413 while (
NULL != (pos = prev))
4456 #ifdef EPOLL_SUPPORT 4459 MHD_epoll (daemon,
MHD_NO);
4523 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4528 MHD_thread_init_(&(daemon->
pid));
4533 #ifdef EPOLL_SUPPORT 4549 return (MHD_THRD_RTRN_TYPE_)0;
4652 #ifdef HAVE_MESSAGES 4654 "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4663 #ifdef EPOLL_SUPPORT 4668 if (0 != epoll_ctl (daemon->
worker_pool[i].epoll_fd,
4672 MHD_PANIC (
_(
"Failed to remove listen FD from epoll set\n"));
4673 daemon->
worker_pool[i].listen_socket_in_epoll =
false;
4680 MHD_PANIC (
_(
"Failed to signal quiesce via inter-thread communication channel"));
4684 #ifdef EPOLL_SUPPORT 4686 (-1 != daemon->epoll_fd) &&
4687 (daemon->listen_socket_in_epoll) )
4689 if ( (0 != epoll_ctl (daemon->epoll_fd,
4695 MHD_PANIC (
"Failed to remove listen FD from epoll set\n");
4696 daemon->listen_socket_in_epoll =
false;
4699 if ( (MHD_ITC_IS_VALID_(daemon->
itc)) &&
4700 (! MHD_itc_activate_ (daemon->
itc,
"q")) )
4701 MHD_PANIC (
_(
"failed to signal quiesce via inter-thread communication channel"));
4729 const struct sockaddr **servaddr,
4743 const struct sockaddr **servaddr,
4749 va_start (ap, servaddr);
4768 const struct sockaddr **servaddr,
4775 #ifdef HTTPS_SUPPORT 4804 #ifdef HAVE_MESSAGES 4806 _(
"Warning: Too large timeout value, ignored.\n"));
4830 *servaddr = va_arg (ap,
4831 const struct sockaddr *);
4844 #ifdef HAVE_MESSAGES 4846 _(
"Warning: Zero size, specified for thread pool size, is ignored. " 4847 "Thread pool is not used.\n"));
4852 #ifdef HAVE_MESSAGES 4854 _(
"Warning: \"1\", specified for thread pool size, is ignored. " 4855 "Thread pool is not used.\n"));
4864 #ifdef HAVE_MESSAGES 4866 _(
"Specified thread pool size (%u) too big\n"),
4875 #ifdef HAVE_MESSAGES 4877 _(
"MHD_OPTION_THREAD_POOL_SIZE option is specified but " 4878 "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
4884 #ifdef HAVE_MESSAGES 4886 _(
"Both MHD_OPTION_THREAD_POOL_SIZE option and " 4887 "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
4893 #ifdef HTTPS_SUPPORT 4896 daemon->https_mem_key = va_arg (ap,
4898 #ifdef HAVE_MESSAGES 4901 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4907 daemon->https_key_password = va_arg (ap,
4909 #ifdef HAVE_MESSAGES 4912 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4918 daemon->https_mem_cert = va_arg (ap,
4920 #ifdef HAVE_MESSAGES 4923 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4929 daemon->https_mem_trust = va_arg (ap,
4931 #ifdef HAVE_MESSAGES 4934 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4939 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
4945 const char *arg = va_arg (ap,
4947 gnutls_datum_t dhpar;
4949 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
4951 #ifdef HAVE_MESSAGES 4953 _(
"Error initializing DH parameters\n"));
4957 dhpar.data = (
unsigned char *) arg;
4958 dhpar.size = strlen (arg);
4959 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
4961 GNUTLS_X509_FMT_PEM) < 0)
4963 #ifdef HAVE_MESSAGES 4965 _(
"Bad Diffie-Hellman parameters format\n"));
4967 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
4970 daemon->have_dhparams =
true;
4974 #ifdef HAVE_MESSAGES 4976 _(
"MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4985 gnutls_priority_deinit (daemon->priority_cache);
4986 ret = gnutls_priority_init (&daemon->priority_cache,
4987 pstr = va_arg (ap,
const char*),
4989 if (GNUTLS_E_SUCCESS != ret)
4991 #ifdef HAVE_MESSAGES 4993 _(
"Setting priorities to `%s' failed: %s\n"),
4995 gnutls_strerror (ret));
4997 daemon->priority_cache =
NULL;
5003 #if GNUTLS_VERSION_MAJOR < 3 5004 #ifdef HAVE_MESSAGES 5006 _(
"MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5011 daemon->cert_callback = va_arg (ap,
5012 gnutls_certificate_retrieve_function2 *);
5016 #ifdef DAUTH_SUPPORT 5018 daemon->digest_auth_rand_size = va_arg (ap,
5020 daemon->digest_auth_random = va_arg (ap,
5024 daemon->nonce_nc_size = va_arg (ap,
5031 #ifdef HAVE_MESSAGES 5033 _(
"MHD_OPTION_LISTEN_SOCKET specified for daemon " 5034 "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5043 #ifdef HAVE_MESSAGES 5044 daemon->custom_error_log = va_arg (ap,
5046 daemon->custom_error_log_cls = va_arg (ap,
5061 daemon->fastopen_queue_size = va_arg (ap,
5067 unsigned int) ? 1 : -1;
5075 #ifdef HAVE_MESSAGES 5080 _(
"Flag MHD_USE_PEDANTIC_CHECKS is ignored because " 5081 "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5099 (
size_t) oa[i].
value,
5115 (
unsigned int) oa[i].
value,
5120 #ifdef HTTPS_SUPPORT 5125 (gnutls_credentials_type_t) oa[i].
value,
5175 (
void *) oa[i].
value,
5185 (
size_t) oa[i].
value,
5202 #ifdef HTTPS_SUPPORT 5204 #if GNUTLS_VERSION_MAJOR >= 3 5205 daemon->cred_callback = va_arg (ap,
5207 daemon->cred_callback_cls = va_arg (ap,
5212 _(
"MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5218 #ifdef HAVE_MESSAGES 5225 _(
"MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5231 _(
"Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5242 #ifdef EPOLL_SUPPORT 5248 #ifndef HAVE_MESSAGES 5252 #ifdef USE_EPOLL_CREATE1 5253 fd = epoll_create1 (EPOLL_CLOEXEC);
5255 fd = epoll_create (MAX_EVENTS);
5259 #ifdef HAVE_MESSAGES 5261 _(
"Call to epoll_create1 failed: %s\n"),
5266 #if !defined(USE_EPOLL_CREATE1) 5269 #ifdef HAVE_MESSAGES 5271 _(
"Failed to set noninheritable mode on epoll FD.\n"));
5289 setup_epoll_to_listen (
struct MHD_Daemon *daemon)
5291 struct epoll_event event;
5294 daemon->epoll_fd = setup_epoll_fd (daemon);
5295 if (-1 == daemon->epoll_fd)
5297 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5300 daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5308 event.events = EPOLLIN;
5309 event.data.ptr = daemon;
5310 if (0 != epoll_ctl (daemon->epoll_fd,
5315 #ifdef HAVE_MESSAGES 5317 _(
"Call to epoll_ctl failed: %s\n"),
5322 daemon->listen_socket_in_epoll =
true;
5323 if (MHD_ITC_IS_VALID_(daemon->
itc))
5325 event.events = EPOLLIN;
5326 event.data.ptr = (
void *) epoll_itc_marker;
5327 if (0 != epoll_ctl (daemon->epoll_fd,
5329 MHD_itc_r_fd_ (daemon->
itc),
5332 #ifdef HAVE_MESSAGES 5334 _(
"Call to epoll_ctl failed: %s\n"),
5378 struct sockaddr_in servaddr4;
5380 struct sockaddr_in6 servaddr6;
5382 const struct sockaddr *servaddr =
NULL;
5399 #ifndef EPOLL_SUPPORT 5403 #ifndef HTTPS_SUPPORT 5407 #ifndef TCP_FASTOPEN 5413 #ifdef UPGRADE_SUPPORT 5444 #if defined(EPOLL_SUPPORT) 5446 #elif defined(HAVE_POLL) 5455 #if defined(EPOLL_SUPPORT) 5465 #ifdef EPOLL_SUPPORT 5466 daemon->epoll_fd = -1;
5467 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 5468 daemon->epoll_upgrade_fd = -1;
5472 #ifdef HTTPS_SUPPORT 5473 daemon->priority_cache =
NULL;
5476 gnutls_priority_init (&daemon->priority_cache,
5486 daemon->
port = port;
5497 MHD_itc_set_invalid_ (daemon->
itc);
5503 #ifdef HAVE_MESSAGES 5505 daemon->custom_error_log_cls = stderr;
5510 #ifdef HAVE_MESSAGES 5512 _(
"Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " 5513 "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " 5514 "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5522 #ifdef HAVE_LISTEN_SHUTDOWN 5527 #ifdef DAUTH_SUPPORT 5528 daemon->digest_auth_rand_size = 0;
5529 daemon->digest_auth_random =
NULL;
5530 daemon->nonce_nc_size = 4;
5532 #ifdef HTTPS_SUPPORT 5535 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5544 #ifdef HTTPS_SUPPORT 5546 (
NULL != daemon->priority_cache) )
5547 gnutls_priority_deinit (daemon->priority_cache);
5558 #ifdef HAVE_MESSAGES 5560 _(
"Using debug build of libmicrohttpd.\n") );
5567 if (! MHD_itc_init_ (daemon->
itc))
5569 #ifdef HAVE_MESSAGES 5571 _(
"Failed to create inter-thread communication channel: %s\n"),
5572 MHD_itc_last_strerror_ ());
5574 #ifdef HTTPS_SUPPORT 5575 if (
NULL != daemon->priority_cache)
5576 gnutls_priority_deinit (daemon->priority_cache);
5585 #ifdef HAVE_MESSAGES 5587 _(
"file descriptor for inter-thread communication channel exceeds maximum value\n"));
5590 #ifdef HTTPS_SUPPORT 5591 if (
NULL != daemon->priority_cache)
5592 gnutls_priority_deinit (daemon->priority_cache);
5599 #ifdef DAUTH_SUPPORT 5600 if (daemon->nonce_nc_size > 0)
5602 if ( ( (
size_t) (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc))) /
5603 sizeof(
struct MHD_NonceNc) != daemon->nonce_nc_size)
5605 #ifdef HAVE_MESSAGES 5607 _(
"Specified value for NC_SIZE too large\n"));
5609 #ifdef HTTPS_SUPPORT 5611 gnutls_priority_deinit (daemon->priority_cache);
5616 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (
struct MHD_NonceNc));
5617 if (
NULL == daemon->nnc)
5619 #ifdef HAVE_MESSAGES 5621 _(
"Failed to allocate memory for nonce-nc map: %s\n"),
5624 #ifdef HTTPS_SUPPORT 5626 gnutls_priority_deinit (daemon->priority_cache);
5633 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5635 #ifdef HAVE_MESSAGES 5637 _(
"MHD failed to initialize nonce-nc mutex\n"));
5639 #ifdef HTTPS_SUPPORT 5641 gnutls_priority_deinit (daemon->priority_cache);
5653 #ifdef HAVE_MESSAGES 5655 _(
"MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5667 domain = (*pflags &
MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5677 #ifdef HAVE_MESSAGES 5679 _(
"Failed to create socket for listening: %s\n"),
5688 #ifndef MHD_WINSOCK_SOCKETS 5693 if (0 > setsockopt (listen_fd,
5696 (
void*)&on,
sizeof (on)))
5698 #ifdef HAVE_MESSAGES 5700 _(
"setsockopt failed: %s\n"),
5709 #ifndef MHD_WINSOCK_SOCKETS 5712 if (0 > setsockopt (listen_fd,
5715 (
void*)&on,
sizeof (on)))
5717 #ifdef HAVE_MESSAGES 5719 _(
"setsockopt failed: %s\n"),
5729 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) 5730 if (0 > setsockopt (listen_fd,
5732 #ifndef MHD_WINSOCK_SOCKETS
5740 #ifdef HAVE_MESSAGES 5742 _(
"setsockopt failed: %s\n"),
5750 #ifdef HAVE_MESSAGES 5752 _(
"Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
5765 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ 5766 (defined(__sun) && defined(SO_EXCLBIND)) 5767 if (0 > setsockopt (listen_fd,
5769 #ifdef SO_EXCLUSIVEADDRUSE
5770 SO_EXCLUSIVEADDRUSE,
5777 #ifdef HAVE_MESSAGES 5779 _(
"setsockopt failed: %s\n"),
5784 #elif defined(MHD_WINSOCK_SOCKETS) 5785 #ifdef HAVE_MESSAGES 5787 _(
"Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
5796 addrlen =
sizeof (
struct sockaddr_in6);
5799 addrlen =
sizeof (
struct sockaddr_in);
5800 if (
NULL == servaddr)
5805 #ifdef IN6ADDR_ANY_INIT 5806 static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
5810 sizeof (
struct sockaddr_in6));
5811 servaddr6.sin6_family = AF_INET6;
5812 servaddr6.sin6_port = htons (port);
5813 #ifdef IN6ADDR_ANY_INIT 5814 servaddr6.sin6_addr = static_in6any;
5816 #if HAVE_SOCKADDR_IN_SIN_LEN 5817 servaddr6.sin6_len =
sizeof (
struct sockaddr_in6);
5819 servaddr = (
struct sockaddr *) &servaddr6;
5826 sizeof (
struct sockaddr_in));
5827 servaddr4.sin_family = AF_INET;
5828 servaddr4.sin_port = htons (port);
5829 if (0 != INADDR_ANY)
5830 servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
5831 #if HAVE_SOCKADDR_IN_SIN_LEN 5832 servaddr4.sin_len =
sizeof (
struct sockaddr_in);
5834 servaddr = (
struct sockaddr *) &servaddr4;
5849 if (0 > setsockopt (listen_fd,
5850 IPPROTO_IPV6, IPV6_V6ONLY,
5851 (
const void *) &v6_only,
5854 #ifdef HAVE_MESSAGES 5856 _(
"setsockopt failed: %s\n"),
5863 if (-1 == bind (listen_fd, servaddr, addrlen))
5865 #ifdef HAVE_MESSAGES 5867 _(
"Failed to bind to port %u: %s\n"),
5868 (
unsigned int) port,
5877 if (0 == daemon->fastopen_queue_size)
5878 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
5879 if (0 != setsockopt (listen_fd,
5882 (
const void*)&daemon->fastopen_queue_size,
5883 sizeof (daemon->fastopen_queue_size)))
5885 #ifdef HAVE_MESSAGES 5887 _(
"setsockopt failed: %s\n"),
5893 if (listen (listen_fd,
5896 #ifdef HAVE_MESSAGES 5898 _(
"Failed to listen for connections: %s\n"),
5910 if ( (0 == daemon->
port) &&
5913 struct sockaddr_storage servaddr;
5917 sizeof (
struct sockaddr_storage));
5918 addrlen =
sizeof (servaddr);
5919 if (0 != getsockname (listen_fd,
5920 (
struct sockaddr *) &servaddr,
5923 #ifdef HAVE_MESSAGES 5925 _(
"Failed to get listen port number: %s\n"),
5929 #ifdef MHD_POSIX_SOCKETS 5930 else if (
sizeof (servaddr) < addrlen)
5933 #ifdef HAVE_MESSAGES 5935 _(
"Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
5941 switch (servaddr.ss_family)
5945 struct sockaddr_in *s4 = (
struct sockaddr_in *) &servaddr;
5947 daemon->
port = ntohs (s4->sin_port);
5953 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *) &servaddr;
5955 daemon->
port = ntohs(s6->sin6_port);
5966 #ifdef HAVE_MESSAGES 5968 _(
"Unknown address family!\n"));
5979 #ifdef HAVE_MESSAGES 5981 _(
"Failed to set nonblocking mode on listening socket: %s\n"),
5999 #ifdef HAVE_MESSAGES 6001 _(
"Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6009 #ifdef EPOLL_SUPPORT 6015 #ifdef HAVE_MESSAGES 6017 _(
"Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6021 if (
MHD_YES != setup_epoll_to_listen (daemon))
6028 #ifdef HAVE_MESSAGES 6030 _(
"MHD failed to initialize IP connection limit mutex\n"));
6041 #ifdef HAVE_MESSAGES 6043 _(
"MHD failed to initialize IP connection limit mutex\n"));
6052 #ifdef HTTPS_SUPPORT 6055 (0 != MHD_TLS_init (daemon)) )
6057 #ifdef HAVE_MESSAGES 6059 _(
"Failed to initialize TLS support\n"));
6076 "MHD-listen" :
"MHD-single",
6081 #ifdef HAVE_MESSAGES 6083 _(
"Failed to create listen thread: %s\n"),
6117 memcpy (d, daemon,
sizeof (
struct MHD_Daemon));
6127 if (! MHD_itc_init_ (d->
itc))
6129 #ifdef HAVE_MESSAGES 6131 _(
"Failed to create worker inter-thread communication channel: %s\n"),
6132 MHD_itc_last_strerror_() );
6140 #ifdef HAVE_MESSAGES 6142 _(
"File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6149 MHD_itc_set_invalid_ (d->
itc);
6155 if (i < leftover_conns)
6157 #ifdef EPOLL_SUPPORT 6159 (
MHD_YES != setup_epoll_to_listen (d)) )
6165 #ifdef HAVE_MESSAGES 6167 _(
"MHD failed to initialize cleanup connection mutex\n"));
6179 #ifdef HAVE_MESSAGES 6181 _(
"Failed to create pool thread: %s\n"),
6192 #ifdef HTTPS_SUPPORT 6195 daemon->https_key_password =
NULL;
6226 #ifdef EPOLL_SUPPORT 6227 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6228 if (daemon->upgrade_fd_in_epoll)
6230 if (0 != epoll_ctl (daemon->epoll_fd,
6232 daemon->epoll_upgrade_fd,
6234 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
6235 daemon->upgrade_fd_in_epoll =
false;
6238 if (-1 != daemon->epoll_fd)
6239 close (daemon->epoll_fd);
6240 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6241 if (-1 != daemon->epoll_upgrade_fd)
6242 close (daemon->epoll_upgrade_fd);
6245 #ifdef DAUTH_SUPPORT 6249 #ifdef HTTPS_SUPPORT 6251 gnutls_priority_deinit (daemon->priority_cache);
6253 if (MHD_ITC_IS_VALID_(daemon->
itc))
6273 #ifdef UPGRADE_SUPPORT 6276 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6277 struct MHD_UpgradeResponseHandle *urh;
6278 struct MHD_UpgradeResponseHandle *urhn;
6285 for (urh = daemon->urh_tail;
NULL != urh; urh = urhn)
6292 urh->clean_ready =
true;
6310 #ifdef UPGRADE_SUPPORT 6316 while (
NULL != susp)
6318 if (
NULL == susp->urh)
6319 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6320 #ifdef HTTPS_SUPPORT 6321 else if (used_tls &&
6323 (! susp->urh->clean_ready) )
6324 shutdown (susp->urh->app.socket,
6329 #ifdef HAVE_MESSAGES 6330 if (! susp->urh->was_closed)
6332 _(
"Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6334 susp->urh->was_closed =
true;
6350 MHD_PANIC (
_(
"MHD_stop_daemon() called while we have suspended connections.\n"));
6355 #if MHD_WINSOCK_SOCKETS 6358 (! MHD_itc_activate_ (
daemon->
itc,
"e")) )
6359 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6372 if (! MHD_join_thread_ (pos->
pid.handle))
6386 #ifdef UPGRADE_SUPPORT 6444 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel."));
6449 #ifdef HAVE_LISTEN_SHUTDOWN 6452 (void) shutdown (
fd,
6462 #ifdef EPOLL_SUPPORT 6464 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6479 MHD_PANIC (
_(
"Failed to signal shutdown via inter-thread communication channel"));
6483 #ifdef HAVE_LISTEN_SHUTDOWN 6487 (void) shutdown (
fd,
6495 if (! MHD_join_thread_ (
daemon->
pid.handle))
6509 #ifdef EPOLL_SUPPORT 6511 (-1 !=
daemon->epoll_fd) )
6513 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 6515 (-1 !=
daemon->epoll_upgrade_fd) )
6531 #ifdef HTTPS_SUPPORT 6532 if (
daemon->have_dhparams)
6534 gnutls_dh_params_deinit (
daemon->https_mem_dhparams);
6535 daemon->have_dhparams =
false;
6539 gnutls_priority_deinit (
daemon->priority_cache);
6541 gnutls_certificate_free_credentials (
daemon->x509_cred);
6543 gnutls_psk_free_server_credentials (
daemon->psk_cred);
6547 #ifdef DAUTH_SUPPORT 6584 #ifdef EPOLL_SUPPORT 6651 #ifdef PACKAGE_VERSION 6652 return PACKAGE_VERSION;
6654 static char ver[12] =
"\0\0\0\0\0\0\0\0\0\0\0";
6657 int res = MHD_snprintf_(ver,
6663 if (0 >= res ||
sizeof(ver) <= res)
6688 #ifdef HAVE_MESSAGES 6694 #ifdef HTTPS_SUPPORT 6700 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 6712 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) 6724 #ifdef EPOLL_SUPPORT 6730 #ifdef HAVE_LISTEN_SHUTDOWN 6736 #ifdef _MHD_ITC_SOCKETPAIR 6748 #ifdef BAUTH_SUPPORT 6754 #ifdef DAUTH_SUPPORT 6760 #ifdef HAVE_POSTPROCESSOR 6766 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 6772 #if defined(HAVE_PREAD64) || defined(_WIN32) 6774 #elif defined(HAVE_PREAD) 6775 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
6776 #elif defined(HAVE_LSEEK64) 6779 return (
sizeof(uint64_t) >
sizeof(off_t)) ?
MHD_NO :
MHD_YES;
6782 #if defined(MHD_USE_THREAD_NAME_) 6788 #if defined(UPGRADE_SUPPORT) 6794 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) 6800 #ifdef MHD_USE_GETSOCKNAME 6806 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL) 6812 #ifdef _MHD_HAVE_SENDFILE 6823 #ifdef MHD_HTTPS_REQUIRE_GRYPT 6824 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600 6825 #if defined(MHD_USE_POSIX_THREADS) 6826 GCRY_THREAD_OPTION_PTHREAD_IMPL;
6827 #elif defined(MHD_W32_MUTEX_) 6830 gcry_w32_mutex_init (
void **ppmtx)
6832 *ppmtx = malloc (
sizeof (MHD_mutex_));
6836 if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
6848 gcry_w32_mutex_destroy (
void **ppmtx)
6850 int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
6857 gcry_w32_mutex_lock (
void **ppmtx)
6859 return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
6864 gcry_w32_mutex_unlock (
void **ppmtx)
6866 return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
6870 static struct gcry_thread_cbs gcry_threads_w32 = {
6871 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
6872 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
6873 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
6886 #if defined(_WIN32) && ! defined(__CYGWIN__) 6893 #if defined(_WIN32) && ! defined(__CYGWIN__) 6894 if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
6895 MHD_PANIC (
_(
"Failed to initialize winsock\n"));
6896 mhd_winsock_inited_ = 1;
6897 if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
6898 MHD_PANIC (
_(
"Winsock version 2.2 is not available\n"));
6900 #ifdef HTTPS_SUPPORT 6901 #ifdef MHD_HTTPS_REQUIRE_GRYPT 6902 #if GCRYPT_VERSION_NUMBER < 0x010600 6903 #if defined(MHD_USE_POSIX_THREADS) 6904 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
6905 &gcry_threads_pthread))
6906 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
6907 #elif defined(MHD_W32_MUTEX_) 6908 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
6910 MHD_PANIC (
_(
"Failed to initialise multithreading in libgcrypt\n"));
6912 gcry_check_version (
NULL);
6914 if (
NULL == gcry_check_version (
"1.6.0"))
6915 MHD_PANIC (
_(
"libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
6918 gnutls_global_init ();
6921 #ifdef HAVE_FREEBSD_SENDFILE 6922 MHD_conn_init_static_ ();
6930 #ifdef HTTPS_SUPPORT 6931 gnutls_global_deinit ();
6933 #if defined(_WIN32) && ! defined(__CYGWIN__) 6934 if (mhd_winsock_inited_)
6940 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
#define MHD_send_(s, b, l)
unsigned int per_ip_connection_limit
void * unescape_callback_cls
volatile int global_init_count
void MHD_connection_handle_write(struct MHD_Connection *connection)
_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)
Header for platform missing functions.
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
_MHD_EXTERN const char * MHD_get_version(void)
bool data_already_pending
void MHD_update_last_activity_(struct MHD_Connection *connection)
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
#define MHD_SYS_select_(n, r, w, e, t)
struct sockaddr_storage addr
struct MHD_Connection * cleanup_head
enum MHD_CONNECTION_STATE state
static int call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
enum MHD_ConnectionEventLoopInfo event_loop_info
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
#define MHD_ITC_IS_INVALID_(itc)
struct MHD_Connection * prevX
MHD_thread_handle_ID_ pid
#define MHD_mutex_unlock_chk_(pmutex)
time_t connection_timeout
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
#define MHD_socket_get_error_()
internal monotonic clock functions implementations
#define MHD_mutex_destroy_chk_(pmutex)
void * MHD_calloc_(size_t nelem, size_t elsize)
#define MHD_socket_strerr_(err)
MHD_socket MHD_socket_create_listen_(int pf)
#define EDLL_insert(head, tail, element)
_MHD_EXTERN int MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
struct MHD_Response * response
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
struct MHD_Connection * manual_timeout_head
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
#define MHD_MAX_CONNECTIONS_DEFAULT
MHD_thread_handle_ID_ pid
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
time_t MHD_monotonic_sec_counter(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
MHD_AccessHandlerCallback default_handler
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
void MHD_suspend_connection(struct MHD_Connection *connection)
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
_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,...)
#define MHD_SCKT_LAST_ERR_IS_(code)
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
#define MHD_UNSIGNED_LONG_LONG
void * uri_log_callback_cls
struct MHD_Daemon * daemon
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
void(* MHD_LogCallback)(void *cls, const char *fm, va_list ap)
#define MHD_TEST_ALLOW_SUSPEND_RESUME
int listening_address_reuse
MHD_mutex_ per_ip_connection_mutex
MHD_NotifyConnectionCallback notify_connection
Header for platform-independent inter-thread communication.
struct MHD_Connection * next
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
#define DLL_insert(head, tail, element)
static int MHD_ip_addr_compare(const void *a1, const void *a2)
#define MHD_socket_last_strerr_()
struct MHD_Connection * connections_tail
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
struct MemoryPool * MHD_pool_create(size_t max)
#define MHD_INVALID_SOCKET
internal shared structures
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
#define MHD_POOL_SIZE_DEFAULT
void MHD_set_https_callbacks(struct MHD_Connection *connection)
#define MHD_SCKT_SEND_MAX_SIZE_
unsigned int connection_limit
unsigned int worker_pool_size
struct MHD_Connection * connections_head
_MHD_EXTERN int 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)
#define MHD_socket_close_chk_(fd)
LogCallback uri_log_callback
void MHD_connection_handle_read(struct MHD_Connection *connection)
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
time_t connection_timeout
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
#define MHD_SCKT_ERR_IS_(err, code)
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Methods for managing connections.
struct MHD_Daemon * master
#define EDLL_remove(head, tail, element)
struct MHD_Connection * manual_timeout_tail
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
struct MHD_Connection * prev
#define TIMEVAL_TV_SEC_MAX
#define DLL_remove(head, tail, element)
#define MHD_strerror_(errnum)
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
static int 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)
struct MHD_Connection * normal_timeout_head
#define _MHD_SYS_DEFAULT_FD_SETSIZE
void MHD_pool_destroy(struct MemoryPool *pool)
UnescapeCallback unescape_callback
void internal_suspend_connection_(struct MHD_Connection *connection)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
unsigned int listen_backlog_size
#define XDLL_remove(head, tail, element)
void MHD_monotonic_sec_counter_finish(void)
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
static int 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)
struct MHD_Connection * suspended_connections_tail
#define MHD_create_named_thread_(t, n, s, r, a)
MHD_AcceptPolicyCallback apc
struct MHD_Connection * cleanup_tail
int MHD_connection_handle_idle(struct MHD_Connection *connection)
static int resume_suspended_connections(struct MHD_Daemon *daemon)
#define MHD_itc_destroy_chk_(itc)
static int internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck)
int(* 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)
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
void MHD_monotonic_sec_counter_init(void)
#define MHD_recv_(s, b, l)
static int MHD_accept_connection(struct MHD_Daemon *daemon)
_MHD_EXTERN int 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 void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
struct MHD_Connection * normal_timeout_tail
void MHD_check_global_init_(void)
MHD_RequestCompletedCallback notify_completed
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
#define MHD_mutex_lock_chk_(pmutex)
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
static void close_connection(struct MHD_Connection *pos)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
void * notify_completed_cls
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
int MHD_socket_nonblocking_(MHD_socket sock)
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
void * notify_connection_cls
Header for platform-independent locks abstraction.
MHD_PanicCallback mhd_panic
#define XDLL_insert(head, tail, element)
#define MHD_UNSIGNED_LONG_LONG_PRINTF
void MHD_resume_connection(struct MHD_Connection *connection)
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
struct MHD_Connection * suspended_connections_head
void * per_ip_connection_count
size_t read_buffer_offset
_MHD_EXTERN int 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 * default_handler_cls
#define MHD_SCKT_ERR_IS_EINTR_(err)
MHD_mutex_ cleanup_connection_mutex
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
_MHD_EXTERN size_t MHD_http_unescape(char *val)
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
static void close_all_connections(struct MHD_Daemon *daemon)
limits values definitions
int MHD_socket_noninheritable_(MHD_socket sock)
struct MHD_Daemon * worker_pool
#define MAYBE_SOCK_NONBLOCK
MHD_FLAG
Flags for the struct MHD_Daemon.
Header for platform-independent threads abstraction.
#define MAYBE_SOCK_CLOEXEC