23#if defined(__GNUC__) || defined(__MINGW32__)
26 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
28#if GCC_VERSION >= 40500
34#if defined(GCC_DIAGNOSTIC)
37#pragma GCC diagnostic ignored "-Wunused-macros"
39#pragma GCC diagnostic ignored "-Wpadded"
46#pragma GCC diagnostic push
47#pragma GCC diagnostic ignored "-Wreserved-id-macro"
51#if !defined(_CRT_SECURE_NO_WARNINGS)
52#define _CRT_SECURE_NO_WARNINGS
54#if !defined(_WIN32_WINNT)
55#define _WIN32_WINNT 0x0601
58#if !defined(_GNU_SOURCE)
61#if defined(__linux__) && !defined(_XOPEN_SOURCE)
62#define _XOPEN_SOURCE 600
64#if defined(__LSB_VERSION__) || defined(__sun)
68#if !defined(_LARGEFILE_SOURCE)
69#define _LARGEFILE_SOURCE
71#if !defined(_FILE_OFFSET_BITS)
72#define _FILE_OFFSET_BITS 64
74#if !defined(__STDC_FORMAT_MACROS)
75#define __STDC_FORMAT_MACROS
77#if !defined(__STDC_LIMIT_MACROS)
78#define __STDC_LIMIT_MACROS
80#if !defined(_DARWIN_UNLIMITED_SELECT)
81#define _DARWIN_UNLIMITED_SELECT
85#define __inline inline
91#pragma GCC diagnostic pop
101#pragma warning(disable : 4306)
103#pragma warning(disable : 4127)
105#pragma warning(disable : 4204)
107#pragma warning(disable : 4820)
109#pragma warning(disable : 4668)
111#pragma warning(disable : 4255)
113#pragma warning(disable : 4711)
120#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201100L
121#define mg_static_assert _Static_assert
122#elif defined(__cplusplus) && __cplusplus >= 201103L
123#define mg_static_assert static_assert
126#define mg_static_assert(cond, txt) \
127 extern char static_assert_replacement[(cond) ? 1 : -1]
131 "int data type size check");
133 "pointer data type size check");
145#if defined(NO_ALTERNATIVE_QUEUE) && defined(ALTERNATIVE_QUEUE)
148 "Define ALTERNATIVE_QUEUE or NO_ALTERNATIVE_QUEUE (or none of them), but not both"
150#if !defined(NO_ALTERNATIVE_QUEUE) && !defined(ALTERNATIVE_QUEUE)
152#define NO_ALTERNATIVE_QUEUE
155#if defined(NO_FILESYSTEMS) && !defined(NO_FILES)
170#error "Inconsistent build flags, NO_FILESYSTEMS requires NO_FILES"
174#if !defined(WIN32_LEAN_AND_MEAN)
175#define WIN32_LEAN_AND_MEAN
178#if defined(__SYMBIAN32__)
183#error "Symbian is no longer maintained. CivetWeb no longer supports Symbian."
186#if defined(__rtems__)
187#include <rtems/version.h>
190#if defined(__ZEPHYR__)
199#include <sys/socket.h>
202#include <zephyr/kernel.h>
207#define MAX_WORKER_THREADS (CONFIG_MAX_PTHREAD_COUNT - 2)
209#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
210#define ZEPHYR_STACK_SIZE USE_STACK_SIZE
212#define ZEPHYR_STACK_SIZE (1024 * 16)
224#if !defined(CIVETWEB_HEADER_INCLUDED)
230#if !defined(DEBUG_TRACE)
237#define DEBUG_TRACE(fmt, ...) \
238 DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
240#define NEED_DEBUG_TRACE_FUNC
241#if !defined(DEBUG_TRACE_STREAM)
242#define DEBUG_TRACE_STREAM stderr
246#define DEBUG_TRACE(fmt, ...) \
253#if !defined(DEBUG_ASSERT)
256#define DEBUG_ASSERT(cond) \
259 DEBUG_TRACE("ASSERTION FAILED: %s", #cond); \
264#define DEBUG_ASSERT(cond)
269#if defined(__GNUC__) && defined(GCC_INSTRUMENTATION)
294#if !defined(IGNORE_UNUSED_RESULT)
295#define IGNORE_UNUSED_RESULT(a) ((void)((a) && 1))
299#if defined(__GNUC__) || defined(__MINGW32__)
315#pragma GCC diagnostic ignored "-Wunused-function"
317#define FUNCTION_MAY_BE_UNUSED
320#define FUNCTION_MAY_BE_UNUSED
325#if !defined(_WIN32_WCE) && !defined(__ZEPHYR__)
331#include <sys/types.h>
335#if defined(__clang__)
339#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
342#if defined(__GNUC__) || defined(__MINGW32__)
359#if defined(__MACH__) && defined(__APPLE__)
361#if defined(__clang__)
362#if (__clang_major__ == 3) && ((__clang_minor__ == 7) || (__clang_minor__ == 8))
364#pragma clang diagnostic ignored "-Wno-reserved-id-macro"
365#pragma clang diagnostic ignored "-Wno-keyword-macro"
369#ifndef CLOCK_MONOTONIC
370#define CLOCK_MONOTONIC (1)
372#ifndef CLOCK_REALTIME
373#define CLOCK_REALTIME (2)
376#include <mach/clock.h>
377#include <mach/mach.h>
378#include <mach/mach_time.h>
379#include <sys/errno.h>
393 t->tv_sec =
now.tv_sec;
394 t->tv_nsec =
now.tv_usec * 1000;
417 t->tv_sec =
now / 1000000000;
418 t->tv_nsec =
now % 1000000000;
425#if defined(__CLOCK_AVAILABILITY)
437#define clock_gettime _civet_safe_clock_gettime
439#define clock_gettime _civet_clock_gettime
446#define ERROR_TRY_AGAIN(err) ((err) == WSAEWOULDBLOCK)
451#define ERROR_TRY_AGAIN(err) \
452 (((err) == EAGAIN) || ((err) == EWOULDBLOCK) || ((err) == EINTR))
468#if !defined(MAX_WORKER_THREADS)
469#define MAX_WORKER_THREADS (1024 * 64)
476#if !defined(SOCKET_TIMEOUT_QUANTUM)
477#define SOCKET_TIMEOUT_QUANTUM (2000)
481#if !defined(MG_FILE_COMPRESSION_SIZE_LIMIT)
482#define MG_FILE_COMPRESSION_SIZE_LIMIT (1024)
485#if !defined(PASSWORDS_FILE_NAME)
486#define PASSWORDS_FILE_NAME ".htpasswd"
491#if !defined(CGI_ENVIRONMENT_SIZE)
492#define CGI_ENVIRONMENT_SIZE (4096)
496#if !defined(MAX_CGI_ENVIR_VARS)
497#define MAX_CGI_ENVIR_VARS (256)
501#if !defined(MG_BUF_LEN)
502#define MG_BUF_LEN (1024 * 8)
509#if !defined(ARRAY_SIZE)
510#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
516#if !defined(INT64_MAX)
517#define INT64_MAX (9223372036854775807)
520#define SHUTDOWN_RD (0)
521#define SHUTDOWN_WR (1)
522#define SHUTDOWN_BOTH (2)
525 "worker threads must be a positive number");
528 "size_t data type size check");
546#define UTF8_PATH_MAX (3 * 260)
549#define UTF16_PATH_MAX (260)
551#if !defined(_IN_PORT_T)
552#if !defined(in_port_t)
553#define in_port_t u_short
557#if defined(_WIN32_WCE)
558#error "WinCE support has ended"
566#define MAKEUQUAD(lo, hi) \
567 ((uint64_t)(((uint32_t)(lo)) | ((uint64_t)((uint32_t)(hi))) << 32))
568#define RATE_DIFF (10000000)
569#define EPOCH_DIFF (MAKEUQUAD(0xd53e8000, 0x019db1de))
570#define SYS2UNIX_TIME(lo, hi) \
571 ((time_t)((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF))
579#define STR(x) STRX(x)
580#define __func__ __FILE__ ":" STR(__LINE__)
581#define strtoull(x, y, z) ((unsigned __int64)_atoi64(x))
582#define strtoll(x, y, z) (_atoi64(x))
584#define __func__ __FUNCTION__
585#define strtoull(x, y, z) (_strtoui64(x, y, z))
586#define strtoll(x, y, z) (_strtoi64(x, y, z))
591#define ERRNO ((int)(GetLastError()))
595#if defined(_WIN64) || defined(__MINGW64__)
598#if defined(OPENSSL_API_3_0)
599#define SSL_LIB "libssl-3-x64.dll"
600#define CRYPTO_LIB "libcrypto-3-x64.dll"
603#if defined(OPENSSL_API_1_1)
604#define SSL_LIB "libssl-1_1-x64.dll"
605#define CRYPTO_LIB "libcrypto-1_1-x64.dll"
608#if defined(OPENSSL_API_1_0)
609#define SSL_LIB "ssleay64.dll"
610#define CRYPTO_LIB "libeay64.dll"
617#if defined(OPENSSL_API_3_0)
618#define SSL_LIB "libssl-3.dll"
619#define CRYPTO_LIB "libcrypto-3.dll"
622#if defined(OPENSSL_API_1_1)
623#define SSL_LIB "libssl-1_1.dll"
624#define CRYPTO_LIB "libcrypto-1_1.dll"
627#if defined(OPENSSL_API_1_0)
628#define SSL_LIB "ssleay32.dll"
629#define CRYPTO_LIB "libeay32.dll"
636#define O_NONBLOCK (0)
641#define INT64_FMT "I64d"
642#define UINT64_FMT "I64u"
644#define WINCDECL __cdecl
645#define vsnprintf_impl _vsnprintf
646#define access _access
647#define mg_sleep(x) (Sleep(x))
649#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
651#define popen(x, y) (_popen(x, y))
654#define pclose(x) (_pclose(x))
656#define close(x) (_close(x))
657#define dlsym(x, y) (GetProcAddress((HINSTANCE)(x), (y)))
659#define fseeko(x, y, z) ((_lseeki64(_fileno(x), (y), (z)) == -1) ? -1 : 0)
660#define fdopen(x, y) (_fdopen((x), (y)))
661#define write(x, y, z) (_write((x), (y), (unsigned)z))
662#define read(x, y, z) (_read((x), (y), (unsigned)z))
663#define flockfile(x) ((void)pthread_mutex_lock(&global_log_file_lock))
664#define funlockfile(x) ((void)pthread_mutex_unlock(&global_log_file_lock))
665#define sleep(x) (Sleep((x)*1000))
666#define rmdir(x) (_rmdir(x))
667#if defined(_WIN64) || !defined(__MINGW32__)
669#define timegm(x) (_mkgmtime(x))
677#define fileno(x) (_fileno(x))
681 CRITICAL_SECTION
sec;
684typedef HANDLE pthread_t;
690#if !defined(__clockid_t_defined)
693#if !defined(CLOCK_MONOTONIC)
694#define CLOCK_MONOTONIC (1)
696#if !defined(CLOCK_REALTIME)
697#define CLOCK_REALTIME (2)
699#if !defined(CLOCK_THREAD)
700#define CLOCK_THREAD (3)
702#if !defined(CLOCK_PROCESS)
703#define CLOCK_PROCESS (4)
707#if defined(_MSC_VER) && (_MSC_VER >= 1900)
708#define _TIMESPEC_DEFINED
710#if !defined(_TIMESPEC_DEFINED)
717#if !defined(WIN_PTHREADS_TIME_H)
718#define MUST_IMPLEMENT_CLOCK_GETTIME
721#if defined(MUST_IMPLEMENT_CLOCK_GETTIME)
722#define clock_gettime mg_clock_gettime
731 static BOOL initialized =
FALSE;
746 li.LowPart =
ft.dwLowDateTime;
747 li.HighPart =
ft.dwHighDateTime;
748 li.QuadPart -= 116444736000000000;
749 tp->tv_sec = (time_t)(
li.QuadPart / 10000000);
750 tp->tv_nsec = (long)(
li.QuadPart % 10000000) * 100;
759 tp->tv_sec = (time_t)
d;
761 tp->tv_nsec = (long)(
d * 1.0E9);
775 li.HighPart =
t_user.dwHighDateTime;
778 li.QuadPart +=
li2.QuadPart;
779 tp->tv_sec = (time_t)(
li.QuadPart / 10000000);
780 tp->tv_nsec = (long)(
li.QuadPart % 10000000) * 100;
795 li.HighPart =
t_user.dwHighDateTime;
798 li.QuadPart +=
li2.QuadPart;
799 tp->tv_sec = (time_t)(
li.QuadPart / 10000000);
800 tp->tv_nsec = (long)(
li.QuadPart % 10000000) * 100;
845#if defined(HAVE_POLL)
846#define mg_pollfd pollfd
857#pragma comment(lib, "Ws2_32.lib")
865#define UTF8_PATH_MAX (PATH_MAX)
873#if !defined(__ZEPHYR__)
874#include <arpa/inet.h>
880#include <netinet/in.h>
881#include <netinet/tcp.h>
890#include <sys/socket.h>
892#if !defined(__rtems__)
893#include <sys/utsname.h>
898#if defined(USE_X_DOM_SOCKET)
903#define vsnprintf_impl vsnprintf
905#if !defined(NO_SSL_DL) && !defined(NO_SSL)
909#if defined(__MACH__) && defined(__APPLE__)
911#if defined(OPENSSL_API_3_0)
912#define SSL_LIB "libssl.3.dylib"
913#define CRYPTO_LIB "libcrypto.3.dylib"
916#if defined(OPENSSL_API_1_1)
917#define SSL_LIB "libssl.1.1.dylib"
918#define CRYPTO_LIB "libcrypto.1.1.dylib"
921#if defined(OPENSSL_API_1_0)
922#define SSL_LIB "libssl.1.0.dylib"
923#define CRYPTO_LIB "libcrypto.1.0.dylib"
928#define SSL_LIB "libssl.so"
930#if !defined(CRYPTO_LIB)
931#define CRYPTO_LIB "libcrypto.so"
934#if !defined(O_BINARY)
937#define closesocket(a) (close(a))
938#define mg_mkdir(conn, path, mode) (mkdir(path, mode))
939#define mg_remove(conn, x) (remove(x))
940#define mg_sleep(x) (usleep((x)*1000))
941#define mg_opendir(conn, x) (opendir(x))
942#define mg_closedir(x) (closedir(x))
943#define mg_readdir(x) (readdir(x))
945#define INVALID_SOCKET (-1)
946#define INT64_FMT PRId64
947#define UINT64_FMT PRIu64
953#if !defined(CLOCK_MONOTONIC)
954#define CLOCK_MONOTONIC CLOCK_REALTIME
968#define mg_pollfd pollfd
973#if defined(NEED_TIMEGM)
977 return (
y % 4 == 0 &&
y % 100 != 0) ||
y % 400 == 0;
983 return (
y - 1969) / 4 - (
y - 1901) / 100 + (
y - 1601) / 400;
989 static const unsigned short ydays[] = {
990 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
991 int year =
tm->tm_year + 1900;
992 int mon =
tm->tm_mon;
993 int mday =
tm->tm_mday - 1;
995 int min =
tm->tm_min;
996 int sec =
tm->tm_sec;
1001 ||
hour < 0 ||
hour > 23 || min < 0 || min > 59 ||
sec < 0 ||
sec > 60)
1004 time_t res =
year - 1970;
1022#if !defined(va_copy)
1023#define va_copy(x, y) ((x) = (y))
1030#if defined(GCC_DIAGNOSTIC)
1032#pragma GCC diagnostic push
1033#pragma GCC diagnostic ignored "-Wunused-function"
1087#if defined(GCC_DIAGNOSTIC)
1089#pragma GCC diagnostic pop
1098#if defined(GCC_DIAGNOSTIC)
1100#pragma GCC diagnostic push
1101#pragma GCC diagnostic ignored "-Wunused-function"
1103#if defined(__clang__)
1105#pragma clang diagnostic push
1106#pragma clang diagnostic ignored "-Wunused-function"
1130#elif defined(_WIN32)
1145#if defined(_WIN64) && !defined(NO_ATOMICS)
1147#elif defined(_WIN32) && !defined(NO_ATOMICS)
1151 static_assert(
sizeof(ptrdiff_t) ==
sizeof(
LONG),
"Size mismatch");
1152 static_assert(
sizeof(ptrdiff_t) ==
sizeof(int32_t),
"Size mismatch");
1157#elif defined(__GNUC__) \
1158 && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1159 && !defined(NO_ATOMICS)
1176#if defined(_WIN64) && !defined(NO_ATOMICS)
1178#elif defined(_WIN32) && !defined(NO_ATOMICS)
1181 static_assert(
sizeof(ptrdiff_t) ==
sizeof(
LONG),
"Size mismatch");
1182 static_assert(
sizeof(ptrdiff_t) ==
sizeof(int32_t),
"Size mismatch");
1187#elif defined(__GNUC__) \
1188 && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1189 && !defined(NO_ATOMICS)
1200#if defined(USE_SERVER_STATS) || defined(STOP_FLAG_NEEDS_LOCK)
1206#if defined(_WIN64) && !defined(NO_ATOMICS)
1208#elif defined(_WIN32) && !defined(NO_ATOMICS)
1210#elif defined(__GNUC__) \
1211 && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1212 && !defined(NO_ATOMICS)
1232#if defined(_WIN64) && !defined(NO_ATOMICS)
1234#elif defined(_WIN32) && !defined(NO_ATOMICS)
1236#elif defined(__GNUC__) \
1237 && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1238 && !defined(NO_ATOMICS)
1255 register ptrdiff_t tmp = *
addr;
1257#if defined(_WIN64) && !defined(NO_ATOMICS)
1258 while (tmp <
value) {
1261#elif defined(_WIN32) && !defined(NO_ATOMICS)
1262 while (tmp <
value) {
1265#elif defined(__GNUC__) \
1266 && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1267 && !defined(NO_ATOMICS)
1268 while (tmp <
value) {
1286#if defined(_WIN64) && !defined(NO_ATOMICS)
1288#elif defined(_WIN32) && !defined(NO_ATOMICS)
1290#elif defined(__GNUC__) \
1291 && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1292 && !defined(NO_ATOMICS)
1305#if defined(GCC_DIAGNOSTIC)
1307#pragma GCC diagnostic pop
1309#if defined(__clang__)
1311#pragma clang diagnostic pop
1315#if defined(USE_SERVER_STATS)
1337#if defined(MEMORY_DEBUGGING)
1351 memory = (
void *)&tmp[2];
1354#if defined(MEMORY_DEBUGGING)
1356 "MEM: %p %5lu alloc %7lu %4lu --- %s:%u\n",
1358 (
unsigned long)
size,
1359 (
unsigned long)
mstat->totalMemUsed,
1360 (
unsigned long)
mstat->blockCount,
1389#if defined(MEMORY_DEBUGGING)
1404#if defined(MEMORY_DEBUGGING)
1406 "MEM: %p %5lu free %7lu %4lu --- %s:%u\n",
1408 (
unsigned long)
size,
1409 (
unsigned long)
mstat->totalMemUsed,
1410 (
unsigned long)
mstat->blockCount,
1431#if defined(MEMORY_DEBUGGING)
1449#if defined(MEMORY_DEBUGGING)
1451 "MEM: %p %5lu r-free %7lu %4lu --- %s:%u\n",
1454 (
unsigned long)
mstat->totalMemUsed,
1455 (
unsigned long)
mstat->blockCount,
1462#if defined(MEMORY_DEBUGGING)
1464 "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n",
1467 (
unsigned long)
mstat->totalMemUsed,
1468 (
unsigned long)
mstat->blockCount,
1476#if defined(MEMORY_DEBUGGING)
1495#define mg_malloc(a) mg_malloc_ex(a, NULL, __FILE__, __LINE__)
1496#define mg_calloc(a, b) mg_calloc_ex(a, b, NULL, __FILE__, __LINE__)
1497#define mg_realloc(a, b) mg_realloc_ex(a, b, NULL, __FILE__, __LINE__)
1498#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__)
1500#define mg_malloc_ctx(a, c) mg_malloc_ex(a, c, __FILE__, __LINE__)
1501#define mg_calloc_ctx(a, b, c) mg_calloc_ex(a, b, c, __FILE__, __LINE__)
1502#define mg_realloc_ctx(a, b, c) mg_realloc_ex(a, b, c, __FILE__, __LINE__)
1532#define mg_malloc_ctx(a, c) mg_malloc(a)
1533#define mg_calloc_ctx(a, b, c) mg_calloc(a, b)
1534#define mg_realloc_ctx(a, b, c) mg_realloc(a, b)
1535#define mg_free_ctx(a, c) mg_free(a)
1568#if defined(snprintf)
1571#if defined(vsnprintf)
1575#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc
1576#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc
1577#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc
1578#define free DO_NOT_USE_THIS_FUNCTION__USE_mg_free
1579#define snprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_snprintf
1584#define vsnprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_vsnprintf
1592#if defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1) \
1593 || defined(OPENSSL_API_3_0)
1596#if !defined(OPENSSL_API_1_0) && !defined(OPENSSL_API_1_1) \
1597 && !defined(OPENSSL_API_3_0) && !defined(USE_MBEDTLS) \
1598 && !defined(USE_GNUTLS)
1599#error "Please define OPENSSL_API_#_# or USE_MBEDTLS or USE_GNUTLS"
1601#if defined(OPENSSL_API_1_0) && defined(OPENSSL_API_1_1)
1602#error "Multiple OPENSSL_API versions defined"
1604#if defined(OPENSSL_API_1_1) && defined(OPENSSL_API_3_0)
1605#error "Multiple OPENSSL_API versions defined"
1607#if defined(OPENSSL_API_1_0) && defined(OPENSSL_API_3_0)
1608#error "Multiple OPENSSL_API versions defined"
1610#if (defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1) \
1611 || defined(OPENSSL_API_3_0)) \
1612 && (defined(USE_MBEDTLS) || defined(USE_GNUTLS))
1613#error "Multiple SSL libraries defined"
1615#if defined(USE_MBEDTLS) && defined(USE_GNUTLS)
1616#error "Multiple SSL libraries defined"
1624#if defined(MG_LEGACY_INTERFACE)
1625#define MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE
1637#if defined(MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE)
1643#if defined(GCC_DIAGNOSTIC)
1645#pragma GCC diagnostic push
1646#pragma GCC diagnostic ignored "-Wunused-function"
1648#if defined(__clang__)
1650#pragma clang diagnostic push
1651#pragma clang diagnostic ignored "-Wunused-function"
1673#if defined(__clang__)
1674#pragma clang diagnostic push
1675#pragma clang diagnostic ignored "-Wunreachable-code"
1683 if (
sizeof(pthread_t) >
sizeof(
unsigned long)) {
1692 tls->is_master = -2;
1696 return tls->thread_idx;
1701 unsigned long ret = 0;
1707#if defined(__clang__)
1708#pragma clang diagnostic pop
1721 return (((uint64_t)
tsnow.tv_sec) * 1000000000) + (uint64_t)
tsnow.tv_nsec;
1725#if defined(GCC_DIAGNOSTIC)
1727#pragma GCC diagnostic pop
1729#if defined(__clang__)
1731#pragma clang diagnostic pop
1735#if defined(NEED_DEBUG_TRACE_FUNC)
1749 "*** %lu.%09lu %lu %s:%u: ",
1750 (
unsigned long)
tsnow.tv_sec,
1751 (
unsigned long)
tsnow.tv_nsec,
1765#define MD5_STATIC static
1769#if defined(NO_SOCKLEN_T)
1773#define IP_ADDR_STR_LEN (50)
1775#if !defined(MSG_NOSIGNAL)
1776#define MSG_NOSIGNAL (0)
1781#if defined(USE_MBEDTLS)
1783#include "mod_mbedtls.inl"
1785#elif defined(USE_GNUTLS)
1787#include "mod_gnutls.inl"
1789#elif defined(NO_SSL)
1794#elif defined(NO_SSL_DL)
1796#include <openssl/bn.h>
1797#include <openssl/conf.h>
1798#include <openssl/crypto.h>
1799#include <openssl/dh.h>
1802#include <openssl/err.h>
1803#include <openssl/opensslv.h>
1804#include <openssl/pem.h>
1805#include <openssl/ssl.h>
1806#include <openssl/tls1.h>
1807#include <openssl/x509.h>
1809#if defined(WOLFSSL_VERSION)
1812#include "wolfssl_extras.inl"
1815#if defined(OPENSSL_IS_BORINGSSL)
1826#define CONF_modules_unload(a) ((void)0)
1827#define ENGINE_cleanup() ((void)0)
1831#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
1832#if !defined(OPENSSL_API_3_0)
1833#define OPENSSL_API_3_0
1835#define OPENSSL_REMOVE_THREAD_STATE()
1837#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1838#if !defined(OPENSSL_API_1_1)
1839#define OPENSSL_API_1_1
1841#define OPENSSL_REMOVE_THREAD_STATE()
1843#if !defined(OPENSSL_API_1_0)
1844#define OPENSSL_API_1_0
1846#define OPENSSL_REMOVE_THREAD_STATE() ERR_remove_thread_state(NULL)
1860#if !defined(NO_CACHING)
1881#if defined(USE_IPV6)
1884#if defined(USE_X_DOM_SOCKET)
1889#if defined(USE_X_DOM_SOCKET)
1890static unsigned short
1894 return s->
sin.sin_port;
1895#if defined(USE_IPV6)
1897 return s->sin6.sin6_port;
1902#if defined(USE_IPV6)
1903#define USA_IN_PORT_UNSAFE(s) \
1904 (((s)->sa.sa_family == AF_INET6) ? (s)->sin6.sin6_port : (s)->sin.sin_port)
1906#define USA_IN_PORT_UNSAFE(s) ((s)->sin.sin_port)
1937#define STRUCT_FILE_INITIALIZER \
1939 {(uint64_t)0, (time_t)0, 0, 0, 0}, \
1978#if defined(__linux__)
1988#if defined(USE_WEBSOCKET)
1998#if defined(USE_HTTP2)
2013#if defined(USE_TIMERS)
2022#if defined(USE_TIMERS)
2027#if defined(USE_4_CGI)
2032#if defined(USE_TIMERS)
2041#if defined(USE_TIMERS)
2076#if defined(MG_EXPERIMENTAL_INTERFACES)
2080#if defined(USE_DUKTAPE)
2084#if defined(USE_WEBSOCKET)
2088#if defined(USE_LUA) && defined(USE_WEBSOCKET)
2098#if !defined(NO_CACHING)
2127#if defined(__linux__)
2137#if defined(USE_WEBSOCKET)
2147#if defined(USE_HTTP2)
2162#if defined(USE_TIMERS)
2171#if defined(USE_TIMERS)
2176#if defined(USE_4_CGI)
2181#if defined(USE_TIMERS)
2190#if defined(USE_TIMERS)
2208 "index.xhtml,index.html,index.htm,"
2209 "index.lp,index.lsp,index.lua,index.cgi,"
2210 "index.shtml,index.php"},
2212 "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
2240#if defined(MG_EXPERIMENTAL_INTERFACES)
2244#if defined(USE_DUKTAPE)
2250#if defined(USE_WEBSOCKET)
2254#if defined(USE_LUA) && defined(USE_WEBSOCKET)
2263#if !defined(NO_CACHING)
2280 "config_options and enum not sync");
2337#if defined(USE_LUA) && defined(USE_WEBSOCKET)
2350#if defined(STOP_FLAG_NEEDS_LOCK)
2382#define STOP_FLAG_IS_ZERO(f) ((*(f)) == 0)
2383#define STOP_FLAG_IS_TWO(f) ((*(f)) == 2)
2384#define STOP_FLAG_ASSIGN(f, v) ((*(f)) = (v))
2389#if !defined(NUM_WEBDAV_LOCKS)
2390#define NUM_WEBDAV_LOCKS 10
2392#if !defined(LOCK_DURATION_S)
2393#define LOCK_DURATION_S 60
2423#if defined(USE_SERVER_STATS)
2451#if defined(ALTERNATIVE_QUEUE)
2463#if defined(USE_SERVER_STATS)
2471#if defined(USE_SERVER_STATS)
2483#if defined(USE_TIMERS)
2519#if defined(USE_SERVER_STATS)
2526 return &(ctx->ctx_memory);
2545#if defined(USE_HTTP2)
2546#if !defined(HTTP2_DYN_TABLE_SIZE)
2547#define HTTP2_DYN_TABLE_SIZE (256)
2563#if defined(USE_HTTP2)
2573#if defined(USE_SERVER_STATS)
2582#if defined(USE_SERVER_STATS)
2611#if defined(USE_WEBSOCKET)
2614#if defined(USE_ZLIB) && defined(USE_WEBSOCKET) \
2615 && defined(MG_EXPERIMENTAL_INTERFACES)
2639#if defined(USE_LUA) && defined(USE_WEBSOCKET)
2655#define mg_cry_internal(conn, fmt, ...) \
2656 mg_cry_internal_wrap(conn, NULL, __func__, __LINE__, fmt, __VA_ARGS__)
2658#define mg_cry_ctx_internal(ctx, fmt, ...) \
2659 mg_cry_internal_wrap(NULL, ctx, __func__, __LINE__, fmt, __VA_ARGS__)
2669#if !defined(NO_THREAD_NAME)
2670#if defined(_WIN32) && defined(_MSC_VER)
2674#pragma pack(push, 8)
2683#elif defined(__linux__)
2685#include <sys/prctl.h>
2686#include <sys/sendfile.h>
2687#if defined(ALTERNATIVE_QUEUE)
2688#include <sys/eventfd.h>
2692#if defined(ALTERNATIVE_QUEUE)
2730 if (s !=
sizeof(
u)) {
2752 if (s !=
sizeof(
u)) {
2781#if !defined(__linux__) && !defined(_WIN32) && defined(ALTERNATIVE_QUEUE)
2784 pthread_mutex_t mutex;
2819 while (!
ev->signaled) {
2860#if defined(_MSC_VER)
2864 info.dwType = 0x1000;
2866 info.dwThreadID = ~0U;
2875#elif defined(__MINGW32__)
2878#elif defined(_GNU_SOURCE) && defined(__GLIBC__) \
2879 && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12)))
2881#if defined(__MACH__) && defined(__APPLE__)
2887#elif defined(__linux__)
2912#define MG_FOPEN_MODE_NONE (0)
2915#define MG_FOPEN_MODE_READ (1)
2918#define MG_FOPEN_MODE_WRITE (2)
2921#define MG_FOPEN_MODE_APPEND (4)
2935#if !defined(NO_FILESYSTEMS)
2945 const uint8_t *
c = (
const uint8_t *)path;
2948 if ((
c ==
NULL) || (
c[0] == 0)) {
2959 if ((*
c ==
'>') || (*
c ==
'<') || (*
c ==
'|')) {
2963 if ((*
c ==
'*') || (*
c ==
'?')) {
3076 for (; *
src !=
'\0' &&
n > 1;
n--) {
3086 return tolower((
unsigned char)*s);
3098 }
while (
diff == 0 &&
s1[-1] !=
'\0' && --
len > 0);
3112 }
while (
diff == 0 &&
s1[-1] !=
'\0');
3182#if defined(__clang__)
3183#pragma clang diagnostic push
3184#pragma clang diagnostic ignored "-Wformat-nonliteral"
3190 ok = (
n >= 0) && ((
size_t)
n < buflen);
3192#if defined(__clang__)
3193#pragma clang diagnostic pop
3205 "truncating vsnprintf buffer: [%.*s]",
3206 (
int)((buflen > 200) ? 200 : (buflen - 1)),
3208 n = (
int)buflen - 1;
3250 }
else if (!ctx || ctx->
dd.config[i] ==
NULL) {
3253 return ctx->
dd.config[i];
3257#define mg_get_option DO_NOT_USE_THIS_FUNCTION_INTERNALLY__access_directly
3291 return tls->user_ptr;
3348 ports[cnt].protocol = 1;
3352 ports[cnt].protocol = 3;
3361#if defined(USE_X_DOM_SOCKET) && !defined(UNIX_DOMAIN_SOCKET_SERVER_NAME)
3362#define UNIX_DOMAIN_SOCKET_SERVER_NAME "*"
3383#if defined(USE_IPV6)
3394#if defined(USE_X_DOM_SOCKET)
3417#if !defined(REENTRANT_TIME)
3445#if defined(MG_EXTERNAL_FUNCTION_mg_cry_internal_impl)
3451#include "external_mg_cry_internal_impl.inl"
3452#elif !defined(NO_FILESYSTEMS)
3470#if defined(GCC_DIAGNOSTIC)
3471#pragma GCC diagnostic push
3472#pragma GCC diagnostic ignored "-Wformat-nonliteral"
3477#if defined(GCC_DIAGNOSTIC)
3478#pragma GCC diagnostic pop
3481 buf[
sizeof(buf) - 1] = 0;
3494 || (conn->
phys_ctx->callbacks.log_message(conn, buf) == 0)) {
3508 if (
fi.access.fp !=
NULL) {
3514 "[%010lu] [error] [client %s] ",
3537#error Must either enable filesystems or provide a custom mg_cry_internal_impl implementation
3549 fc->dom_ctx = &(ctx->
dd);
3584#define mg_cry DO_NOT_USE_THIS_FUNCTION__USE_mg_cry_internal
3600#if defined(MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE)
3615 ((
struct mg_connection *)conn)->request_info.local_uri_raw =
3650#if defined(__clang__)
3651#pragma clang diagnostic push
3652#pragma clang diagnostic ignored "-Wunreachable-code"
3663 ? (ri->
is_ssl ?
"wss" :
"ws")
3664 : (ri->
is_ssl ?
"https" :
"http"));
3668#if defined(__clang__)
3669#pragma clang diagnostic pop
3682 if ((buflen < 1) || (buf == 0) || (conn == 0)) {
3722#if defined(USE_X_DOM_SOCKET)
3761#if defined(USE_IPV6)
3869#if defined(GCC_DIAGNOSTIC)
3871#pragma GCC diagnostic push
3872#pragma GCC diagnostic ignored "-Wsign-conversion"
3877#if defined(GCC_DIAGNOSTIC)
3878#pragma GCC diagnostic pop
3897 for (i = 0; i <
num_hdr; i++) {
3899 return hdr[i].value;
3978 if (val ==
NULL || list ==
NULL || *list ==
'\0') {
3984 while (*list ==
' ' || *list ==
'\t')
3990 val->
len = ((size_t)(list - val->
ptr));
3995 val->
len = ((size_t)(list - val->
ptr));
4000 while (end >= 0 && ((val->
ptr[end] ==
' ') || (val->
ptr[end] ==
'\t')))
4002 val->
len = (size_t)(end) + (size_t)(1);
4004 if (val->
len == 0) {
4060 const char *http_version;
4086 if (http_version && (0 ==
strcmp(http_version,
"1.1"))) {
4099 if (!conn || !conn->
dom_ctx) {
4110 if (!conn || !conn->
dom_ctx) {
4135 "no-cache, no-store, "
4136 "must-revalidate, private, max-age=0",
4150#if !defined(NO_CACHING)
4185 conn,
NULL, val,
sizeof(val),
"max-age=%lu", (
unsigned long)
max_age);
4218 if (header && header[0]) {
4245 "Access-Control-Allow-Origin",
4255 "Access-Control-Allow-Credentials",
4262 "Access-Control-Allow-Headers",
4269 "Access-Control-Expose-Headers",
4276 "Access-Control-Allow-Methods",
4283#if !defined(NO_FILESYSTEMS)
4302 return "Switching Protocols";
4304 return "Processing";
4314 return "Non-Authoritative Information";
4316 return "No Content";
4318 return "Reset Content";
4320 return "Partial Content";
4322 return "Multi-Status";
4325 return "Already Reported";
4332 return "Multiple Choices";
4334 return "Moved Permanently";
4340 return "Not Modified";
4344 return "Temporary Redirect";
4346 return "Permanent Redirect";
4350 return "Bad Request";
4352 return "Unauthorized";
4354 return "Payment Required";
4360 return "Method Not Allowed";
4362 return "Not Acceptable";
4364 return "Proxy Authentication Required";
4366 return "Request Time-out";
4372 return "Length Required";
4374 return "Precondition Failed";
4376 return "Request Entity Too Large";
4378 return "Request-URI Too Large";
4380 return "Unsupported Media Type";
4382 return "Requested range not satisfiable";
4385 return "Expectation Failed";
4388 return "Misdirected Request";
4390 return "Unproccessable entity";
4395 return "Failed Dependency";
4399 return "Upgrade Required";
4402 return "Precondition Required";
4404 return "Too Many Requests";
4407 return "Request Header Fields Too Large";
4410 return "Unavailable For Legal Reasons";
4415 return "Internal Server Error";
4417 return "Not Implemented";
4419 return "Bad Gateway";
4421 return "Service Unavailable";
4423 return "Gateway Time-out";
4425 return "HTTP Version not supported";
4427 return "Variant Also Negotiates";
4429 return "Insufficient Storage";
4432 return "Loop Detected";
4435 return "Not Extended";
4437 return "Network Authentication Required";
4443 return "I am a teapot";
4445 return "Authentication Timeout";
4447 return "Enhance Your Calm";
4449 return "Login Timeout";
4451 return "Bandwidth Limit Exceeded";
4457 "Unknown HTTP response code: %u",
4464 return "Information";
4472 return "Redirection";
4476 return "Client Error";
4480 return "Server Error";
4499#if !defined(NO_FILESYSTEMS)
4516 has_body = ((status > 199) && (status != 204) && (status != 304));
4547 "Recursion when handling error %u - fall back to default",
4549#if !defined(NO_FILESYSTEMS)
4609 (i < 32) && (tstr[i] != 0) && (tstr[i] !=
',');
4632 tstr =
strchr(tstr + i,
'.');
4655 "text/plain; charset=utf-8",
4664 mg_printf(conn,
"Error %d: %s\n", status, status_text);
4692 const char *mime_type,
4693 long long content_length)
4695 if ((mime_type ==
NULL) || (*mime_type == 0)) {
4697 mime_type =
"text/html";
4705 if (content_length < 0) {
4719 (uint64_t)content_length);
4749#if defined(MG_SEND_REDIRECT_BODY)
4751 size_t content_len = 0;
4773#if defined(MG_SEND_REDIRECT_BODY)
4801 "<html><head>%s</head><body><a href=\"%s\">%s</a></body></html>",
4821#if defined(MG_SEND_REDIRECT_BODY)
4829#if defined(MG_SEND_REDIRECT_BODY)
4844#if defined(GCC_DIAGNOSTIC)
4846#pragma GCC diagnostic push
4847#pragma GCC diagnostic ignored "-Wunused-function"
4891 cv->waiting_thread =
NULL;
4899 pthread_mutex_t *mutex,
4911 ptls = &
cv->waiting_thread;
4912 for (; *
ptls !=
NULL;
ptls = &(*ptls)->next_waiting_thread)
4914 tls->next_waiting_thread =
NULL;
4937 ptls = &
cv->waiting_thread;
4938 for (; *
ptls !=
NULL;
ptls = &(*ptls)->next_waiting_thread) {
4940 *
ptls =
tls->next_waiting_thread;
4974 if (
cv->waiting_thread) {
4975 wkup =
cv->waiting_thread->pthread_cond_helper_mutex;
4976 cv->waiting_thread =
cv->waiting_thread->next_waiting_thread;
4978 ok = SetEvent(
wkup);
4992 while (
cv->waiting_thread) {
5014#if defined(ALTERNATIVE_QUEUE)
5036 return (
int)SetEvent((HANDLE)
eventhdl);
5049#if defined(GCC_DIAGNOSTIC)
5051#pragma GCC diagnostic pop
5061 for (i = 0; path[i] !=
'\0'; i++) {
5062 if (path[i] ==
'/') {
5068 if ((i > 0) && (path[i] ==
'\\')) {
5069 while ((path[i + 1] ==
'\\') || (path[i + 1] ==
'/')) {
5070 (void)
memmove(path + i + 1, path + i + 2,
strlen(path + i + 1));
5084 - ((*
s2 >=
L'A') && (*
s2 <=
L'Z') ? (*
s2 -
L'A' +
L'a') : *
s2);
5087 }
while ((
diff == 0) && (
s1[-1] != L
'\0'));
5155#if !defined(NO_FILESYSTEMS)
5181 if ((
len > 0) && (path[
len - 1] !=
' ') && (path[
len - 1] !=
'.')
5184 filep->last_modified =
5186 info.ftLastWriteTime.dwHighDateTime);
5193 info.ftCreationTime.dwHighDateTime);
5228#if defined(GCC_DIAGNOSTIC)
5230#pragma GCC diagnostic push
5231#pragma GCC diagnostic ignored "-Wunused-function"
5255 dir->result.d_name[0] =
'\0';
5297 dir->info.cFileName,
5320#if !defined(HAVE_POLL)
5349 for (i = 0; i <
n; i++) {
5368 for (i = 0; i <
n; i++) {
5393#if defined(GCC_DIAGNOSTIC)
5395#pragma GCC diagnostic pop
5414#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
5473#if !defined(NO_SSL_DL) && !defined(NO_SSL)
5477#if defined(GCC_DIAGNOSTIC)
5479#pragma GCC diagnostic push
5480#pragma GCC diagnostic ignored "-Wunused-function"
5511#if defined(GCC_DIAGNOSTIC)
5513#pragma GCC diagnostic pop
5532#if !defined(WNOHANG)
5538waitpid(pid_t pid,
int *status,
int flags)
5564 while ((
e > s) &&
isspace((
unsigned char)
e[-1])) {
5645 buf[0] = buf[1] =
'\0';
5652 pi.hProcess = (pid_t)-1;
5662 buf[
sizeof(buf) - 1] =
'\0';
5665 if ((buf[0] ==
'#') && (buf[1] ==
'!')) {
5682 "\"%s\" %s \"%s\\%s\"",
5692 "\"%s\" \"%s\\%s\"",
5709 pi.hProcess = (pid_t)-1;
5727 pi.hProcess = (pid_t)-1;
5735 if (pi.hThread !=
NULL) {
5739 return (pid_t)pi.hProcess;
5763#if !defined(NO_FILESYSTEMS)
5779 if (0 == stat(path, &
st)) {
5780 filep->size = (uint64_t)(
st.st_size);
5781 filep->last_modified =
st.st_mtime;
5796#if defined(__ZEPHYR__)
5805 "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s",
5824#if defined(__ZEPHYR__)
5826#elif defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
5851#if defined(__ZEPHYR__)
5855#elif defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
5898 if ((pid =
fork()) == -1) {
5901 }
else if (pid != 0) {
5909 if (
chdir(dir) != 0) {
5912 }
else if (
dup2(
fdin[0], 0) == -1) {
5914 "%s: dup2(%d, 0): %s",
5920 "%s: dup2(%d, 1): %s",
5926 "%s: dup2(%d, 2): %s",
5936 (void)close(
fdin[0]);
5937 (void)close(
fdout[1]);
5938 (void)close(
fderr[1]);
5941 (void)close(
fdin[1]);
5942 (void)close(
fdout[0]);
5943 (void)close(
fderr[0]);
5950 memset(&sa, 0,
sizeof(sa));
5959 "%s: execle(%s): %s",
5975 "%s: execle(%s %s): %s",
6026 static uint64_t
lfsr = 0;
6027 static uint64_t
lcg = 0;
6040 lcg =
lcg * 6364136223846793005LL + 1442695040888963407LL;
6064 if ((
n == 1) && ((
pfd[0].events &
POLLERR) == 0)) {
6133 typedef size_t len_t;
6146#if defined(NO_SSL) && !defined(USE_MBEDTLS) && !defined(USE_GNUTLS)
6156#if defined(USE_MBEDTLS)
6172#elif defined(USE_GNUTLS)
6177 "SSL write failed (%d): %s",
6185#elif !defined(NO_SSL)
6209 n = (
int)fwrite(buf, 1, (
size_t)
len, fp);
6218 err = (
n < 0) ?
ERRNO : 0;
6233 if ((
n > 0) || ((
n == 0) && (
len == 0))) {
6327 }
else if (
n == 0) {
6357 typedef size_t len_t;
6378#if defined(USE_MBEDTLS)
6379 }
else if (conn->
ssl !=
NULL) {
6401 conn->
phys_ctx->thread_shutdown_notification_socket;
6441#elif defined(USE_GNUTLS)
6442 }
else if (conn->
ssl !=
NULL) {
6464 conn->
phys_ctx->thread_shutdown_notification_socket;
6485 "SSL read failed (%d): %s",
6500#elif !defined(NO_SSL)
6501 }
else if (conn->
ssl !=
NULL) {
6521 conn->
phys_ctx->thread_shutdown_notification_socket;
6574 conn->
phys_ctx->thread_shutdown_notification_socket;
6626 DEBUG_TRACE(
"read()/recv() failed, error %d", err);
6648 DEBUG_TRACE(
"read()/recv() failed, error %d", err);
6683 }
else if (
n == -1) {
6692 }
else if (
n == 0) {
6709 while (
mg_read(conn, buf,
sizeof(buf)) > 0)
6731 if (content_len < 0) {
6785#if defined(USE_SERVER_STATS)
6787 conn->conn_state = 4;
6793#if defined(USE_SERVER_STATS)
6794 conn->conn_state = 5;
6814#if defined(USE_HTTP2)
6816#error "HTTP2 requires ALPN, ALPN requires SSL/TLS"
6823 if (conn->protocol_type == PROTOCOL_TYPE_HTTP2) { \
6824 http2_must_use_http1(conn); \
6825 DEBUG_TRACE("%s", "must use HTTP/1.x"); \
6877 || (
x[1] !=
'\n')) {
6891 for (i = 0; i < (
sizeof(lenbuf) - 1); i++) {
6896 if ((i > 0) && (lenbuf[i] ==
';')) {
6910 && lenbuf[i] !=
'\r');
6912 if ((i > 0) && (lenbuf[i] ==
'\r')
6913 && (lenbuf[i - 1] !=
'\r')) {
6916 if ((i > 1) && (lenbuf[i] ==
'\n')
6917 && (lenbuf[i - 1] ==
'\r')) {
6926 if (!
isxdigit((
unsigned char)lenbuf[i])) {
6932 if ((end ==
NULL) || (*end !=
'\r')) {
6962 if (lenbuf[0] ==
'\r')
6970 if (lenbuf[0] ==
'\n')
7014#if defined(USE_HTTP2)
7039 buf = (
const char *)buf +
total;
7060 buf = (
const char *)buf +
n;
7117#if defined(GCC_DIAGNOSTIC)
7120#pragma GCC diagnostic push
7121#pragma GCC diagnostic ignored "-Wformat-nonliteral"
7148 (*buf)[
size - 1] = 0;
7230#if defined(GCC_DIAGNOSTIC)
7232#pragma GCC diagnostic pop
7276#define HEXTOI(x) (isdigit(x) ? (x - '0') : (x - 'W'))
7327 const char *
p, *
e, *s;
7338 e =
data + data_len;
7350 s = (
const char *)
memchr(
p,
'&', (
size_t)(
e -
p));
7414 while ((*
data ==
' ') || (*
data ==
'\t')) {
7426 while ((*
b != 0) && (*
b !=
'&') && (*
b !=
'=')) {
7433 }
else if (*
b ==
'&') {
7461 for (i = 0; i < num; i++) {
7482 const char *s, *
p, *end;
7507 if ((*s ==
'"') && (
p[-1] ==
'"') && (
p > s + 1)) {
7531 static const char *
b64 =
7532 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7550 for (i =
j = 0; i <
src_len; i += 3) {
7556 dst[
j++] =
b64[((
a & 3) << 4) | (
b >> 4)];
7558 dst[
j++] =
b64[(
b & 15) << 2 | (
c >> 6)];
7564 while (
j % 4 != 0) {
7582 return (
unsigned char)(
letter -
'A');
7585 return (
unsigned char)(
letter -
'a' + 26);
7588 return (
unsigned char)(
letter -
'0' + 52);
7610 unsigned char a,
b,
c,
d;
7619 for (i = 0; i <
src_len; i += 4) {
7644 + (
unsigned char)(
b >> 4));
7652 + (
unsigned char)(
c >> 2));
7658 (
unsigned char)((
unsigned char)(
c << 6) +
d);
7714 return (!
strcmp(s,
"PROPFIND") || !
strcmp(s,
"PROPPATCH")
7723#if !defined(NO_FILES)
7741#if defined(USE_DUKTAPE)
7808 while ((
n > 0) && (path[
n - 1] ==
'/')) {
7912#if !defined(NO_FILES)
7924#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE)
7949#if defined(USE_WEBSOCKET)
7951#if !defined(NO_FILES)
7969#if !defined(NO_FILES)
8120#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE)
8180 DEBUG_TRACE(
"Substitute script %s serving path %s",
8227#if !defined(NO_FILES)
8248 for (i = 0; i < buflen; i++) {
8250 const unsigned char c = (
unsigned char)buf[i];
8252 if ((
c < 128) && ((char)
c !=
'\r') && ((char)
c !=
'\n')
8258 if (i < buflen - 1) {
8259 if ((buf[i] ==
'\n') && (buf[i + 1] ==
'\n')) {
8266 if (i < buflen - 3) {
8267 if ((buf[i] ==
'\r') && (buf[i + 1] ==
'\n') && (buf[i + 2] ==
'\r')
8268 && (buf[i + 3] ==
'\n')) {
8279#if !defined(NO_CACHING)
8302 time_t
result = (time_t)0;
8306 "%d/%3s/%d %d:%d:%d",
8315 "%d %3s %d %d:%d:%d",
8324 "%*3s, %d %3s %d %d:%d:%d",
8333 "%d-%3s-%d %d:%d:%d",
8344 tm.tm_year =
year - 1900;
8461 }
while ((*
in != 0) && (*
in !=
'/'));
8499 }
else if (*
in ==
'/') {
8504 }
while (*
in ==
'/');
8514static const struct {
8515 const char *extension;
8517 const char *mime_type;
8522 {
".bin", 4,
"application/octet-stream"},
8523 {
".cer", 4,
"application/pkix-cert"},
8524 {
".crl", 4,
"application/pkix-crl"},
8525 {
".crt", 4,
"application/pkix-cert"},
8526 {
".deb", 4,
"application/octet-stream"},
8527 {
".dmg", 4,
"application/octet-stream"},
8528 {
".dll", 4,
"application/octet-stream"},
8529 {
".doc", 4,
"application/msword"},
8530 {
".eps", 4,
"application/postscript"},
8531 {
".exe", 4,
"application/octet-stream"},
8532 {
".iso", 4,
"application/octet-stream"},
8533 {
".js", 3,
"application/javascript"},
8534 {
".json", 5,
"application/json"},
8535 {
".mjs", 4,
"application/javascript"},
8536 {
".msi", 4,
"application/octet-stream"},
8537 {
".pem", 4,
"application/x-pem-file"},
8538 {
".pdf", 4,
"application/pdf"},
8539 {
".ps", 3,
"application/postscript"},
8540 {
".rtf", 4,
"application/rtf"},
8541 {
".wasm", 5,
"application/wasm"},
8542 {
".xhtml", 6,
"application/xhtml+xml"},
8543 {
".xsl", 4,
"application/xml"},
8544 {
".xslt", 5,
"application/xml"},
8547 {
".ttf", 4,
"application/font-sfnt"},
8548 {
".cff", 4,
"application/font-sfnt"},
8549 {
".otf", 4,
"application/font-sfnt"},
8550 {
".aat", 4,
"application/font-sfnt"},
8551 {
".sil", 4,
"application/font-sfnt"},
8552 {
".pfr", 4,
"application/font-tdpfr"},
8553 {
".woff", 5,
"application/font-woff"},
8554 {
".woff2", 6,
"application/font-woff2"},
8557 {
".mp3", 4,
"audio/mpeg"},
8558 {
".oga", 4,
"audio/ogg"},
8559 {
".ogg", 4,
"audio/ogg"},
8562 {
".gif", 4,
"image/gif"},
8563 {
".ief", 4,
"image/ief"},
8564 {
".jpeg", 5,
"image/jpeg"},
8565 {
".jpg", 4,
"image/jpeg"},
8566 {
".jpm", 4,
"image/jpm"},
8567 {
".jpx", 4,
"image/jpx"},
8568 {
".png", 4,
"image/png"},
8569 {
".svg", 4,
"image/svg+xml"},
8570 {
".tif", 4,
"image/tiff"},
8571 {
".tiff", 5,
"image/tiff"},
8574 {
".wrl", 4,
"model/vrml"},
8577 {
".css", 4,
"text/css"},
8578 {
".csv", 4,
"text/csv"},
8579 {
".htm", 4,
"text/html"},
8580 {
".html", 5,
"text/html"},
8581 {
".sgm", 4,
"text/sgml"},
8582 {
".shtm", 5,
"text/html"},
8583 {
".shtml", 6,
"text/html"},
8584 {
".txt", 4,
"text/plain"},
8585 {
".xml", 4,
"text/xml"},
8588 {
".mov", 4,
"video/quicktime"},
8589 {
".mp4", 4,
"video/mp4"},
8590 {
".mpeg", 5,
"video/mpeg"},
8591 {
".mpg", 4,
"video/mpeg"},
8592 {
".ogv", 4,
"video/ogg"},
8593 {
".qt", 3,
"video/quicktime"},
8598 {
".arj", 4,
"application/x-arj-compressed"},
8599 {
".gz", 3,
"application/x-gunzip"},
8600 {
".rar", 4,
"application/x-arj-compressed"},
8601 {
".swf", 4,
"application/x-shockwave-flash"},
8602 {
".tar", 4,
"application/x-tar"},
8603 {
".tgz", 4,
"application/x-tar-gz"},
8604 {
".torrent", 8,
"application/x-bittorrent"},
8605 {
".ppt", 4,
"application/x-mspowerpoint"},
8606 {
".xls", 4,
"application/x-msexcel"},
8607 {
".zip", 4,
"application/x-zip-compressed"},
8611 {
".flac", 5,
"audio/flac"},
8612 {
".aif", 4,
"audio/x-aif"},
8613 {
".m3u", 4,
"audio/x-mpegurl"},
8614 {
".mid", 4,
"audio/x-midi"},
8615 {
".ra", 3,
"audio/x-pn-realaudio"},
8616 {
".ram", 4,
"audio/x-pn-realaudio"},
8617 {
".wav", 4,
"audio/x-wav"},
8618 {
".bmp", 4,
"image/bmp"},
8619 {
".ico", 4,
"image/x-icon"},
8620 {
".pct", 4,
"image/x-pct"},
8621 {
".pict", 5,
"image/pict"},
8622 {
".rgb", 4,
"image/x-rgb"},
8623 {
".webm", 5,
"video/webm"},
8624 {
".asf", 4,
"video/x-ms-asf"},
8625 {
".avi", 4,
"video/x-msvideo"},
8626 {
".m4v", 4,
"video/x-m4v"},
8646 return "text/plain";
8656 const char *list, *
ext;
8690 static const char *hex =
"0123456789abcdef";
8692 for (;
len--;
p++) {
8693 *to++ = hex[
p[0] >> 4];
8694 *to++ = hex[
p[0] & 0x0f];
8733 const char *response)
8739 || (qop ==
NULL) || (response ==
NULL)) {
8744 if (
strlen(response) != 32) {
8767#if !defined(NO_FILESYSTEMS)
8796 &&
filep->stat.is_directory) {
8885 split =
strchr(buf,
':');
8916 while (
isspace((
unsigned char)*s)) {
8932 if (*
name ==
'\0') {
8953#if !defined(NO_NONCE_CHECK)
8960 if ((s ==
NULL) || (*s != 0)) {
8965 nonce ^= conn->
dom_ctx->auth_nonce_mask;
8975 if (nonce < (uint64_t)conn->
phys_ctx->start_time) {
8982 if (nonce >= ((uint64_t)conn->
phys_ctx->start_time
8983 + conn->
dom_ctx->nonce_count)) {
9014#define INITIAL_DEPTH 9
9015#if INITIAL_DEPTH <= 0
9016#error Bad INITIAL_DEPTH for recursion, set to at least 1
9019#if !defined(NO_FILESYSTEMS)
9086 "%s: cannot open authorization file: %s",
9095 "%s: syntax error in authorization file: %s",
9104 "%s: syntax error in authorization file: %s",
9115 "%s: syntax error in authorization file: %s",
9125 switch (
workdata->auth_header.type) {
9134 workdata->auth_header.plain_password,
9140 workdata->conn->request_info.request_method,
9177 conn->request_info.remote_user =
9219#if !defined(NO_FILESYSTEMS)
9226 if (!conn || !conn->
dom_ctx) {
9244 "%s: cannot open %s: %s",
9275 uint64_t nonce = (uint64_t)(conn->
phys_ctx->start_time);
9284 nonce += conn->
dom_ctx->nonce_count;
9288 nonce ^= conn->
dom_ctx->auth_nonce_mask;
9302 "Digest qop=\"auth\", realm=\"%s\", "
9332#if !defined(NO_FILES)
9361 int found = 0, i,
result = 1;
9362 char line[512],
u[256],
d[256],
h[256];
9363 struct stat
st = {0};
9389 for (i = 0; ((i < 255) && (user[i] != 0)); i++) {
9390 if (
iscntrl((
unsigned char)user[i])) {
9397 for (i = 0; ((i < 255) && (domain[i] != 0)); i++) {
9398 if (
iscntrl((
unsigned char)domain[i])) {
9414 if (
st.st_size > 10485760) {
9441 if (
sscanf(
line,
"%255[^:]:%255[^:]:%255s",
u,
d,
h) != 3) {
9451 if ((
ha1 !=
NULL) && (!found)) {
9502 if ((
ha1 !=
NULL) && (!found)) {
9503 if (
fprintf(fp,
"%s:%s:%s\n", user, domain,
ha1) < 6) {
9540 return (port <= 0xffff);
9572 if ((
dstlen >= (
size_t)res->ai_addrlen)
9573 && (res->ai_addr->sa_family ==
af)) {
9574 memcpy(
dst, res->ai_addr, res->ai_addrlen);
9600 memset(sa, 0,
sizeof(*sa));
9603 if (error !=
NULL) {
9615#if defined(USE_X_DOM_SOCKET)
9619 if (
hostlen >=
sizeof(sa->sun.sun_path)) {
9620 if (error !=
NULL) {
9627 "host length exceeds limit");
9634 if (error !=
NULL) {
9646#if !defined(NO_SSL) && !defined(USE_MBEDTLS) && !defined(USE_GNUTLS) \
9647 && !defined(NO_SSL_DL)
9648#if defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0)
9650 if (error !=
NULL) {
9657 "SSL is not initialized");
9670 "SSL is not initialized");
9679#if defined(USE_X_DOM_SOCKET)
9685 memset(sa->sun.sun_path, 0,
sizeof(sa->sun.sun_path));
9690 sa->
sin.sin_port =
htons((uint16_t)port);
9692#if defined(USE_IPV6)
9694 sa->sin6.sin6_port =
htons((uint16_t)port);
9696 }
else if (host[0] ==
'[') {
9704 sa->sin6.sin6_port =
htons((uint16_t)port);
9713 if (error !=
NULL) {
9728#if defined(USE_IPV6)
9733#if defined(USE_X_DOM_SOCKET)
9734 else if (
ip_ver == -99) {
9740 if (error !=
NULL) {
9754 if (error !=
NULL) {
9761 "Cannot set socket to non-blocking: %s",
9777#if defined(USE_IPV6)
9781 (
struct sockaddr *)((
void *)&sa->sin6),
9785#if defined(USE_X_DOM_SOCKET)
9786 else if (
ip_ver == -99) {
9789 (
struct sockaddr *)((
void *)&sa->sun),
9839 if (error !=
NULL) {
9845 "connect(%s:%d): timeout",
9867 if (error !=
NULL) {
9874 "connect(%s:%d): error %s",
9892 static const char *hex =
"0123456789abcdef";
9896 for (; ((*
src !=
'\0') && (pos < end));
src++, pos++) {
9900 }
else if (pos + 2 < end) {
9902 pos[1] = hex[(
unsigned char)*
src >> 4];
9903 pos[2] = hex[(
unsigned char)*
src & 0xf];
9911 return (*
src ==
'\0') ? (
int)(pos -
dst) : -1;
9922#if defined(REENTRANT_TIME)
9945 }
else if (*
p ==
'<') {
9947 }
else if (*
p ==
'>') {
9953 if (
de->
file.is_directory) {
9963 if (
de->
file.size < 1024) {
9970 }
else if (
de->
file.size < 0x100000) {
9976 (
double)
de->
file.size / 1024.0);
9977 }
else if (
de->
file.size < 0x40000000) {
9983 (
double)
de->
file.size / 1048576);
9990 (
double)
de->
file.size / 1073741824);
9997#if defined(REENTRANT_TIME)
10008 "<tr><td><a href=\"%s%s\">%s%s</a></td>"
10009 "<td> %s</td><td> %s</td></tr>\n",
10011 de->
file.is_directory ?
"/" :
"",
10013 de->
file.is_directory ?
"/" :
"",
10026 const char *query_string = (
const char *)(arg !=
NULL ? arg :
"");
10028 const struct de *
a = (
const struct de *)
p1, *
b = (
const struct de *)
p2;
10031 if ((query_string ==
NULL) || (query_string[0] ==
'\0')) {
10032 query_string =
"n";
10036 if (
a->file.is_directory && !
b->file.is_directory) {
10038 }
else if (!
a->file.is_directory &&
b->file.is_directory) {
10043 if (*query_string ==
's') {
10046 : ((
a->file.size >
b->file.size) ? 1 : -1);
10047 }
else if (*query_string ==
'd') {
10049 (
a->file.last_modified ==
b->file.last_modified)
10051 : ((
a->file.last_modified >
b->file.last_modified) ? 1
10083#if !defined(NO_FILESYSTEMS)
10088 int (*cb)(
struct de *,
void *))
10108 conn, &
truncated, path,
sizeof(path),
"%s/%s", dir,
dp->d_name);
10124 "%s: mg_stat(%s) failed: %s",
10142#if !defined(NO_FILES)
10165 conn, &
truncated, path,
sizeof(path),
"%s/%s", dir,
dp->d_name);
10182 "%s: mg_stat(%s) failed: %s",
10189 if (
de.
file.is_directory) {
10217#if !defined(NO_FILESYSTEMS)
10222 struct de *entries =
dsd->entries;
10224 if ((entries ==
NULL) || (
dsd->num_entries >=
dsd->arr_size)) {
10229 dsd->arr_size * 2 *
sizeof(entries[0]));
10230 if (entries ==
NULL) {
10234 dsd->entries = entries;
10235 dsd->arr_size *= 2;
10243 dsd->num_entries++;
10266 "Error: Cannot open directory\nopendir(%s): %s",
10276 if (title[
strcspn(title,
"&<>")]) {
10284 }
else if (*
p ==
'<') {
10286 }
else if (*
p ==
'>') {
10309 "text/html; charset=utf-8",
10318 "<html><head><title>Index of %s</title>"
10319 "<style>th {text-align: left;}</style></head>"
10320 "<body><h1>Index of %s</h1><pre><table cellpadding=\"0\">"
10321 "<tr><th><a href=\"?n%c\">Name</a></th>"
10322 "<th><a href=\"?d%c\">Modified</a></th>"
10323 "<th><a href=\"?s%c\">Size</a></th></tr>"
10324 "<tr><td colspan=\"3\"><hr></td></tr>",
10334 "<tr><td><a href=\"%s\">%s</a></td>"
10335 "<td> %s</td><td> %s</td></tr>\n",
10337 "Parent directory",
10345 sizeof(
data.entries[0]),
10348 for (i = 0; i <
data.num_entries; i++) {
10355 mg_printf(conn,
"%s",
"</table></pre></body></html>");
10373 if (!
filep || !conn) {
10379 : (int64_t)(
filep->stat.size);
10384#if defined(__linux__)
10398 (size_t)((
len < 0x7FFFF000) ?
len : 0x7FFFF000);
10430 "%s: fseeko() failed: %s",
10437 "Error: Unable to access file at requested position.");
10500 (
unsigned long)
filestat->last_modified,
10515 "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s",
10524#if defined(USE_ZLIB)
10525#include "mod_zlib.inl"
10529#if !defined(NO_FILESYSTEMS)
10534 const char *mime_type,
10540 int64_t cl,
r1,
r2;
10544 const char *encoding = 0;
10547#if defined(USE_ZLIB)
10560 if (mime_type ==
NULL) {
10569 "Error: File size is too large to send\n%" INT64_FMT,
10573 cl = (int64_t)
filep->stat.size;
10577#if defined(USE_ZLIB)
10590 if (
filep->stat.is_gzipped) {
10596 "Error: Path of zipped file too long (%s)",
10604#if defined(USE_ZLIB)
10618 cl = (int64_t)
filep->stat.size;
10622#if defined(USE_ZLIB)
10632 "Error: Cannot open file\nfopen(%s): %s",
10648 if (
filep->stat.is_gzipped) {
10653 "Error: Range requests in gzipped files are not supported");
10659 cl = (
n == 2) ? (((
r2 > cl) ? cl :
r2) -
r1 + 1) : (cl -
r1);
10670#if defined(USE_ZLIB)
10678#if defined(USE_ZLIB)
10701#if defined(USE_ZLIB)
10732 if (
range[0] != 0) {
10746#if defined(USE_ZLIB)
10776#if !defined(NO_CACHING)
10819#if !defined(NO_FILESYSTEMS)
10830 const char *mime_type)
10839 const char *mime_type,
10850#if !defined(NO_CACHING)
10856 if (file.
stat.is_directory) {
10864 "Error: Directory listing denied");
10891 for (s =
p = path + 2; (
p =
strchr(s,
'/')) !=
NULL; s = ++
p) {
10892 len = (size_t)(
p - path);
10893 if (
len >=
sizeof(buf)) {
10910 if (
p[1] ==
'\0') {
10925 "%s: Cannot remove invalid file %s",
10962 n = (
int)fwrite(buf, 1, (
size_t)
ret,
fi.access.fp);
10996 while ((
unsigned char)**
ppw > 127 ||
isgraph((
unsigned char)**
ppw)) {
11003 if ((**
ppw !=
'\r') && (**
ppw !=
'\n')) {
11008 if (**
ppw !=
' ') {
11040 int num_headers = 0;
11046 while ((*
dp !=
':') && (*
dp >= 33) && (*
dp <= 126)) {
11055 while (*
dp ==
' ') {
11067 hdr[i].name = *buf;
11072 }
while ((*
dp ==
' ') || (*
dp ==
'\t'));
11078 while ((*
dp != 0) && (*
dp !=
'\r') && (*
dp !=
'\n')) {
11094 num_headers = i + 1;
11101 if ((
dp[0] ==
'\r') || (
dp[0] ==
'\n')) {
11112 return num_headers;
11129 {
"GET", 0, 1, 1, 1, 1},
11130 {
"POST", 1, 1, 0, 0, 0},
11131 {
"PUT", 1, 0, 0, 1, 0},
11132 {
"DELETE", 0, 0, 0, 1, 0},
11133 {
"HEAD", 0, 0, 1, 1, 1},
11134 {
"OPTIONS", 0, 0, 1, 1, 0},
11135 {
"CONNECT", 1, 1, 0, 0, 0},
11139 {
"PATCH", 1, 0, 0, 0, 0},
11143 {
"PROPFIND", 0, 1, 1, 1, 0},
11149 {
"MKCOL", 0, 0, 0, 1, 0},
11162 {
"LOCK", 1, 1, 0, 0, 0},
11163 {
"UNLOCK", 1, 0, 0, 0, 0},
11164 {
"PROPPATCH", 1, 1, 0, 0, 0},
11165 {
"COPY", 1, 0, 0, 0, 0},
11166 {
"MOVE", 1, 1, 0, 0, 0},
11177 {
"REPORT", 1, 1, 1, 1, 1},
11184 {
NULL, 0, 0, 0, 0, 0}
11243 while ((
len > 0) &&
isspace((
unsigned char)*buf)) {
11255 if (
iscntrl((
unsigned char)*buf)) {
11266 if ((*buf == 0) || (*buf ==
'\r') || (*buf ==
'\n')) {
11329 while ((
len > 0) &&
isspace((
unsigned char)*buf)) {
11341 if (
iscntrl((
unsigned char)*buf)) {
11352 if ((*buf == 0) || (*buf ==
'\r') || (*buf ==
'\n')) {
11358 if (
strncmp(buf,
"HTTP/", 5) != 0) {
11363 if (!
isgraph((
unsigned char)buf[0])) {
11381 if ((
l < 100) || (
l >= 1000) || ((
tmp2 - tmp) != 3) || (*
tmp2 != 0)) {
11392 while (
isprint((
unsigned char)*buf)) {
11395 if ((*buf !=
'\r') && (*buf !=
'\n')) {
11402 }
while (
isspace((
unsigned char)*buf));
11427 int request_len,
n = 0;
11456 while (request_len == 0) {
11492 return request_len;
11496#if !defined(NO_CGI) || !defined(NO_FILES)
11521 (void)
mg_printf(conn,
"%s",
"HTTP/1.1 100 Continue\r\n\r\n");
11559#if defined(USE_TIMERS)
11561#define TIMER_API static
11562#include "timer.inl"
11567#if !defined(NO_CGI)
11600 size_t i,
n, space;
11605 if ((
env->varlen -
env->varused) < 2) {
11607 "%s: Cannot register CGI variable [%s]",
11614 space = (
env->buflen -
env->bufused);
11626 "%s: Cannot allocate memory for CGI variable [%s]",
11634 for (i = 0,
n = 0; i <
env->varused; i++) {
11638 space = (
env->buflen -
env->bufused);
11688 "%s: Not enough memory for environmental buffer",
11698 "%s: Not enough memory for environmental variables",
11709 "FALLBACK_DOCUMENT_ROOT=%s",
11715 addenv(
env,
"%s",
"GATEWAY_INTERFACE=CGI/1.1");
11716 addenv(
env,
"%s",
"SERVER_PROTOCOL=HTTP/1.1");
11717 addenv(
env,
"%s",
"REDIRECT_STATUS=200");
11734 if (conn->
request_info.local_uri[uri_len - 1] !=
'/') {
11742 "SCRIPT_NAME=%s%s",
11750 "SCRIPT_NAME=%.*s",
11760 "PATH_TRANSLATED=%s%s",
11801 if ((s =
getenv(
"ProgramFiles(x86)")) !=
NULL) {
11802 addenv(
env,
"ProgramFiles(x86)=%s", s);
11805 if ((s =
getenv(
"LD_LIBRARY_PATH")) !=
NULL) {
11820 for (i = 0; i < conn->
request_info.num_headers; i++) {
11831 "%s: HTTP header variable too long [%s]",
11858 env->buf[
env->bufused] =
'\0';
11882 if ((
ret_pid != (pid_t)-1) && (status == 0)) {
11888 while (
waitpid(
proc->pid, &status, 0) != (pid_t)-1)
11891 DEBUG_TRACE(
"CGI timer: Child process %d already stopped\n",
proc->pid);
11913 int fdin[2] = {-1, -1},
fdout[2] = {-1, -1},
fderr[2] = {-1, -1};
11914 const char *status, *status_text;
11920 pid_t pid = (pid_t)-1;
11925#if defined(USE_TIMERS)
11943 buflen = conn->
phys_ctx->max_request_size;
11974 "Error: CGI program \"%s\": Can not create CGI pipes: %s",
11979 "Error: Cannot create CGI pipe: %s",
11996 if (
pid == (pid_t)-1) {
12000 "Error: CGI program \"%s\": Can not spawn CGI process: %s",
12011 proc->references = 1;
12013#if defined(USE_TIMERS)
12015 proc->references = 2;
12032 (void)close(
fdin[0]);
12033 (void)close(
fdout[1]);
12034 (void)close(
fderr[1]);
12042 "Error: CGI program \"%s\": Can not open fd: %s",
12047 "Error: CGI can not open fd\nfdopen: %s",
12055 fout.access.fp = out;
12066 "Error: CGI program \"%s\": Forward body data failed",
12086 "Error: Not enough memory for CGI buffer (%u bytes)",
12087 (
unsigned int)buflen);
12090 "Error: CGI program \"%s\": Not enough memory for buffer (%u "
12093 (
unsigned int)buflen);
12105 i =
pull_all(err, conn, buf, (
int)buflen);
12110 "Error: CGI program \"%s\" sent error "
12118 "Error: CGI program \"%s\" failed.",
12124 "Error: CGI program sent malformed or too big "
12125 "(>%u bytes) HTTP headers: [%.*s]",
12132 "Error: CGI program sent malformed or too big "
12133 "(>%u bytes) HTTP headers: [%.*s]",
12148 status_text =
"OK";
12152 status_text = status;
12153 while (
isdigit((
unsigned char)*status_text) || *status_text ==
' ') {
12195 if (
pid != (pid_t)-1) {
12199 if (
fdin[0] != -1) {
12202 if (
fdout[1] != -1) {
12205 if (
fderr[1] != -1) {
12211 }
else if (
fdin[1] != -1) {
12217 }
else if (
fdout[0] != -1) {
12223 }
else if (
fderr[0] != -1) {
12232#if !defined(NO_FILES)
12239 if (conn ==
NULL) {
12249 "%s: mg_stat(%s) failed: %s",
12255 if (
de.
file.last_modified) {
12298 "Error processing %s: %s",
12325 if (conn ==
NULL) {
12341 if (root !=
NULL) {
12388 "Cannot overwrite file: %s",
12396 "Destination already exists: %s",
12427 "Destination already exists: %s",
12484 if (conn ==
NULL) {
12494 if (file.
stat.is_directory) {
12511 "Error: Put not possible\nReplacing %s is not allowed",
12543 "Error: Path too long\nput_dir(%s): %s",
12553 "Error: Can not create directory\nput_dir(%s): %s",
12566 "Error: Can not create file\nfopen(%s): %s",
12580 "Error: Internal error processing file %s",
12620 "Error: Cannot delete file\nFile %s not found",
12627 if (
de.
file.is_directory) {
12640 if (access(path,
W_OK) != 0) {
12645 "Error: Delete not possible\nDeleting %s is not allowed",
12663 "Error: Cannot delete file\nremove(%s): %s",
12671#if !defined(NO_FILESYSTEMS)
12687 if (conn ==
NULL) {
12694 if (
sscanf(tag,
" virtual=\"%511[^\"]\"", file_name) == 1) {
12696 file_name[511] = 0;
12705 }
else if (
sscanf(tag,
" abspath=\"%511[^\"]\"", file_name) == 1) {
12708 file_name[511] = 0;
12712 }
else if ((
sscanf(tag,
" file=\"%511[^\"]\"", file_name) == 1)
12713 || (
sscanf(tag,
" \"%511[^\"]\"", file_name) == 1)) {
12715 file_name[511] = 0;
12726 sizeof(path) -
len,
12737 mg_cry_internal(conn,
"SSI #include path length overflow: [%s]", tag);
12743 "Cannot open SSI #include: [%s]: fopen(%s): %s",
12760#if !defined(NO_POPEN)
12764 char cmd[1024] =
"";
12767 if (
sscanf(tag,
" \"%1023[^\"]\"",
cmd) != 1) {
12773 "Cannot SSI #exec: [%s]: %s",
12830 if ((
len > 12) && !
memcmp(buf + 5,
"include", 7)) {
12832#if !defined(NO_POPEN)
12833 }
else if ((
len > 9) && !
memcmp(buf + 5,
"exec", 4)) {
12856 buf[
len++] = (char)(ch & 0xff);
12858 if ((
len == 5) && !
memcmp(buf,
"<!--#", 5)) {
12863 if ((
len + 2) > (
int)
sizeof(buf)) {
12889 buf[
len++] = (char)(ch & 0xff);
12891 if (
len == (
int)
sizeof(buf)) {
12923 "Error: Cannot read file\nfopen(%s): %s",
12949#if !defined(NO_FILES)
13019 "<d:href>%s</d:href>"
13022 "<d:resourcetype>%s</d:resourcetype>"
13023 "<d:getcontentlength>%" INT64_FMT "</d:getcontentlength>"
13024 "<d:getlastmodified>%s</d:getlastmodified>"
13025 "<d:lockdiscovery>",
13027 filep->is_directory ?
"<d:collection/>" :
"",
13036 "<d:locktype><d:write/></d:locktype>"
13037 "<d:lockscope><d:exclusive/></d:lockscope>"
13038 "<d:depth>0</d:depth>"
13039 "<d:owner>%s</d:owner>"
13040 "<d:timeout>Second-%u</d:timeout>"
13042 "<d:href>%s</d:href>"
13044 "</d:activelock>\n",
13052 "</d:lockdiscovery>"
13054 "<d:status>HTTP/1.1 200 OK</d:status>"
13056 "</d:response>\n");
13095 "application/xml; charset=utf-8",
13101 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
13102 "<d:multistatus xmlns:d='DAV:'>\n");
13109 if (
filep->is_directory
13116 mg_printf(conn,
"%s\n",
"</d:multistatus>");
13221 "application/xml; charset=utf-8",
13228 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
13229 "<d:prop xmlns:d=\"DAV:\">\n"
13230 " <d:lockdiscovery>\n"
13231 " <d:activelock>\n"
13232 " <d:lockscope><d:exclusive/></d:lockscope>\n"
13233 " <d:locktype><d:write/></d:locktype>\n"
13235 " <d:href>%s</d:href>\n"
13237 " <d:timeout>Second-%u</d:timeout>\n"
13238 " <d:locktoken><d:href>%s</d:href></d:locktoken>\n"
13240 " <d:href>%s</d:href>\n"
13242 " </d:activelock>\n"
13243 " </d:lockdiscovery>\n"
13301 "application/xml; charset=utf-8",
13309 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
13310 "<d:multistatus xmlns:d='DAV:'>\n"
13311 "<d:response>\n<d:href>%s</d:href>\n",
13314 "<d:propstat><d:status>HTTP/1.1 403 "
13315 "Forbidden</d:status></d:propstat>\n");
13316 mg_printf(conn,
"%s\n",
"</d:response></d:multistatus>");
13357#if defined(USE_LUA)
13358#include "mod_lua.inl"
13361#if defined(USE_DUKTAPE)
13362#include "mod_duktape.inl"
13365#if defined(USE_WEBSOCKET)
13367#if !defined(NO_SSL_DL)
13368#if !defined(OPENSSL_API_3_0)
13369#define SHA_API static
13377 static const char *
magic =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
13380#if !defined(OPENSSL_API_3_0)
13394#if defined(OPENSSL_API_3_0)
13397 (
unsigned char *)
sha,
13408 "HTTP/1.1 101 Switching Protocols\r\n"
13409 "Upgrade: websocket\r\n"
13410 "Connection: Upgrade\r\n"
13411 "Sec-WebSocket-Accept: %s\r\n",
13414#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES)
13419 if (conn->
request_info.acceptedWebSocketSubprotocol) {
13421 "Sec-WebSocket-Protocol: %s\r\n\r\n",
13431#if !defined(MG_MAX_UNANSWERED_PING)
13437#define MG_MAX_UNANSWERED_PING (5)
13444 void *callback_data)
13450 unsigned char *buf = (
unsigned char *)conn->
buf + conn->
request_len;
13459 uint64_t data_len = 0;
13464 unsigned char mask[4];
13469 unsigned char mem[4096];
13494 DEBUG_TRACE(
"Websocket connection %s:%u start data processing loop",
13497 conn->in_websocket_handling = 1;
13507 len = buf[1] & 127;
13508 mask_len = (buf[1] & 128) ? 4 : 0;
13516 data_len = ((((size_t)buf[2]) << 8) + buf[3]);
13525 if (data_len > (uint64_t)0x7FFF0000ul) {
13530 "websocket out of memory; closing connection");
13540 if ((
size_t)data_len > (
size_t)
sizeof(
mem)) {
13549 "websocket out of memory; closing connection");
13570 while ((uint64_t)
len < data_len) {
13574 (
int)(data_len -
len),
13579 }
else if (
n > 0) {
13590 "Websocket pull failed; closing connection");
13623 for (i = 0; i < (size_t)data_len; i++) {
13656#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES)
13659 if (!conn->websocket_deflate_initialized) {
13671 conn->websocket_inflate_state.avail_in =
13672 (
uInt)(data_len + 4);
13673 conn->websocket_inflate_state.next_in =
data;
13675 data[data_len] =
'\x00';
13676 data[data_len + 1] =
'\x00';
13677 data[data_len + 2] =
'\xff';
13678 data[data_len + 3] =
'\xff';
13693 "Out of memory: Cannot allocate "
13694 "inflate buffer of %lu bytes",
13700 conn->websocket_inflate_state.avail_out =
13703 conn->websocket_inflate_state.next_out =
13705 ret =
inflate(&conn->websocket_inflate_state,
13711 "ZLIB inflate error: %i %s",
13713 (conn->websocket_inflate_state.msg
13714 ? conn->websocket_inflate_state.msg
13715 :
"<no error message>"));
13721 }
while (conn->websocket_inflate_state.avail_out
13724 conn->websocket_inflate_state.avail_out;
13752 DEBUG_TRACE(
"Callback requests to close connection from %s:%u",
13759 DEBUG_TRACE(
"Message requests to close connection from %s:%u",
13790 DEBUG_TRACE(
"Too many (%i) unanswered ping from %s:%u "
13791 "- closing connection",
13823 conn->in_websocket_handling = 0;
13824 DEBUG_TRACE(
"Websocket connection %s:%u left data processing loop",
13837 unsigned char header[14];
13841#if defined(GCC_DIAGNOSTIC)
13843#pragma GCC diagnostic push
13844#pragma GCC diagnostic ignored "-Wconversion"
13860#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES)
13867 if (!conn->websocket_deflate_initialized) {
13873 header[0] = 0xC0u | (
unsigned char)((
unsigned)opcode & 0xf);
13874 conn->websocket_deflate_state.avail_in = (
uInt)
dataLen;
13875 conn->websocket_deflate_state.next_in = (
unsigned char *)
data;
13881 "Out of memory: Cannot allocate deflate buffer of %lu bytes",
13887 conn->websocket_deflate_state.next_out =
deflated;
13888 deflate(&conn->websocket_deflate_state, conn->websocket_deflate_flush);
13893 header[0] = 0x80u | (
unsigned char)((
unsigned)opcode & 0xf);
13895#if defined(GCC_DIAGNOSTIC)
13896#pragma GCC diagnostic pop
13902 header[1] = (
unsigned char)
dataLen;
13904 }
else if (
dataLen <= 0xFFFF) {
13933#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES)
13967 if ((
in_len > 3) && ((ptrdiff_t)
in % 4) == 0) {
13969 while (i < (
in_len - 3)) {
13970 *(uint32_t *)(
void *)(out + i) =
13978 *(uint8_t *)(
void *)(out + i) =
13979 *(uint8_t *)(
void *)(
in + i)
14002 "Cannot allocate buffer for masked websocket response: "
14037#if !defined(USE_LUA)
14062 "Protocol upgrade to RFC 6455 required");
14087 "Sec-WebSocket-Protocol",
14096 *acceptedWebSocketSubprotocol =
NULL;
14124 acceptedWebSocketSubprotocol =
14134 acceptedWebSocketSubprotocol;
14137#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES)
14152#if defined(USE_LUA)
14164 if (!conn->lua_websocket_state) {
14193#if defined(USE_LUA)
14205#if defined(USE_LUA)
14211#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES)
14213 if (conn->websocket_deflate_initialized) {
14306 if ((
n > 0) && ((
size_t)
n ==
vec->
len)) {
14307 if ((
a < 256) && (
b < 256) && (
c < 256) && (
d < 256) && (
slash < 33)) {
14310 uint32_t
ip =
ntohl(sa->
sin.sin_addr.s_addr);
14311 uint32_t
net = ((uint32_t)
a << 24) | ((uint32_t)
b << 16)
14312 | ((uint32_t)
c << 8) | (uint32_t)
d;
14319#if defined(USE_IPV6)
14335 if (((
size_t)(
p -
vec->
ptr) <
sizeof(
ad))
14342 }
else if (
vec->
len <
sizeof(
ad)) {
14353 while (
isxdigit((
unsigned char)*
p) || (*
p ==
'.') || (*
p ==
':')) {
14354 if (*(
p++) ==
':') {
14358 if ((*
p ==
'\0') && (
c >= 2)) {
14368 for (i = 0; i < 16; i++) {
14369 uint8_t
ip = sa->sin6.sin6_addr.s6_addr[i];
14370 uint8_t
net =
sin6.sin6_addr.s6_addr[i];
14373 if (8 * i + 8 <
slash) {
14375 }
else if (8 * i <
slash) {
14376 mask = (uint8_t)(0xFFu << (8 * i + 8 -
slash));
14413 && (
mult !=
','))) {
14448 for (i = 0; ((idx == -1) && (
i < ctx->num_listening_sockets)); i++) {
14475 DEBUG_TRACE(
"%s",
"Host name format error '[' without ']'");
14512 DEBUG_TRACE(
"Host mismatch: SNI: %s, HTTPS: %.*s",
14543 conn->
ssl ?
"S" :
"",
14675 if (!phys_ctx || !dom_ctx) {
14752 "Cannot create new request handler struct, OOM");
14761 "Cannot create new request handler struct, OOM");
14895 if (request_info) {
14896 const char *uri = request_info->
local_uri;
14907 for (step = 0; step < 3; step++) {
14917 }
else if (step == 1) {
14977#if defined(USE_WEBSOCKET) && defined(MG_EXPERIMENTAL_INTERFACES)
15043 void *callback_data =
NULL;
15076 "Error: SSL forward not configured properly");
15079 "Can not redirect to SSL, no SSL port available");
15121 if (conn->
phys_ctx->callbacks.begin_request !=
NULL) {
15125 i = conn->
phys_ctx->callbacks.begin_request(conn);
15133 DEBUG_TRACE(
"%s",
"begin_request handled request");
15135 }
else if (i == 0) {
15139 DEBUG_TRACE(
"%s",
"done (undocumented behavior)");
15162 "Access-Control-Request-Method");
15175 "Access-Control-Request-Headers");
15183 "HTTP/1.1 200 OK\r\n"
15185 "Access-Control-Allow-Origin: %s\r\n"
15186 "Access-Control-Allow-Methods: %s\r\n"
15187 "Content-Length: 0\r\n"
15188 "Connection: %s\r\n",
15196 "Access-Control-Allow-Credentials: %s\r\n",
15202 "Access-Control-Expose-Headers: %s\r\n",
15218 "Access-Control-Allow-Headers: %s\r\n",
15223 mg_printf(conn,
"Access-Control-Max-Age: 60\r\n");
15236#if defined(USE_WEBSOCKET)
15293 "%s method not allowed",
15317 DEBUG_TRACE(
"%s",
"auth handler rejected request");
15325#if defined(NO_FILES)
15338 "%s method not allowed",
15340 DEBUG_TRACE(
"%s",
"all file based put/delete requests rejected");
15344#if !defined(NO_FILES)
15350 DEBUG_TRACE(
"%s",
"file write needs authorization");
15364 DEBUG_TRACE(
"%s",
"access authorization required");
15420#if defined(USE_WEBSOCKET)
15437#if defined(USE_WEBSOCKET)
15465#if defined(NO_FILES)
15562 "%s method not allowed",
15574 DEBUG_TRACE(
"handling %s request to %s: file not found",
15582 && (ri->
local_uri[uri_len - 1] !=
'/')) {
15605 DEBUG_TRACE(
"%s request to %s: directory redirection sent",
15634 "%s method not allowed",
15641 if (file.
stat.is_directory) {
15652 "Error: Directory listing denied");
15662 DEBUG_TRACE(
"handling %s request to %s done (template)",
15669#if !defined(NO_CACHING)
15673 DEBUG_TRACE(
"handling %s request to %s done (not modified)",
15682 DEBUG_TRACE(
"handling %s request to %s done (static)",
15690#if !defined(NO_FILESYSTEMS)
15696#if !defined(NO_CGI)
15700 if (!conn || !conn->
dom_ctx) {
15704#if defined(USE_LUA)
15733#if defined(USE_DUKTAPE)
15748#if !defined(NO_CGI)
15780#if !defined(NO_CACHING)
15803#if defined(USE_X_DOM_SOCKET)
15841 unsigned int a,
b,
c,
d;
15847#if defined(USE_IPV6)
15848 char buf[100] = {0};
15854 memset(so, 0,
sizeof(*so));
15864 "%u.%u.%u.%u:%u%n",
15875 so->
lsa.sin.sin_addr.s_addr =
15876 htonl((
a << 24) | (
b << 16) | (
c << 8) |
d);
15877 so->
lsa.sin.sin_port =
htons((uint16_t)port);
15880#if defined(USE_IPV6)
15888 so->
lsa.sin6.sin6_port =
htons((uint16_t)port);
15892 }
else if ((
vec->
ptr[0] ==
'+')
15903#if defined(USE_IPV6)
15906 so->
lsa.sin6.sin6_port =
htons((uint16_t)port);
15910 so->
lsa.sin.sin_port =
htons((uint16_t)port);
15917 port = (uint16_t)
portUL;
15919 so->
lsa.sin.sin_port =
htons((uint16_t)port);
15945 if (
sscanf(cb + 1,
"%u%n", &port, &
len)
15951 so->
lsa.sin.sin_port =
htons((uint16_t)port);
15956#if defined(USE_IPV6)
15960 sizeof(so->
lsa.sin6),
15962 if (
sscanf(cb + 1,
"%u%n", &port, &
len) == 1) {
15964 so->
lsa.sin6.sin6_port =
htons((uint16_t)port);
15974#if defined(USE_X_DOM_SOCKET)
15976 }
else if (
vec->
ptr[0] ==
'x') {
15978 if (
vec->
len <
sizeof(so->
lsa.sun.sun_path)) {
15981 memset(so->
lsa.sun.sun_path, 0,
sizeof(so->
lsa.sun.sun_path));
16005 unsigned char *opt =
NULL;
16020 if ((opt) && (*opt == 0))
16108#if defined(USE_IPV6)
16129 memset(&so, 0,
sizeof(so));
16141 "%.*s: invalid port spec (entry %i). Expecting list of: %s",
16145 "[IP_ADDRESS:]PORT[s|r]");
16149#if !defined(NO_SSL)
16153 "Cannot add SSL socket (entry %i)",
16169 "cannot create socket (entry %i)",
16198 "cannot set socket option SO_EXCLUSIVEADDRUSE (entry %i)",
16212 "cannot set socket option SO_REUSEADDR (entry %i)",
16217#if defined(USE_X_DOM_SOCKET)
16225#if defined(USE_IPV6)
16237 "cannot set socket option "
16238 "IPV6_V6ONLY=off (entry %i)",
16252 "cannot set socket option "
16253 "IPV6_V6ONLY=on (entry %i)",
16271 len =
sizeof(so.
lsa.sin);
16274 "cannot bind to %.*s: %d (%s)",
16288#if defined(USE_IPV6)
16291 len =
sizeof(so.
lsa.sin6);
16294 "cannot bind to IPv6 %.*s: %d (%s)",
16309#if defined(USE_X_DOM_SOCKET)
16312 len =
sizeof(so.
lsa.sun);
16315 "cannot bind to unix socket %s: %d (%s)",
16316 so.
lsa.sun.sun_path,
16332 "cannot bind: address family not supported (entry %i)",
16343 "%s value \"%s\" is invalid",
16354 "cannot listen to %.*s: %d (%s)",
16365 || (
usa.
sa.sa_family != so.
lsa.sa.sa_family)) {
16369 "call to getsockname failed %.*s: %d (%s)",
16380#if defined(USE_IPV6)
16382 so.
lsa.sin6.sin6_port =
usa.sin6.sin6_port;
16386 so.
lsa.sin.sin_port =
usa.
sin.sin_port;
16389 if ((ptr = (
struct socket *)
16451#if defined(MG_EXTERNAL_FUNCTION_log_access)
16452#include "external_log_access.inl"
16453#elif !defined(NO_FILESYSTEMS)
16461#if defined(REENTRANT_TIME)
16473 if (!conn || !conn->
dom_ctx) {
16480#if defined(USE_LUA)
16481 if (conn->
phys_ctx->lua_bg_log_available) {
16504 if ((
len == 0) || (*
txt == 0)) {
16537 if ((
fi.access.fp ==
NULL)
16544#if defined(REENTRANT_TIME)
16565 "%s - %s [%s] \"%s %s%s%s HTTP/%s\" %d %" INT64_FMT
16582 if (conn->
phys_ctx->callbacks.log_access) {
16585 if (
fi.access.fp) {
16593 if (
fi.access.fp) {
16608 "Error writing log file %s",
16614#error "Either enable filesystems or provide a custom log_access implementation"
16643 "%s: subnet must be [+|-]IP-addr[/x]",
16658#if !defined(_WIN32) && !defined(__ZEPHYR__)
16675 "%s: unknown user [%s]",
16687 "%s: setgid(%s): %s",
16693 "%s: setgroups(): %s",
16698 "%s: setuid(%s): %s",
16720 if (
tls->is_master == 2) {
16721 tls->is_master = -3;
16729#if defined(USE_MBEDTLS)
16740 dom_ctx = &(phys_ctx->
dd);
16760#elif defined(USE_GNUTLS)
16771 dom_ctx = &(phys_ctx->
dd);
16791#elif !defined(NO_SSL)
16796 const char *chain);
16815 if (chain ==
NULL) {
16828 if ((t != 0) && (conn->
dom_ctx->ssl_cert_last_mtime != t)) {
16829 conn->
dom_ctx->ssl_cert_last_mtime = t;
16853 "SSL_CTX_load_verify_locations error: %s "
16854 "ssl_verify_peer requires setting "
16855 "either ssl_ca_path or ssl_ca_file. Is any of them "
16873#if defined(OPENSSL_API_1_1)
16880 int (*func)(
SSL *),
16941 for (i = 0; i <=
timeout; i += 50) {
16944 ret = func(conn->ssl);
16965 pfd[0].fd = conn->client.sock;
16973 conn->phys_ctx->thread_shutdown_notification_socket;
16981 &(conn->phys_ctx->stop_flag));
17032 const char hexdigit[] =
"0123456789abcdef";
17034 if ((
memlen <= 0) || (buflen <= 0)) {
17037 if (buflen < (3 *
memlen)) {
17041 for (i = 0; i <
memlen; i++) {
17043 buf[3 * i - 1] =
' ';
17045 buf[3 * i] =
hexdigit[(((uint8_t *)
mem)[i] >> 4) & 0xF];
17046 buf[3 * i + 1] =
hexdigit[((uint8_t *)
mem)[i] & 0xF];
17048 buf[3 *
memlen - 1] = 0;
17061 unsigned char buf[256];
17066 unsigned char *
tmp_p;
17129#if defined(OPENSSL_API_1_1)
17147#if !defined(NO_SSL_DL)
17170 "%s: cannot load %s",
17191 if (
u.fp ==
NULL) {
17205 "%s: %s: cannot find %s",
17246#if defined(SSL_ALREADY_INITIALIZED)
17258#if !defined(OPENSSL_API_1_1) && !defined(OPENSSL_API_3_0)
17267#if !defined(NO_SSL_DL)
17277 "%s: error loading library %s",
17290#if !defined(OPENSSL_API_1_1) && !defined(OPENSSL_API_3_0)
17314 "%s: cannot allocate mutexes: %s",
17328 "%s: error initializing mutex %i of %i",
17343#if !defined(NO_SSL_DL)
17348#if !defined(OPENSSL_API_1_1)
17357#if (defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0)) \
17358 && !defined(NO_SSL_DL)
17382 "%s: cannot open certificate file %s: %s",
17392 "%s: cannot open private key file %s: %s",
17401 "%s: certificate and private key do not match: %s",
17418 "%s: cannot use certificate chain file %s: %s",
17429#if defined(OPENSSL_API_1_1)
17430static unsigned long
17444#if defined(SSL_OP_NO_TLSv1_3)
17465#if defined(SSL_OP_NO_TLSv1_3)
17503#if defined(GCC_DIAGNOSTIC)
17504#pragma GCC diagnostic push
17505#pragma GCC diagnostic ignored "-Wcast-align"
17511#if defined(GCC_DIAGNOSTIC)
17512#pragma GCC diagnostic pop
17533 DEBUG_TRACE(
"%s",
"SSL connection not supporting SNI");
17568#if defined(USE_ALPN)
17569static const char alpn_proto_list[] =
"\x02h2\x08http/1.1\x08http/1.0";
17573#if defined(USE_HTTP2)
17582 const unsigned char **out,
17584 const unsigned char *
in,
17585 unsigned int inlen,
17603#if defined(USE_HTTP2)
17614 for (i = 0; i <
inlen; i++) {
17631 const unsigned char **
data,
17655 "SSL_CTX_set_alpn_protos error: %s",
17692#if (defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0)) \
17693 && !defined(NO_SSL_DL)
17696 "SSL_CTX_new (server) error: %s",
17703 "SSL_CTX_new (server) error: %s",
17709#if defined(SSL_OP_NO_TLSv1_3)
17728#if defined(SSL_OP_NO_RENEGOTIATION)
17732#if !defined(NO_SSL_DL)
17765 "SSL callback returned error: %i",
17777 : (phys_ctx->
callbacks.init_ssl_domain(
17787 "Domain SSL callback returned error: %i",
17849 "SSL_CTX_load_verify_locations error: %s "
17850 "ssl_verify_peer requires setting "
17851 "either ssl_ca_path or ssl_ca_file. "
17852 "Is any of them present in the "
17870 "SSL_CTX_set_default_verify_paths error: %s",
17886 "SSL_CTX_set_cipher_list error: %s",
17902#if defined(USE_ALPN)
17904#if !defined(NO_SSL_DL)
17933 dom_ctx = &(phys_ctx->
dd);
17945 : (phys_ctx->
callbacks.external_ssl_ctx(&ssl_ctx,
17951 "external_ssl_ctx callback returned error: %i",
17970 : (phys_ctx->
callbacks.external_ssl_ctx_domain(
17979 "external_ssl_ctx_domain callback returned error: %i",
18003 "Initializing SSL failed: -%s is not set",
18010 if (chain ==
NULL) {
18014 if ((chain !=
NULL) && (*chain == 0)) {
18031#if defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0)
18069#if !defined(NO_FILESYSTEMS)
18084 "Cannot open %s: %s",
18101#if defined(USE_IPV6)
18146#if defined(USE_SERVER_STATS)
18147 conn->processing_time = 0;
18173#if !defined(__ZEPHYR__)
18182 int error_code = 0;
18220#if defined(_MSC_VER)
18221#pragma warning(push)
18222#pragma warning(disable : 4244)
18224#if defined(GCC_DIAGNOSTIC)
18225#pragma GCC diagnostic push
18226#pragma GCC diagnostic ignored "-Wconversion"
18234#if defined(GCC_DIAGNOSTIC)
18235#pragma GCC diagnostic pop
18237#if defined(_MSC_VER)
18238#pragma warning(pop)
18252 (
char *)&error_code,
18262 "%s: getsockopt(SOL_SOCKET SO_ERROR) failed: %s",
18283 "%s: setsockopt(SOL_SOCKET SO_LINGER(%i,%i)) failed: %s",
18301#if defined(USE_SERVER_STATS)
18302 conn->conn_state = 6;
18305#if defined(USE_LUA) && defined(USE_WEBSOCKET)
18306 if (conn->lua_websocket_state) {
18308 conn->lua_websocket_state =
NULL;
18318 if (conn->
phys_ctx->callbacks.connection_close !=
NULL) {
18320 conn->
phys_ctx->callbacks.connection_close(conn);
18329#if defined(USE_SERVER_STATS)
18330 conn->conn_state = 7;
18333#if defined(USE_MBEDTLS)
18338#elif defined(USE_GNUTLS)
18343#elif !defined(NO_SSL)
18354#if defined(__ZEPHYR__)
18363 if (conn->
phys_ctx->callbacks.connection_closed !=
NULL) {
18365 conn->
phys_ctx->callbacks.connection_closed(conn);
18371#if defined(USE_SERVER_STATS)
18372 conn->conn_state = 8;
18384#if defined(USE_WEBSOCKET)
18386 if (conn->in_websocket_handling) {
18406 for (i = 0; i < conn->
phys_ctx->spawned_worker_threads; i++) {
18414#if !defined(NO_SSL) && !defined(USE_MBEDTLS) \
18415 && !defined(USE_GNUTLS)
18423#if defined(USE_WEBSOCKET)
18465 if (error !=
NULL) {
18469 error->
text[0] = 0;
18473 if (conn ==
NULL) {
18474 if (error !=
NULL) {
18487#if defined(GCC_DIAGNOSTIC)
18488#pragma GCC diagnostic push
18489#pragma GCC diagnostic ignored "-Wcast-align"
18495#if defined(GCC_DIAGNOSTIC)
18496#pragma GCC diagnostic pop
18517#if !defined(NO_SSL) && !defined(USE_MBEDTLS) \
18518 && !defined(USE_GNUTLS)
18519#if (defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0)) \
18520 && !defined(NO_SSL_DL)
18525 if (error !=
NULL) {
18531 "SSL_CTX_new error: %s",
18545 if (error !=
NULL) {
18551 "SSL_CTX_new error: %s",
18563#if defined(USE_IPV6)
18565 :
sizeof(conn->
client.rsa.sin6);
18574 conn->
client.sock = sock;
18579 "%s: getsockname() failed: %s",
18586 if (error !=
NULL) {
18593 "Can not create mutex");
18595#if !defined(NO_SSL) && !defined(USE_MBEDTLS) \
18596 && !defined(USE_GNUTLS)
18604#if !defined(NO_SSL) && !defined(USE_MBEDTLS) \
18605 && !defined(USE_GNUTLS)
18619 if (error !=
NULL) {
18625 "Can not use SSL client certificate");
18640 if (error !=
NULL) {
18646 "SSL_CTX_load_verify_locations error: %s",
18660 if (error !=
NULL) {
18666 "SSL connection error");
18688 memset(&init, 0,
sizeof(init));
18689 memset(&error, 0,
sizeof(error));
18707 memset(&init, 0,
sizeof(init));
18709 memset(&error, 0,
sizeof(error));
18717 opts.host_name = host;
18724#if defined(MG_EXPERIMENTAL_INTERFACES)
18727 const char *protocol,
18738 if (error !=
NULL) {
18746 if ((host ==
NULL) || (protocol ==
NULL)) {
18747 if (error !=
NULL) {
18754 "Invalid parameters");
18766#if defined(USE_WEBSOCKET)
18775 if (error !=
NULL) {
18781 "Protocol %s not supported",
18790#if defined(USE_WEBSOCKET)
18798 ((error !=
NULL) ? error->text_buffer_size : 0),
18799 (path ? path :
""),
18803 (void *)init->callbacks);
18821static const struct {
18826 {
"https://", 8, 443},
18828 {
"wss://", 6, 443},
18844 unsigned long port;
18850 if ((uri[0] ==
'*') && (uri[1] ==
'\0')) {
18861 for (i = 0; uri[i] != 0; i++) {
18862 if ((
unsigned char)uri[i] < 33) {
18870 if (uri[0] ==
'/') {
18914 unsigned long port = 0;
19046 "Invalid message size");
19057 "Message too large");
19070 :
"Malformed message");
19080 "No data received");
19121 "Bad request: Host mismatch");
19129 "Accept-Encoding"))
19131 &&
strstr(cl,
"gzip")) {
19137 "Transfer-Encoding"))
19209 "Transfer-Encoding"))
19287 "Parameter error");
19314 return (
ret == 0) ? -1 : +1;
19341 if (conn !=
NULL) {
19349 "Error sending request");
19361 if ((
ebuf[0] !=
'\0') && (conn !=
NULL)) {
19379#if defined(USE_WEBSOCKET)
19392#if !defined(_WIN32) && !defined(__ZEPHYR__)
19396 memset(&sa, 0,
sizeof(sa));
19403 if (
cdata->conn->phys_ctx) {
19404 if (
cdata->conn->phys_ctx->callbacks.init_thread) {
19408 cdata->conn->phys_ctx, 3);
19414 DEBUG_TRACE(
"%s",
"Websocket client thread exited\n");
19424 if (
cdata->conn->phys_ctx->callbacks.exit_thread) {
19425 cdata->conn->phys_ctx->callbacks.exit_thread(
cdata->conn->phys_ctx,
19441#if defined(USE_WEBSOCKET)
19446 unsigned char buffer[2 *
sizeof(
rnd)];
19473#if defined(USE_WEBSOCKET)
19484 memset(&init, 0,
sizeof(init));
19485 memset(&error, 0,
sizeof(error));
19489#if defined(__clang__)
19490#pragma clang diagnostic push
19491#pragma clang diagnostic ignored "-Wformat-nonliteral"
19498 if (conn ==
NULL) {
19506 "Unexpected error");
19514 "GET %s HTTP/1.1\r\n"
19516 "Upgrade: websocket\r\n"
19517 "Connection: Upgrade\r\n"
19518 "Sec-WebSocket-Key: %s\r\n"
19519 "Sec-WebSocket-Version: 13\r\n"
19520 "Sec-WebSocket-Extensions: %s\r\n"
19530 "GET %s HTTP/1.1\r\n"
19532 "Upgrade: websocket\r\n"
19533 "Connection: Upgrade\r\n"
19534 "Sec-WebSocket-Key: %s\r\n"
19535 "Sec-WebSocket-Version: 13\r\n"
19547 "GET %s HTTP/1.1\r\n"
19549 "Upgrade: websocket\r\n"
19550 "Connection: Upgrade\r\n"
19551 "Sec-WebSocket-Key: %s\r\n"
19552 "Sec-WebSocket-Version: 13\r\n"
19553 "Sec-WebSocket-Extensions: %s\r\n"
19561 "GET %s HTTP/1.1\r\n"
19563 "Upgrade: websocket\r\n"
19564 "Connection: Upgrade\r\n"
19565 "Sec-WebSocket-Key: %s\r\n"
19566 "Sec-WebSocket-Version: 13\r\n"
19579 "Error sending request");
19592#if defined(__clang__)
19593#pragma clang diagnostic pop
19607 "Unexpected server reply");
19628 conn->phys_ctx->worker_threadids =
19630 if (!
conn->phys_ctx->worker_threadids) {
19638 conn->phys_ctx->user_data = user_data;
19640 conn->phys_ctx->cfg_max_worker_threads = 1;
19641 conn->phys_ctx->spawned_worker_threads = 1;
19648 conn->phys_ctx->worker_threadids)
19650 conn->phys_ctx->spawned_worker_threads = 0;
19655 "Websocket client connect thread could not be started\r\n");
19815#if defined(USE_SERVER_STATS)
19816 conn->conn_state = 2;
19820 if (conn->
phys_ctx->callbacks.init_connection !=
NULL) {
19822 void *conn_data =
NULL;
19823 conn->
phys_ctx->callbacks.init_connection(conn, &conn_data);
19844#if defined(USE_SERVER_STATS)
19850 DEBUG_TRACE(
"Start processing connection from %s",
19856 DEBUG_TRACE(
"calling get_request (%i times for this connection)",
19859#if defined(USE_SERVER_STATS)
19860 conn->conn_state = 3;
19879 "Bad HTTP version: [%s]",
19884 if (
ebuf[0] ==
'\0') {
19922 if (
ebuf[0] !=
'\0') {
19944 if (
ebuf[0] ==
'\0') {
20004 DEBUG_TRACE(
"internal error: data_len = %li, buf_size = %li",
20012 DEBUG_TRACE(
"Done processing connection from %s (%f sec)",
20018#if defined(USE_SERVER_STATS)
20028#if defined(ALTERNATIVE_QUEUE)
20042 if (ctx->client_socks[i].in_use == 2) {
20044 if ((ctx->client_socks[i].in_use == 2) && !ctx->
stop_flag) {
20045 ctx->client_socks[i] = *
sp;
20046 ctx->client_socks[i].in_use = 1;
20086 if (
sp->in_use == 1) {
20095 if (
sp->in_use == 1) {
20167#if defined(USE_SERVER_STATS)
20185#if defined(USE_SERVER_STATS)
20235 "Internal error: Invalid worker index %i",
20247 "Out of memory: Cannot allocate buffer for worker %i",
20267#if defined(USE_SERVER_STATS)
20268 conn->conn_state = 1;
20281#if defined(USE_SERVER_STATS)
20282 conn->conn_close_time = 0;
20301 (conn->
client.is_ssl ?
"SSL " :
""),
20306 if (conn->
client.is_ssl) {
20308#if defined(USE_MBEDTLS)
20312 (
int *)&(conn->
client.sock),
20326#elif defined(USE_GNUTLS)
20344#elif !defined(NO_SSL)
20356#if defined(USE_HTTP2)
20358 && (!
memcmp(
tls.alpn_proto,
"\x02h2", 3))) {
20411#if defined(USE_SERVER_STATS)
20412 conn->conn_close_time = time(
NULL);
20439#if defined(USE_SERVER_STATS)
20440 conn->conn_state = 9;
20458#if !defined(__ZEPHYR__)
20462 memset(&sa, 0,
sizeof(sa));
20481#if !defined(__ZEPHYR__)
20484 memset(&so, 0,
sizeof(so));
20491 "%s: %s is not allowed to connect",
20504 "%s: getsockname() failed: %s",
20509#if !defined(__ZEPHYR__)
20527 "%s: setsockopt(SOL_SOCKET SO_KEEPALIVE) failed: %s",
20546 "%s: setsockopt(IPPROTO_TCP TCP_NODELAY) failed: %s",
20580#elif defined(USE_MASTER_THREAD_PRIORITY)
20607#if defined(USE_LUA)
20608 if (ctx->lua_background_state) {
20621 "lua_background_script",
20631 ctx->lua_bg_log_available = 1;
20685#if defined(ALTERNATIVE_QUEUE)
20703#if defined(USE_LUA)
20705 if (ctx->lua_background_state) {
20707 ctx->lua_bg_log_available = 0;
20719 "lua_background_script",
20726 ctx->lua_background_state = 0;
20762#if !defined(__ZEPHYR__)
20766 memset(&sa, 0,
sizeof(sa));
20797#if defined(ALTERNATIVE_QUEUE)
20799 if (ctx->client_wait_events !=
NULL) {
20800 for (i = 0; (unsigned)
i < ctx->spawned_worker_threads; i++) {
20803 mg_free(ctx->client_wait_events);
20814#if defined(USE_LUA)
20828 if (ctx->
dd.config[i] !=
NULL) {
20829#if defined(_MSC_VER)
20830#pragma warning(suppress : 6001)
20837 while (ctx->
dd.handlers) {
20844#if defined(USE_MBEDTLS)
20845 if (ctx->
dd.ssl_ctx !=
NULL) {
20851#elif defined(USE_GNUTLS)
20852 if (ctx->
dd.ssl_ctx !=
NULL) {
20858#elif !defined(NO_SSL)
20860 if (ctx->
dd.ssl_ctx !=
NULL) {
20861 void *ssl_ctx = (
void *)ctx->
dd.ssl_ctx;
20916#if defined(USE_TIMERS)
20929#if defined(USE_LUA)
20949#if defined(_MSC_VER)
20950#pragma warning(push)
20952#pragma warning(disable : 4996)
20955#if defined(_MSC_VER)
20956#pragma warning(pop)
20974#elif defined(__rtems__)
20976#elif defined(__ZEPHYR__)
21015#if !defined(HAVE_SOCKETPAIR) && !defined(_WIN32)
21016#define HAVE_SOCKETPAIR 1
21022 int temp[2] = {-1, -1};
21029#if defined(HAVE_SOCKETPAIR)
21057 if ((temp[0] >= 0) && (
connect(temp[0],
pa,
sizeof(
addr)) == 0)) {
21059 if (temp[1] >= 0) {
21092#if defined(ALTERNATIVE_QUEUE)
21128 const char *
name, *
value, *default_value;
21133 const char **options =
21138 if (error !=
NULL) {
21153 if (error !=
NULL) {
21160 "Library uninitialized");
21168 if (error !=
NULL) {
21170 error->
code_sub = (unsigned)
sizeof(*ctx);
21182 ctx->
dd.auth_nonce_mask =
21183 (uint64_t)
get_random() ^ (uint64_t)(ptrdiff_t)(options);
21189 tls.is_master = -1;
21192 tls.pthread_cond_helper_mutex =
NULL;
21197#if !defined(ALTERNATIVE_QUEUE)
21203#if defined(USE_LUA)
21218 "Cannot initialize thread synchronization objects";
21223 if (error !=
NULL) {
21249 ctx->
dd.handlers =
NULL;
21252#if defined(USE_LUA)
21257 while (options && (
name = *options++) !=
NULL) {
21261 if (error !=
NULL) {
21268 "Invalid configuration option: %s",
21276 }
else if ((
value = *options++) ==
NULL) {
21278 if (error !=
NULL) {
21285 "Invalid configuration option value: %s",
21293 if (ctx->
dd.config[idx] !=
NULL) {
21306 if ((ctx->
dd.config[i] ==
NULL) && (default_value !=
NULL)) {
21317 if (error !=
NULL) {
21324 "Invalid configuration option value: %s",
21335#if !defined(ALTERNATIVE_QUEUE)
21341 if (error !=
NULL) {
21348 "Invalid configuration option value: %s",
21360 "Out of memory: Cannot allocate %s",
21362 if (error !=
NULL) {
21369 "Out of memory: Cannot allocate %s",
21396 if (error !=
NULL) {
21403 "Invalid configuration option value: %s",
21413#if defined(NO_FILES)
21416 if (error !=
NULL) {
21423 "Invalid configuration option value: %s",
21435#if defined(USE_LUA)
21437 ctx->lua_bg_log_available = 0;
21452 "lua_background_script load error: %s",
21454 if (error !=
NULL) {
21460 "Error in script %s: %s",
21498 "lua_background_script start error: %s",
21500 if (error !=
NULL) {
21506 "Error in script %s: %s",
21518 ctx->lua_background_state = (
void *)state;
21522 ctx->lua_background_state = 0;
21527#if !defined(NO_FILESYSTEMS)
21529 const char *
err_msg =
"Invalid global password file";
21533 if (error !=
NULL) {
21548#if defined(USE_MBEDTLS) || defined(USE_GNUTLS)
21550 const char *
err_msg =
"Error initializing SSL context";
21554 if (error !=
NULL) {
21569#elif !defined(NO_SSL)
21571 const char *
err_msg =
"Error initializing SSL context";
21575 if (error !=
NULL) {
21592 const char *
err_msg =
"Failed to setup server ports";
21596 if (error !=
NULL) {
21611#if !defined(_WIN32) && !defined(__ZEPHYR__)
21613 const char *
err_msg =
"Failed to run as configured user";
21617 if (error !=
NULL) {
21634 const char *
err_msg =
"Failed to setup access control list";
21638 if (error !=
NULL) {
21660 const char *
err_msg =
"Not enough memory for worker thread ID array";
21663 if (error !=
NULL) {
21666 * (
unsigned)
sizeof(pthread_t);
21685 "Not enough memory for worker thread connection array";
21688 if (error !=
NULL) {
21705#if defined(ALTERNATIVE_QUEUE)
21706 ctx->client_wait_events =
21708 sizeof(ctx->client_wait_events[0]),
21710 if (ctx->client_wait_events ==
NULL) {
21711 const char *
err_msg =
"Not enough memory for worker event array";
21715 if (error !=
NULL) {
21718 * (
unsigned)
sizeof(ctx->client_wait_events[0]);
21732 ctx->client_socks =
21734 sizeof(ctx->client_socks[0]),
21736 if (ctx->client_socks ==
NULL) {
21737 const char *
err_msg =
"Not enough memory for worker socket array";
21739 mg_free(ctx->client_wait_events);
21742 if (error !=
NULL) {
21745 * (
unsigned)
sizeof(ctx->client_socks[0]);
21759 for (i = 0; (unsigned)
i < ctx->cfg_max_worker_threads; i++) {
21761 if (ctx->client_wait_events[i] == 0) {
21762 const char *
err_msg =
"Error creating worker event %i";
21769 mg_free(ctx->client_wait_events);
21772 if (error !=
NULL) {
21790#if defined(USE_TIMERS)
21792 const char *
err_msg =
"Error creating timers";
21795 if (error !=
NULL) {
21833 "Cannot start worker thread %i: error %ld",
21846 "Cannot create threads: error %ld",
21849 if (error !=
NULL) {
21857 "Cannot create first worker thread: error %ld",
21880 const char **options)
21894 const char **options,
21899 const char *default_value;
21904 if (error !=
NULL) {
21912 if ((ctx ==
NULL) || (options ==
NULL)) {
21913 if (error !=
NULL) {
21920 "Invalid parameters");
21926 if (error !=
NULL) {
21933 "Server already stopped");
21943 if (error !=
NULL) {
21957 while (options && (
name = *options++) !=
NULL) {
21961 if (error !=
NULL) {
21968 "Invalid option: %s",
21973 }
else if ((
value = *options++) ==
NULL) {
21975 if (error !=
NULL) {
21982 "Invalid option value: %s",
22001 if (error !=
NULL) {
22008 "Mandatory option %s missing",
22018 default_value = ctx->
dd.config[i];
22029#if defined(USE_LUA) && defined(USE_WEBSOCKET)
22033#if !defined(NO_SSL) && !defined(USE_MBEDTLS) && !defined(USE_GNUTLS)
22036 if (error !=
NULL) {
22043 "Initializing SSL context failed");
22060 "domain %s already in use",
22062 if (error !=
NULL) {
22068 "Domain %s specified by %s is already in use",
22109#if !defined(NO_FILES)
22112#if !defined(NO_SSL) || defined(USE_MBEDTLS) || defined(USE_GNUTLS)
22115#if !defined(NO_CGI)
22118#if defined(USE_IPV6)
22121#if defined(USE_WEBSOCKET)
22124#if defined(USE_LUA)
22127#if defined(USE_DUKTAPE)
22130#if !defined(NO_CACHING)
22133#if defined(USE_SERVER_STATS)
22136#if defined(USE_ZLIB)
22139#if defined(USE_HTTP2)
22142#if defined(USE_X_DOM_SOCKET)
22148#if defined(MG_LEGACY_INTERFACE)
22151#if defined(MG_EXPERIMENTAL_INTERFACES)
22154#if !defined(NO_RESPONSE_BUFFERING)
22157#if defined(MEMORY_DEBUGGING)
22171 if ((
size_t)(end - *
dst) >
len) {
22191 static const char eol[] =
"\r\n",
eoobj[] =
"\r\n}\r\n";
22193 static const char eol[] =
"\n",
eoobj[] =
"\n}\n";
22196 if ((buffer ==
NULL) || (buflen < 1)) {
22201 end = buffer + buflen;
22203 if (buflen > (
int)(
sizeof(
eoobj) - 1)) {
22207 end -=
sizeof(
eoobj) - 1;
22220 "%s\"version\" : \"%s\"",
22236#if defined(_MSC_VER)
22237#pragma warning(push)
22239#pragma warning(disable : 4996)
22242#if defined(_MSC_VER)
22243#pragma warning(pop)
22253 ",%s\"os\" : \"Windows %u.%u\"",
22263 ",%s\"cpu\" : \"type %u, cores %u, mask %x\"",
22265 (
unsigned)
si.wProcessorArchitecture,
22266 (
unsigned)
si.dwNumberOfProcessors,
22267 (
unsigned)
si.dwActiveProcessorMask);
22269#elif defined(__rtems__)
22274 ",%s\"os\" : \"%s %s\"",
22279#elif defined(__ZEPHYR__)
22284 ",%s\"os\" : \"%s\"",
22298 ",%s\"os\" : \"%s %s (%s) - %s\"",
22314 ",%s\"features\" : %lu"
22315 ",%s\"feature_list\" : \"Server:%s%s%s%s%s%s%s%s%s\"",
22331#if defined(USE_LUA)
22336 ",%s\"lua_version\" : \"%u (%s)\"",
22342#if defined(USE_DUKTAPE)
22347 ",%s\"javascript\" : \"Duktape %u.%u.%u\"",
22358#if defined(BUILD_DATE)
22361#if defined(GCC_DIAGNOSTIC)
22362#if GCC_VERSION >= 40900
22363#pragma GCC diagnostic push
22367#pragma GCC diagnostic ignored "-Wdate-time"
22371#if defined(GCC_DIAGNOSTIC)
22372#if GCC_VERSION >= 40900
22373#pragma GCC diagnostic pop
22387#if defined(_MSC_VER)
22392 ",%s\"compiler\" : \"MSC: %u (%u)\"",
22397#elif defined(__MINGW64__)
22402 ",%s\"compiler\" : \"MinGW64: %u.%u\"",
22411 ",%s\"compiler\" : \"MinGW32: %u.%u\"",
22416#elif defined(__MINGW32__)
22421 ",%s\"compiler\" : \"MinGW32: %u.%u\"",
22426#elif defined(__clang__)
22431 ",%s\"compiler\" : \"clang: %u.%u.%u (%s)\"",
22438#elif defined(__GNUC__)
22443 ",%s\"compiler\" : \"gcc: %u.%u.%u\"",
22449#elif defined(__INTEL_COMPILER)
22454 ",%s\"compiler\" : \"Intel C/C++: %u\"",
22458#elif defined(__BORLANDC__)
22463 ",%s\"compiler\" : \"Borland C: 0x%x\"",
22467#elif defined(__SUNPRO_C)
22472 ",%s\"compiler\" : \"Solaris: 0x%x\"",
22481 ",%s\"compiler\" : \"other\"",
22494 ",%s\"data_model\" : \"int:%u/%u/%u/%u, float:%u/%u/%u, "
22496 "ptr:%u, size:%u, time:%u\"",
22498 (
unsigned)
sizeof(
short),
22499 (
unsigned)
sizeof(
int),
22500 (
unsigned)
sizeof(
long),
22501 (
unsigned)
sizeof(
long long),
22502 (
unsigned)
sizeof(
float),
22503 (
unsigned)
sizeof(
double),
22504 (
unsigned)
sizeof(
long double),
22505 (
unsigned)
sizeof(
char),
22506 (
unsigned)
sizeof(
wchar_t),
22507 (
unsigned)
sizeof(
void *),
22508 (
unsigned)
sizeof(
size_t),
22509 (
unsigned)
sizeof(time_t));
22528#if defined(USE_SERVER_STATS)
22533 static const char eol[] =
"\r\n",
eoobj[] =
"\r\n}\r\n";
22535 static const char eol[] =
"\n",
eoobj[] =
"\n}\n";
22539 if ((buffer ==
NULL) || (buflen < 1)) {
22544 end = buffer + buflen;
22546 if (buflen > (
int)(
sizeof(
eoobj) - 1)) {
22549 end -=
sizeof(
eoobj) - 1;
22567 "%s\"memory\" : {%s"
22568 "\"blocks\" : %i,%s"
22606 ",%s\"connections\" : {%s"
22607 "\"active\" : %i,%s"
22608 "\"maxActive\" : %i,%s"
22622#if !defined(ALTERNATIVE_QUEUE)
22627 ",%s\"queue\" : {%s"
22628 "\"length\" : %i,%s"
22629 "\"filled\" : %i,%s"
22630 "\"maxFilled\" : %i,%s"
22651 ",%s\"requests\" : {%s"
22652 "\"total\" : %lu%s"
22656 (
unsigned long)ctx->total_requests,
22669 ",%s\"data\" : {%s"
22691 ",%s\"time\" : {%s"
22692 "\"uptime\" : %.0f,%s"
22693 "\"start\" : \"%s\",%s"
22694 "\"now\" : \"%s\"%s"
22716 if ((buffer !=
NULL) && (buflen > 0)) {
22728 if (conn !=
NULL) {
22734#if defined(MG_EXPERIMENTAL_INTERFACES)
22751 static const char eol[] =
"\r\n",
eoobj[] =
"\r\n}\r\n";
22753 static const char eol[] =
"\n",
eoobj[] =
"\n}\n";
22756 if ((buffer ==
NULL) || (buflen < 1)) {
22761 end = buffer + buflen;
22763 if (buflen > (
int)(
sizeof(
eoobj) - 1)) {
22769 if ((ctx ==
NULL) || (idx < 0)) {
22789#if defined(USE_SERVER_STATS)
22790 state = conn->conn_state;
22828 if ((state >= 3) && (state < 9)) {
22833 "%s\"connection\" : {%s"
22835 "\"protocol\" : \"%s\",%s"
22836 "\"addr\" : \"%s\",%s"
22839 "\"handled_requests\" : %u%s"
22857 if ((state >= 4) && (state < 6)) {
22862 "%s%s\"request_info\" : {%s"
22863 "\"method\" : \"%s\",%s"
22864 "\"uri\" : \"%s\",%s"
22865 "\"query\" : %s%s%s%s"
22882 if ((state >= 2) && (state < 9)) {
22892#if defined(USE_SERVER_STATS)
22910 "%s%s\"time\" : {%s"
22911 "\"uptime\" : %.0f,%s"
22912 "\"start\" : \"%s\",%s"
22913 "\"closed\" : \"%s\"%s"
22933 "%s%s\"user\" : {%s"
22934 "\"name\" : \"%s\",%s"
22950 "%s%s\"data\" : {%s"
22957 conn->consumed_content,
22959 conn->num_bytes_sent,
22969 "%s%s\"state\" : \"%s\"",
23003 switch (
tmp_rh->handler_type) {
23008 (void)
tmp_rh->connect_handler;
23009 (void)
tmp_rh->ready_handler;
23010 (void)
tmp_rh->data_handler;
23011 (void)
tmp_rh->close_handler;
23014 (void)
tmp_rh->auth_handler;
23122#if defined(USE_LUA)
23126#if (defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1) \
23127 || defined(OPENSSL_API_3_0)) \
23128 && !defined(NO_SSL)
23170#if (defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1)) && !defined(NO_SSL)
23186#if defined(USE_LUA)
static int esc(const char **)
Map escape sequences into their equivalent symbols.
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
static unsigned int total
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
#define INVALID_HANDLE_VALUE
R__EXTERN C unsigned int sleep(unsigned int seconds)
static void process_new_connection(struct mg_connection *conn)
static int is_authorized_for_put(struct mg_connection *conn)
static int parse_http_request(char *buf, int len, struct mg_request_info *ri)
void mg_send_mime_file2(struct mg_connection *conn, const char *path, const char *mime_type, const char *additional_headers)
static pthread_key_t sTlsKey
static void sockaddr_to_string(char *buf, size_t len, const union usa *usa)
static void open_auth_file(struct mg_connection *conn, const char *path, struct mg_file *filep)
int mg_strncasecmp(const char *s1, const char *s2, size_t len)
static int check_authorization(struct mg_connection *conn, const char *path)
#define mg_malloc_ctx(a, c)
static void redirect_to_https_port(struct mg_connection *conn, int port)
static int should_switch_to_protocol(const struct mg_connection *conn)
void mg_unlock_connection(struct mg_connection *conn)
static void remove_bad_file(const struct mg_connection *conn, const char *path)
const struct mg_option * mg_get_valid_options(void)
static pid_t spawn_process(struct mg_connection *conn, const char *prog, char *envblk, char *envp[], int fdin[2], int fdout[2], int fderr[2], const char *dir, int cgi_config_idx)
static int print_dir_entry(struct mg_connection *conn, struct de *de)
static int mg_path_suspicious(const struct mg_connection *conn, const char *path)
static int set_non_blocking_mode(SOCKET sock)
static void ssl_locking_callback(int mode, int mutex_num, const char *file, int line)
int mg_send_http_error(struct mg_connection *conn, int status, const char *fmt,...)
static const char * get_rel_url_at_current_server(const char *uri, const struct mg_connection *conn)
static void mg_cry_internal_impl(const struct mg_connection *conn, const char *func, unsigned line, const char *fmt, va_list ap)
void mg_lock_context(struct mg_context *ctx)
#define MAX_WORKER_THREADS
int mg_base64_decode(const char *src, size_t src_len, unsigned char *dst, size_t *dst_len)
static void put_file(struct mg_connection *conn, const char *path)
static void do_ssi_exec(struct mg_connection *conn, char *tag)
static void tls_dtor(void *key)
static int is_civetweb_webdav_method(const struct mg_connection *conn)
const void * SOCK_OPT_TYPE
static int header_has_option(const char *header, const char *option)
int mg_send_http_redirect(struct mg_connection *conn, const char *target_url, int redirect_code)
int mg_get_cookie(const char *cookie_header, const char *var_name, char *dst, size_t dst_size)
static int ssl_get_client_cert_info(const struct mg_connection *conn, struct mg_client_cert *client_cert)
#define mg_cry_ctx_internal(ctx, fmt,...)
@ PROTOCOL_TYPE_WEBSOCKET
@ ENABLE_DIRECTORY_LISTING
@ ACCESS_CONTROL_ALLOW_ORIGIN
@ ACCESS_CONTROL_EXPOSE_HEADERS
@ ALLOW_INDEX_SCRIPT_SUB_RES
@ ACCESS_CONTROL_ALLOW_HEADERS
@ SSL_DEFAULT_VERIFY_PATHS
@ ACCESS_CONTROL_ALLOW_METHODS
@ STATIC_FILE_CACHE_CONTROL
@ PUT_DELETE_PASSWORDS_FILE
@ ENABLE_AUTH_DOMAIN_CHECK
@ ACCESS_CONTROL_ALLOW_CREDENTIALS
static void mg_snprintf(const struct mg_connection *conn, int *truncated, char *buf, size_t buflen, const char *fmt,...)
#define mg_opendir(conn, x)
static char * mg_strndup_ctx(const char *ptr, size_t len, struct mg_context *ctx)
static int put_dir(struct mg_connection *conn, const char *path)
static void send_static_cache_header(struct mg_connection *conn)
static int mg_socketpair(int *sockA, int *sockB)
static ptrdiff_t mg_atomic_dec(volatile ptrdiff_t *addr)
static int print_dav_dir_entry(struct de *de, void *data)
static void delete_file(struct mg_connection *conn, const char *path)
#define mg_calloc_ctx(a, b, c)
struct mg_connection * mg_connect_websocket_client_secure(const struct mg_client_options *client_options, char *error_buffer, size_t error_buffer_size, const char *path, const char *origin, mg_websocket_data_handler data_func, mg_websocket_close_handler close_func, void *user_data)
int mg_get_server_ports(const struct mg_context *ctx, int size, struct mg_server_port *ports)
static ptrdiff_t mg_atomic_inc(volatile ptrdiff_t *addr)
int mg_printf(struct mg_connection *conn, const char *fmt,...)
static int abort_cgi_process(void *data)
static int should_keep_alive(const struct mg_connection *conn)
static __inline void * mg_malloc(size_t a)
static int mg_fopen(const struct mg_connection *conn, const char *path, int mode, struct mg_file *filep)
static int alloc_printf(char **out_buf, const char *fmt,...)
void mg_disable_connection_keep_alive(struct mg_connection *conn)
static int connect_socket(struct mg_context *ctx, const char *host, int port, int use_ssl, struct mg_error_data *error, SOCKET *sock, union usa *sa)
static void mg_global_lock(void)
static void handle_static_file_request(struct mg_connection *conn, const char *path, struct mg_file *filep, const char *mime_type, const char *additional_headers)
static void dav_move_file(struct mg_connection *conn, const char *path, int do_copy)
static int ssl_use_pem_file(struct mg_context *phys_ctx, struct mg_domain_context *dom_ctx, const char *pem, const char *chain)
static const char * ssl_error(void)
static int must_hide_file(struct mg_connection *conn, const char *path)
static void dav_proppatch(struct mg_connection *conn, const char *path)
static void log_access(const struct mg_connection *)
struct mg_connection * mg_connect_client_secure(const struct mg_client_options *client_options, char *error_buffer, size_t error_buffer_size)
#define mg_remove(conn, x)
int mg_send_http_ok(struct mg_connection *conn, const char *mime_type, long long content_length)
static void close_all_listening_sockets(struct mg_context *ctx)
static const struct @141 abs_uri_protocols[]
void mg_send_file(struct mg_connection *conn, const char *path)
static void send_authorization_request(struct mg_connection *conn, const char *realm)
static int get_req_headers(const struct mg_request_info *ri, const char *name, const char **output, int output_max_size)
static int check_acl(struct mg_context *phys_ctx, const union usa *sa)
static const struct mg_option config_options[]
static const struct mg_http_method_info * get_http_method_info(const char *method)
#define STOP_FLAG_IS_ZERO(f)
const char * mg_get_response_code_text(const struct mg_connection *conn, int response_code)
static int get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
static void mg_cry_internal_wrap(const struct mg_connection *conn, struct mg_context *ctx, const char *func, unsigned line, const char *fmt,...)
static int set_uid_option(struct mg_context *phys_ctx)
static int switch_domain_context(struct mg_connection *conn)
static struct mg_connection * fake_connection(struct mg_connection *fc, struct mg_context *ctx)
static void reset_per_request_attributes(struct mg_connection *conn)
static void handle_file_based_request(struct mg_connection *conn, const char *path, struct mg_file *filep)
static int compare_dir_entries(const void *p1, const void *p2, void *arg)
#define FUNCTION_MAY_BE_UNUSED
static pthread_mutex_t * ssl_mutexes
static int get_option_index(const char *name)
static char * mg_strdup(const char *str)
static void send_no_cache_header(struct mg_connection *conn)
static void master_thread_run(struct mg_context *ctx)
static const char month_names[][4]
const struct mg_response_info * mg_get_response_info(const struct mg_connection *conn)
static __inline void * mg_realloc(void *a, size_t b)
static void accept_new_connection(const struct socket *listener, struct mg_context *ctx)
static volatile ptrdiff_t cryptolib_users
static void send_file_data(struct mg_connection *conn, struct mg_file *filep, int64_t offset, int64_t len, int no_buffering)
static int get_message(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
static pthread_mutex_t global_lock_mutex
struct mg_context * mg_start2(struct mg_init_data *init, struct mg_error_data *error)
#define CGI_ENVIRONMENT_SIZE
static int parse_http_headers(char **buf, struct mg_header hdr[(64)])
static long ssl_get_protocol(int version_id)
void * mg_get_user_context_data(const struct mg_connection *conn)
static int mg_init_library_called
long long mg_store_body(struct mg_connection *conn, const char *path)
struct mg_connection * mg_download(const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len, const char *fmt,...)
#define DEBUG_ASSERT(cond)
static size_t mg_str_append(char **dst, char *end, const char *src)
static int pull_inner(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout)
int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout)
#define MG_FILE_COMPRESSION_SIZE_LIMIT
#define USA_IN_PORT_UNSAFE(s)
unsigned mg_check_feature(unsigned feature)
static int mg_read_inner(struct mg_connection *conn, void *buf, size_t len)
static int mg_send_http_error_impl(struct mg_connection *conn, int status, const char *fmt, va_list args)
struct mg_context * mg_start(const struct mg_callbacks *callbacks, void *user_data, const char **options)
#define MG_FOPEN_MODE_READ
#define STOP_FLAG_ASSIGN(f, v)
static int extention_matches_script(struct mg_connection *conn, const char *filename)
static void get_host_from_request_info(struct vec *host, const struct mg_request_info *ri)
void mg_set_websocket_handler(struct mg_context *ctx, const char *uri, mg_websocket_connect_handler connect_handler, mg_websocket_ready_handler ready_handler, mg_websocket_data_handler data_handler, mg_websocket_close_handler close_handler, void *cbdata)
int mg_start_domain(struct mg_context *ctx, const char **options)
static pthread_mutexattr_t pthread_mutex_attr
void mg_unlock_context(struct mg_context *ctx)
static int ssl_servername_callback(SSL *ssl, int *ad, void *arg)
int mg_modify_passwords_file(const char *fname, const char *domain, const char *user, const char *pass)
static char * skip_quoted(char **buf, const char *delimiters, const char *whitespace, char quotechar)
static void fclose_on_exec(struct mg_file_access *filep, struct mg_connection *conn)
int mg_start_thread(mg_thread_func_t func, void *param)
static const char * get_header(const struct mg_header *hdr, int num_hdr, const char *name)
static int mg_inet_pton(int af, const char *src, void *dst, size_t dstlen, int resolve_src)
static int init_ssl_ctx_impl(struct mg_context *phys_ctx, struct mg_domain_context *dom_ctx, const char *pem, const char *chain)
unsigned mg_init_library(unsigned features)
struct mg_connection * mg_connect_client(const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size)
static int forward_body_data(struct mg_connection *conn, FILE *fp, SOCKET sock, SSL *ssl)
static void dav_lock_file(struct mg_connection *conn, const char *path)
static int set_gpass_option(struct mg_context *phys_ctx, struct mg_domain_context *dom_ctx)
static int skip_to_end_of_word_and_terminate(char **ppw, int eol)
static int get_request(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
static int set_tcp_nodelay(const struct socket *so, int nodelay_on)
int mg_get_var(const char *data, size_t data_len, const char *name, char *dst, size_t dst_len)
#define ARRAY_SIZE(array)
static void dav_unlock_file(struct mg_connection *conn, const char *path)
static int parse_port_string(const struct vec *vec, struct socket *so, int *ip_version)
static int get_first_ssl_listener_index(const struct mg_context *ctx)
void mg_send_mime_file(struct mg_connection *conn, const char *path, const char *mime_type)
const char * mg_get_header(const struct mg_connection *conn, const char *name)
#define mg_mkdir(conn, path, mode)
int mg_split_form_urlencoded(char *data, struct mg_header *form_fields, unsigned num_form_fields)
static int hexdump2string(void *mem, int memlen, char *buf, int buflen)
static const struct mg_http_method_info http_methods[]
static int mg_poll(struct pollfd *pfd, unsigned int n, int milliseconds, const stop_flag_t *stop_flag)
static void handle_directory_request(struct mg_connection *conn, const char *dir)
static int set_ports_option(struct mg_context *phys_ctx)
static int read_auth_file(struct mg_file *filep, struct read_auth_file_struct *workdata, int depth)
static int mg_start_thread_with_id(mg_thread_func_t func, void *param, pthread_t *threadidptr)
unsigned mg_exit_library(void)
static void * load_tls_dll(char *ebuf, size_t ebuf_len, const char *dll_name, struct ssl_func *sw, int *feature_missing)
static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
int mg_send_digest_access_authentication_request(struct mg_connection *conn, const char *realm)
static const char * mg_strcasestr(const char *big_str, const char *small_str)
struct mg_connection * mg_connect_websocket_client(const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size, const char *path, const char *origin, mg_websocket_data_handler data_func, mg_websocket_close_handler close_func, void *user_data)
static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
static void handle_ssi_file_request(struct mg_connection *conn, const char *path, struct mg_file *filep)
int mg_write(struct mg_connection *conn, const void *buf, size_t len)
static int set_throttle(const char *spec, const union usa *rsa, const char *uri)
static void ssl_info_callback(const SSL *ssl, int what, int ret)
static void bin2str(char *to, const unsigned char *p, size_t len)
const struct mg_request_info * mg_get_request_info(const struct mg_connection *conn)
static int substitute_index_file_aux(struct mg_connection *conn, char *path, size_t path_len, struct mg_file_stat *filestat)
#define MG_FOPEN_MODE_APPEND
char * mg_md5(char buf[33],...)
#define STOP_FLAG_IS_TWO(f)
static const char * next_option(const char *list, struct vec *val, struct vec *eq_val)
static const char * suggest_connection_header(const struct mg_connection *conn)
static char * all_methods
static int alloc_vprintf(char **out_buf, char *prealloc_buf, size_t prealloc_size, const char *fmt, va_list ap)
static time_t parse_date_string(const char *datetime)
static void do_ssi_include(struct mg_connection *conn, const char *ssi, char *tag, int include_level)
static void uninitialize_openssl(void)
int mg_get_request_link(const struct mg_connection *conn, char *buf, size_t buflen)
static int parse_match_net(const struct vec *vec, const union usa *sa, int no_strict)
int mg_modify_passwords_file_ha1(const char *fname, const char *domain, const char *user, const char *ha1)
static void send_options(struct mg_connection *conn)
static int lowercase(const char *s)
static void release_handler_ref(struct mg_connection *conn, struct mg_handler_info *handler_info)
static int parse_range_header(const char *header, int64_t *a, int64_t *b)
static int mg_stat(const struct mg_connection *conn, const char *path, struct mg_file_stat *filep)
static int get_uri_type(const char *uri)
#define DEBUG_TRACE(fmt,...)
static void get_system_name(char **sysName)
int mg_url_encode(const char *src, char *dst, size_t dst_len)
static const char * header_val(const struct mg_connection *conn, const char *header)
#define mg_cry_internal(conn, fmt,...)
static int set_acl_option(struct mg_context *phys_ctx)
static void mg_set_thread_name(const char *name)
static void get_mime_type(struct mg_connection *conn, const char *path, struct vec *vec)
static int set_blocking_mode(SOCKET sock)
#define MAX_CGI_ENVIR_VARS
static char * mg_strdup_ctx(const char *str, struct mg_context *ctx)
struct mg_connection * mg_connect_websocket_client_extensions(const char *host, int port, int use_ssl, char *error_buffer, size_t error_buffer_size, const char *path, const char *origin, const char *extensions, mg_websocket_data_handler data_func, mg_websocket_close_handler close_func, void *user_data)
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
void mg_set_user_connection_data(const struct mg_connection *const_conn, void *data)
int mg_get_var2(const char *data, size_t data_len, const char *name, char *dst, size_t dst_len, size_t occurrence)
static int is_not_modified(const struct mg_connection *conn, const struct mg_file_stat *filestat)
static void worker_thread_run(struct mg_connection *conn)
static int prepare_cgi_environment(struct mg_connection *conn, const char *prog, struct cgi_environment *env, int cgi_config_idx)
static const char * get_proto_name(const struct mg_connection *conn)
static void * master_thread(void *thread_func_param)
static void mg_set_handler_type(struct mg_context *phys_ctx, struct mg_domain_context *dom_ctx, const char *uri, int handler_type, int is_delete_request, mg_request_handler handler, struct mg_websocket_subprotocols *subprotocols, mg_websocket_connect_handler connect_handler, mg_websocket_ready_handler ready_handler, mg_websocket_data_handler data_handler, mg_websocket_close_handler close_handler, mg_authorization_handler auth_handler, void *cbdata)
static int is_file_opened(const struct mg_file_access *fileacc)
static int get_http_header_len(const char *buf, int buflen)
struct mg_connection * mg_connect_websocket_client_secure_extensions(const struct mg_client_options *client_options, char *error_buffer, size_t error_buffer_size, const char *path, const char *origin, const char *extensions, mg_websocket_data_handler data_func, mg_websocket_close_handler close_func, void *user_data)
void mg_close_connection(struct mg_connection *conn)
static int is_valid_port(unsigned long port)
static void handle_propfind(struct mg_connection *conn, const char *path, struct mg_file_stat *filep)
static void interpret_uri(struct mg_connection *conn, char *filename, size_t filename_buf_len, struct mg_file_stat *filestat, int *is_found, int *is_script_resource, int *is_websocket_request, int *is_put_or_delete_request, int *is_webdav_request, int *is_template_text)
static int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap)
#define mg_realloc_ctx(a, b, c)
static void send_additional_header(struct mg_connection *conn)
static int push_all(struct mg_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int len)
static int is_put_or_delete_method(const struct mg_connection *conn)
static int read_message(FILE *fp, struct mg_connection *conn, char *buf, int bufsiz, int *nread)
#define MG_FOPEN_MODE_WRITE
void * mg_get_user_connection_data(const struct mg_connection *conn)
static int authorize(struct mg_connection *conn, struct mg_file *filep, const char *realm)
static void send_ssi_file(struct mg_connection *, const char *, struct mg_file *, int)
#define mg_static_assert(cond, txt)
#define SOCKET_TIMEOUT_QUANTUM
static void produce_socket(struct mg_context *ctx, const struct socket *sp)
static void dav_mkcol(struct mg_connection *conn, const char *path)
int mg_send_chunk(struct mg_connection *conn, const char *chunk, unsigned int chunk_len)
static void remove_dot_segments(char *inout)
static int get_request_handler(struct mg_connection *conn, int handler_type, mg_request_handler *handler, struct mg_websocket_subprotocols **subprotocols, mg_websocket_connect_handler *connect_handler, mg_websocket_ready_handler *ready_handler, mg_websocket_data_handler *data_handler, mg_websocket_close_handler *close_handler, mg_authorization_handler *auth_handler, void **cbdata, struct mg_handler_info **handler_info)
void mg_set_auth_handler(struct mg_context *ctx, const char *uri, mg_authorization_handler handler, void *cbdata)
int mg_start_domain2(struct mg_context *ctx, const char **options, struct mg_error_data *error)
static int alloc_vprintf2(char **buf, const char *fmt, va_list ap)
static int extention_matches_template_text(struct mg_connection *conn, const char *filename)
static int is_in_script_path(const struct mg_connection *conn, const char *path)
static int should_decode_query_string(const struct mg_connection *conn)
static double mg_difftimespec(const struct timespec *ts_now, const struct timespec *ts_before)
static void free_context(struct mg_context *ctx)
static int sslize(struct mg_connection *conn, int(*func)(SSL *), const struct mg_client_options *client_options)
static void legacy_init(const char **options)
static void construct_etag(char *buf, size_t buf_len, const struct mg_file_stat *filestat)
int mg_get_context_info(const struct mg_context *ctx, char *buffer, int buflen)
static int mg_start_worker_thread(struct mg_context *ctx, int only_if_no_idle_threads)
static int refresh_trust(struct mg_connection *conn)
void * mg_get_thread_pointer(const struct mg_connection *conn)
static void mg_vsnprintf(const struct mg_connection *conn, int *truncated, char *buf, size_t buflen, const char *fmt, va_list ap)
static int should_decode_url(const struct mg_connection *conn)
static int mg_construct_local_link(const struct mg_connection *conn, char *buf, size_t buflen, const char *define_proto, int define_port, const char *define_uri)
static int consume_socket(struct mg_context *ctx, struct socket *sp, int thread_index, int counter_was_preincremented)
char static_assert_replacement[1]
#define ERROR_TRY_AGAIN(err)
static void send_cors_header(struct mg_connection *conn)
static unsigned char b64reverse(char letter)
static unsigned long mg_current_thread_id(void)
@ CONNECTION_TYPE_RESPONSE
@ CONNECTION_TYPE_INVALID
@ CONNECTION_TYPE_REQUEST
static void mg_strlcpy(char *dst, const char *src, size_t n)
static int remove_directory(struct mg_connection *conn, const char *dir)
static const char * get_http_version(const struct mg_connection *conn)
static __inline void * mg_calloc(size_t a, size_t b)
static int check_password_digest(const char *method, const char *ha1, const char *uri, const char *nonce, const char *nc, const char *cnonce, const char *qop, const char *response)
static void handle_request(struct mg_connection *)
static int parse_http_response(char *buf, int len, struct mg_response_info *ri)
static void * cryptolib_dll_handle
static uint64_t mg_get_current_time_ns(void)
const char * mg_get_builtin_mime_type(const char *path)
static const char * mg_fgets(char *buf, size_t size, struct mg_file *filep)
int mg_read(struct mg_connection *conn, void *buf, size_t len)
#define IGNORE_UNUSED_RESULT(a)
static void addenv(struct cgi_environment *env, const char *fmt,...)
static void discard_unread_request_data(struct mg_connection *conn)
int mg_strcasecmp(const char *s1, const char *s2)
static int mg_fclose(struct mg_file_access *fileacc)
static struct mg_connection * mg_connect_websocket_client_impl(const struct mg_client_options *client_options, int use_ssl, char *error_buffer, size_t error_buffer_size, const char *path, const char *origin, const char *extensions, mg_websocket_data_handler data_func, mg_websocket_close_handler close_func, void *user_data)
void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata)
static void * worker_thread(void *thread_func_param)
static struct mg_connection * mg_connect_client_impl(const struct mg_client_options *client_options, int use_ssl, struct mg_init_data *init, struct mg_error_data *error)
static __inline void mg_free(void *a)
static void handle_request_stat_log(struct mg_connection *conn)
int mg_check_digest_access_authentication(struct mg_connection *conn, const char *realm, const char *filename)
static int mg_join_thread(pthread_t threadid)
static void mg_global_unlock(void)
int mg_get_system_info(char *buffer, int buflen)
static void handle_not_modified_static_file_request(struct mg_connection *conn, struct mg_file *filep)
static int init_ssl_ctx(struct mg_context *phys_ctx, struct mg_domain_context *dom_ctx)
static void close_socket_gracefully(struct mg_connection *conn)
struct mg_context * mg_get_context(const struct mg_connection *conn)
static int is_ssl_port_used(const char *ports)
static void init_connection(struct mg_connection *conn)
static int print_props(struct mg_connection *conn, const char *uri, const char *name, struct mg_file_stat *filep)
static int dir_scan_callback(struct de *de, void *data)
int mg_base64_encode(const unsigned char *src, size_t src_len, char *dst, size_t *dst_len)
static void set_close_on_exec(int fd, const struct mg_connection *conn, struct mg_context *ctx)
static int get_month_index(const char *s)
void mg_set_websocket_handler_with_subprotocols(struct mg_context *ctx, const char *uri, struct mg_websocket_subprotocols *subprotocols, mg_websocket_connect_handler connect_handler, mg_websocket_ready_handler ready_handler, mg_websocket_data_handler data_handler, mg_websocket_close_handler close_handler, void *cbdata)
static void * ssllib_dll_handle
static int mg_fgetc(struct mg_file *filep)
static const struct @140 builtin_mime_types[]
static void handle_cgi_request(struct mg_connection *conn, const char *prog, int cgi_config_idx)
#define PASSWORDS_FILE_NAME
static void close_connection(struct mg_connection *conn)
static int initialize_openssl(char *ebuf, size_t ebuf_len)
static int substitute_index_file(struct mg_connection *conn, char *path, size_t path_len, struct mg_file_stat *filestat)
void mg_stop(struct mg_context *ctx)
#define STRUCT_FILE_INITIALIZER
static volatile ptrdiff_t thread_idx_max
void * mg_get_user_data(const struct mg_context *ctx)
static int scan_directory(struct mg_connection *conn, const char *dir, void *data, int(*cb)(struct de *, void *))
static int push_inner(struct mg_context *ctx, FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int len, double timeout)
const char * mg_version(void)
static int parse_auth_header(struct mg_connection *conn, char *buf, size_t buf_size, struct auth_header *auth_header)
static uint64_t get_random(void)
void mg_lock_connection(struct mg_connection *conn)
int mg_send_file_body(struct mg_connection *conn, const char *path)
static int is_valid_http_method(const char *method)
static void url_decode_in_place(char *buf)
int mg_websocket_client_write(struct mg_connection *conn, int opcode, const char *data, size_t data_len)
@ MG_FEATURES_X_DOMAIN_SOCKET
@ MG_FEATURES_COMPRESSION
int mg_response_header_add(struct mg_connection *conn, const char *header, const char *value, int value_len)
void *(* mg_thread_func_t)(void *)
int mg_response_header_send(struct mg_connection *conn)
int mg_websocket_write(struct mg_connection *conn, int opcode, const char *data, size_t data_len)
#define PRINTF_FORMAT_STRING(s)
int(* mg_authorization_handler)(struct mg_connection *conn, void *cbdata)
@ MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE
@ MG_WEBSOCKET_OPCODE_PONG
@ MG_WEBSOCKET_OPCODE_PING
void(* mg_websocket_ready_handler)(struct mg_connection *, void *)
int mg_response_header_add_lines(struct mg_connection *conn, const char *http1_headers)
@ MG_CONFIG_TYPE_DIRECTORY
@ MG_CONFIG_TYPE_EXT_PATTERN
@ MG_CONFIG_TYPE_STRING_MULTILINE
@ MG_CONFIG_TYPE_STRING_LIST
@ MG_CONFIG_TYPE_YES_NO_OPTIONAL
#define PRINTF_ARGS(x, y)
@ MG_ERROR_DATA_CODE_TLS_CONNECT_ERROR
@ MG_ERROR_DATA_CODE_INIT_LIBRARY_FAILED
@ MG_ERROR_DATA_CODE_OS_ERROR
@ MG_ERROR_DATA_CODE_MISSING_OPTION
@ MG_ERROR_DATA_CODE_CONNECT_FAILED
@ MG_ERROR_DATA_CODE_DUPLICATE_DOMAIN
@ MG_ERROR_DATA_CODE_INVALID_OPTION
@ MG_ERROR_DATA_CODE_TLS_SERVER_CERT_ERROR
@ MG_ERROR_DATA_CODE_INIT_ACL_FAILED
@ MG_ERROR_DATA_CODE_SCRIPT_ERROR
@ MG_ERROR_DATA_CODE_CONNECT_TIMEOUT
@ MG_ERROR_DATA_CODE_INIT_PORTS_FAILED
@ MG_ERROR_DATA_CODE_INVALID_PARAM
@ MG_ERROR_DATA_CODE_OUT_OF_MEMORY
@ MG_ERROR_DATA_CODE_HOST_NOT_FOUND
@ MG_ERROR_DATA_CODE_INIT_TLS_FAILED
@ MG_ERROR_DATA_CODE_INIT_USER_FAILED
@ MG_ERROR_DATA_CODE_SERVER_STOPPED
@ MG_ERROR_DATA_CODE_INVALID_PASS_FILE
@ MG_ERROR_DATA_CODE_TLS_CLIENT_CERT_ERROR
int(* mg_websocket_data_handler)(struct mg_connection *, int, char *, size_t, void *)
int(* mg_request_handler)(struct mg_connection *conn, void *cbdata)
int mg_response_header_start(struct mg_connection *conn, int status)
void(* mg_websocket_close_handler)(const struct mg_connection *, void *)
int(* mg_websocket_connect_handler)(const struct mg_connection *, void *)
static ptrdiff_t match_prefix_strlen(const char *pattern, const char *str)
static ptrdiff_t match_prefix(const char *pattern, size_t pattern_len, const char *str)
MD5_STATIC void md5_finish(md5_state_t *pms, md5_byte_t digest[16])
MD5_STATIC void md5_init(md5_state_t *pms)
MD5_STATIC void md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes)
RooArgList L(Args_t &&... args)
#define SSL_OP_CIPHER_SERVER_PREFERENCE
struct ssl_ctx_st SSL_CTX
#define SSL_OP_NO_TLSv1_3
#define SSL_OP_SINGLE_DH_USE
#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT
#define SSL_SESS_CACHE_BOTH
#define SSL_TLSEXT_ERR_OK
#define SSL_TLSEXT_ERR_NOACK
#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS
#define SSL_OP_NO_COMPRESSION
#define SSL_ERROR_SYSCALL
#define SSL_ERROR_WANT_READ
#define SSL_ERROR_WANT_ACCEPT
#define SSL_ERROR_WANT_X509_LOOKUP
#define SSL_CB_HANDSHAKE_START
#define SSL_ERROR_WANT_CONNECT
#define SSL_OP_NO_TLSv1_2
#define SSL_OP_NO_RENEGOTIATION
#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
#define TLSEXT_NAMETYPE_host_name
#define SSL_CB_HANDSHAKE_DONE
#define OPENSSL_INIT_LOAD_SSL_STRINGS
#define SSL_OP_NO_TLSv1_1
static int tls_feature_missing[TLS_END_OF_LIST]
#define SSL_ERROR_WANT_WRITE
static void free_buffered_response_header_list(struct mg_connection *conn)
SHA_API void SHA1_Init(SHA_CTX *context)
SHA_API void SHA1_Update(SHA_CTX *context, const uint8_t *data, const uint32_t len)
SHA_API void SHA1_Final(unsigned char *digest, SHA_CTX *context)
static void mg_sort(void *data, size_t elemcount, size_t elemsize, int(*compfunc)(const void *data1, const void *data2, void *userarg), void *userarg)
struct mg_connection * conn
time_t last_throttle_time
struct mg_response_info response_info
struct mg_request_info request_info
struct mg_context * phys_ctx
struct mg_domain_context * dom_ctx
int thread_shutdown_notification_socket
pthread_t * worker_threadids
unsigned int idle_worker_thread_count
unsigned int spawned_worker_threads
unsigned long starter_thread_idx
struct mg_connection * worker_connections
struct socket * listening_sockets
pthread_mutex_t thread_mutex
struct mg_callbacks callbacks
struct mg_domain_context dd
struct pollfd * listening_socket_fds
int user_shutdown_notification_socket
unsigned int cfg_max_worker_threads
struct twebdav_lock webdav_lock[10]
unsigned int num_listening_sockets
unsigned int max_request_size
pthread_mutex_t nonce_mutex
char * config[NUM_OPTIONS]
unsigned long nonce_count
int64_t ssl_cert_last_mtime
struct mg_domain_context * next
struct mg_handler_info * handlers
struct mg_file_access access
mg_request_handler handler
mg_authorization_handler auth_handler
mg_websocket_close_handler close_handler
struct mg_handler_info * next
mg_websocket_connect_handler connect_handler
struct mg_websocket_subprotocols * subprotocols
mg_websocket_data_handler data_handler
mg_websocket_ready_handler ready_handler
const struct mg_callbacks * callbacks
const char ** configuration_options
struct mg_header http_headers[(64)]
const char * local_uri_raw
const char * request_method
const char * query_string
const char * http_version
struct mg_header http_headers[(64)]
const char * http_version
const char ** subprotocols
struct mg_connection * conn
unsigned char is_optional
enum ssl_func_category required
mg_websocket_close_handler close_handler
mg_websocket_data_handler data_handler
struct mg_connection * conn