23#if defined(__GNUC__) || defined(__MINGW32__) 
   25   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 
   26#if GCC_VERSION >= 40500 
   32#if defined(GCC_DIAGNOSTIC) 
   35#pragma GCC diagnostic ignored "-Wunused-macros" 
   37#pragma GCC diagnostic ignored "-Wpadded" 
   44#pragma GCC diagnostic push 
   45#pragma GCC diagnostic ignored "-Wreserved-id-macro" 
   49#if !defined(_CRT_SECURE_NO_WARNINGS) 
   50#define _CRT_SECURE_NO_WARNINGS  
   52#if !defined(_WIN32_WINNT)  
   53#define _WIN32_WINNT 0x0502 
   56#if !defined(_GNU_SOURCE) 
   59#if defined(__linux__) && !defined(_XOPEN_SOURCE) 
   60#define _XOPEN_SOURCE 600  
   62#if defined(__LSB_VERSION__) || defined(__sun) 
   66#if !defined(_LARGEFILE_SOURCE) 
   67#define _LARGEFILE_SOURCE  
   69#if !defined(_FILE_OFFSET_BITS) 
   70#define _FILE_OFFSET_BITS 64  
   72#if !defined(__STDC_FORMAT_MACROS) 
   73#define __STDC_FORMAT_MACROS  
   75#if !defined(__STDC_LIMIT_MACROS) 
   76#define __STDC_LIMIT_MACROS  
   78#if !defined(_DARWIN_UNLIMITED_SELECT) 
   79#define _DARWIN_UNLIMITED_SELECT 
   83#define __inline inline  
   89#pragma GCC diagnostic pop 
   99#pragma warning(disable : 4306) 
  101#pragma warning(disable : 4127) 
  103#pragma warning(disable : 4204) 
  105#pragma warning(disable : 4820) 
  107#pragma warning(disable : 4668) 
  109#pragma warning(disable : 4255) 
  111#pragma warning(disable : 4711) 
  118#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201100L 
  119#define mg_static_assert _Static_assert 
  120#elif defined(__cplusplus) && __cplusplus >= 201103L 
  121#define mg_static_assert static_assert 
  124#define mg_static_assert(cond, txt)                                            \ 
  125   extern char static_assert_replacement[(cond) ? 1 : -1] 
  129                 "int data type size check");
 
  131                 "pointer data type size check");
 
  143#if defined(NO_ALTERNATIVE_QUEUE) && defined(ALTERNATIVE_QUEUE) 
  146    "Define ALTERNATIVE_QUEUE or NO_ALTERNATIVE_QUEUE (or none of them), but not both" 
  148#if !defined(NO_ALTERNATIVE_QUEUE) && !defined(ALTERNATIVE_QUEUE) 
  150#define NO_ALTERNATIVE_QUEUE 
  153#if defined(NO_FILESYSTEMS) && !defined(NO_FILES) 
  168#error "Inconsistent build flags, NO_FILESYSTEMS requires NO_FILES" 
  172#if !defined(WIN32_LEAN_AND_MEAN) 
  173#define WIN32_LEAN_AND_MEAN 
  176#if defined(__SYMBIAN32__) 
  181#error "Symbian is no longer maintained. CivetWeb no longer supports Symbian." 
  184#if defined(__ZEPHYR__) 
  188#include <net/socket.h> 
  189#include <posix/pthread.h> 
  190#include <posix/time.h> 
  198#include <libc_extensions.h> 
  203#define MAX_WORKER_THREADS (CONFIG_MAX_PTHREAD_COUNT - 2) 
  205#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) 
  206#define ZEPHYR_STACK_SIZE USE_STACK_SIZE 
  208#define ZEPHYR_STACK_SIZE (1024 * 16) 
  211K_THREAD_STACK_DEFINE(civetweb_main_stack, ZEPHYR_STACK_SIZE);
 
  212K_THREAD_STACK_ARRAY_DEFINE(civetweb_worker_stacks,
 
  216static int zephyr_worker_stack_index;
 
  220#if !defined(CIVETWEB_HEADER_INCLUDED) 
  226#if !defined(DEBUG_TRACE) 
  228static void DEBUG_TRACE_FUNC(
const char *func,
 
  233#define DEBUG_TRACE(fmt, ...)                                                  \ 
  234   DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__) 
  236#define NEED_DEBUG_TRACE_FUNC 
  237#if !defined(DEBUG_TRACE_STREAM) 
  238#define DEBUG_TRACE_STREAM stdout 
  242#define DEBUG_TRACE(fmt, ...)                                                  \ 
  249#if !defined(DEBUG_ASSERT) 
  252#define DEBUG_ASSERT(cond)                                                     \ 
  255         DEBUG_TRACE("ASSERTION FAILED: %s", #cond);                        \
 
  260#define DEBUG_ASSERT(cond) 
  265#if defined(__GNUC__) && defined(GCC_INSTRUMENTATION) 
  266void __cyg_profile_func_enter(
void *this_fn, 
void *call_site)
 
  267    __attribute__((no_instrument_function));
 
  269void __cyg_profile_func_exit(
void *this_fn, 
void *call_site)
 
  270    __attribute__((no_instrument_function));
 
  273__cyg_profile_func_enter(
void *this_fn, 
void *call_site)
 
  275   if ((
void *)this_fn != (
void *)printf) {
 
  276      printf(
"E %p %p\n", this_fn, call_site);
 
  281__cyg_profile_func_exit(
void *this_fn, 
void *call_site)
 
  283   if ((
void *)this_fn != (
void *)printf) {
 
  284      printf(
"X %p %p\n", this_fn, call_site);
 
  290#if !defined(IGNORE_UNUSED_RESULT) 
  291#define IGNORE_UNUSED_RESULT(a) ((void)((a) && 1)) 
  295#if defined(__GNUC__) || defined(__MINGW32__) 
  311#pragma GCC diagnostic ignored "-Wunused-function" 
  313#define FUNCTION_MAY_BE_UNUSED  
  316#define FUNCTION_MAY_BE_UNUSED 
  321#if !defined(_WIN32_WCE) && !defined(__ZEPHYR__) 
  327#include <sys/types.h> 
  331#if defined(__clang__) 
  335#pragma clang diagnostic ignored "-Wdisabled-macro-expansion" 
  338#if defined(__GNUC__) || defined(__MINGW32__) 
  357#if defined(__clang__) 
  358#if (__clang_major__ == 3) && ((__clang_minor__ == 7) || (__clang_minor__ == 8)) 
  360#pragma clang diagnostic ignored "-Wno-reserved-id-macro" 
  361#pragma clang diagnostic ignored "-Wno-keyword-macro" 
  365#ifndef CLOCK_MONOTONIC 
  366#define CLOCK_MONOTONIC (1) 
  368#ifndef CLOCK_REALTIME 
  369#define CLOCK_REALTIME (2) 
  372#include <mach/clock.h> 
  373#include <mach/mach.h> 
  374#include <mach/mach_time.h> 
  375#include <sys/errno.h> 
  380_civet_clock_gettime(
int clk_id, 
struct timespec *t)
 
  382   memset(t, 0, 
sizeof(*t));
 
  383   if (clk_id == CLOCK_REALTIME) {
 
  385      int rv = gettimeofday(&now, NULL);
 
  389      t->tv_sec = now.tv_sec;
 
  390      t->tv_nsec = now.tv_usec * 1000;
 
  393   } 
else if (clk_id == CLOCK_MONOTONIC) {
 
  394      static uint64_t clock_start_time = 0;
 
  395      static mach_timebase_info_data_t timebase_ifo = {0, 0};
 
  397      uint64_t now = mach_absolute_time();
 
  399      if (clock_start_time == 0) {
 
  400         kern_return_t mach_status = mach_timebase_info(&timebase_ifo);
 
  406         clock_start_time = now;
 
  409      now = (uint64_t)((
double)(now - clock_start_time)
 
  410                       * (
double)timebase_ifo.numer
 
  411                       / (
double)timebase_ifo.denom);
 
  413      t->tv_sec = now / 1000000000;
 
  414      t->tv_nsec = now % 1000000000;
 
  421#if defined(__CLOCK_AVAILABILITY) 
  426_civet_safe_clock_gettime(
int clk_id, 
struct timespec *t)
 
  429      return clock_gettime(clk_id, t);
 
  431   return _civet_clock_gettime(clk_id, t);
 
  433#define clock_gettime _civet_safe_clock_gettime 
  435#define clock_gettime _civet_clock_gettime 
  445#define ERROR_TRY_AGAIN(err)                                                   \ 
  446   (((err) == EAGAIN) || ((err) == EWOULDBLOCK) || ((err) == EINTR)) 
  462#if !defined(MAX_WORKER_THREADS) 
  463#define MAX_WORKER_THREADS (1024 * 64)  
  470#if !defined(SOCKET_TIMEOUT_QUANTUM) 
  471#define SOCKET_TIMEOUT_QUANTUM (2000)  
  475#if !defined(MG_FILE_COMPRESSION_SIZE_LIMIT) 
  476#define MG_FILE_COMPRESSION_SIZE_LIMIT (1024)  
  479#if !defined(PASSWORDS_FILE_NAME) 
  480#define PASSWORDS_FILE_NAME ".htpasswd" 
  485#if !defined(CGI_ENVIRONMENT_SIZE) 
  486#define CGI_ENVIRONMENT_SIZE (4096)  
  490#if !defined(MAX_CGI_ENVIR_VARS) 
  491#define MAX_CGI_ENVIR_VARS (256)  
  495#if !defined(MG_BUF_LEN)  
  496#define MG_BUF_LEN (1024 * 8) 
  503#if !defined(ARRAY_SIZE) 
  504#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) 
  510#if !defined(INT64_MAX) 
  511#define INT64_MAX (9223372036854775807) 
  514#define SHUTDOWN_RD (0) 
  515#define SHUTDOWN_WR (1) 
  516#define SHUTDOWN_BOTH (2) 
  519                 "worker threads must be a positive number");
 
  522                 "size_t data type size check");
 
  540#define UTF8_PATH_MAX (3 * 260) 
  543#define UTF16_PATH_MAX (260) 
  545#if !defined(_IN_PORT_T) 
  546#if !defined(in_port_t) 
  547#define in_port_t u_short 
  551#if defined(_WIN32_WCE) 
  552#error "WinCE support has ended" 
  560#define MAKEUQUAD(lo, hi)                                                      \ 
  561   ((uint64_t)(((uint32_t)(lo)) | ((uint64_t)((uint32_t)(hi))) << 32)) 
  562#define RATE_DIFF (10000000)  
  563#define EPOCH_DIFF (MAKEUQUAD(0xd53e8000, 0x019db1de)) 
  564#define SYS2UNIX_TIME(lo, hi)                                                  \ 
  565   ((time_t)((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)) 
  573#define STR(x) STRX(x) 
  574#define __func__ __FILE__ ":" STR(__LINE__)
 
  575#define strtoull(x, y, z) ((unsigned __int64)_atoi64(x)) 
  576#define strtoll(x, y, z) (_atoi64(x)) 
  578#define __func__ __FUNCTION__ 
  579#define strtoull(x, y, z) (_strtoui64(x, y, z)) 
  580#define strtoll(x, y, z) (_strtoi64(x, y, z)) 
  584#define ERRNO ((int)(GetLastError())) 
  588#if defined(_WIN64) || defined(__MINGW64__) 
  591#if defined(OPENSSL_API_3_0) 
  592#define SSL_LIB "libssl-3-x64.dll" 
  593#define CRYPTO_LIB "libcrypto-3-x64.dll" 
  596#if defined(OPENSSL_API_1_1) 
  597#define SSL_LIB "libssl-1_1-x64.dll" 
  598#define CRYPTO_LIB "libcrypto-1_1-x64.dll" 
  601#if defined(OPENSSL_API_1_0) 
  602#define SSL_LIB "ssleay64.dll" 
  603#define CRYPTO_LIB "libeay64.dll" 
  610#if defined(OPENSSL_API_3_0) 
  611#define SSL_LIB "libssl-3.dll" 
  612#define CRYPTO_LIB "libcrypto-3.dll" 
  615#if defined(OPENSSL_API_1_1) 
  616#define SSL_LIB "libssl-1_1.dll" 
  617#define CRYPTO_LIB "libcrypto-1_1.dll" 
  620#if defined(OPENSSL_API_1_0) 
  621#define SSL_LIB "ssleay32.dll" 
  622#define CRYPTO_LIB "libeay32.dll" 
  629#define O_NONBLOCK (0) 
  634#define INT64_FMT "I64d" 
  635#define UINT64_FMT "I64u" 
  637#define WINCDECL __cdecl 
  638#define vsnprintf_impl _vsnprintf 
  639#define access _access 
  640#define mg_sleep(x) (Sleep(x)) 
  642#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY) 
  644#define popen(x, y) (_popen(x, y)) 
  647#define pclose(x) (_pclose(x)) 
  649#define close(x) (_close(x)) 
  650#define dlsym(x, y) (GetProcAddress((HINSTANCE)(x), (y))) 
  652#define fseeko(x, y, z) ((_lseeki64(_fileno(x), (y), (z)) == -1) ? -1 : 0) 
  653#define fdopen(x, y) (_fdopen((x), (y))) 
  654#define write(x, y, z) (_write((x), (y), (unsigned)z)) 
  655#define read(x, y, z) (_read((x), (y), (unsigned)z)) 
  656#define flockfile(x) ((void)pthread_mutex_lock(&global_log_file_lock)) 
  657#define funlockfile(x) ((void)pthread_mutex_unlock(&global_log_file_lock)) 
  658#define sleep(x) (Sleep((x)*1000)) 
  659#define rmdir(x) (_rmdir(x)) 
  660#if defined(_WIN64) || !defined(__MINGW32__) 
  662#define timegm(x) (_mkgmtime(x)) 
  664time_t timegm(
struct tm *tm);
 
  670#define fileno(x) (_fileno(x)) 
  674   CRITICAL_SECTION sec; 
 
  676typedef DWORD pthread_key_t;
 
  677typedef HANDLE pthread_t;
 
  679   pthread_mutex_t threadIdSec;
 
  683#if !defined(__clockid_t_defined) 
  684typedef DWORD clockid_t;
 
  686#if !defined(CLOCK_MONOTONIC) 
  687#define CLOCK_MONOTONIC (1) 
  689#if !defined(CLOCK_REALTIME) 
  690#define CLOCK_REALTIME (2) 
  692#if !defined(CLOCK_THREAD) 
  693#define CLOCK_THREAD (3) 
  695#if !defined(CLOCK_PROCESS) 
  696#define CLOCK_PROCESS (4) 
  700#if defined(_MSC_VER) && (_MSC_VER >= 1900) 
  701#define _TIMESPEC_DEFINED 
  703#if !defined(_TIMESPEC_DEFINED) 
  710#if !defined(WIN_PTHREADS_TIME_H) 
  711#define MUST_IMPLEMENT_CLOCK_GETTIME 
  714#if defined(MUST_IMPLEMENT_CLOCK_GETTIME) 
  715#define clock_gettime mg_clock_gettime 
  717clock_gettime(clockid_t clk_id, 
struct timespec *tp)
 
  720   ULARGE_INTEGER li, li2;
 
  723   static double perfcnt_per_sec = 0.0;
 
  727      QueryPerformanceFrequency((LARGE_INTEGER *)&li);
 
  728      perfcnt_per_sec = 1.0 / li.QuadPart;
 
  733      memset(tp, 0, 
sizeof(*tp));
 
  735      if (clk_id == CLOCK_REALTIME) {
 
  738         GetSystemTimeAsFileTime(&ft);
 
  739         li.LowPart = ft.dwLowDateTime;
 
  740         li.HighPart = ft.dwHighDateTime;
 
  741         li.QuadPart -= 116444736000000000; 
 
  742         tp->tv_sec = (time_t)(li.QuadPart / 10000000);
 
  743         tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
 
  747      } 
else if (clk_id == CLOCK_MONOTONIC) {
 
  750         QueryPerformanceCounter((LARGE_INTEGER *)&li);
 
  751         d = li.QuadPart * perfcnt_per_sec;
 
  752         tp->tv_sec = (time_t)
d;
 
  754         tp->tv_nsec = (long)(
d * 1.0E9);
 
  758      } 
else if (clk_id == CLOCK_THREAD) {
 
  761         FILETIME t_create, t_exit, t_kernel, t_user;
 
  762         if (GetThreadTimes(GetCurrentThread(),
 
  767            li.LowPart = t_user.dwLowDateTime;
 
  768            li.HighPart = t_user.dwHighDateTime;
 
  769            li2.LowPart = t_kernel.dwLowDateTime;
 
  770            li2.HighPart = t_kernel.dwHighDateTime;
 
  771            li.QuadPart += li2.QuadPart;
 
  772            tp->tv_sec = (time_t)(li.QuadPart / 10000000);
 
  773            tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
 
  778      } 
else if (clk_id == CLOCK_PROCESS) {
 
  781         FILETIME t_create, t_exit, t_kernel, t_user;
 
  782         if (GetProcessTimes(GetCurrentProcess(),
 
  787            li.LowPart = t_user.dwLowDateTime;
 
  788            li.HighPart = t_user.dwHighDateTime;
 
  789            li2.LowPart = t_kernel.dwLowDateTime;
 
  790            li2.HighPart = t_kernel.dwHighDateTime;
 
  791            li.QuadPart += li2.QuadPart;
 
  792            tp->tv_sec = (time_t)(li.QuadPart / 10000000);
 
  793            tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
 
  813static int pthread_mutex_lock(pthread_mutex_t *);
 
  814static int pthread_mutex_unlock(pthread_mutex_t *);
 
  834   WIN32_FIND_DATAW info;
 
  838#if defined(HAVE_POLL) 
  839#define mg_pollfd pollfd 
  850#pragma comment(lib, "Ws2_32.lib")
 
  858#define UTF8_PATH_MAX (PATH_MAX) 
  863typedef unsigned short int in_port_t;
 
  866#if !defined(__ZEPHYR__) 
  867#include <arpa/inet.h> 
  873#include <netinet/in.h> 
  874#include <netinet/tcp.h> 
  883#include <sys/socket.h> 
  885#include <sys/utsname.h> 
  889#if defined(USE_X_DOM_SOCKET) 
  894#define vsnprintf_impl vsnprintf 
  896#if !defined(NO_SSL_DL) && !defined(NO_SSL) 
  901#define SSL_LIB "libssl.dylib" 
  902#define CRYPTO_LIB "libcrypto.dylib" 
  905#define SSL_LIB "libssl.so" 
  907#if !defined(CRYPTO_LIB) 
  908#define CRYPTO_LIB "libcrypto.so" 
  911#if !defined(O_BINARY) 
  914#define closesocket(a) (close(a)) 
  915#define mg_mkdir(conn, path, mode) (mkdir(path, mode)) 
  916#define mg_remove(conn, x) (remove(x)) 
  917#define mg_sleep(x) (usleep((x)*1000)) 
  918#define mg_opendir(conn, x) (opendir(x)) 
  919#define mg_closedir(x) (closedir(x)) 
  920#define mg_readdir(x) (readdir(x)) 
  922#define INVALID_SOCKET (-1) 
  923#define INT64_FMT PRId64 
  924#define UINT64_FMT PRIu64 
  930#if !defined(CLOCK_MONOTONIC) 
  931#define CLOCK_MONOTONIC CLOCK_REALTIME 
  945#define mg_pollfd pollfd 
  950#if defined(NEED_TIMEGM) 
  954   return (
y % 4 == 0 && 
y % 100 != 0) || 
y % 400 == 0;
 
  960   return (
y - 1969) / 4 - (
y - 1901) / 100 + (
y - 1601) / 400;
 
  966   static const unsigned short ydays[] = {
 
  967       0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
 
  968   int year = tm->tm_year + 1900;
 
  969   int mon = tm->tm_mon;
 
  970   int mday = tm->tm_mday - 1;
 
  971   int hour = tm->tm_hour;
 
  972   int min = tm->tm_min;
 
  973   int sec = tm->tm_sec;
 
  975   if (year < 1970 || mon < 0 || mon > 11 || mday < 0
 
  976       || (mday >= ydays[mon + 1] - ydays[mon]
 
  977                       + (mon == 1 && is_leap(year) ? 1 : 0))
 
  978       || hour < 0 || hour > 23 || 
min < 0 || 
min > 59 || sec < 0 || sec > 60)
 
  981   time_t res = year - 1970;
 
  984   res += ydays[mon] + (mon > 1 && is_leap(year) ? 1 : 0);
 
  985   res += count_leap(year);
 
 1000#define va_copy(x, y) ((x) = (y)) 
 1007#if defined(GCC_DIAGNOSTIC) 
 1009#pragma GCC diagnostic push 
 1010#pragma GCC diagnostic ignored "-Wunused-function" 
 1014static pthread_mutex_t global_log_file_lock;
 
 1020   return GetCurrentThreadId();
 
 1028    void (*_ignored)(
void *) 
 
 1035      return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1;
 
 1043pthread_key_delete(pthread_key_t key)
 
 1045   return TlsFree(key) ? 0 : 1;
 
 1051pthread_setspecific(pthread_key_t key, 
void *
value)
 
 1053   return TlsSetValue(key, 
value) ? 0 : 1;
 
 1059pthread_getspecific(pthread_key_t key)
 
 1061   return TlsGetValue(key);
 
 1064#if defined(GCC_DIAGNOSTIC) 
 1066#pragma GCC diagnostic pop 
 1075#if defined(GCC_DIAGNOSTIC) 
 1077#pragma GCC diagnostic push 
 1078#pragma GCC diagnostic ignored "-Wunused-function" 
 1080#if defined(__clang__) 
 1082#pragma clang diagnostic push 
 1083#pragma clang diagnostic ignored "-Wunused-function" 
 1106mg_static_assert(SIZE_MAX == 0xFFFFFFFFFFFFFFFFu, 
"Mismatch for atomic types");
 
 1107#elif defined(_WIN32) 
 1122#if defined(_WIN64) && !defined(NO_ATOMICS) 
 1123   ret = InterlockedIncrement64(addr);
 
 1124#elif defined(_WIN32) && !defined(NO_ATOMICS) 
 1125   ret = InterlockedIncrement(addr);
 
 1126#elif defined(__GNUC__)                                                        \ 
 1127    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \ 
 1128    && !defined(NO_ATOMICS) 
 1129   ret = __sync_add_and_fetch(addr, 1);
 
 1145#if defined(_WIN64) && !defined(NO_ATOMICS) 
 1146   ret = InterlockedDecrement64(addr);
 
 1147#elif defined(_WIN32) && !defined(NO_ATOMICS) 
 1148   ret = InterlockedDecrement(addr);
 
 1149#elif defined(__GNUC__)                                                        \ 
 1150    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \ 
 1151    && !defined(NO_ATOMICS) 
 1152   ret = __sync_sub_and_fetch(addr, 1);
 
 1162#if defined(USE_SERVER_STATS) || defined(STOP_FLAG_NEEDS_LOCK) 
 1164mg_atomic_add(
volatile ptrdiff_t *addr, ptrdiff_t 
value)
 
 1168#if defined(_WIN64) && !defined(NO_ATOMICS) 
 1169   ret = InterlockedAdd64(addr, 
value);
 
 1170#elif defined(_WIN32) && !defined(NO_ATOMICS) 
 1171   ret = InterlockedExchangeAdd(addr, 
value) + 
value;
 
 1172#elif defined(__GNUC__)                                                        \ 
 1173    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \ 
 1174    && !defined(NO_ATOMICS) 
 1175   ret = __sync_add_and_fetch(addr, 
value);
 
 1188mg_atomic_compare_and_swap(
volatile ptrdiff_t *addr,
 
 1194#if defined(_WIN64) && !defined(NO_ATOMICS) 
 1195   ret = InterlockedCompareExchange64(addr, newval, oldval);
 
 1196#elif defined(_WIN32) && !defined(NO_ATOMICS) 
 1197   ret = InterlockedCompareExchange(addr, newval, oldval);
 
 1198#elif defined(__GNUC__)                                                        \ 
 1199    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \ 
 1200    && !defined(NO_ATOMICS) 
 1201   ret = __sync_val_compare_and_swap(addr, oldval, newval);
 
 1205   if ((ret != newval) && (ret == oldval)) {
 
 1215mg_atomic_max(
volatile ptrdiff_t *addr, ptrdiff_t 
value)
 
 1217   register ptrdiff_t tmp = *addr;
 
 1219#if defined(_WIN64) && !defined(NO_ATOMICS) 
 1220   while (tmp < 
value) {
 
 1221      tmp = InterlockedCompareExchange64(addr, 
value, tmp);
 
 1223#elif defined(_WIN32) && !defined(NO_ATOMICS) 
 1224   while (tmp < 
value) {
 
 1225      tmp = InterlockedCompareExchange(addr, 
value, tmp);
 
 1227#elif defined(__GNUC__)                                                        \ 
 1228    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \ 
 1229    && !defined(NO_ATOMICS) 
 1230   while (tmp < 
value) {
 
 1231      tmp = __sync_val_compare_and_swap(addr, tmp, 
value);
 
 1235   if (*addr < 
value) {
 
 1244mg_atomic_add64(
volatile int64_t *addr, int64_t 
value)
 
 1248#if defined(_WIN64) && !defined(NO_ATOMICS) 
 1249   ret = InterlockedAdd64(addr, 
value);
 
 1250#elif defined(_WIN32) && !defined(NO_ATOMICS) 
 1251   ret = InterlockedExchangeAdd64(addr, 
value) + 
value;
 
 1252#elif defined(__GNUC__)                                                        \ 
 1253    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \ 
 1254    && !defined(NO_ATOMICS) 
 1255   ret = __sync_add_and_fetch(addr, 
value);
 
 1267#if defined(GCC_DIAGNOSTIC) 
 1269#pragma GCC diagnostic pop 
 1271#if defined(__clang__) 
 1273#pragma clang diagnostic pop 
 1277#if defined(USE_SERVER_STATS) 
 1279struct mg_memory_stat {
 
 1280   volatile ptrdiff_t totalMemUsed;
 
 1281   volatile ptrdiff_t maxMemUsed;
 
 1282   volatile ptrdiff_t blockCount;
 
 1286static struct mg_memory_stat *get_memory_stat(
struct mg_context *ctx);
 
 1290mg_malloc_ex(
size_t size,
 
 1297   struct mg_memory_stat *mstat = get_memory_stat(ctx);
 
 1299#if defined(MEMORY_DEBUGGING) 
 1300   char mallocStr[256];
 
 1307      ptrdiff_t mmem = mg_atomic_add(&mstat->totalMemUsed, (ptrdiff_t)
size);
 
 1308      mg_atomic_max(&mstat->maxMemUsed, mmem);
 
 1312      ((uintptr_t *)
data)[1] = (uintptr_t)mstat;
 
 1313      memory = (
void *)(((
char *)
data) + 2 * 
sizeof(uintptr_t));
 
 1316#if defined(MEMORY_DEBUGGING) 
 1318           "MEM: %p %5lu alloc   %7lu %4lu --- %s:%u\n",
 
 1320           (
unsigned long)
size,
 
 1321           (
unsigned long)mstat->totalMemUsed,
 
 1322           (
unsigned long)mstat->blockCount,
 
 1333mg_calloc_ex(
size_t count,
 
 1349mg_free_ex(
void *memory, 
const char *
file, 
unsigned line)
 
 1351#if defined(MEMORY_DEBUGGING) 
 1352   char mallocStr[256];
 
 1359      void *
data = (
void *)(((
char *)memory) - 2 * 
sizeof(uintptr_t));
 
 1360      uintptr_t 
size = ((uintptr_t *)
data)[0];
 
 1361      struct mg_memory_stat *mstat =
 
 1362          (
struct mg_memory_stat *)(((uintptr_t *)
data)[1]);
 
 1363      mg_atomic_add(&mstat->totalMemUsed, -(ptrdiff_t)
size);
 
 1366#if defined(MEMORY_DEBUGGING) 
 1368              "MEM: %p %5lu free    %7lu %4lu --- %s:%u\n",
 
 1370              (
unsigned long)
size,
 
 1371              (
unsigned long)mstat->totalMemUsed,
 
 1372              (
unsigned long)mstat->blockCount,
 
 1383mg_realloc_ex(
void *memory,
 
 1393#if defined(MEMORY_DEBUGGING) 
 1394   char mallocStr[256];
 
 1403         struct mg_memory_stat *mstat;
 
 1404         data = (
void *)(((
char *)memory) - 2 * 
sizeof(uintptr_t));
 
 1405         oldsize = ((uintptr_t *)
data)[0];
 
 1406         mstat = (
struct mg_memory_stat *)((uintptr_t *)
data)[1];
 
 1407         _realloc = 
realloc(
data, newsize + 2 * 
sizeof(uintptr_t));
 
 1410            mg_atomic_add(&mstat->totalMemUsed, -(ptrdiff_t)oldsize);
 
 1411#if defined(MEMORY_DEBUGGING) 
 1413                    "MEM: %p %5lu r-free  %7lu %4lu --- %s:%u\n",
 
 1415                    (
unsigned long)oldsize,
 
 1416                    (
unsigned long)mstat->totalMemUsed,
 
 1417                    (
unsigned long)mstat->blockCount,
 
 1422            mg_atomic_add(&mstat->totalMemUsed, (ptrdiff_t)newsize);
 
 1424#if defined(MEMORY_DEBUGGING) 
 1426                    "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n",
 
 1428                    (
unsigned long)newsize,
 
 1429                    (
unsigned long)mstat->totalMemUsed,
 
 1430                    (
unsigned long)mstat->blockCount,
 
 1435            *(uintptr_t *)
data = newsize;
 
 1436            data = (
void *)(((
char *)
data) + 2 * 
sizeof(uintptr_t));
 
 1438#if defined(MEMORY_DEBUGGING) 
 1457#define mg_malloc(a) mg_malloc_ex(a, NULL, __FILE__, __LINE__) 
 1458#define mg_calloc(a, b) mg_calloc_ex(a, b, NULL, __FILE__, __LINE__) 
 1459#define mg_realloc(a, b) mg_realloc_ex(a, b, NULL, __FILE__, __LINE__) 
 1460#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__) 
 1462#define mg_malloc_ctx(a, c) mg_malloc_ex(a, c, __FILE__, __LINE__) 
 1463#define mg_calloc_ctx(a, b, c) mg_calloc_ex(a, b, c, __FILE__, __LINE__) 
 1464#define mg_realloc_ctx(a, b, c) mg_realloc_ex(a, b, c, __FILE__, __LINE__) 
 1470static __inline 
void *
 
 1476static __inline 
void *
 
 1482static __inline 
void *
 
 1494#define mg_malloc_ctx(a, c) mg_malloc(a) 
 1495#define mg_calloc_ctx(a, b, c) mg_calloc(a, b) 
 1496#define mg_realloc_ctx(a, b, c) mg_realloc(a, b) 
 1497#define mg_free_ctx(a, c) mg_free(a) 
 1530#if defined(snprintf) 
 1533#if defined(vsnprintf) 
 1536#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc 
 1537#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc 
 1538#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc 
 1539#define free DO_NOT_USE_THIS_FUNCTION__USE_mg_free 
 1540#define snprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_snprintf 
 1544#define vsnprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_vsnprintf 
 1552#if defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1)                       \ 
 1553    || defined(OPENSSL_API_3_0) 
 1554static int mg_openssl_initialized = 0;
 
 1556#if !defined(OPENSSL_API_1_0) && !defined(OPENSSL_API_1_1)                     \ 
 1557    && !defined(OPENSSL_API_3_0) && !defined(USE_MBEDTLS) 
 1558#error "Please define OPENSSL_API_1_0 or OPENSSL_API_1_1" 
 1560#if defined(OPENSSL_API_1_0) && defined(OPENSSL_API_1_1)                       \ 
 1561    && defined(OPENSSL_API_3_0) 
 1562#error "Multiple OPENSSL_API versions defined" 
 1564#if (defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1)                      \ 
 1565     || defined(OPENSSL_API_3_0))                                              \ 
 1566    && defined(USE_MBEDTLS) 
 1567#error "Multiple SSL libraries defined" 
 1575#if defined(MG_LEGACY_INTERFACE) 
 1576#define MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE 
 1584   HANDLE pthread_cond_helper_mutex;
 
 1588#if defined(MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE) 
 1594#if defined(GCC_DIAGNOSTIC) 
 1596#pragma GCC diagnostic push 
 1597#pragma GCC diagnostic ignored "-Wunused-function" 
 1599#if defined(__clang__) 
 1601#pragma clang diagnostic push 
 1602#pragma clang diagnostic ignored "-Wunused-function" 
 1621   return GetCurrentThreadId();
 
 1624#if defined(__clang__) 
 1625#pragma clang diagnostic push 
 1626#pragma clang diagnostic ignored "-Wunreachable-code" 
 1634   if (
sizeof(pthread_t) > 
sizeof(
unsigned long)) {
 
 1645         pthread_setspecific(
sTlsKey, tls);
 
 1652      unsigned long ret = 0;
 
 1653      pthread_t t = pthread_self();
 
 1654      memcpy(&ret, &t, 
sizeof(pthread_t));
 
 1658#if defined(__clang__) 
 1659#pragma clang diagnostic pop 
 1670   struct timespec tsnow;
 
 1671   clock_gettime(CLOCK_REALTIME, &tsnow);
 
 1672   return (((uint64_t)tsnow.tv_sec) * 1000000000) + (uint64_t)tsnow.tv_nsec;
 
 1676#if defined(GCC_DIAGNOSTIC) 
 1678#pragma GCC diagnostic pop 
 1680#if defined(__clang__) 
 1682#pragma clang diagnostic pop 
 1686#if defined(NEED_DEBUG_TRACE_FUNC) 
 1688DEBUG_TRACE_FUNC(
const char *func, 
unsigned line, 
const char *fmt, ...)
 
 1691   struct timespec tsnow;
 
 1696   clock_gettime(CLOCK_REALTIME, &tsnow);
 
 1698   flockfile(DEBUG_TRACE_STREAM);
 
 1699   fprintf(DEBUG_TRACE_STREAM,
 
 1700           "*** %lu.%09lu %lu %s:%u: ",
 
 1701           (
unsigned long)tsnow.tv_sec,
 
 1702           (
unsigned long)tsnow.tv_nsec,
 
 1706   va_start(args, fmt);
 
 1707   vfprintf(DEBUG_TRACE_STREAM, fmt, args);
 
 1709   putc(
'\n', DEBUG_TRACE_STREAM);
 
 1710   fflush(DEBUG_TRACE_STREAM);
 
 1711   funlockfile(DEBUG_TRACE_STREAM);
 
 1716#define MD5_STATIC static 
 1720#if defined(NO_SOCKLEN_T) 
 1721typedef int socklen_t;
 
 1724#define IP_ADDR_STR_LEN (50)  
 1726#if !defined(MSG_NOSIGNAL) 
 1727#define MSG_NOSIGNAL (0) 
 1732#if defined(USE_MBEDTLS) 
 1734#include "mod_mbedtls.inl" 
 1736#elif defined(NO_SSL) 
 1741#elif defined(NO_SSL_DL) 
 1743#include <openssl/bn.h> 
 1744#include <openssl/conf.h> 
 1745#include <openssl/crypto.h> 
 1746#include <openssl/dh.h> 
 1747#include <openssl/engine.h> 
 1748#include <openssl/err.h> 
 1749#include <openssl/opensslv.h> 
 1750#include <openssl/pem.h> 
 1751#include <openssl/ssl.h> 
 1752#include <openssl/tls1.h> 
 1753#include <openssl/x509.h> 
 1755#if defined(WOLFSSL_VERSION) 
 1758#include "wolfssl_extras.inl" 
 1761#if defined(OPENSSL_IS_BORINGSSL) 
 1772#define CONF_modules_unload(a) ((void)0) 
 1773#define ENGINE_cleanup() ((void)0) 
 1777#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) 
 1778#if !defined(OPENSSL_API_3_0) 
 1779#define OPENSSL_API_3_0 
 1781#define OPENSSL_REMOVE_THREAD_STATE() 
 1783#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) 
 1784#if !defined(OPENSSL_API_1_1) 
 1785#define OPENSSL_API_1_1 
 1787#define OPENSSL_REMOVE_THREAD_STATE() 
 1789#if !defined(OPENSSL_API_1_0) 
 1790#define OPENSSL_API_1_0 
 1792#define OPENSSL_REMOVE_THREAD_STATE() ERR_remove_thread_state(NULL) 
 1806#if !defined(NO_CACHING) 
 1827#if defined(USE_IPV6) 
 1828   struct sockaddr_in6 sin6;
 
 1830#if defined(USE_X_DOM_SOCKET) 
 1831   struct sockaddr_un sun;
 
 1835#if defined(USE_X_DOM_SOCKET) 
 1836static unsigned short 
 1839   if (s->
sa.sa_family == AF_INET)
 
 1840      return s->
sin.sin_port;
 
 1841#if defined(USE_IPV6) 
 1842   if (s->
sa.sa_family == AF_INET6)
 
 1843      return s->sin6.sin6_port;
 
 1848#if defined(USE_IPV6) 
 1849#define USA_IN_PORT_UNSAFE(s)                                                  \ 
 1850   (((s)->sa.sa_family == AF_INET6) ? (s)->sin6.sin6_port : (s)->sin.sin_port) 
 1852#define USA_IN_PORT_UNSAFE(s) ((s)->sin.sin_port) 
 1883#define STRUCT_FILE_INITIALIZER                                                \ 
 1885      {(uint64_t)0, (time_t)0, 0, 0, 0},                                     \ 
 1921#if defined(__linux__) 
 1922   ALLOW_SENDFILE_CALL,
 
 1925   CASE_SENSITIVE_FILES,
 
 1931#if defined(USE_WEBSOCKET) 
 1933   ENABLE_WEBSOCKET_PING_PONG,
 
 1938   LUA_BACKGROUND_SCRIPT,
 
 1939   LUA_BACKGROUND_SCRIPT_PARAMS,
 
 1941#if defined(USE_HTTP2) 
 1955#if defined(USE_TIMERS) 
 1963#if defined(USE_TIMERS) 
 1967#if defined(USE_4_CGI) 
 1971   CGI3_INTERPRETER_ARGS,
 
 1972#if defined(USE_TIMERS) 
 1979   CGI4_INTERPRETER_ARGS,
 
 1980#if defined(USE_TIMERS) 
 2011   LUA_SCRIPT_EXTENSIONS,
 
 2012   LUA_SERVER_PAGE_EXTENSIONS,
 
 2013#if defined(MG_EXPERIMENTAL_INTERFACES) 
 2017#if defined(USE_DUKTAPE) 
 2018   DUKTAPE_SCRIPT_EXTENSIONS,
 
 2021#if defined(USE_WEBSOCKET) 
 2024#if defined(USE_LUA) && defined(USE_WEBSOCKET) 
 2025   LUA_WEBSOCKET_EXTENSIONS,
 
 2033#if !defined(NO_CACHING) 
 2061#if defined(__linux__) 
 2071#if defined(USE_WEBSOCKET) 
 2081#if defined(USE_HTTP2) 
 2095#if defined(USE_TIMERS) 
 2103#if defined(USE_TIMERS) 
 2107#if defined(USE_4_CGI) 
 2112#if defined(USE_TIMERS) 
 2120#if defined(USE_TIMERS) 
 2135     "index.xhtml,index.html,index.htm," 
 2136     "index.lp,index.lsp,index.lua,index.cgi," 
 2137     "index.shtml,index.php"},
 
 2139     "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
 
 2167#if defined(MG_EXPERIMENTAL_INTERFACES) 
 2171#if defined(USE_DUKTAPE) 
 2177#if defined(USE_WEBSOCKET) 
 2180#if defined(USE_LUA) && defined(USE_WEBSOCKET) 
 2188#if !defined(NO_CACHING) 
 2205                 "config_options and enum not sync");
 
 2262#if defined(USE_LUA) && defined(USE_WEBSOCKET) 
 2264   struct mg_shared_lua_websocket_list *shared_lua_websockets;
 
 2275#if defined(STOP_FLAG_NEEDS_LOCK) 
 2298      sf = mg_atomic_compare_and_swap(
f, *
f, 
v);
 
 2305#define STOP_FLAG_IS_ZERO(f) ((*(f)) == 0) 
 2306#define STOP_FLAG_IS_TWO(f) ((*(f)) == 2) 
 2307#define STOP_FLAG_ASSIGN(f, v) ((*(f)) = (v)) 
 2330#if defined(USE_SERVER_STATS) 
 2331   volatile ptrdiff_t active_connections;
 
 2332   volatile ptrdiff_t max_active_connections;
 
 2333   volatile ptrdiff_t total_connections;
 
 2334   volatile ptrdiff_t total_requests;
 
 2335   volatile int64_t total_data_read;
 
 2336   volatile int64_t total_data_written;
 
 2350#if defined(ALTERNATIVE_QUEUE) 
 2351   struct socket *client_socks;
 
 2352   void **client_wait_events;
 
 2362#if defined(USE_SERVER_STATS) 
 2370#if defined(USE_SERVER_STATS) 
 2371   struct mg_memory_stat ctx_memory;
 
 2379#if defined(USE_TIMERS) 
 2380   struct ttimers *timers;
 
 2385   void *lua_background_state;   
 
 2386   pthread_mutex_t lua_bg_mutex; 
 
 2387   int lua_bg_log_available;     
 
 2410#if defined(USE_SERVER_STATS) 
 2411static struct mg_memory_stat mg_common_memory = {0, 0, 0};
 
 2413static struct mg_memory_stat *
 
 2417      return &(ctx->ctx_memory);
 
 2419   return &mg_common_memory;
 
 2436#if defined(USE_HTTP2) 
 2437#if !defined(HTTP2_DYN_TABLE_SIZE) 
 2438#define HTTP2_DYN_TABLE_SIZE (256) 
 2441struct mg_http2_connection {
 
 2443   uint32_t dyn_table_size;
 
 2444   struct mg_header dyn_table[HTTP2_DYN_TABLE_SIZE];
 
 2454#if defined(USE_HTTP2) 
 2455   struct mg_http2_connection http2;
 
 2464#if defined(USE_SERVER_STATS) 
 2474#if defined(USE_SERVER_STATS) 
 2475   time_t conn_close_time; 
 
 2477   double processing_time; 
 
 2503#if defined(USE_WEBSOCKET) 
 2504   int in_websocket_handling; 
 
 2506#if defined(USE_ZLIB) && defined(USE_WEBSOCKET)                                \ 
 2507    && defined(MG_EXPERIMENTAL_INTERFACES) 
 2509   int websocket_deflate_server_max_windows_bits;
 
 2510   int websocket_deflate_client_max_windows_bits;
 
 2511   int websocket_deflate_server_no_context_takeover;
 
 2512   int websocket_deflate_client_no_context_takeover;
 
 2513   int websocket_deflate_initialized;
 
 2514   int websocket_deflate_flush;
 
 2515   z_stream websocket_deflate_state;
 
 2516   z_stream websocket_inflate_state;
 
 2531#if defined(USE_LUA) && defined(USE_WEBSOCKET) 
 2532   void *lua_websocket_state; 
 
 2548#define mg_cry_internal(conn, fmt, ...)                                        \ 
 2549   mg_cry_internal_wrap(conn, NULL, __func__, __LINE__, fmt, __VA_ARGS__) 
 2551#define mg_cry_ctx_internal(ctx, fmt, ...)                                     \ 
 2552   mg_cry_internal_wrap(NULL, ctx, __func__, __LINE__, fmt, __VA_ARGS__) 
 2562#if !defined(NO_THREAD_NAME) 
 2563#if defined(_WIN32) && defined(_MSC_VER) 
 2567#pragma pack(push, 8) 
 2568typedef struct tagTHREADNAME_INFO {
 
 2576#elif defined(__linux__) 
 2578#include <sys/prctl.h> 
 2579#include <sys/sendfile.h> 
 2580#if defined(ALTERNATIVE_QUEUE) 
 2581#include <sys/eventfd.h> 
 2585#if defined(ALTERNATIVE_QUEUE) 
 2590   int evhdl = eventfd(0, EFD_CLOEXEC);
 
 2611event_wait(
void *eventhdl)
 
 2620   evhdl = *(
int *)eventhdl;
 
 2622   s = (
int)read(evhdl, &u, 
sizeof(u));
 
 2623   if (s != 
sizeof(u)) {
 
 2633event_signal(
void *eventhdl)
 
 2642   evhdl = *(
int *)eventhdl;
 
 2644   s = (
int)write(evhdl, &u, 
sizeof(u));
 
 2645   if (s != 
sizeof(u)) {
 
 2654event_destroy(
void *eventhdl)
 
 2662   evhdl = *(
int *)eventhdl;
 
 2674#if !defined(__linux__) && !defined(_WIN32) && defined(ALTERNATIVE_QUEUE) 
 2677   pthread_mutex_t mutex;
 
 2686   struct posix_event *ret = 
mg_malloc(
sizeof(
struct posix_event));
 
 2691   if (0 != pthread_mutex_init(&(ret->mutex), NULL)) {
 
 2696   if (0 != pthread_cond_init(&(ret->cond), NULL)) {
 
 2698      pthread_mutex_destroy(&(ret->mutex));
 
 2708event_wait(
void *eventhdl)
 
 2710   struct posix_event *ev = (
struct posix_event *)eventhdl;
 
 2711   pthread_mutex_lock(&(ev->mutex));
 
 2712   while (!ev->signaled) {
 
 2713      pthread_cond_wait(&(ev->cond), &(ev->mutex));
 
 2716   pthread_mutex_unlock(&(ev->mutex));
 
 2722event_signal(
void *eventhdl)
 
 2724   struct posix_event *ev = (
struct posix_event *)eventhdl;
 
 2725   pthread_mutex_lock(&(ev->mutex));
 
 2726   pthread_cond_signal(&(ev->cond));
 
 2728   pthread_mutex_unlock(&(ev->mutex));
 
 2734event_destroy(
void *eventhdl)
 
 2736   struct posix_event *ev = (
struct posix_event *)eventhdl;
 
 2737   pthread_cond_destroy(&(ev->cond));
 
 2738   pthread_mutex_destroy(&(ev->mutex));
 
 2747   char threadName[16 + 1]; 
 
 2750       NULL, NULL, threadName, 
sizeof(threadName), 
"civetweb-%s", 
name);
 
 2753#if defined(_MSC_VER) 
 2756      THREADNAME_INFO info;
 
 2757      info.dwType = 0x1000;
 
 2758      info.szName = threadName;
 
 2759      info.dwThreadID = ~0U;
 
 2762      RaiseException(0x406D1388,
 
 2764                     sizeof(info) / 
sizeof(ULONG_PTR),
 
 2765                     (ULONG_PTR *)&info);
 
 2766   } __except (EXCEPTION_EXECUTE_HANDLER) {
 
 2768#elif defined(__MINGW32__) 
 2771#elif defined(_GNU_SOURCE) && defined(__GLIBC__)                               \ 
 2772    && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12))) 
 2774#if defined(__MACH__) 
 2776   (void)pthread_setname_np(threadName);
 
 2778   (void)pthread_setname_np(pthread_self(), threadName);
 
 2780#elif defined(__linux__) 
 2786   (void)prctl(PR_SET_NAME, threadName, 0, 0, 0);
 
 2805#define MG_FOPEN_MODE_NONE (0) 
 2808#define MG_FOPEN_MODE_READ (1) 
 2811#define MG_FOPEN_MODE_WRITE (2) 
 2814#define MG_FOPEN_MODE_APPEND (4) 
 2824   return (fileacc->
fp != NULL);
 
 2828#if !defined(NO_FILESYSTEMS) 
 2838   const uint8_t *
c = (
const uint8_t *)path;
 
 2841   if ((
c == NULL) || (
c[0] == 0)) {
 
 2852      if ((*
c == 
'>') || (*
c == 
'<') || (*
c == 
'|')) {
 
 2856      if ((*
c == 
'*') || (*
c == 
'?')) {
 
 2907      wchar_t wbuf[UTF16_PATH_MAX];
 
 2908      path_to_unicode(conn, path, wbuf, 
ARRAY_SIZE(wbuf));
 
 2911         filep->
access.
fp = _wfopen(wbuf, L
"rb");
 
 2914         filep->
access.
fp = _wfopen(wbuf, L
"wb");
 
 2917         filep->
access.
fp = _wfopen(wbuf, L
"ab");
 
 2925      filep->
access.
fp = fopen(path, 
"r");
 
 2928      filep->
access.
fp = fopen(path, 
"w");
 
 2931      filep->
access.
fp = fopen(path, 
"a");
 
 2954   if (fileacc != NULL) {
 
 2955      if (fileacc->
fp != NULL) {
 
 2956         ret = fclose(fileacc->
fp);
 
 2959      memset(fileacc, 0, 
sizeof(*fileacc));
 
 2969   for (; *
src != 
'\0' && 
n > 1; 
n--) {
 
 2979   return tolower((
unsigned char)*s);
 
 2991      } 
while (diff == 0 && 
s1[-1] != 
'\0' && --
len > 0);
 
 3005   } 
while (diff == 0 && 
s1[-1] != 
'\0');
 
 3042   size_t i, big_len = strlen(big_str), small_len = strlen(small_str);
 
 3044   if (big_len >= small_len) {
 
 3045      for (i = 0; i <= (big_len - small_len); i++) {
 
 3075#if defined(__clang__) 
 3076#pragma clang diagnostic push 
 3077#pragma clang diagnostic ignored "-Wformat-nonliteral" 
 3083   ok = (
n >= 0) && ((
size_t)
n < buflen);
 
 3085#if defined(__clang__) 
 3086#pragma clang diagnostic pop 
 3098                      "truncating vsnprintf buffer: [%.*s]",
 
 3099                      (
int)((buflen > 200) ? 200 : (buflen - 1)),
 
 3101      n = (
int)buflen - 1;
 
 3143   } 
else if (!ctx || ctx->
dd.
config[i] == NULL) {
 
 3150#define mg_get_option DO_NOT_USE_THIS_FUNCTION_INTERNALLY__access_directly 
 3162   return (ctx == NULL) ? NULL : ctx->
user_data;
 
 3192   if (const_conn != NULL) {
 
 3222   memset(ports, 0, 
sizeof(*ports) * (
size_t)
size);
 
 3252#if defined(USE_X_DOM_SOCKET) && !defined(UNIX_DOMAIN_SOCKET_SERVER_NAME) 
 3253#define UNIX_DOMAIN_SOCKET_SERVER_NAME "*" 
 3265   if (
usa->
sa.sa_family == AF_INET) {
 
 3266      getnameinfo(&
usa->
sa,
 
 3274#if defined(USE_IPV6) 
 3275   else if (
usa->
sa.sa_family == AF_INET6) {
 
 3276      getnameinfo(&
usa->
sa,
 
 3285#if defined(USE_X_DOM_SOCKET) 
 3286   else if (
usa->
sa.sa_family == AF_UNIX) {
 
 3297      strncpy(
buf, UNIX_DOMAIN_SOCKET_SERVER_NAME, 
len);
 
 3309#if !defined(REENTRANT_TIME) 
 3312   tm = ((t != NULL) ? gmtime(t) : NULL);
 
 3316   struct tm *tm = &_tm;
 
 3321      strftime(buf, buf_len, 
"%a, %d %b %Y %H:%M:%S GMT", tm);
 
 3323      mg_strlcpy(buf, 
"Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
 
 3324      buf[buf_len - 1] = 
'\0';
 
 3333   return (
double)(ts_now->tv_nsec - ts_before->tv_nsec) * 1.0E-9
 
 3334          + (
double)(ts_now->tv_sec - ts_before->tv_sec);
 
 3338#if defined(MG_EXTERNAL_FUNCTION_mg_cry_internal_impl) 
 3344#include "external_mg_cry_internal_impl.inl" 
 3345#elif !defined(NO_FILESYSTEMS) 
 3363#if defined(GCC_DIAGNOSTIC) 
 3364#pragma GCC diagnostic push 
 3365#pragma GCC diagnostic ignored "-Wformat-nonliteral" 
 3370#if defined(GCC_DIAGNOSTIC) 
 3371#pragma GCC diagnostic pop 
 3374   buf[
sizeof(buf) - 1] = 0;
 
 3403         timestamp = time(NULL);
 
 3407                 "[%010lu] [error] [client %s] ",
 
 3408                 (
unsigned long)timestamp,
 
 3430#error Must either enable filesystems or provide a custom mg_cry_internal_impl implementation 
 3477#define mg_cry DO_NOT_USE_THIS_FUNCTION__USE_mg_cry_internal 
 3493#if defined(MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE) 
 3500      if (strlen(txt) == 3) {
 
 3501         memcpy(tls->txtbuf, txt, 4);
 
 3503         strcpy(tls->txtbuf, 
"ERR");
 
 3508      ((
struct mg_connection *)conn)->request_info.local_uri_raw =
 
 3543#if defined(__clang__) 
 3544#pragma clang diagnostic push 
 3545#pragma clang diagnostic ignored "-Wunreachable-code" 
 3556                            ? (ri->
is_ssl ? 
"wss" : 
"ws")
 
 3557                            : (ri->
is_ssl ? 
"https" : 
"http"));
 
 3561#if defined(__clang__) 
 3562#pragma clang diagnostic pop 
 3571                        const char *define_proto,
 
 3573                        const char *define_uri)
 
 3575   if ((buflen < 1) || (buf == 0) || (conn == 0)) {
 
 3584          (define_uri != NULL)
 
 3587      int port = (define_port > 0) ? define_port : ri->
server_port;
 
 3594#if defined(USE_X_DOM_SOCKET) 
 3605         const char *server_name = UNIX_DOMAIN_SOCKET_SERVER_NAME;
 
 3621         if ((0 == strcmp(define_proto, 
"https"))
 
 3622             || (0 == strcmp(define_proto, 
"wss"))) {
 
 3632#if defined(USE_IPV6) 
 3633         int is_ipv6 = (conn->
client.
lsa.
sa.sa_family == AF_INET6);
 
 3635         int auth_domain_check_enabled =
 
 3640         const char *server_domain =
 
 3647            sprintf(portstr, 
":%u", (
unsigned)port);
 
 3652         if (!auth_domain_check_enabled || !server_domain) {
 
 3658            server_domain = server_ip;
 
 3665#
if defined(USE_IPV6)
 
 3668                     (is_ipv6 && (server_domain == server_ip)) ? 
"[" : 
"",
 
 3670                     (is_ipv6 && (server_domain == server_ip)) ? 
"]" : 
"",
 
 3702            const char *delimiters,
 
 3703            const char *whitespace,
 
 3706   char *
p, *begin_word, *end_word, *end_whitespace;
 
 3709   end_word = begin_word + strcspn(begin_word, delimiters);
 
 3712   if (end_word > begin_word) {
 
 3714      while (*
p == quotechar) {
 
 3721         if (*end_word != 
'\0') {
 
 3722            size_t end_off = strcspn(end_word + 1, delimiters);
 
 3723            memmove(
p, end_word, end_off + 1);
 
 3725            end_word += end_off + 1;
 
 3731      for (
p++; 
p < end_word; 
p++) {
 
 3736   if (*end_word == 
'\0') {
 
 3740#if defined(GCC_DIAGNOSTIC) 
 3742#pragma GCC diagnostic push 
 3743#pragma GCC diagnostic ignored "-Wsign-conversion" 
 3746      end_whitespace = end_word + strspn(&end_word[1], whitespace) + 1;
 
 3748#if defined(GCC_DIAGNOSTIC) 
 3749#pragma GCC diagnostic pop 
 3752      for (
p = end_word; 
p < end_whitespace; 
p++) {
 
 3756      *buf = end_whitespace;
 
 3768   for (i = 0; i < num_hdr; i++) {
 
 3770         return hdr[i].
value;
 
 3778#if defined(USE_WEBSOCKET) 
 3785                int output_max_size)
 
 3851   if (val == NULL || list == NULL || *list == 
'\0') {
 
 3857   while (*list == 
' ' || *list == 
'\t')
 
 3861   if ((list = strchr(val->
ptr, 
',')) != NULL) {
 
 3863      val->
len = ((size_t)(list - val->
ptr));
 
 3867      list = val->
ptr + strlen(val->
ptr);
 
 3868      val->
len = ((size_t)(list - val->
ptr));
 
 3873   while (end >= 0 && ((val->
ptr[end] == 
' ') || (val->
ptr[end] == 
'\t')))
 
 3875   val->
len = (size_t)(end) + (size_t)(1);
 
 3877   if (val->
len == 0) {
 
 3882   if (eq_val != NULL) {
 
 3886      eq_val->
ptr = (
const char *)memchr(val->
ptr, 
'=', val->
len);
 
 3887      if (eq_val->
ptr != NULL) {
 
 3889         eq_val->
len = ((size_t)(val->
ptr - eq_val->
ptr)) + val->
len;
 
 3890         val->
len = ((size_t)(eq_val->
ptr - val->
ptr)) - 1;
 
 3911   while ((header = 
next_option(header, &opt_vec, &eq_vec)) != NULL) {
 
 3925   ptrdiff_t i, j, 
len, res;
 
 3927   if ((or_str = (
const char *)memchr(pattern, 
'|', pattern_len)) != NULL) {
 
 3928      res = 
match_prefix(pattern, (
size_t)(or_str - pattern), str);
 
 3929      return (res > 0) ? res
 
 3931                                      (
size_t)((pattern + pattern_len)
 
 3936   for (i = 0, j = 0; (i < (ptrdiff_t)pattern_len); i++, j++) {
 
 3937      if ((pattern[i] == 
'?') && (str[j] != 
'\0')) {
 
 3939      } 
else if (pattern[i] == 
'$') {
 
 3940         return (str[j] == 
'\0') ? j : -1;
 
 3941      } 
else if (pattern[i] == 
'*') {
 
 3943         if (pattern[i] == 
'*') {
 
 3945            len = (ptrdiff_t)strlen(str + j);
 
 3947            len = (ptrdiff_t)strcspn(str + j, 
"/");
 
 3949         if (i == (ptrdiff_t)pattern_len) {
 
 3954                               (pattern_len - (
size_t)i),
 
 3956         } 
while (res == -1 && 
len-- > 0);
 
 3957         return (res == -1) ? -1 : j + res + 
len;
 
 3962   return (ptrdiff_t)j;
 
 3969   if (pattern == NULL) {
 
 3982   const char *http_version;
 
 4008   if (http_version && (0 == strcmp(http_version, 
"1.1"))) {
 
 4021   if (!conn || !conn->
dom_ctx) {
 
 4032   if (!conn || !conn->
dom_ctx) {
 
 4057                          "no-cache, no-store, " 
 4058                          "must-revalidate, private, max-age=0",
 
 4072#if !defined(NO_CACHING) 
 4076   const char *cache_control =
 
 4080   if (cache_control != NULL) {
 
 4107       conn, NULL, val, 
sizeof(val), 
"max-age=%lu", (
unsigned long)max_age);
 
 4132                     (
unsigned long)max_age);
 
 4138   if (header && header[0]) {
 
 4144#if !defined(NO_FILESYSTEMS) 
 4158   switch (response_code) {
 
 4163      return "Switching Protocols"; 
 
 4165      return "Processing"; 
 
 4175      return "Non-Authoritative Information"; 
 
 4177      return "No Content"; 
 
 4179      return "Reset Content"; 
 
 4181      return "Partial Content"; 
 
 4183      return "Multi-Status"; 
 
 4186      return "Already Reported"; 
 
 4193      return "Multiple Choices"; 
 
 4195      return "Moved Permanently"; 
 
 4201      return "Not Modified"; 
 
 4205      return "Temporary Redirect"; 
 
 4207      return "Permanent Redirect"; 
 
 4211      return "Bad Request"; 
 
 4213      return "Unauthorized"; 
 
 4215      return "Payment Required"; 
 
 4221      return "Method Not Allowed"; 
 
 4223      return "Not Acceptable"; 
 
 4225      return "Proxy Authentication Required"; 
 
 4227      return "Request Time-out"; 
 
 4233      return "Length Required"; 
 
 4235      return "Precondition Failed"; 
 
 4237      return "Request Entity Too Large"; 
 
 4239      return "Request-URI Too Large"; 
 
 4241      return "Unsupported Media Type"; 
 
 4243      return "Requested range not satisfiable"; 
 
 4246      return "Expectation Failed"; 
 
 4249      return "Misdirected Request"; 
 
 4251      return "Unproccessable entity"; 
 
 4256      return "Failed Dependency"; 
 
 4260      return "Upgrade Required"; 
 
 4263      return "Precondition Required"; 
 
 4265      return "Too Many Requests"; 
 
 4268      return "Request Header Fields Too Large"; 
 
 4271      return "Unavailable For Legal Reasons"; 
 
 4276      return "Internal Server Error"; 
 
 4278      return "Not Implemented"; 
 
 4280      return "Bad Gateway"; 
 
 4282      return "Service Unavailable"; 
 
 4284      return "Gateway Time-out"; 
 
 4286      return "HTTP Version not supported"; 
 
 4288      return "Variant Also Negotiates"; 
 
 4290      return "Insufficient Storage"; 
 
 4293      return "Loop Detected"; 
 
 4296      return "Not Extended"; 
 
 4298      return "Network Authentication Required"; 
 
 4304      return "I am a teapot"; 
 
 4306      return "Authentication Timeout"; 
 
 4308      return "Enhance Your Calm"; 
 
 4310      return "Login Timeout"; 
 
 4312      return "Bandwidth Limit Exceeded"; 
 
 4318                         "Unknown HTTP response code: %u",
 
 4323      if (response_code >= 100 && response_code < 200) {
 
 4325         return "Information";
 
 4327      if (response_code >= 200 && response_code < 300) {
 
 4331      if (response_code >= 300 && response_code < 400) {
 
 4333         return "Redirection";
 
 4335      if (response_code >= 400 && response_code < 500) {
 
 4337         return "Client Error";
 
 4339      if (response_code >= 500 && response_code < 600) {
 
 4341         return "Server Error";
 
 4360#if !defined(NO_FILESYSTEMS) 
 4362   int len, i, page_handler_found, scope, truncated;
 
 4363   const char *error_handler = NULL;
 
 4365   const char *error_page_file_ext, *tstr;
 
 4367   int handled_by_callback = 0;
 
 4369   if ((conn == NULL) || (fmt == NULL)) {
 
 4377   has_body = ((status > 199) && (status != 204) && (status != 304));
 
 4385      mg_vsnprintf(conn, NULL, errmsg_buf, 
sizeof(errmsg_buf), fmt, ap);
 
 4388      DEBUG_TRACE(
"Error %i - [%s]", status, errmsg_buf);
 
 4398      handled_by_callback =
 
 4404   if (!handled_by_callback) {
 
 4408             "Recursion when handling error %u - fall back to default",
 
 4410#if !defined(NO_FILESYSTEMS) 
 4415         page_handler_found = 0;
 
 4417         if (error_handler != NULL) {
 
 4418            for (scope = 1; (scope <= 3) && !page_handler_found; scope++) {
 
 4424                              sizeof(path_buf) - 32,
 
 4435                              sizeof(path_buf) - 32,
 
 4444                              sizeof(path_buf) - 32,
 
 4459               path_buf[
sizeof(path_buf) - 32] = 0;
 
 4460               len = (
int)strlen(path_buf);
 
 4461               if (
len > (
int)
sizeof(path_buf) - 32) {
 
 4462                  len = (
int)
sizeof(path_buf) - 32;
 
 4466               tstr = strchr(error_page_file_ext, 
'.');
 
 4470                       (i < 32) && (tstr[i] != 0) && (tstr[i] != 
',');
 
 4475                     path_buf[
len + i - 1] = tstr[i];
 
 4480                  path_buf[
len + i - 1] = 0;
 
 4482                  if (
mg_stat(conn, path_buf, &error_page_file.
stat)) {
 
 4485                     page_handler_found = 1;
 
 4493                  tstr = strchr(tstr + i, 
'.');
 
 4498         if (page_handler_found) {
 
 4515                                "text/plain; charset=utf-8",
 
 4524         mg_printf(conn, 
"Error %d: %s\n", status, status_text);
 
 4525         mg_write(conn, errmsg_buf, strlen(errmsg_buf));
 
 4553                long long content_length)
 
 4564   if (content_length < 0) {
 
 4578                  (uint64_t)content_length);
 
 4593                      const char *target_url,
 
 4607   const char *redirect_text;
 
 4609   size_t content_len = 0;
 
 4610#if defined(MG_SEND_REDIRECT_BODY) 
 4615   if (redirect_code == 0) {
 
 4616      redirect_code = 307;
 
 4620   if ((redirect_code != 301) && (redirect_code != 302)
 
 4621       && (redirect_code != 303) && (redirect_code != 307)
 
 4622       && (redirect_code != 308)) {
 
 4631   if ((target_url == NULL) || (*target_url == 0)) {
 
 4635#if defined(MG_SEND_REDIRECT_BODY) 
 4663       "<html><head>%s</head><body><a href=\"%s\">%s</a></body></html>",
 
 4667   content_len = strlen(reply);
 
 4673                   "HTTP/1.1 %i %s\r\n" 
 4675                   "Content-Length: %u\r\n" 
 4676                   "Connection: %s\r\n\r\n",
 
 4680                   (
unsigned int)content_len,
 
 4683#if defined(MG_SEND_REDIRECT_BODY) 
 4688         ret = 
mg_write(conn, reply, content_len);
 
 4693   return (ret > 0) ? ret : -1;
 
 4700#if defined(GCC_DIAGNOSTIC) 
 4702#pragma GCC diagnostic push 
 4703#pragma GCC diagnostic ignored "-Wunused-function" 
 4708pthread_mutex_init(pthread_mutex_t *mutex, 
void *unused)
 
 4712   InitializeCriticalSection(&mutex->sec);
 
 4718pthread_mutex_destroy(pthread_mutex_t *mutex)
 
 4720   DeleteCriticalSection(&mutex->sec);
 
 4726pthread_mutex_lock(pthread_mutex_t *mutex)
 
 4728   EnterCriticalSection(&mutex->sec);
 
 4734pthread_mutex_unlock(pthread_mutex_t *mutex)
 
 4736   LeaveCriticalSection(&mutex->sec);
 
 4747   cv->waiting_thread = NULL;
 
 4755                       pthread_mutex_t *mutex,
 
 4761   uint64_t nsnow, nswaitabs;
 
 4765   pthread_mutex_lock(&cv->threadIdSec);
 
 4767   ptls = &cv->waiting_thread;
 
 4768   for (; *ptls != NULL; ptls = &(*ptls)->next_waiting_thread)
 
 4770   tls->next_waiting_thread = NULL;
 
 4772   pthread_mutex_unlock(&cv->threadIdSec);
 
 4777          (((uint64_t)abstime->tv_sec) * 1000000000) + abstime->tv_nsec;
 
 4778      nswaitrel = nswaitabs - nsnow;
 
 4779      if (nswaitrel < 0) {
 
 4782      mswaitrel = (DWORD)(nswaitrel / 1000000);
 
 4784      mswaitrel = (DWORD)INFINITE;
 
 4787   pthread_mutex_unlock(mutex);
 
 4789         == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
 
 4792      pthread_mutex_lock(&cv->threadIdSec);
 
 4793      ptls = &cv->waiting_thread;
 
 4794      for (; *ptls != NULL; ptls = &(*ptls)->next_waiting_thread) {
 
 4796            *ptls = tls->next_waiting_thread;
 
 4801      pthread_mutex_unlock(&cv->threadIdSec);
 
 4803         WaitForSingleObject(tls->pthread_cond_helper_mutex,
 
 4808   pthread_mutex_lock(mutex);
 
 4818   return pthread_cond_timedwait(cv, mutex, NULL);
 
 4829   pthread_mutex_lock(&cv->threadIdSec);
 
 4830   if (cv->waiting_thread) {
 
 4831      wkup = cv->waiting_thread->pthread_cond_helper_mutex;
 
 4832      cv->waiting_thread = cv->waiting_thread->next_waiting_thread;
 
 4834      ok = SetEvent(wkup);
 
 4837   pthread_mutex_unlock(&cv->threadIdSec);
 
 4847   pthread_mutex_lock(&cv->threadIdSec);
 
 4848   while (cv->waiting_thread) {
 
 4849      pthread_cond_signal(cv);
 
 4851   pthread_mutex_unlock(&cv->threadIdSec);
 
 4861   pthread_mutex_lock(&cv->threadIdSec);
 
 4863   pthread_mutex_unlock(&cv->threadIdSec);
 
 4864   pthread_mutex_destroy(&cv->threadIdSec);
 
 4870#if defined(ALTERNATIVE_QUEUE) 
 4875   return (
void *)CreateEvent(NULL, 
FALSE, 
FALSE, NULL);
 
 4881event_wait(
void *eventhdl)
 
 4883   int res = WaitForSingleObject((HANDLE)eventhdl, (DWORD)INFINITE);
 
 4884   return (res == WAIT_OBJECT_0);
 
 4890event_signal(
void *eventhdl)
 
 4892   return (
int)SetEvent((HANDLE)eventhdl);
 
 4898event_destroy(
void *eventhdl)
 
 4900   CloseHandle((HANDLE)eventhdl);
 
 4905#if defined(GCC_DIAGNOSTIC) 
 4907#pragma GCC diagnostic pop 
 4913change_slashes_to_backslashes(
char *path)
 
 4917   for (i = 0; path[i] != 
'\0'; i++) {
 
 4918      if (path[i] == 
'/') {
 
 4924      if ((i > 0) && (path[i] == 
'\\')) {
 
 4925         while ((path[i + 1] == 
'\\') || (path[i + 1] == 
'/')) {
 
 4926            (
void)memmove(path + i + 1, path + i + 2, strlen(path + i + 1));
 
 4934mg_wcscasecmp(
const wchar_t *
s1, 
const wchar_t *s2)
 
 4939      diff = ((*
s1 >= 
L'A') && (*
s1 <= L
'Z') ? (*
s1 - 
L'A' + 
L'a') : *
s1)
 
 4940             - ((*s2 >= 
L'A') && (*s2 <= 
L'Z') ? (*s2 - 
L'A' + 
L'a') : *s2);
 
 4943   } 
while ((diff == 0) && (
s1[-1] != L
'\0'));
 
 4958   wchar_t wbuf2[UTF16_PATH_MAX + 1];
 
 4959   DWORD long_len, err;
 
 4960   int (*fcompare)(
const wchar_t *, 
const wchar_t *) = mg_wcscasecmp;
 
 4963   change_slashes_to_backslashes(buf);
 
 4967   memset(wbuf, 0, wbuf_len * 
sizeof(
wchar_t));
 
 4968   MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (
int)wbuf_len);
 
 4969   WideCharToMultiByte(
 
 4970       CP_UTF8, 0, wbuf, (
int)wbuf_len, buf2, 
sizeof(buf2), NULL, NULL);
 
 4971   if (strcmp(buf, buf2) != 0) {
 
 4995   memset(wbuf2, 0, 
ARRAY_SIZE(wbuf2) * 
sizeof(
wchar_t));
 
 4996   long_len = GetLongPathNameW(wbuf, wbuf2, 
ARRAY_SIZE(wbuf2) - 1);
 
 4997   if (long_len == 0) {
 
 4998      err = GetLastError();
 
 4999      if (err == ERROR_FILE_NOT_FOUND) {
 
 5004   if ((long_len >= 
ARRAY_SIZE(wbuf2)) || (fcompare(wbuf, wbuf2) != 0)) {
 
 5011#if !defined(NO_FILESYSTEMS) 
 5018   wchar_t wbuf[UTF16_PATH_MAX];
 
 5019   WIN32_FILE_ATTRIBUTE_DATA info;
 
 5020   time_t creation_time;
 
 5026   memset(filep, 0, 
sizeof(*filep));
 
 5032   path_to_unicode(conn, path, wbuf, 
ARRAY_SIZE(wbuf));
 
 5037   if ((
len > 0) && (path[
len - 1] != 
' ') && (path[
len - 1] != 
'.')
 
 5038       && (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0)) {
 
 5039      filep->
size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
 
 5041          SYS2UNIX_TIME(info.ftLastWriteTime.dwLowDateTime,
 
 5042                        info.ftLastWriteTime.dwHighDateTime);
 
 5048      creation_time = SYS2UNIX_TIME(info.ftCreationTime.dwLowDateTime,
 
 5049                                    info.ftCreationTime.dwHighDateTime);
 
 5054      filep->
is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
 
 5066   wchar_t wbuf[UTF16_PATH_MAX];
 
 5067   path_to_unicode(conn, path, wbuf, 
ARRAY_SIZE(wbuf));
 
 5068   return DeleteFileW(wbuf) ? 0 : -1;
 
 5075   wchar_t wbuf[UTF16_PATH_MAX];
 
 5077   path_to_unicode(conn, path, wbuf, 
ARRAY_SIZE(wbuf));
 
 5078   return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
 
 5084#if defined(GCC_DIAGNOSTIC) 
 5086#pragma GCC diagnostic push 
 5087#pragma GCC diagnostic ignored "-Wunused-function" 
 5097   wchar_t wpath[UTF16_PATH_MAX];
 
 5101      SetLastError(ERROR_BAD_ARGUMENTS);
 
 5102   } 
else if ((dir = (DIR *)
mg_malloc(
sizeof(*dir))) == NULL) {
 
 5103      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
 
 5106      attrs = GetFileAttributesW(wpath);
 
 5107      if ((wcslen(wpath) + 2 < 
ARRAY_SIZE(wpath)) && (attrs != 0xFFFFFFFF)
 
 5108          && ((attrs & FILE_ATTRIBUTE_DIRECTORY) != 0)) {
 
 5109         (
void)wcscat(wpath, L
"\\*");
 
 5110         dir->handle = FindFirstFileW(wpath, &dir->info);
 
 5111         dir->result.d_name[0] = 
'\0';
 
 5130         result = FindClose(dir->handle) ? 0 : -1;
 
 5135      SetLastError(ERROR_BAD_ARGUMENTS);
 
 5143static struct dirent *
 
 5146   struct dirent *
result = 0;
 
 5151         (
void)WideCharToMultiByte(CP_UTF8,
 
 5153                                   dir->info.cFileName,
 
 5160         if (!FindNextFileW(dir->handle, &dir->info)) {
 
 5161            (
void)FindClose(dir->handle);
 
 5166         SetLastError(ERROR_FILE_NOT_FOUND);
 
 5169      SetLastError(ERROR_BAD_ARGUMENTS);
 
 5176#if !defined(HAVE_POLL) 
 5188poll(
struct mg_pollfd *pfd, 
unsigned int n, 
int milliseconds)
 
 5198   memset(&tv, 0, 
sizeof(tv));
 
 5199   tv.tv_sec = milliseconds / 1000;
 
 5200   tv.tv_usec = (milliseconds % 1000) * 1000;
 
 5205   for (i = 0; i < 
n; i++) {
 
 5206      if (pfd[i].events & (POLLIN | POLLOUT | POLLERR)) {
 
 5207         if (pfd[i].events & POLLIN) {
 
 5208            FD_SET(pfd[i].fd, &rset);
 
 5210         if (pfd[i].events & POLLOUT) {
 
 5211            FD_SET(pfd[i].fd, &wset);
 
 5214         FD_SET(pfd[i].fd, &eset);
 
 5218      if (pfd[i].fd > maxfd) {
 
 5223   if ((
result = select((
int)maxfd + 1, &rset, &wset, &eset, &tv)) > 0) {
 
 5224      for (i = 0; i < 
n; i++) {
 
 5225         if (FD_ISSET(pfd[i].fd, &rset)) {
 
 5226            pfd[i].revents |= POLLIN;
 
 5228         if (FD_ISSET(pfd[i].fd, &wset)) {
 
 5229            pfd[i].revents |= POLLOUT;
 
 5231         if (FD_ISSET(pfd[i].fd, &eset)) {
 
 5232            pfd[i].revents |= POLLERR;
 
 5249#if defined(GCC_DIAGNOSTIC) 
 5251#pragma GCC diagnostic pop 
 5263   (
void)SetHandleInformation((HANDLE)(intptr_t)sock, HANDLE_FLAG_INHERIT, 0);
 
 5270#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) 
 5274   return ((_beginthread((
void(__cdecl *)(
void *))
f, USE_STACK_SIZE, 
p)
 
 5275            == ((uintptr_t)(-1L)))
 
 5280       (_beginthread((
void(__cdecl *)(
void *))
f, 0, 
p) == ((uintptr_t)(-1L)))
 
 5291                        pthread_t *threadidptr)
 
 5294   HANDLE threadhandle;
 
 5297   uip = _beginthreadex(NULL, 0, 
f, 
p, 0, NULL);
 
 5298   threadhandle = (HANDLE)uip;
 
 5299   if ((uip != 0) && (threadidptr != NULL)) {
 
 5300      *threadidptr = threadhandle;
 
 5316   dwevent = WaitForSingleObject(threadid, (DWORD)INFINITE);
 
 5317   if (dwevent == WAIT_FAILED) {
 
 5320      if (dwevent == WAIT_OBJECT_0) {
 
 5321         CloseHandle(threadid);
 
 5329#if !defined(NO_SSL_DL) && !defined(NO_SSL) 
 5333#if defined(GCC_DIAGNOSTIC) 
 5335#pragma GCC diagnostic push 
 5336#pragma GCC diagnostic ignored "-Wunused-function" 
 5342dlopen(
const char *dll_name, 
int flags)
 
 5344   wchar_t wbuf[UTF16_PATH_MAX];
 
 5346   path_to_unicode(NULL, dll_name, wbuf, 
ARRAY_SIZE(wbuf));
 
 5347   return LoadLibraryW(wbuf);
 
 5353dlclose(
void *handle)
 
 5357   if (FreeLibrary((HMODULE)handle) != 0) {
 
 5367#if defined(GCC_DIAGNOSTIC) 
 5369#pragma GCC diagnostic pop 
 5380kill(pid_t pid, 
int sig_num)
 
 5382   (
void)TerminateProcess((HANDLE)pid, (UINT)sig_num);
 
 5383   (
void)CloseHandle((HANDLE)pid);
 
 5388#if !defined(WNOHANG) 
 5394waitpid(pid_t pid, 
int *status, 
int flags)
 
 5396   DWORD timeout = INFINITE;
 
 5401   if ((flags | WNOHANG) == WNOHANG) {
 
 5405   waitres = WaitForSingleObject((HANDLE)pid, timeout);
 
 5406   if (waitres == WAIT_OBJECT_0) {
 
 5409   if (waitres == WAIT_TIMEOUT) {
 
 5417trim_trailing_whitespaces(
char *s)
 
 5419   char *
e = s + strlen(s);
 
 5420   while ((
e > s) && isspace((
unsigned char)
e[-1])) {
 
 5435              unsigned char cgi_config_idx)
 
 5439   char *interp_arg = 0;
 
 5444   PROCESS_INFORMATION pi = {0};
 
 5448   memset(&si, 0, 
sizeof(si));
 
 5451   si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
 
 5452   si.wShowWindow = SW_HIDE;
 
 5454   me = GetCurrentProcess();
 
 5456                   (HANDLE)_get_osfhandle(fdin[0]),
 
 5461                   DUPLICATE_SAME_ACCESS);
 
 5463                   (HANDLE)_get_osfhandle(fdout[1]),
 
 5468                   DUPLICATE_SAME_ACCESS);
 
 5470                   (HANDLE)_get_osfhandle(fderr[1]),
 
 5475                   DUPLICATE_SAME_ACCESS);
 
 5480   SetHandleInformation((HANDLE)_get_osfhandle(fdin[1]),
 
 5481                        HANDLE_FLAG_INHERIT,
 
 5483   SetHandleInformation((HANDLE)_get_osfhandle(fdout[0]),
 
 5484                        HANDLE_FLAG_INHERIT,
 
 5486   SetHandleInformation((HANDLE)_get_osfhandle(fderr[0]),
 
 5487                        HANDLE_FLAG_INHERIT,
 
 5493   if (interp != NULL) {
 
 5501      buf[0] = buf[1] = 
'\0';
 
 5505          conn, &truncated, cmdline, 
sizeof(cmdline), 
"%s/%s", dir, prog);
 
 5508         pi.hProcess = (pid_t)-1;
 
 5518         buf[
sizeof(buf) - 1] = 
'\0';
 
 5521      if ((buf[0] == 
'#') && (buf[1] == 
'!')) {
 
 5522         trim_trailing_whitespaces(buf + 2);
 
 5529   GetFullPathNameA(dir, 
sizeof(full_dir), full_dir, NULL);
 
 5531   if (interp[0] != 
'\0') {
 
 5533      if ((interp_arg != 0) && (interp_arg[0] != 0)) {
 
 5538                     "\"%s\" %s \"%s\\%s\"",
 
 5548                     "\"%s\" \"%s\\%s\"",
 
 5565      pi.hProcess = (pid_t)-1;
 
 5570   if (CreateProcessA(NULL,
 
 5575                      CREATE_NEW_PROCESS_GROUP,
 
 5582          conn, 
"%s: CreateProcess(%s): %ld", __func__, cmdline, (
long)
ERRNO);
 
 5583      pi.hProcess = (pid_t)-1;
 
 5588   (
void)CloseHandle(si.hStdOutput);
 
 5589   (
void)CloseHandle(si.hStdError);
 
 5590   (
void)CloseHandle(si.hStdInput);
 
 5591   if (pi.hThread != NULL) {
 
 5592      (
void)CloseHandle(pi.hThread);
 
 5595   return (pid_t)pi.hProcess;
 
 5603   unsigned long non_blocking = 0;
 
 5604   return ioctlsocket(sock, (
long)FIONBIO, &non_blocking);
 
 5611   unsigned long non_blocking = 1;
 
 5612   return ioctlsocket(sock, (
long)FIONBIO, &non_blocking);
 
 5619#if !defined(NO_FILESYSTEMS) 
 5629   memset(filep, 0, 
sizeof(*filep));
 
 5635   if (0 == stat(path, &st)) {
 
 5636      filep->
size = (uint64_t)(st.st_size);
 
 5652#if defined(__ZEPHYR__) 
 5657   if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
 
 5661                         "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s",
 
 5673   pthread_t thread_id;
 
 5674   pthread_attr_t 
attr;
 
 5677   (void)pthread_attr_init(&
attr);
 
 5678   (void)pthread_attr_setdetachstate(&
attr, PTHREAD_CREATE_DETACHED);
 
 5680#if defined(__ZEPHYR__) 
 5681   pthread_attr_setstack(&
attr, &civetweb_main_stack, ZEPHYR_STACK_SIZE);
 
 5682#elif defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) 
 5685   (void)pthread_attr_setstacksize(&
attr, USE_STACK_SIZE);
 
 5688   result = pthread_create(&thread_id, &
attr, func, param);
 
 5689   pthread_attr_destroy(&
attr);
 
 5699                        pthread_t *threadidptr)
 
 5701   pthread_t thread_id;
 
 5702   pthread_attr_t 
attr;
 
 5705   (void)pthread_attr_init(&
attr);
 
 5707#if defined(__ZEPHYR__) 
 5708   pthread_attr_setstack(&
attr,
 
 5709                         &civetweb_worker_stacks[zephyr_worker_stack_index++],
 
 5711#elif defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) 
 5714   (void)pthread_attr_setstacksize(&
attr, USE_STACK_SIZE);
 
 5717   result = pthread_create(&thread_id, &
attr, func, param);
 
 5718   pthread_attr_destroy(&
attr);
 
 5719   if ((
result == 0) && (threadidptr != NULL)) {
 
 5720      *threadidptr = thread_id;
 
 5732   result = pthread_join(threadid, NULL);
 
 5747              unsigned char cgi_config_idx)
 
 5754   if ((pid = fork()) == -1) {
 
 5757   } 
else if (pid != 0) {
 
 5765      if (chdir(dir) != 0) {
 
 5767             conn, 
"%s: chdir(%s): %s", __func__, dir, strerror(
ERRNO));
 
 5768      } 
else if (dup2(fdin[0], 0) == -1) {
 
 5770                         "%s: dup2(%d, 0): %s",
 
 5774      } 
else if (dup2(fdout[1], 1) == -1) {
 
 5776                         "%s: dup2(%d, 1): %s",
 
 5780      } 
else if (dup2(fderr[1], 2) == -1) {
 
 5782                         "%s: dup2(%d, 2): %s",
 
 5787         struct sigaction sa;
 
 5792         (void)close(fdin[0]);
 
 5793         (void)close(fdout[1]);
 
 5794         (void)close(fderr[1]);
 
 5797         (void)close(fdin[1]);
 
 5798         (void)close(fdout[0]);
 
 5799         (void)close(fderr[0]);
 
 5806         memset(&sa, 0, 
sizeof(sa));
 
 5807         sa.sa_handler = SIG_DFL;
 
 5808         sigaction(SIGCHLD, &sa, NULL);
 
 5811         if (interp == NULL) {
 
 5813            (void)execle(prog, prog, NULL, envp);
 
 5815                            "%s: execle(%s): %s",
 
 5821            const char *interp_args =
 
 5825            if ((interp_args != NULL) && (interp_args[0] != 0)) {
 
 5826               (void)execle(interp, interp, interp_args, prog, NULL, envp);
 
 5828               (void)execle(interp, interp, prog, NULL, envp);
 
 5831                            "%s: execle(%s %s): %s",
 
 5849   int flags = fcntl(sock, F_GETFL, 0);
 
 5854   if (fcntl(sock, F_SETFL, (flags | O_NONBLOCK)) < 0) {
 
 5863   int flags = fcntl(sock, F_GETFL, 0);
 
 5868   if (fcntl(sock, F_SETFL, flags & (~(
int)(O_NONBLOCK))) < 0) {
 
 5882   static uint64_t lfsr = 0; 
 
 5883   static uint64_t lcg = 0;  
 
 5894             | ((((lfsr >> 0) ^ (lfsr >> 1) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1)
 
 5896      lcg = lcg * 6364136223846793005LL + 1442695040888963407LL;
 
 5904   return (lfsr ^ lcg ^ now);
 
 5919   int check_pollerr = 0;
 
 5920   if ((
n == 1) && ((pfd[0].events & POLLERR) == 0)) {
 
 5922      pfd[0].events |= POLLERR;
 
 5934      if ((milliseconds >= 0) && (milliseconds < ms_now)) {
 
 5935         ms_now = milliseconds;
 
 5938      result = poll(pfd, 
n, ms_now);
 
 5943             && ((pfd[0].revents & (POLLIN | POLLOUT | POLLERR))
 
 5952      if (milliseconds > 0) {
 
 5953         milliseconds -= ms_now;
 
 5956   } 
while (milliseconds > 0);
 
 5979   uint64_t start = 0, now = 0, timeout_ns = 0;
 
 5986   typedef size_t len_t;
 
 5992      timeout_ns = (uint64_t)(timeout * 1.0E9);
 
 5999#if defined(NO_SSL) && !defined(USE_MBEDTLS) 
 6009#if defined(USE_MBEDTLS) 
 6011         n = mbed_ssl_write(ssl, (
const unsigned char *)buf, 
len);
 
 6013            if ((
n == MBEDTLS_ERR_SSL_WANT_READ)
 
 6014                || (
n == MBEDTLS_ERR_SSL_WANT_WRITE)
 
 6015                || 
n == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
 
 6018               fprintf(stderr, 
"SSL write failed, error %d\n", 
n);
 
 6025#elif !defined(NO_SSL) 
 6028         n = SSL_write(ssl, buf, 
len);
 
 6030            err = SSL_get_error(ssl, 
n);
 
 6049         n = (
int)fwrite(buf, 1, (
size_t)
len, fp);
 
 6058         err = (
n < 0) ? 
ERRNO : 0;
 
 6060         if (err == WSAEWOULDBLOCK) {
 
 6080      if ((
n > 0) || ((
n == 0) && (
len == 0))) {
 
 6110         pfd[0].events = POLLOUT;
 
 6122         if ((now - start) > timeout_ns) {
 
 6144   double timeout = -1.0;
 
 6145   int n, nwritten = 0;
 
 6154   if (timeout <= 0.0) {
 
 6160      n = 
push_inner(ctx, fp, sock, ssl, buf + nwritten, 
len, timeout);
 
 6162         if (nwritten == 0) {
 
 6166      } 
else if (
n == 0) {
 
 6196   typedef size_t len_t;
 
 6209      nread = (
int)read(fileno(fp), buf, (size_t)
len);
 
 6211      err = (nread < 0) ? 
ERRNO : 0;
 
 6212      if ((nread == 0) && (
len > 0)) {
 
 6217#if defined(USE_MBEDTLS) 
 6218   } 
else if (conn->
ssl != NULL) {
 
 6223      to_read = mbedtls_ssl_get_bytes_avail(conn->
ssl);
 
 6235         pfd[0].events = POLLIN;
 
 6241                           (
int)(timeout * 1000.0),
 
 6250         nread = mbed_ssl_read(conn->
ssl, (
unsigned char *)buf, to_read);
 
 6252            if ((nread == MBEDTLS_ERR_SSL_WANT_READ)
 
 6253                || (nread == MBEDTLS_ERR_SSL_WANT_WRITE)
 
 6254                || nread == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
 
 6257               fprintf(stderr, 
"SSL read failed, error %d\n", nread);
 
 6264      } 
else if (pollres < 0) {
 
 6272#elif !defined(NO_SSL) 
 6273   } 
else if (conn->
ssl != NULL) {
 
 6278      if ((ssl_pending = SSL_pending(conn->
ssl)) > 0) {
 
 6282         if (ssl_pending > 
len) {
 
 6288         pfd[0].events = POLLIN;
 
 6291                           (
int)(timeout * 1000.0),
 
 6300             SSL_read(conn->
ssl, buf, (ssl_pending > 0) ? ssl_pending : 
len);
 
 6302            err = SSL_get_error(conn->
ssl, nread);
 
 6318      } 
else if (pollres < 0) {
 
 6332      pfd[0].events = POLLIN;
 
 6335                        (
int)(timeout * 1000.0),
 
 6342         err = (nread < 0) ? 
ERRNO : 0;
 
 6347      } 
else if (pollres < 0) {
 
 6360   if ((nread > 0) || ((nread == 0) && (
len == 0))) {
 
 6368      if (err == WSAEWOULDBLOCK) {
 
 6372      } 
else if (err == WSAETIMEDOUT) {
 
 6376      } 
else if (err == WSAECONNABORTED) {
 
 6417   double timeout = -1.0;
 
 6418   uint64_t start_time = 0, now = 0, timeout_ns = 0;
 
 6423   if (timeout <= 0.0) {
 
 6428   timeout_ns = (uint64_t)(timeout * 1.0E9);
 
 6437      } 
else if (
n == -1) {
 
 6439         if (timeout >= 0.0) {
 
 6441            if ((now - start_time) <= timeout_ns) {
 
 6446      } 
else if (
n == 0) {
 
 6463   while (
mg_read(conn, buf, 
sizeof(buf)) > 0)
 
 6471   int64_t content_len, 
n, buffered_len, nread;
 
 6473       (int64_t)((
len > INT_MAX) ? INT_MAX : 
len); 
 
 6485   if (content_len < 0) {
 
 6494      if (left_to_read < len64) {
 
 6498         len64 = left_to_read;
 
 6504      if (buffered_len > 0) {
 
 6505         if (len64 < buffered_len) {
 
 6506            buffered_len = len64;
 
 6509         memcpy(buf, body, (
size_t)buffered_len);
 
 6510         len64 -= buffered_len;
 
 6512         nread += buffered_len;
 
 6513         buf = (
char *)buf + buffered_len;
 
 6519      if ((
n = 
pull_all(NULL, conn, (
char *)buf, (
int)len64)) >= 0) {
 
 6523         nread = ((nread > 0) ? nread : 
n);
 
 6539#if defined(USE_SERVER_STATS) 
 6540   struct timespec tnow;
 
 6541   conn->conn_state = 4; 
 
 6547#if defined(USE_SERVER_STATS) 
 6548   conn->conn_state = 5; 
 
 6550   clock_gettime(CLOCK_MONOTONIC, &tnow);
 
 6554   mg_atomic_add64(&(conn->
phys_ctx->total_data_written),
 
 6568#if defined(USE_HTTP2) 
 6570#error "HTTP2 requires ALPN, APLN requires SSL/TLS" 
 6573#include "mod_http2.inl" 
 6577      if (conn->protocol_type == PROTOCOL_TYPE_HTTP2) {                      \ 
 6578         http2_must_use_http1(conn);                                        \ 
 6590   if (
len > INT_MAX) {
 
 6599      size_t all_read = 0;
 
 6621            all_read += (size_t)read_ret;
 
 6622            len -= (size_t)read_ret;
 
 6630                   || (
x[1] != 
'\n')) {
 
 6642            unsigned long chunkSize = 0;
 
 6644            for (i = 0; i < (
sizeof(lenbuf) - 1); i++) {
 
 6649               if ((i > 0) && (lenbuf[i] == 
'\r')
 
 6650                   && (lenbuf[i - 1] != 
'\r')) {
 
 6653               if ((i > 1) && (lenbuf[i] == 
'\n')
 
 6654                   && (lenbuf[i - 1] == 
'\r')) {
 
 6656                  chunkSize = strtoul(lenbuf, &end, 16);
 
 6657                  if (chunkSize == 0) {
 
 6663               if (!isxdigit((
unsigned char)lenbuf[i])) {
 
 6669            if ((end == NULL) || (*end != 
'\r')) {
 
 6674            if (chunkSize == 0) {
 
 6678                   && (lenbuf[0] == 
'\r') && (lenbuf[1] == 
'\n')) {
 
 6689      return (
int)all_read;
 
 6704   if (
len > INT_MAX) {
 
 6710#if defined(USE_HTTP2) 
 6712      http2_data_frame_head(conn, 
len, 0);
 
 6722      if (allowed > (
int)
len) {
 
 6733      if (
total == allowed) {
 
 6735         buf = (
const char *)buf + 
total;
 
 6756            buf = (
const char *)buf + 
n;
 
 6779              unsigned int chunk_len)
 
 6787   sprintf(lenbuf, 
"%x\r\n", chunk_len);
 
 6788   lenbuf_len = strlen(lenbuf);
 
 6791   ret = 
mg_write(conn, lenbuf, lenbuf_len);
 
 6792   if (ret != (
int)lenbuf_len) {
 
 6797   ret = 
mg_write(conn, chunk, chunk_len);
 
 6798   if (ret != (
int)chunk_len) {
 
 6813#if defined(GCC_DIAGNOSTIC) 
 6816#pragma GCC diagnostic push 
 6817#pragma GCC diagnostic ignored "-Wformat-nonliteral" 
 6844      (*buf)[
size - 1] = 0;
 
 6858              size_t prealloc_size,
 
 6884   } 
else if ((
size_t)(
len) >= prealloc_size) {
 
 6905      *out_buf = prealloc_buf;
 
 6912#if defined(GCC_DIAGNOSTIC) 
 6914#pragma GCC diagnostic pop 
 6955              int is_form_url_encoded)
 
 6958#define HEXTOI(x) (isdigit(x) ? (x - '0') : (x - 'W')) 
 6960   for (i = j = 0; (i < src_len) && (j < (dst_len - 1)); i++, j++) {
 
 6961      if ((i < src_len - 2) && (
src[i] == 
'%')
 
 6962          && isxdigit((
unsigned char)
src[i + 1])
 
 6963          && isxdigit((
unsigned char)
src[i + 2])) {
 
 6964         a = tolower((
unsigned char)
src[i + 1]);
 
 6965         b = tolower((
unsigned char)
src[i + 2]);
 
 6968      } 
else if (is_form_url_encoded && (
src[i] == 
'+')) {
 
 6977   return (i >= src_len) ? j : -1;
 
 6985   int len = (
int)strlen(buf);
 
 7009   const char *
p, *
e, *s;
 
 7013   if ((dst == NULL) || (dst_len == 0)) {
 
 7015   } 
else if ((
data == NULL) || (
name == NULL) || (data_len == 0)) {
 
 7019      name_len = strlen(
name);
 
 7020      e = 
data + data_len;
 
 7025      for (
p = 
data; 
p + name_len < 
e; 
p++) {
 
 7026         if (((
p == 
data) || (
p[-1] == 
'&')) && (
p[name_len] == 
'=')
 
 7032            s = (
const char *)memchr(
p, 
'&', (
size_t)(
e - 
p));
 
 7062                         unsigned num_form_fields)
 
 7073   if ((form_fields == NULL) && (num_form_fields == 0)) {
 
 7089   if ((form_fields == NULL) || ((
int)num_form_fields <= 0)) {
 
 7094   for (i = 0; i < (
int)num_form_fields; i++) {
 
 7096      while ((*
data == 
' ') || (*
data == 
'\t')) {
 
 7108      while ((*
b != 0) && (*
b != 
'&') && (*
b != 
'=')) {
 
 7114         form_fields[num].
value = NULL;
 
 7115      } 
else if (*
b == 
'&') {
 
 7117         form_fields[num].
value = NULL;
 
 7130      b = strchr(
data, 
'&');
 
 7143   for (i = 0; i < num; i++) {
 
 7144      if (form_fields[i].
name) {
 
 7147      if (form_fields[i].
value) {
 
 7160              const char *var_name,
 
 7164   const char *s, *
p, *end;
 
 7165   int name_len, 
len = -1;
 
 7167   if ((dst == NULL) || (dst_size == 0)) {
 
 7172   if ((var_name == NULL) || ((s = cookie_header) == NULL)) {
 
 7176   name_len = (
int)strlen(var_name);
 
 7177   end = s + strlen(s);
 
 7178   for (; (s = 
mg_strcasestr(s, var_name)) != NULL; s += name_len) {
 
 7179      if (s[name_len] == 
'=') {
 
 7181         if ((s == cookie_header) || (s[-1] == 
' ')) {
 
 7183            if ((
p = strchr(s, 
' ')) == NULL) {
 
 7189            if ((*s == 
'"') && (
p[-1] == 
'"') && (
p > s + 1)) {
 
 7193            if ((
size_t)(
p - s) < dst_size) {
 
 7207#if defined(USE_WEBSOCKET) || defined(USE_LUA) 
 7209base64_encode(
const unsigned char *
src, 
int src_len, 
char *dst)
 
 7211   static const char *b64 =
 
 7212       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 7215   for (i = j = 0; i < src_len; i += 3) {
 
 7217      b = ((i + 1) >= src_len) ? 0 : 
src[i + 1];
 
 7218      c = ((i + 2) >= src_len) ? 0 : 
src[i + 2];
 
 7220      dst[j++] = b64[
a >> 2];
 
 7221      dst[j++] = b64[((
a & 3) << 4) | (
b >> 4)];
 
 7222      if (i + 1 < src_len) {
 
 7223         dst[j++] = b64[(
b & 15) << 2 | (
c >> 6)];
 
 7225      if (i + 2 < src_len) {
 
 7226         dst[j++] = b64[
c & 63];
 
 7229   while (j % 4 != 0) {
 
 7239b64reverse(
char letter)
 
 7241   if ((letter >= 
'A') && (letter <= 
'Z')) {
 
 7242      return letter - 
'A';
 
 7244   if ((letter >= 
'a') && (letter <= 
'z')) {
 
 7245      return letter - 
'a' + 26;
 
 7247   if ((letter >= 
'0') && (letter <= 
'9')) {
 
 7248      return letter - 
'0' + 52;
 
 7250   if (letter == 
'+') {
 
 7253   if (letter == 
'/') {
 
 7256   if (letter == 
'=') {
 
 7264base64_decode(
const unsigned char *
src, 
int src_len, 
char *dst, 
size_t *dst_len)
 
 7267   unsigned char a, 
b, 
c, 
d;
 
 7271   for (i = 0; i < src_len; i += 4) {
 
 7272      a = b64reverse(
src[i]);
 
 7277      b = b64reverse(((i + 1) >= src_len) ? 0 : 
src[i + 1]);
 
 7282      c = b64reverse(((i + 2) >= src_len) ? 0 : 
src[i + 2]);
 
 7287      d = b64reverse(((i + 3) >= src_len) ? 0 : 
src[i + 3]);
 
 7292      dst[(*dst_len)++] = (
a << 2) + (
b >> 4);
 
 7294         dst[(*dst_len)++] = (
b << 4) + (
c >> 2);
 
 7296            dst[(*dst_len)++] = (
c << 6) + 
d;
 
 7311             && (!strcmp(s, 
"PUT") || !strcmp(s, 
"DELETE")
 
 7312                 || !strcmp(s, 
"MKCOL") || !strcmp(s, 
"PATCH"));
 
 7318#if !defined(NO_FILES) 
 7326   unsigned char cgi_config_idx, inc, max;
 
 7336#if defined(USE_DUKTAPE) 
 7346   for (cgi_config_idx = 0; cgi_config_idx < max; cgi_config_idx += inc) {
 
 7396   struct vec filename_vec;
 
 7397   size_t n = strlen(path);
 
 7403   while ((
n > 0) && (path[
n - 1] == 
'/')) {
 
 7410   while ((list = 
next_option(list, &filename_vec, NULL)) != NULL) {
 
 7412      if ((filename_vec.
len + 1) > (path_len - (
n + 1))) {
 
 7420      if (
mg_stat(conn, path, filestat)) {
 
 7440              size_t filename_buf_len,    
 
 7443              int *is_script_resource,       
 
 7444              int *is_websocket_request,     
 
 7445              int *is_put_or_delete_request, 
 
 7446              int *is_template_text          
 
 7449   char const *accept_encoding;
 
 7451#if !defined(NO_FILES) 
 7454   const char *rewrite;
 
 7456   ptrdiff_t match_len;
 
 7459#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) 
 7461   size_t tmp_str_len, sep_pos;
 
 7462   int allow_substitute_script_subresources;
 
 7465   (void)filename_buf_len; 
 
 7469   memset(filestat, 0, 
sizeof(*filestat));
 
 7472   *is_script_resource = 0;
 
 7473   *is_template_text = 0;
 
 7480#if defined(USE_WEBSOCKET) 
 7482#if !defined(NO_FILES) 
 7483   if (*is_websocket_request && conn->
dom_ctx->
config[WEBSOCKET_ROOT]) {
 
 7488   *is_websocket_request = 0;
 
 7493   if ((accept_encoding = 
mg_get_header(conn, 
"Accept-Encoding")) != NULL) {
 
 7494      if (strstr(accept_encoding, 
"gzip") != NULL) {
 
 7499#if !defined(NO_FILES) 
 7516       conn, &truncated, 
filename, filename_buf_len - 1, 
"%s%s", root, uri);
 
 7519      goto interpret_cleanup;
 
 7529                     filename_buf_len - 1,
 
 7539      goto interpret_cleanup;
 
 7546      int uri_len = (
int)strlen(uri);
 
 7547      int is_uri_end_slash = (uri_len > 0) && (uri[uri_len - 1] == 
'/');
 
 7565         *is_script_resource = (!*is_put_or_delete_request);
 
 7575         *is_template_text = (!*is_put_or_delete_request);
 
 7584         memset(&tmp_filestat, 0, 
sizeof(tmp_filestat));
 
 7587                 conn, 
filename, filename_buf_len, &tmp_filestat)) {
 
 7591            *filestat = tmp_filestat;
 
 7595               *is_script_resource = 1;
 
 7598               *is_template_text = 1;
 
 7601               *is_script_resource = 0;
 
 7620          conn, &truncated, gz_path, 
sizeof(gz_path), 
"%s.gz", 
filename);
 
 7623         goto interpret_cleanup;
 
 7626      if (
mg_stat(conn, gz_path, filestat)) {
 
 7636#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) 
 7644      goto interpret_cleanup;
 
 7646   memcpy(tmp_str, 
filename, tmp_str_len + 1);
 
 7649   allow_substitute_script_subresources =
 
 7653   sep_pos = tmp_str_len;
 
 7654   while (sep_pos > 0) {
 
 7656      if (tmp_str[sep_pos] == 
'/') {
 
 7657         int is_script = 0, does_exist = 0;
 
 7659         tmp_str[sep_pos] = 0;
 
 7662            does_exist = 
mg_stat(conn, tmp_str, filestat);
 
 7665         if (does_exist && is_script) {
 
 7669                    strlen(
filename + sep_pos + 1) + 1);
 
 7672            *is_script_resource = 1;
 
 7677         if (allow_substitute_script_subresources) {
 
 7684                  size_t script_name_len = strlen(tmp_str);
 
 7688                  char *subres_name = 
filename + sep_pos;
 
 7689                  size_t subres_name_len = strlen(subres_name);
 
 7691                  DEBUG_TRACE(
"Substitute script %s serving path %s",
 
 7696                  if ((script_name_len + subres_name_len + 2)
 
 7697                      >= filename_buf_len) {
 
 7699                     goto interpret_cleanup;
 
 7704                  memmove(conn->
path_info, subres_name, subres_name_len);
 
 7706                  memcpy(
filename, tmp_str, script_name_len + 1);
 
 7708                  *is_script_resource = 1;
 
 7721                  *is_script_resource = 0;
 
 7728         tmp_str[sep_pos] = 
'/';
 
 7738#if !defined(NO_FILES) 
 7741   memset(filestat, 0, 
sizeof(*filestat));
 
 7744   *is_script_resource = 0;
 
 7745   *is_websocket_request = 0;
 
 7746   *is_put_or_delete_request = 0;
 
 7759   for (i = 0; i < buflen; i++) {
 
 7761      const unsigned char c = (
unsigned char)buf[i];
 
 7763      if ((
c < 128) && ((char)
c != 
'\r') && ((char)
c != 
'\n')
 
 7769      if (i < buflen - 1) {
 
 7770         if ((buf[i] == 
'\n') && (buf[i + 1] == 
'\n')) {
 
 7777      if (i < buflen - 3) {
 
 7778         if ((buf[i] == 
'\r') && (buf[i + 1] == 
'\n') && (buf[i + 2] == 
'\r')
 
 7779             && (buf[i + 3] == 
'\n')) {
 
 7790#if !defined(NO_CACHING) 
 7811   char month_str[32] = {0};
 
 7812   int second, minute, hour, day, month, year;
 
 7813   time_t 
result = (time_t)0;
 
 7816   if ((sscanf(datetime,
 
 7817               "%d/%3s/%d %d:%d:%d",
 
 7825       || (sscanf(datetime,
 
 7826                  "%d %3s %d %d:%d:%d",
 
 7834       || (sscanf(datetime,
 
 7835                  "%*3s, %d %3s %d %d:%d:%d",
 
 7843       || (sscanf(datetime,
 
 7844                  "%d-%3s-%d %d:%d:%d",
 
 7853      if ((month >= 0) && (year >= 1970)) {
 
 7854         memset(&tm, 0, 
sizeof(tm));
 
 7855         tm.tm_year = year - 1900;
 
 7878   char *out_end = inout;
 
 7911      if (!strncmp(in, 
"../", 3)) {
 
 7913      } 
else if (!strncmp(in, 
"./", 2)) {
 
 7922      else if (!strncmp(in, 
"/./", 3)) {
 
 7924      } 
else if (!strcmp(in, 
"/.")) {
 
 7935      else if (!strncmp(in, 
"/../", 4)) {
 
 7937         if (inout != out_end) {
 
 7941            } 
while ((inout != out_end) && (*out_end != 
'/'));
 
 7943      } 
else if (!strcmp(in, 
"/..")) {
 
 7945         if (inout != out_end) {
 
 7949            } 
while ((inout != out_end) && (*out_end != 
'/'));
 
 7957      else if (!strcmp(in, 
".") || !strcmp(in, 
"..")) {
 
 7972         } 
while ((*in != 0) && (*in != 
'/'));
 
 7988   out_end = in = inout;
 
 7992         char *in_ahead = in;
 
 7995         } 
while (*in_ahead == 
'.');
 
 7996         if (*in_ahead == 
'/') {
 
 7998            if ((out_end != inout) && (out_end[-1] == 
'/')) {
 
 8002         } 
else if (*in_ahead == 0) {
 
 8008            } 
while (in != in_ahead);
 
 8010      } 
else if (*in == 
'/') {
 
 8015         } 
while (*in == 
'/');
 
 8025static const struct {
 
 8033    {
".bin", 4, 
"application/octet-stream"},
 
 8034    {
".deb", 4, 
"application/octet-stream"},
 
 8035    {
".dmg", 4, 
"application/octet-stream"},
 
 8036    {
".dll", 4, 
"application/octet-stream"},
 
 8037    {
".doc", 4, 
"application/msword"},
 
 8038    {
".eps", 4, 
"application/postscript"},
 
 8039    {
".exe", 4, 
"application/octet-stream"},
 
 8040    {
".iso", 4, 
"application/octet-stream"},
 
 8041    {
".js", 3, 
"application/javascript"},
 
 8042    {
".json", 5, 
"application/json"},
 
 8043    {
".msi", 4, 
"application/octet-stream"},
 
 8044    {
".pdf", 4, 
"application/pdf"},
 
 8045    {
".ps", 3, 
"application/postscript"},
 
 8046    {
".rtf", 4, 
"application/rtf"},
 
 8047    {
".xhtml", 6, 
"application/xhtml+xml"},
 
 8048    {
".xsl", 4, 
"application/xml"},
 
 8049    {
".xslt", 5, 
"application/xml"},
 
 8052    {
".ttf", 4, 
"application/font-sfnt"},
 
 8053    {
".cff", 4, 
"application/font-sfnt"},
 
 8054    {
".otf", 4, 
"application/font-sfnt"},
 
 8055    {
".aat", 4, 
"application/font-sfnt"},
 
 8056    {
".sil", 4, 
"application/font-sfnt"},
 
 8057    {
".pfr", 4, 
"application/font-tdpfr"},
 
 8058    {
".woff", 5, 
"application/font-woff"},
 
 8059    {
".woff2", 6, 
"application/font-woff2"},
 
 8062    {
".mp3", 4, 
"audio/mpeg"},
 
 8063    {
".oga", 4, 
"audio/ogg"},
 
 8064    {
".ogg", 4, 
"audio/ogg"},
 
 8067    {
".gif", 4, 
"image/gif"},
 
 8068    {
".ief", 4, 
"image/ief"},
 
 8069    {
".jpeg", 5, 
"image/jpeg"},
 
 8070    {
".jpg", 4, 
"image/jpeg"},
 
 8071    {
".jpm", 4, 
"image/jpm"},
 
 8072    {
".jpx", 4, 
"image/jpx"},
 
 8073    {
".png", 4, 
"image/png"},
 
 8074    {
".svg", 4, 
"image/svg+xml"},
 
 8075    {
".tif", 4, 
"image/tiff"},
 
 8076    {
".tiff", 5, 
"image/tiff"},
 
 8079    {
".wrl", 4, 
"model/vrml"},
 
 8082    {
".css", 4, 
"text/css"},
 
 8083    {
".csv", 4, 
"text/csv"},
 
 8084    {
".htm", 4, 
"text/html"},
 
 8085    {
".html", 5, 
"text/html"},
 
 8086    {
".sgm", 4, 
"text/sgml"},
 
 8087    {
".shtm", 5, 
"text/html"},
 
 8088    {
".shtml", 6, 
"text/html"},
 
 8089    {
".txt", 4, 
"text/plain"},
 
 8090    {
".xml", 4, 
"text/xml"},
 
 8093    {
".mov", 4, 
"video/quicktime"},
 
 8094    {
".mp4", 4, 
"video/mp4"},
 
 8095    {
".mpeg", 5, 
"video/mpeg"},
 
 8096    {
".mpg", 4, 
"video/mpeg"},
 
 8097    {
".ogv", 4, 
"video/ogg"},
 
 8098    {
".qt", 3, 
"video/quicktime"},
 
 8103    {
".arj", 4, 
"application/x-arj-compressed"},
 
 8104    {
".gz", 3, 
"application/x-gunzip"},
 
 8105    {
".rar", 4, 
"application/x-arj-compressed"},
 
 8106    {
".swf", 4, 
"application/x-shockwave-flash"},
 
 8107    {
".tar", 4, 
"application/x-tar"},
 
 8108    {
".tgz", 4, 
"application/x-tar-gz"},
 
 8109    {
".torrent", 8, 
"application/x-bittorrent"},
 
 8110    {
".ppt", 4, 
"application/x-mspowerpoint"},
 
 8111    {
".xls", 4, 
"application/x-msexcel"},
 
 8112    {
".zip", 4, 
"application/x-zip-compressed"},
 
 8116    {
".flac", 5, 
"audio/flac"},
 
 8117    {
".aif", 4, 
"audio/x-aif"},
 
 8118    {
".m3u", 4, 
"audio/x-mpegurl"},
 
 8119    {
".mid", 4, 
"audio/x-midi"},
 
 8120    {
".ra", 3, 
"audio/x-pn-realaudio"},
 
 8121    {
".ram", 4, 
"audio/x-pn-realaudio"},
 
 8122    {
".wav", 4, 
"audio/x-wav"},
 
 8123    {
".bmp", 4, 
"image/bmp"},
 
 8124    {
".ico", 4, 
"image/x-icon"},
 
 8125    {
".pct", 4, 
"image/x-pct"},
 
 8126    {
".pict", 5, 
"image/pict"},
 
 8127    {
".rgb", 4, 
"image/x-rgb"},
 
 8128    {
".webm", 5, 
"video/webm"}, 
 
 8129    {
".asf", 4, 
"video/x-ms-asf"},
 
 8130    {
".avi", 4, 
"video/x-msvideo"},
 
 8131    {
".m4v", 4, 
"video/x-m4v"},
 
 8141   path_len = strlen(path);
 
 8151   return "text/plain";
 
 8160   struct vec ext_vec, mime_vec;
 
 8161   const char *list, *ext;
 
 8164   path_len = strlen(path);
 
 8166   if ((conn == NULL) || (
vec == NULL)) {
 
 8168         memset(
vec, 
'\0', 
sizeof(
struct vec));
 
 8176   while ((list = 
next_option(list, &ext_vec, &mime_vec)) != NULL) {
 
 8178      ext = path + path_len - ext_vec.
len;
 
 8195   static const char *hex = 
"0123456789abcdef";
 
 8197   for (; 
len--; 
p++) {
 
 8198      *to++ = hex[
p[0] >> 4];
 
 8199      *to++ = hex[
p[0] & 0x0f];
 
 8218   while ((
p = va_arg(ap, 
const char *)) != NULL) {
 
 8224   bin2str(buf, hash, 
sizeof(hash));
 
 8238               const char *response)
 
 8240   char ha2[32 + 1], expected_response[32 + 1];
 
 8243   if ((method == NULL) || (nonce == NULL) || (nc == NULL) || (cnonce == NULL)
 
 8244       || (qop == NULL) || (response == NULL)) {
 
 8249   if (strlen(response) != 32) {
 
 8253   mg_md5(ha2, method, 
":", uri, NULL);
 
 8254   mg_md5(expected_response,
 
 8272#if !defined(NO_FILESYSTEMS) 
 8280   if ((conn != NULL) && (conn->
dom_ctx != NULL)) {
 
 8286      if (gpass != NULL) {
 
 8320         for (
p = path, 
e = 
p + strlen(
p) - 1; 
e > 
p; 
e--) {
 
 8362   const char *auth_header;
 
 8369   (void)memset(
ah, 0, 
sizeof(*
ah));
 
 8370   if (((auth_header = 
mg_get_header(conn, 
"Authorization")) == NULL)
 
 8376   (void)
mg_strlcpy(buf, auth_header + 7, buf_size);
 
 8382      while (isspace((
unsigned char)*s)) {
 
 8398      if (*
name == 
'\0') {
 
 8402      if (!strcmp(
name, 
"username")) {
 
 8404      } 
else if (!strcmp(
name, 
"cnonce")) {
 
 8406      } 
else if (!strcmp(
name, 
"response")) {
 
 8408      } 
else if (!strcmp(
name, 
"uri")) {
 
 8410      } 
else if (!strcmp(
name, 
"qop")) {
 
 8412      } 
else if (!strcmp(
name, 
"nc")) {
 
 8414      } 
else if (!strcmp(
name, 
"nonce")) {
 
 8419#if !defined(NO_NONCE_CHECK) 
 8425   nonce = strtoull(
ah->
nonce, &s, 10);
 
 8426   if ((s == NULL) || (*s != 0)) {
 
 8488#define INITIAL_DEPTH 9 
 8489#if INITIAL_DEPTH <= 0 
 8490#error Bad INITIAL_DEPTH for recursion, set to at least 1 
 8493#if !defined(NO_FILESYSTEMS) 
 8510   int is_authorized = 0;
 
 8514   if (!filep || !workdata || (0 == depth)) {
 
 8519   while (
mg_fgets(workdata->
buf, 
sizeof(workdata->
buf), filep) != NULL) {
 
 8520      l = strlen(workdata->
buf);
 
 8522         if (isspace((
unsigned char)workdata->
buf[
l - 1])
 
 8523             || iscntrl((
unsigned char)workdata->
buf[
l - 1])) {
 
 8525            workdata->
buf[
l] = 0;
 
 8535      if (workdata->
f_user[0] == 
':') {
 
 8539         if (workdata->
f_user[1] == 
'#') {
 
 8542         } 
else if (!strncmp(workdata->
f_user + 1, 
"include=", 8)) {
 
 8555               if (is_authorized) {
 
 8556                  return is_authorized;
 
 8560                               "%s: cannot open authorization file: %s",
 
 8569                         "%s: syntax error in authorization file: %s",
 
 8578                         "%s: syntax error in authorization file: %s",
 
 8587      if (workdata->
f_ha1 == NULL) {
 
 8589                         "%s: syntax error in authorization file: %s",
 
 8594      *(
char *)(workdata->
f_ha1) = 0;
 
 8595      (workdata->
f_ha1)++;
 
 8610   return is_authorized;
 
 8625   memset(&workdata, 0, 
sizeof(workdata));
 
 8671#if !defined(NO_FILESYSTEMS) 
 8673   struct vec uri_vec, filename_vec;
 
 8676   int authorized = 1, truncated;
 
 8678   if (!conn || !conn->
dom_ctx) {
 
 8683   while ((list = 
next_option(list, &uri_vec, &filename_vec)) != NULL) {
 
 8690                     (
int)filename_vec.
len,
 
 8696                            "%s: cannot open %s: %s",
 
 8754               "Digest qop=\"auth\", realm=\"%s\", " 
 8784#if !defined(NO_FILES) 
 8793      if (passfile != NULL
 
 8814   char line[512], u[512] = 
"", 
d[512] = 
"", ha1buf[33],
 
 8822   if ((pass != NULL) && (pass[0] == 
'\0')) {
 
 8827   if ((fname == NULL) || (domain == NULL) || (user == NULL)) {
 
 8834   if (strchr(user, 
':') != NULL) {
 
 8837   if (strchr(domain, 
':') != NULL) {
 
 8843   for (i = 0; ((i < 255) && (user[i] != 0)); i++) {
 
 8844      if (iscntrl((
unsigned char)user[i])) {
 
 8851   for (i = 0; ((i < 255) && (domain[i] != 0)); i++) {
 
 8852      if (iscntrl((
unsigned char)domain[i])) {
 
 8867   strcat(tmp, 
".tmp");
 
 8871   if ((fp = fopen(fname, 
"a+")) != NULL) {
 
 8876   if ((fp = fopen(fname, 
"r")) == NULL) {
 
 8878   } 
else if ((fp2 = fopen(tmp, 
"w+")) == NULL) {
 
 8884   while (fgets(
line, 
sizeof(
line), fp) != NULL) {
 
 8885      if (sscanf(
line, 
"%255[^:]:%255[^:]:%*s", u, 
d) != 2) {
 
 8891      if (!strcmp(u, user) && !strcmp(
d, domain)) {
 
 8894            mg_md5(ha1buf, user, 
":", domain, 
":", pass, NULL);
 
 8895            fprintf(fp2, 
"%s:%s:%s\n", user, domain, ha1buf);
 
 8896         } 
else if (ha1 != NULL) {
 
 8897            fprintf(fp2, 
"%s:%s:%s\n", user, domain, ha1);
 
 8900         fprintf(fp2, 
"%s", 
line);
 
 8907         mg_md5(ha1buf, user, 
":", domain, 
":", pass, NULL);
 
 8908         fprintf(fp2, 
"%s:%s:%s\n", user, domain, ha1buf);
 
 8909      } 
else if (ha1 != NULL) {
 
 8910         fprintf(fp2, 
"%s:%s:%s\n", user, domain, ha1);
 
 8949   return (port <= 0xffff);
 
 8956   struct addrinfo hints, *res, *ressave;
 
 8960   memset(&hints, 0, 
sizeof(
struct addrinfo));
 
 8961   hints.ai_family = af;
 
 8963      hints.ai_flags = AI_NUMERICHOST;
 
 8966   gai_ret = getaddrinfo(
src, NULL, &hints, &res);
 
 8981      if ((dstlen >= (
size_t)res->ai_addrlen)
 
 8982          && (res->ai_addr->sa_family == af)) {
 
 8983         memcpy(dst, res->ai_addr, res->ai_addrlen);
 
 8989   freeaddrinfo(ressave);
 
 9010   memset(sa, 0, 
sizeof(*sa));
 
 9026#if defined(USE_X_DOM_SOCKET) 
 9029      size_t hostlen = strlen(host);
 
 9030      if (hostlen >= 
sizeof(sa->sun.sun_path)) {
 
 9036                     "host length exceeds limit");
 
 9051#if !defined(NO_SSL) && !defined(USE_MBEDTLS) && !defined(NO_SSL_DL) 
 9052#if defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0) 
 9053   if (use_ssl && (TLS_client_method == NULL)) {
 
 9059                  "SSL is not initialized");
 
 9063   if (use_ssl && (SSLv23_client_method == NULL)) {
 
 9069                  "SSL is not initialized");
 
 9078#if defined(USE_X_DOM_SOCKET) 
 9080      size_t hostlen = strlen(host);
 
 9083      sa->sun.sun_family = AF_UNIX;
 
 9084      memset(sa->sun.sun_path, 0, 
sizeof(sa->sun.sun_path));
 
 9085      memcpy(sa->sun.sun_path, host, hostlen);
 
 9089      sa->
sin.sin_port = htons((uint16_t)port);
 
 9091#if defined(USE_IPV6) 
 9092   } 
else if (
mg_inet_pton(AF_INET6, host, &sa->sin6, 
sizeof(sa->sin6), 1)) {
 
 9093      sa->sin6.sin6_port = htons((uint16_t)port);
 
 9095   } 
else if (host[0] == 
'[') {
 
 9098      size_t l = strlen(host + 1);
 
 9102         if (
mg_inet_pton(AF_INET6, 
h, &sa->sin6, 
sizeof(sa->sin6), 0)) {
 
 9103            sa->sin6.sin6_port = htons((uint16_t)port);
 
 9122      *sock = 
socket(PF_INET, SOCK_STREAM, 0);
 
 9124#if defined(USE_IPV6) 
 9125   else if (ip_ver == 6) {
 
 9126      *sock = 
socket(PF_INET6, SOCK_STREAM, 0);
 
 9129#if defined(USE_X_DOM_SOCKET) 
 9130   else if (ip_ver == -99) {
 
 9131      *sock = 
socket(AF_UNIX, SOCK_STREAM, 0);
 
 9150                  "Cannot set socket to non-blocking: %s",
 
 9161      conn_ret = connect(*sock,
 
 9162                         (
struct sockaddr *)((
void *)&sa->
sin),
 
 9165#if defined(USE_IPV6) 
 9166   else if (ip_ver == 6) {
 
 9168      conn_ret = connect(*sock,
 
 9169                         (
struct sockaddr *)((
void *)&sa->sin6),
 
 9173#if defined(USE_X_DOM_SOCKET) 
 9174   else if (ip_ver == -99) {
 
 9176      conn_ret = connect(*sock,
 
 9177                         (
struct sockaddr *)((
void *)&sa->sun),
 
 9182   if (conn_ret != 0) {
 
 9187   if ((conn_ret != 0) && (sockerr == WSAEWOULDBLOCK)) {
 
 9189   if ((conn_ret != 0) && (sockerr == EINPROGRESS)) {
 
 9192      void *psockerr = &sockerr;
 
 9196      int len = (
int)
sizeof(sockerr);
 
 9198      socklen_t 
len = (socklen_t)
sizeof(sockerr);
 
 9204      int ms_wait = 10000; 
 
 9214      pfd[0].events = POLLOUT;
 
 9223                     "connect(%s:%d): timeout",
 
 9232      ret = getsockopt(*sock, SOL_SOCKET, SO_ERROR, (
char *)psockerr, &
len);
 
 9234      ret = getsockopt(*sock, SOL_SOCKET, SO_ERROR, psockerr, &
len);
 
 9237      if ((ret == 0) && (sockerr == 0)) {
 
 9242   if (conn_ret != 0) {
 
 9248                  "connect(%s:%d): error %s",
 
 9264   static const char *dont_escape = 
"._-$,;~()";
 
 9265   static const char *hex = 
"0123456789abcdef";
 
 9267   const char *end = dst + dst_len - 1;
 
 9269   for (; ((*
src != 
'\0') && (pos < end)); 
src++, pos++) {
 
 9270      if (isalnum((
unsigned char)*
src)
 
 9271          || (strchr(dont_escape, *
src) != NULL)) {
 
 9273      } 
else if (pos + 2 < end) {
 
 9275         pos[1] = hex[(
unsigned char)*
src >> 4];
 
 9276         pos[2] = hex[(
unsigned char)*
src & 0xf];
 
 9284   return (*
src == 
'\0') ? (
int)(pos - dst) : -1;
 
 9292   size_t namesize, escsize, i;
 
 9293   char *href, *
esc, *
p;
 
 9294   char size[64], mod[64];
 
 9295#if defined(REENTRANT_TIME) 
 9297   struct tm *tm = &_tm;
 
 9305   href = (
char *)
mg_malloc(namesize * 3 + escsize);
 
 9313      esc = href + namesize * 3;
 
 9318         } 
else if (*
p == 
'<') {
 
 9320         } 
else if (*
p == 
'>') {
 
 9370#if defined(REENTRANT_TIME) 
 9376      strftime(mod, 
sizeof(mod), 
"%d-%b-%Y %H:%M", tm);
 
 9378      mg_strlcpy(mod, 
"01-Jan-1970 00:00", 
sizeof(mod));
 
 9379      mod[
sizeof(mod) - 1] = 
'\0';
 
 9382             "<tr><td><a href=\"%s%s\">%s%s</a></td>" 
 9383             "<td> %s</td><td>  %s</td></tr>\n",
 
 9403      const struct de *
a = (
const struct de *)p1, *
b = (
const struct de *)p2;
 
 9407      if ((query_string == NULL) || (query_string[0] == 
'\0')) {
 
 9411      if (
a->file.is_directory && !
b->file.is_directory) {
 
 9413      } 
else if (!
a->file.is_directory && 
b->file.is_directory) {
 
 9415      } 
else if (*query_string == 
'n') {
 
 9416         cmp_result = strcmp(
a->file_name, 
b->file_name);
 
 9417      } 
else if (*query_string == 
's') {
 
 9418         cmp_result = (
a->file.size == 
b->file.size)
 
 9420                          : ((
a->file.size > 
b->file.size) ? 1 : -1);
 
 9421      } 
else if (*query_string == 
'd') {
 
 9423             (
a->file.last_modified == 
b->file.last_modified)
 
 9425                 : ((
a->file.last_modified > 
b->file.last_modified) ? 1
 
 9429      return (query_string[1] == 
'd') ? -cmp_result : cmp_result;
 
 9448#if !defined(NO_FILESYSTEMS) 
 9453               int (*cb)(
struct de *, 
void *))
 
 9468         if (!strcmp(dp->d_name, 
".") || !strcmp(dp->d_name, 
"..")
 
 9474             conn, &truncated, path, 
sizeof(path), 
"%s/%s", dir, dp->d_name);
 
 9490                            "%s: mg_stat(%s) failed: %s",
 
 9508#if !defined(NO_FILES) 
 9527         if (!strcmp(dp->d_name, 
".") || !strcmp(dp->d_name, 
"..")) {
 
 9532             conn, &truncated, path, 
sizeof(path), 
"%s/%s", dir, dp->d_name);
 
 9549                            "%s: mg_stat(%s) failed: %s",
 
 9584#if !defined(NO_FILESYSTEMS) 
 9596                                  dsd->
arr_size * 2 * 
sizeof(entries[0]));
 
 9597      if (entries == NULL) {
 
 9623   char date[64], *
esc, *
p;
 
 9625   time_t curtime = time(NULL);
 
 9634                         "Error: Cannot open directory\nopendir(%s): %s",
 
 9644   if (title[strcspn(title, 
"&<>")]) {
 
 9648         for (i = 0, 
p = 
esc; title[i]; i++, 
p += strlen(
p)) {
 
 9652            } 
else if (*
p == 
'<') {
 
 9654            } 
else if (*
p == 
'>') {
 
 9677                          "text/html; charset=utf-8",
 
 9685             "<html><head><title>Index of %s</title>" 
 9686             "<style>th {text-align: left;}</style></head>" 
 9687             "<body><h1>Index of %s</h1><pre><table cellpadding=\"0\">" 
 9688             "<tr><th><a href=\"?n%c\">Name</a></th>" 
 9689             "<th><a href=\"?d%c\">Modified</a></th>" 
 9690             "<th><a href=\"?s%c\">Size</a></th></tr>" 
 9691             "<tr><td colspan=\"3\"><hr></td></tr>",
 
 9701             "<tr><td><a href=\"%s\">%s</a></td>" 
 9702             "<td> %s</td><td>  %s</td></tr>\n",
 
 9709   if (
data.entries != NULL) {
 
 9712            sizeof(
data.entries[0]),
 
 9714      for (i = 0; i < 
data.num_entries; i++) {
 
 9721   mg_printf(conn, 
"%s", 
"</table></pre></body></html>");
 
 9735   int to_read, num_read, num_written;
 
 9738   if (!filep || !conn) {
 
 9749#if defined(__linux__) 
 9754         off_t sf_offs = (off_t)
offset;
 
 9756         int sf_file = fileno(filep->
access.
fp);
 
 9763                (size_t)((
len < 0x7FFFF000) ? 
len : 0x7FFFF000);
 
 9765                sendfile(conn->
client.
sock, sf_file, &sf_offs, sf_tosend);
 
 9769            } 
else if (loop_cnt == 0) {
 
 9775            } 
else if (sf_sent == 0) {
 
 9781         } 
while ((
len > 0) && (sf_sent >= 0));
 
 9790         offset = (int64_t)sf_offs;
 
 9795                         "%s: fseeko() failed: %s",
 
 9802             "Error: Unable to access file at requested position.");
 
 9806            to_read = 
sizeof(buf);
 
 9807            if ((int64_t)to_read > 
len) {
 
 9813                     (
int)fread(buf, 1, (
size_t)to_read, filep->
access.
fp))
 
 9819            if ((num_written = 
mg_write(conn, buf, (
size_t)num_read))
 
 9835   return sscanf(header,
 
 9847   if ((filestat != NULL) && (buf != NULL)) {
 
 9862   if (filep != NULL && filep->
fp != NULL) {
 
 9866      if (fcntl(fileno(filep->
fp), F_SETFD, FD_CLOEXEC) != 0) {
 
 9868                         "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s",
 
 9877#if defined(USE_ZLIB) 
 9878#include "mod_zlib.inl" 
 9882#if !defined(NO_FILESYSTEMS) 
 9888                           const char *additional_headers)
 
 9890   char lm[64], etag[64];
 
 9892   const char *range_hdr;
 
 9894   struct vec mime_vec;
 
 9897   const char *encoding = 0;
 
 9898   const char *origin_hdr;
 
 9899   const char *cors_orig_cfg, *cors_cred_cfg;
 
 9900   const char *cors1, *cors2, *cors3, *cors4;
 
 9901   int is_head_request;
 
 9903#if defined(USE_ZLIB) 
 9907   int allow_on_the_fly_compression = 1;
 
 9910   if ((conn == NULL) || (conn->
dom_ctx == NULL) || (filep == NULL)) {
 
 9925                         "Error: File size is too large to send\n%" INT64_FMT,
 
 9933#if defined(USE_ZLIB) 
 9938      allow_on_the_fly_compression = 0;
 
 9947      mg_snprintf(conn, &truncated, gz_path, 
sizeof(gz_path), 
"%s.gz", path);
 
 9952                            "Error: Path of zipped file too long (%s)",
 
 9960#if defined(USE_ZLIB) 
 9962      allow_on_the_fly_compression = 0;
 
 9964   } 
else if ((conn->
accept_gzip) && (range_hdr == NULL)
 
 9968      mg_snprintf(conn, &truncated, gz_path, 
sizeof(gz_path), 
"%s.gz", path);
 
 9970      if (!truncated && 
mg_stat(conn, gz_path, &file_stat)
 
 9973         filep->
stat = file_stat;
 
 9978#if defined(USE_ZLIB) 
 9980         allow_on_the_fly_compression = 0;
 
 9988                         "Error: Cannot open file\nfopen(%s): %s",
 
 9999   if ((range_hdr != NULL)
 
10009             "Error: Range requests in gzipped files are not supported");
 
10015      cl = (
n == 2) ? (((r2 > cl) ? cl : r2) - r1 + 1) : (cl - r1);
 
10026#if defined(USE_ZLIB) 
10028      allow_on_the_fly_compression = 0;
 
10034#if defined(USE_ZLIB) 
10037      allow_on_the_fly_compression = 0;
 
10044   if (cors_orig_cfg && *cors_orig_cfg && origin_hdr) {
 
10050      cors1 = 
"Access-Control-Allow-Origin";
 
10051      cors2 = cors_orig_cfg;
 
10053      cors1 = cors2 = 
"";
 
10058   if (cors_cred_cfg && *cors_cred_cfg && origin_hdr) {
 
10059      cors3 = 
"Access-Control-Allow-Credentials";
 
10060      cors4 = cors_cred_cfg;
 
10062      cors3 = cors4 = 
"";
 
10076                          (
int)mime_vec.
len);
 
10077   if (cors1[0] != 0) {
 
10080   if (cors3[0] != 0) {
 
10086#if defined(USE_ZLIB) 
10088   if (allow_on_the_fly_compression) {
 
10117   if (range[0] != 0) {
 
10123   if ((additional_headers != NULL) && (*additional_headers != 0)) {
 
10130   if (!is_head_request) {
 
10131#if defined(USE_ZLIB) 
10132      if (allow_on_the_fly_compression) {
 
10134         send_compressed_data(conn, filep);
 
10161#if !defined(NO_CACHING) 
10168   const char *ims = 
mg_get_header(conn, 
"If-Modified-Since");
 
10182   char lm[64], etag[64];
 
10184   if ((conn == NULL) || (filep == NULL)) {
 
10204#if !defined(NO_FILESYSTEMS) 
10225                   const char *additional_headers)
 
10235#if !defined(NO_CACHING) 
10241          if (
file.stat.is_directory) {
 
10249                               "Error: Directory listing denied");
 
10276   for (s = 
p = path + 2; (
p = strchr(s, 
'/')) != NULL; s = ++
p) {
 
10277      len = (size_t)(
p - path);
 
10278      if (
len >= 
sizeof(buf)) {
 
10283      memcpy(buf, path, 
len);
 
10295      if (
p[1] == 
'\0') {
 
10310                      "%s: Cannot remove invalid file %s",
 
10345   ret = 
mg_read(conn, buf, 
sizeof(buf));
 
10355      ret = 
mg_read(conn, buf, 
sizeof(buf));
 
10380   while (isgraph((
unsigned char)**ppw)) {
 
10387      if ((**ppw != 
'\r') && (**ppw != 
'\n')) {
 
10392      if (**ppw != 
' ') {
 
10401   } 
while (isspace((
unsigned char)**ppw));
 
10406      if (!isgraph((
unsigned char)**ppw)) {
 
10424   int num_headers = 0;
 
10430      while ((*dp != 
':') && (*dp >= 33) && (*dp <= 126)) {
 
10439      while (*dp == 
' ') {
 
10451      hdr[i].name = *buf;
 
10456      } 
while ((*dp == 
' ') || (*dp == 
'\t'));
 
10462      while ((*dp != 0) && (*dp != 
'\r') && (*dp != 
'\n')) {
 
10478      num_headers = i + 1;
 
10485         if ((dp[0] == 
'\r') || (dp[0] == 
'\n')) {
 
10494   return num_headers;
 
10511    {
"GET", 0, 1, 1, 1, 1},
 
10512    {
"POST", 1, 1, 0, 0, 0},
 
10513    {
"PUT", 1, 0, 0, 1, 0},
 
10514    {
"DELETE", 0, 0, 0, 1, 0},
 
10515    {
"HEAD", 0, 0, 1, 1, 1},
 
10516    {
"OPTIONS", 0, 0, 1, 1, 0},
 
10517    {
"CONNECT", 1, 1, 0, 0, 0},
 
10521    {
"PATCH", 1, 0, 0, 0, 0},
 
10525    {
"PROPFIND", 0, 1, 1, 1, 0},
 
10531    {
"MKCOL", 0, 0, 0, 1, 0},
 
10544    {
"LOCK", 1, 1, 0, 0, 0},
 
10545    {
"UNLOCK", 1, 0, 0, 0, 0},
 
10546    {
"PROPPATCH", 1, 1, 0, 0, 0},
 
10558    {
"REPORT", 1, 1, 1, 1, 1},
 
10565    {NULL, 0, 0, 0, 0, 0}
 
10580      if (!strcmp(
m->name, method)) {
 
10608   int request_length;
 
10620   while ((
len > 0) && isspace((
unsigned char)*buf)) {
 
10632   if (iscntrl((
unsigned char)*buf)) {
 
10638   if (request_length <= 0) {
 
10639      return request_length;
 
10641   buf[request_length - 1] = 
'\0';
 
10643   if ((*buf == 0) || (*buf == 
'\r') || (*buf == 
'\n')) {
 
10687   return request_length + init_skip;
 
10694   int response_length;
 
10706   while ((
len > 0) && isspace((
unsigned char)*buf)) {
 
10718   if (iscntrl((
unsigned char)*buf)) {
 
10724   if (response_length <= 0) {
 
10725      return response_length;
 
10727   buf[response_length - 1] = 
'\0';
 
10729   if ((*buf == 0) || (*buf == 
'\r') || (*buf == 
'\n')) {
 
10735   if (strncmp(buf, 
"HTTP/", 5) != 0) {
 
10740   if (!isgraph((
unsigned char)buf[0])) {
 
10757   l = strtol(tmp, &tmp2, 10);
 
10758   if ((
l < 100) || (
l >= 1000) || ((tmp2 - tmp) != 3) || (*tmp2 != 0)) {
 
10769   while (isprint((
unsigned char)*buf)) {
 
10772   if ((*buf != 
'\r') && (*buf != 
'\n')) {
 
10779   } 
while (isspace((
unsigned char)*buf));
 
10789   return response_length + init_skip;
 
10805   int request_len, 
n = 0;
 
10806   struct timespec last_action_time;
 
10807   double request_timeout;
 
10813   memset(&last_action_time, 0, 
sizeof(last_action_time));
 
10834   while (request_len == 0) {
 
10841      if (*nread >= bufsiz) {
 
10847          fp, conn, buf + *nread, bufsiz - *nread, request_timeout);
 
10854      clock_gettime(CLOCK_MONOTONIC, &last_action_time);
 
10861      if ((request_len == 0) && (request_timeout >= 0)) {
 
10863             > request_timeout) {
 
10870   return request_len;
 
10874#if !defined(NO_CGI) || !defined(NO_FILES) 
10878   const char *expect;
 
10893   if ((expect != NULL) && (
mg_strcasecmp(expect, 
"100-continue") != 0)) {
 
10898      if (expect != NULL) {
 
10899         (void)
mg_printf(conn, 
"%s", 
"HTTP/1.1 100 Continue\r\n\r\n");
 
10913         int nread = 
mg_read(conn, buf, 
sizeof(buf));
 
10915            success = (nread == 0);
 
10937#if defined(USE_TIMERS) 
10939#define TIMER_API static 
10940#include "timer.inl" 
10945#if !defined(NO_CGI) 
10978   size_t i, 
n, space;
 
10983   if ((env->varlen - env->varused) < 2) {
 
10985                      "%s: Cannot register CGI variable [%s]",
 
10992   space = (env->buflen - env->bufused);
 
11004                "%s: Cannot allocate memory for CGI variable [%s]",
 
11012         for (i = 0, 
n = 0; i < env->varused; i++) {
 
11013            env->var[i] = added + 
n;
 
11014            n += strlen(added + 
n) + 1;
 
11016         space = (env->buflen - env->bufused);
 
11020      added = env->buf + env->bufused;
 
11024      mg_vsnprintf(env->conn, &truncated, added, space - 1, fmt, ap);
 
11032   } 
while (truncated);
 
11035   n = strlen(added) + 1;
 
11039   env->var[env->varused] = added;
 
11049                        unsigned char cgi_config_idx)
 
11052   struct vec var_vec;
 
11054   int i, truncated, uri_len;
 
11056   if ((conn == NULL) || (prog == NULL) || (env == NULL)) {
 
11064   if (env->
buf == NULL) {
 
11066                      "%s: Not enough memory for environmental buffer",
 
11074   if (env->
var == NULL) {
 
11076                      "%s: Not enough memory for environmental variables",
 
11088   addenv(env, 
"%s", 
"GATEWAY_INTERFACE=CGI/1.1");
 
11089   addenv(env, 
"%s", 
"SERVER_PROTOCOL=HTTP/1.1");
 
11090   addenv(env, 
"%s", 
"REDIRECT_STATUS=200"); 
 
11095   addenv(env, 
"REMOTE_ADDR=%s", src_addr);
 
11112         const char *index_file = strrchr(prog, 
'/');
 
11115                   "SCRIPT_NAME=%s%s",
 
11123             "SCRIPT_NAME=%.*s",
 
11124             uri_len - (
int)strlen(conn->
path_info),
 
11128   addenv(env, 
"SCRIPT_FILENAME=%s", prog);
 
11133             "PATH_TRANSLATED=%s%s",
 
11138   addenv(env, 
"HTTPS=%s", (conn->
ssl == NULL) ? 
"off" : 
"on");
 
11141      addenv(env, 
"CONTENT_TYPE=%s", s);
 
11147      addenv(env, 
"CONTENT_LENGTH=%s", s);
 
11149   if ((s = getenv(
"PATH")) != NULL) {
 
11150      addenv(env, 
"PATH=%s", s);
 
11162   if ((s = getenv(
"COMSPEC")) != NULL) {
 
11163      addenv(env, 
"COMSPEC=%s", s);
 
11165   if ((s = getenv(
"SYSTEMROOT")) != NULL) {
 
11166      addenv(env, 
"SYSTEMROOT=%s", s);
 
11168   if ((s = getenv(
"SystemDrive")) != NULL) {
 
11169      addenv(env, 
"SystemDrive=%s", s);
 
11171   if ((s = getenv(
"ProgramFiles")) != NULL) {
 
11172      addenv(env, 
"ProgramFiles=%s", s);
 
11174   if ((s = getenv(
"ProgramFiles(x86)")) != NULL) {
 
11175      addenv(env, 
"ProgramFiles(x86)=%s", s);
 
11178   if ((s = getenv(
"LD_LIBRARY_PATH")) != NULL) {
 
11179      addenv(env, 
"LD_LIBRARY_PATH=%s", s);
 
11183   if ((s = getenv(
"PERLLIB")) != NULL) {
 
11184      addenv(env, 
"PERLLIB=%s", s);
 
11189      addenv(env, 
"%s", 
"AUTH_TYPE=Digest");
 
11198                        sizeof(http_var_name),
 
11204                         "%s: HTTP header variable too long [%s]",
 
11211      for (
p = http_var_name; *
p != 
'\0'; 
p++) {
 
11215         *
p = (char)toupper((
unsigned char)*
p);
 
11226   while ((s = 
next_option(s, &var_vec, NULL)) != NULL) {
 
11254   ret_pid = waitpid(proc->
pid, &status, WNOHANG);
 
11255   if ((ret_pid != (pid_t)-1) && (status == 0)) {
 
11258      kill(proc->
pid, SIGABRT);
 
11261      while (waitpid(proc->
pid, &status, 0) != (pid_t)-1) 
 
11264      DEBUG_TRACE(
"CGI timer: Child process %d already stopped\n", proc->
pid);
 
11281                   unsigned char cgi_config_idx)
 
11285   int headers_len, data_len, i, truncated;
 
11286   int fdin[2] = {-1, -1}, fdout[2] = {-1, -1}, fderr[2] = {-1, -1};
 
11287   const char *status, *status_text, *connection_state;
 
11291   FILE *in = NULL, *out = NULL, *err = NULL;
 
11293   pid_t pid = (pid_t)-1;
 
11296#if defined(USE_TIMERS) 
11297   double cgi_timeout;
 
11301          atof(conn->
dom_ctx->
config[CGI_TIMEOUT + cgi_config_idx]) * 0.001;
 
11321   (void)
mg_snprintf(conn, &truncated, dir, 
sizeof(dir), 
"%s", prog);
 
11324      mg_cry_internal(conn, 
"Error: CGI program \"%s\": Path too long", prog);
 
11329   if ((
p = strrchr(dir, 
'/')) != NULL) {
 
11337   if ((pipe(fdin) != 0) || (pipe(fdout) != 0) || (pipe(fderr) != 0)) {
 
11338      status = strerror(
ERRNO);
 
11341          "Error: CGI program \"%s\": Can not create CGI pipes: %s",
 
11346                         "Error: Cannot create CGI pipe: %s",
 
11353   if (proc == NULL) {
 
11354      mg_cry_internal(conn, 
"Error: CGI program \"%s\": Out or memory", prog);
 
11361       conn, 
p, 
blk.buf, 
blk.var, fdin, fdout, fderr, dir, cgi_config_idx);
 
11363   if (
pid == (pid_t)-1) {
 
11364      status = strerror(
ERRNO);
 
11367          "Error: CGI program \"%s\": Can not spawn CGI process: %s",
 
11380#if defined(USE_TIMERS) 
11381   if (cgi_timeout > 0.0) {
 
11399   (void)close(fdin[0]);
 
11400   (void)close(fdout[1]);
 
11401   (void)close(fderr[1]);
 
11402   fdin[0] = fdout[1] = fderr[1] = -1;
 
11404   if (((in = fdopen(fdin[1], 
"wb")) == NULL)
 
11405       || ((out = fdopen(fdout[0], 
"rb")) == NULL)
 
11406       || ((err = fdopen(fderr[0], 
"rb")) == NULL)) {
 
11407      status = strerror(
ERRNO);
 
11409                      "Error: CGI program \"%s\": Can not open fd: %s",
 
11414                         "Error: CGI can not open fd\nfdopen: %s",
 
11433             "Error: CGI program \"%s\": Forward body data failed",
 
11453                         "Error: Not enough memory for CGI buffer (%u bytes)",
 
11454                         (
unsigned int)buflen);
 
11457          "Error: CGI program \"%s\": Not enough memory for buffer (%u " 
11460          (
unsigned int)buflen);
 
11465   headers_len = 
read_message(out, conn, buf, (
int)buflen, &data_len);
 
11466   DEBUG_TRACE(
"CGI: response: %li", (
signed long)headers_len);
 
11468   if (headers_len <= 0) {
 
11472      i = 
pull_all(err, conn, buf, (
int)buflen);
 
11477                         "Error: CGI program \"%s\" sent error " 
11485                            "Error: CGI program \"%s\" failed.",
 
11491                         "Error: CGI program sent malformed or too big " 
11492                         "(>%u bytes) HTTP headers: [%.*s]",
 
11499                            "Error: CGI program sent malformed or too big " 
11500                            "(>%u bytes) HTTP headers: [%.*s]",
 
11511   buf[headers_len - 1] = 
'\0';
 
11515   status_text = 
"OK";
 
11519      status_text = status;
 
11520      while (isdigit((
unsigned char)*status_text) || *status_text == 
' ') {
 
11552   mg_write(conn, buf + headers_len, (
size_t)(data_len - headers_len));
 
11563   if (
pid != (pid_t)-1) {
 
11567   if (fdin[0] != -1) {
 
11570   if (fdout[1] != -1) {
 
11573   if (fderr[1] != -1) {
 
11579   } 
else if (fdin[1] != -1) {
 
11585   } 
else if (fdout[0] != -1) {
 
11591   } 
else if (fderr[0] != -1) {
 
11600#if !defined(NO_FILES) 
11607   if (
conn == NULL) {
 
11617                      "%s: mg_stat(%s) failed: %s",
 
11628          conn, 405, 
"Error: mkcol(%s): %s", path, strerror(
ERRNO));
 
11633   if (body_len > 0) {
 
11635          conn, 415, 
"Error: mkcol(%s): %s", path, strerror(
ERRNO));
 
11653      if (errno == EEXIST) {
 
11655             conn, 405, 
"Error: mkcol(%s): %s", path, strerror(
ERRNO));
 
11656      } 
else if (errno == EACCES) {
 
11658             conn, 403, 
"Error: mkcol(%s): %s", path, strerror(
ERRNO));
 
11659      } 
else if (errno == ENOENT) {
 
11661             conn, 409, 
"Error: mkcol(%s): %s", path, strerror(
ERRNO));
 
11664             conn, 500, 
"fopen(%s): %s", path, strerror(
ERRNO));
 
11678   if (conn == NULL) {
 
11686      if (
file.stat.is_directory) {
 
11696         if (
access(path, W_OK) == 0) {
 
11703                "Error: Put not possible\nReplacing %s is not allowed",
 
11735                         "Error: Path too long\nput_dir(%s): %s",
 
11745                         "Error: Can not create directory\nput_dir(%s): %s",
 
11754       || 
file.access.fp == NULL) {
 
11758                         "Error: Can not create file\nfopen(%s): %s",
 
11769      fseeko(
file.access.fp, r1, SEEK_SET);
 
11806                         "Error: Cannot delete file\nFile %s not found",
 
11824   if (access(path, W_OK) != 0) {
 
11829          "Error: Delete not possible\nDeleting %s is not allowed",
 
11847                         "Error: Cannot delete file\nremove(%s): %s",
 
11855#if !defined(NO_FILESYSTEMS) 
11871   if (conn == NULL) {
 
11878   if (sscanf(tag, 
" virtual=\"%511[^\"]\"", file_name) == 1) {
 
11880      file_name[511] = 0;
 
11889   } 
else if (sscanf(tag, 
" abspath=\"%511[^\"]\"", file_name) == 1) {
 
11892      file_name[511] = 0;
 
11894          mg_snprintf(conn, &truncated, path, 
sizeof(path), 
"%s", file_name);
 
11896   } 
else if ((sscanf(tag, 
" file=\"%511[^\"]\"", file_name) == 1)
 
11897              || (sscanf(tag, 
" \"%511[^\"]\"", file_name) == 1)) {
 
11899      file_name[511] = 0;
 
11900      (void)
mg_snprintf(conn, &truncated, path, 
sizeof(path), 
"%s", ssi);
 
11903         if ((
p = strrchr(path, 
'/')) != NULL) {
 
11906         len = strlen(path);
 
11910                           sizeof(path) - 
len,
 
11921      mg_cry_internal(conn, 
"SSI #include path length overflow: [%s]", tag);
 
11927                      "Cannot open SSI #include: [%s]: fopen(%s): %s",
 
11944#if !defined(NO_POPEN) 
11948   char cmd[1024] = 
"";
 
11951   if (sscanf(tag, 
" \"%1023[^\"]\"", cmd) != 1) {
 
11955      if ((
file.access.fp = popen(cmd, 
"r")) == NULL) {
 
11957                         "Cannot SSI #exec: [%s]: %s",
 
11962         pclose(
file.access.fp);
 
11972   if (filep == NULL) {
 
11991   int ch, 
len, in_tag, in_ssi_tag;
 
11993   if (include_level > 10) {
 
11998   in_tag = in_ssi_tag = 
len = 0;
 
12001   while ((ch = 
mg_fgetc(filep)) != EOF) {
 
12014               if ((
len > 12) && !memcmp(buf + 5, 
"include", 7)) {
 
12016#if !defined(NO_POPEN) 
12017               } 
else if ((
len > 9) && !memcmp(buf + 5, 
"exec", 4)) {
 
12028               in_ssi_tag = in_tag = 0;
 
12040            buf[
len++] = (char)(ch & 0xff);
 
12042            if ((
len == 5) && !memcmp(buf, 
"<!--#", 5)) {
 
12047            if ((
len + 2) > (
int)
sizeof(buf)) {
 
12073            buf[
len++] = (char)(ch & 0xff);
 
12075            if (
len == (
int)
sizeof(buf)) {
 
12096   time_t curtime = time(NULL);
 
12097   const char *cors_orig_cfg, *cors_cred_cfg;
 
12098   const char *cors1, *cors2, *cors3, *cors4;
 
12100   if ((conn == NULL) || (path == NULL) || (filep == NULL)) {
 
12105   if (cors_orig_cfg && *cors_orig_cfg && 
mg_get_header(conn, 
"Origin")) {
 
12107      cors1 = 
"Access-Control-Allow-Origin";
 
12108      cors2 = cors_orig_cfg;
 
12110      cors1 = cors2 = 
"";
 
12114   if (cors_cred_cfg && *cors_cred_cfg && 
mg_get_header(conn, 
"Origin")) {
 
12116      cors3 = 
"Access-Control-Allow-Credentials";
 
12117      cors4 = cors_cred_cfg;
 
12119      cors3 = cors4 = 
"";
 
12127                         "Error: Cannot read file\nfopen(%s): %s",
 
12158#if !defined(NO_FILES) 
12177          "GET, POST, HEAD, CONNECT, PUT, DELETE, OPTIONS, PROPFIND, MKCOL",
 
12196   size_t href_size, i, j;
 
12198   char *href, mtime[64];
 
12200   if ((conn == NULL) || (uri == NULL) || (
name == NULL) || (filep == NULL)) {
 
12204   href_size = (strlen(uri) + strlen(
name)) * 3 + 1;
 
12206   if (href == NULL) {
 
12215   for (i = j = 0; href[i]; j++) {
 
12216      if (!strncmp(href + i, 
"%2f", 3)) {
 
12220         href[j] = href[i++];
 
12228             "<d:href>%s</d:href>" 
12231             "<d:resourcetype>%s</d:resourcetype>" 
12232             "<d:getcontentlength>%" INT64_FMT "</d:getcontentlength>" 
12233             "<d:getlastmodified>%s</d:getlastmodified>" 
12235             "<d:status>HTTP/1.1 200 OK</d:status>" 
12268   time_t curtime = time(NULL);
 
12272   if (!conn || !path || !filep || !conn->
dom_ctx) {
 
12287             "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 
12288             "<d:multistatus xmlns:d='DAV:'>\n");
 
12298       && ((depth == NULL) || (strcmp(depth, 
"0") != 0))) {
 
12302   mg_printf(conn, 
"%s\n", 
"</d:multistatus>");
 
12310      (void)pthread_mutex_lock(&conn->
mutex);
 
12318      (void)pthread_mutex_unlock(&conn->
mutex);
 
12339#if defined(USE_LUA) 
12340#include "mod_lua.inl" 
12343#if defined(USE_DUKTAPE) 
12344#include "mod_duktape.inl" 
12347#if defined(USE_WEBSOCKET) 
12349#if !defined(NO_SSL_DL) 
12350#if !defined(OPENSSL_API_3_0) 
12351#define SHA_API static 
12357send_websocket_handshake(
struct mg_connection *conn, 
const char *websock_key)
 
12359   static const char *magic = 
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
 
12360   char buf[100], sha[20], b64_sha[
sizeof(sha) * 2];
 
12361#if !defined(OPENSSL_API_3_0) 
12375#if defined(OPENSSL_API_3_0) 
12376   EVP_Digest((
unsigned char *)
buf, (uint32_t)strlen(
buf), (
unsigned char *)sha,
 
12377      NULL, EVP_get_digestbyname(
"sha1"), NULL);
 
12383   base64_encode((
unsigned char *)sha, 
sizeof(sha), b64_sha);
 
12385             "HTTP/1.1 101 Switching Protocols\r\n" 
12386             "Upgrade: websocket\r\n" 
12387             "Connection: Upgrade\r\n" 
12388             "Sec-WebSocket-Accept: %s\r\n",
 
12391#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES) 
12393   websocket_deflate_response(conn);
 
12398                "Sec-WebSocket-Protocol: %s\r\n\r\n",
 
12408#if !defined(MG_MAX_UNANSWERED_PING) 
12414#define MG_MAX_UNANSWERED_PING (5) 
12421               void *callback_data)
 
12428   int n, error, exit_by_callback;
 
12435   size_t i, 
len, mask_len = 0, header_len, body_len;
 
12441   unsigned char mask[4];
 
12446   unsigned char mem[4096];
 
12451   double timeout = -1.0;
 
12452   int enable_ping_pong = 0;
 
12453   int ping_count = 0;
 
12462      timeout = atoi(conn->
dom_ctx->
config[WEBSOCKET_TIMEOUT]) / 1000.0;
 
12467   if (timeout <= 0.0) {
 
12472   DEBUG_TRACE(
"Websocket connection %s:%u start data processing loop",
 
12475   conn->in_websocket_handling = 1;
 
12486         mask_len = (
buf[1] & 128) ? 4 : 0;
 
12487         if ((
len < 126) && (body_len >= mask_len)) {
 
12490            header_len = 2 + mask_len;
 
12491         } 
else if ((
len == 126) && (body_len >= (4 + mask_len))) {
 
12493            header_len = 4 + mask_len;
 
12495         } 
else if (body_len >= (10 + mask_len)) {
 
12498            memcpy(&l1, &
buf[2], 4); 
 
12499            memcpy(&l2, &
buf[6], 4);
 
12500            header_len = 10 + mask_len;
 
12501            data_len = (((uint64_t)ntohl(l1)) << 32) + ntohl(l2);
 
12503            if (
data_len > (uint64_t)0x7FFF0000ul) {
 
12508                   "websocket out of memory; closing connection");
 
12514      if ((header_len > 0) && (body_len >= header_len)) {
 
12516         unsigned char *
data = mem;
 
12518         if ((
size_t)
data_len > (
size_t)
sizeof(mem)) {
 
12521            if (
data == NULL) {
 
12527                   "websocket out of memory; closing connection");
 
12533         if (mask_len > 0) {
 
12534            memcpy(
mask, 
buf + header_len - mask_len, 
sizeof(
mask));
 
12542         if (
data_len + (uint64_t)header_len > (uint64_t)body_len) {
 
12545            len = body_len - header_len;
 
12557               } 
else if (
n > 0) {
 
12568                   "Websocket pull failed; closing connection");
 
12600         if (mask_len > 0) {
 
12601            for (i = 0; i < (size_t)
data_len; i++) {
 
12606         exit_by_callback = 0;
 
12614         } 
else if (enable_ping_pong
 
12634            if (ws_data_handler != NULL) {
 
12635#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES) 
12638                  if (!conn->websocket_deflate_initialized) {
 
12639                     if (websocket_deflate_initialize(conn, 1) != Z_OK)
 
12640                        exit_by_callback = 1;
 
12642                  if (!exit_by_callback) {
 
12643                     size_t inflate_buf_size_old = 0;
 
12644                     size_t inflate_buf_size =
 
12648                     Bytef *inflated = NULL;
 
12649                     Bytef *new_mem = NULL;
 
12650                     conn->websocket_inflate_state.avail_in =
 
12652                     conn->websocket_inflate_state.next_in = 
data;
 
12659                        if (inflate_buf_size_old == 0) {
 
12664                           inflate_buf_size *= 2;
 
12669                        if (new_mem == NULL) {
 
12672                               "Out of memory: Cannot allocate " 
12673                               "inflate buffer of %lu bytes",
 
12674                               (
unsigned long)inflate_buf_size);
 
12675                           exit_by_callback = 1;
 
12678                        inflated = new_mem;
 
12679                        conn->websocket_inflate_state.avail_out =
 
12680                            (uInt)(inflate_buf_size
 
12681                                   - inflate_buf_size_old);
 
12682                        conn->websocket_inflate_state.next_out =
 
12683                            inflated + inflate_buf_size_old;
 
12684                        ret = inflate(&conn->websocket_inflate_state,
 
12686                        if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR
 
12687                            || ret == Z_MEM_ERROR) {
 
12690                               "ZLIB inflate error: %i %s",
 
12692                               (conn->websocket_inflate_state.msg
 
12693                                    ? conn->websocket_inflate_state.msg
 
12694                                    : 
"<no error message>"));
 
12695                           exit_by_callback = 1;
 
12698                        inflate_buf_size_old = inflate_buf_size;
 
12700                     } 
while (conn->websocket_inflate_state.avail_out
 
12702                     inflate_buf_size -=
 
12703                         conn->websocket_inflate_state.avail_out;
 
12704                     if (!ws_data_handler(conn,
 
12709                        exit_by_callback = 1;
 
12715                   if (!ws_data_handler(conn,
 
12720                  exit_by_callback = 1;
 
12730         if (exit_by_callback) {
 
12731            DEBUG_TRACE(
"Callback requests to close connection from %s:%u",
 
12738            DEBUG_TRACE(
"Message requests to close connection from %s:%u",
 
12767               if (ping_count > MG_MAX_UNANSWERED_PING) {
 
12769                  DEBUG_TRACE(
"Too many (%i) unanswered ping from %s:%u " 
12770                              "- closing connection",
 
12776               if (enable_ping_pong) {
 
12802   conn->in_websocket_handling = 0;
 
12803   DEBUG_TRACE(
"Websocket connection %s:%u left data processing loop",
 
12814                        uint32_t masking_key)
 
12816   unsigned char header[14];
 
12820#if defined(GCC_DIAGNOSTIC) 
12822#pragma GCC diagnostic push 
12823#pragma GCC diagnostic ignored "-Wconversion" 
12839#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES) 
12840   size_t deflated_size = 0;
 
12841   Bytef *deflated = 0;
 
12843   int use_deflate = dataLen > 100 * 1024 && conn->
accept_gzip;
 
12846      if (!conn->websocket_deflate_initialized) {
 
12847         if (websocket_deflate_initialize(conn, 1) != Z_OK)
 
12852      header[0] = 0xC0u | (
unsigned char)((
unsigned)opcode & 0xf);
 
12853      conn->websocket_deflate_state.avail_in = (uInt)dataLen;
 
12854      conn->websocket_deflate_state.next_in = (
unsigned char *)
data;
 
12855      deflated_size = (Bytef *)compressBound((uLong)dataLen);
 
12856      deflated = 
mg_calloc(deflated_size, 
sizeof(Bytef));
 
12857      if (deflated == NULL) {
 
12860             "Out of memory: Cannot allocate deflate buffer of %lu bytes",
 
12861             (
unsigned long)deflated_size);
 
12865      conn->websocket_deflate_state.avail_out = (uInt)deflated_size;
 
12866      conn->websocket_deflate_state.next_out = deflated;
 
12867      deflate(&conn->websocket_deflate_state, conn->websocket_deflate_flush);
 
12868      dataLen = deflated_size - conn->websocket_deflate_state.avail_out
 
12872      header[0] = 0x80u | (
unsigned char)((
unsigned)opcode & 0xf);
 
12874#if defined(GCC_DIAGNOSTIC) 
12875#pragma GCC diagnostic pop 
12879   if (dataLen < 126) {
 
12881      header[1] = (
unsigned char)dataLen;
 
12883   } 
else if (dataLen <= 0xFFFF) {
 
12885      uint16_t 
len = htons((uint16_t)dataLen);
 
12887      memcpy(header + 2, &
len, 2);
 
12891      uint32_t len1 = htonl((uint32_t)((uint64_t)dataLen >> 32));
 
12892      uint32_t len2 = htonl((uint32_t)(dataLen & 0xFFFFFFFFu));
 
12894      memcpy(header + 2, &len1, 4);
 
12895      memcpy(header + 6, &len2, 4);
 
12902      memcpy(header + headerLen, &masking_key, 4);
 
12906   retval = 
mg_write(conn, header, headerLen);
 
12907   if (retval != (
int)headerLen) {
 
12912#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES) 
12914            retval = 
mg_write(conn, deflated, dataLen);
 
12935   return mg_websocket_write_exec(conn, opcode, 
data, dataLen, 0);
 
12940mask_data(
const char *in, 
size_t in_len, uint32_t masking_key, 
char *out)
 
12945   if ((in_len > 3) && ((ptrdiff_t)in % 4) == 0) {
 
12947      while (i < (in_len - 3)) {
 
12948         *(uint32_t *)(
void *)(
out + i) =
 
12949             *(uint32_t *)(
void *)(in + i) ^ masking_key;
 
12955      while (i < in_len) {
 
12956         *(uint8_t *)(
void *)(
out + i) =
 
12957             *(uint8_t *)(
void *)(in + i)
 
12958             ^ *(((uint8_t *)&masking_key) + (i % 4));
 
12972   char *masked_data =
 
12974   uint32_t masking_key = 0;
 
12976   if (masked_data == NULL) {
 
12980                      "Cannot allocate buffer for masked websocket response: " 
12988   } 
while (masking_key == 0);
 
12990   mask_data(
data, dataLen, masking_key, masked_data);
 
12992   retval = mg_websocket_write_exec(
 
12993       conn, opcode, masked_data, dataLen, masking_key);
 
13003                         int is_callback_resource,
 
13011   const char *websock_key = 
mg_get_header(conn, 
"Sec-WebSocket-Key");
 
13012   const char *version = 
mg_get_header(conn, 
"Sec-WebSocket-Version");
 
13013   ptrdiff_t lua_websock = 0;
 
13015#if !defined(USE_LUA) 
13021   if (!websock_key) {
 
13028      const char *key1 = 
mg_get_header(conn, 
"Sec-WebSocket-Key1");
 
13029      const char *key2 = 
mg_get_header(conn, 
"Sec-WebSocket-Key2");
 
13032      if ((key1 != NULL) && (key2 != NULL)) {
 
13035         if (8 == 
mg_read(conn, key3, 8)) {
 
13040                               "Protocol upgrade to RFC 6455 required");
 
13051   if ((version == NULL) || (strcmp(version, 
"13") != 0)) {
 
13061   if (is_callback_resource) {
 
13063      const char *protocols[64]; 
 
13064      int nbSubprotocolHeader = get_req_headers(&conn->
request_info,
 
13065                                                "Sec-WebSocket-Protocol",
 
13068      if ((nbSubprotocolHeader > 0) && subprotocols) {
 
13072         const char *
sep, *curSubProtocol,
 
13073             *acceptedWebSocketSubprotocol = NULL;
 
13078            const char *protocol = protocols[
cnt];
 
13081               sep = strchr(protocol, 
',');
 
13082               curSubProtocol = protocol;
 
13083               len = 
sep ? (
unsigned long)(sep - protocol)
 
13084                         : (unsigned long)strlen(protocol);
 
13085               while (sep && isspace((
unsigned char)*++sep))
 
13091                      && (strncmp(curSubProtocol,
 
13095                     acceptedWebSocketSubprotocol =
 
13100            } 
while (sep && !acceptedWebSocketSubprotocol);
 
13101         } 
while (++cnt < nbSubprotocolHeader
 
13102                  && !acceptedWebSocketSubprotocol);
 
13105             acceptedWebSocketSubprotocol;
 
13107      } 
else if (nbSubprotocolHeader > 0) {
 
13109         const char *protocol = protocols[0];
 
13114         const char *
sep = strrchr(protocol, 
',');
 
13127            while (isspace((
unsigned char)*++sep)) {
 
13134#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES) 
13135      websocket_deflate_negotiate(conn);
 
13138      if ((ws_connect_handler != NULL)
 
13139          && (ws_connect_handler(conn, cbData) != 0)) {
 
13149#if defined(USE_LUA) 
13160         conn->lua_websocket_state = lua_websocket_new(path, conn);
 
13161         if (!conn->lua_websocket_state) {
 
13170   if (!is_callback_resource && !lua_websock) {
 
13180   if (!send_websocket_handshake(conn, websock_key)) {
 
13186   if (is_callback_resource) {
 
13187      if (ws_ready_handler != NULL) {
 
13188         ws_ready_handler(conn, cbData);
 
13190#if defined(USE_LUA) 
13191   } 
else if (lua_websock) {
 
13192      if (!lua_websocket_ready(conn, conn->lua_websocket_state)) {
 
13200   if (is_callback_resource) {
 
13201      read_websocket(conn, ws_data_handler, cbData);
 
13202#if defined(USE_LUA) 
13203   } 
else if (lua_websock) {
 
13204      read_websocket(conn, lua_websocket_data, conn->lua_websocket_state);
 
13208#if defined(USE_ZLIB) && defined(MG_EXPERIMENTAL_INTERFACES) 
13210   if (conn->websocket_deflate_initialized) {
 
13211      deflateEnd(&conn->websocket_deflate_state);
 
13212      inflateEnd(&conn->websocket_inflate_state);
 
13217   if (ws_close_handler) {
 
13218      ws_close_handler(conn, cbData);
 
13233   const char *upgrade, *connection;
 
13242   if (connection == NULL) {
 
13250   if (upgrade == NULL) {
 
13285      if (sscanf(
vec->
ptr, 
"%u.%u.%u.%u%n", &
a, &
b, &
c, &
d, &
n)
 
13293   if ((
n > 0) && ((
size_t)
n == 
vec->
len)) {
 
13294      if ((
a < 256) && (
b < 256) && (
c < 256) && (
d < 256) && (
slash < 33)) {
 
13296         if (sa->
sa.sa_family == AF_INET) {
 
13297            uint32_t ip = ntohl(sa->
sin.sin_addr.s_addr);
 
13298            uint32_t net = ((uint32_t)
a << 24) | ((uint32_t)
b << 16)
 
13299                           | ((uint32_t)
c << 8) | (uint32_t)
d;
 
13301            return (ip & 
mask) == net;
 
13306#if defined(USE_IPV6) 
13311      if (sscanf(
vec->
ptr, 
"[%49[^]]]/%u%n", ad, &
slash, &
n) != 2) {
 
13313         if (sscanf(
vec->
ptr, 
"[%49[^]]]%n", ad, &
n) != 1) {
 
13318      if ((
n <= 0) && no_strict) {
 
13322            if (((
size_t)(
p - 
vec->
ptr) < 
sizeof(ad))
 
13323                && (sscanf(
p, 
"/%u%n", &
slash, &
n) == 1)) {
 
13329         } 
else if (
vec->
len < 
sizeof(ad)) {
 
13340         while (isxdigit((
unsigned char)*
p) || (*
p == 
'.') || (*
p == 
':')) {
 
13341            if (*(
p++) == 
':') {
 
13345         if ((*
p == 
'\0') && (
c >= 2)) {
 
13346            struct sockaddr_in6 sin6;
 
13350            if (sa->
sa.sa_family != AF_INET6) {
 
13353            if (
mg_inet_pton(AF_INET6, ad, &sin6, 
sizeof(sin6), 0)) {
 
13355               for (i = 0; i < 16; i++) {
 
13356                  uint8_t ip = sa->sin6.sin6_addr.s6_addr[i];
 
13357                  uint8_t net = sin6.sin6_addr.s6_addr[i];
 
13360                  if (8 * i + 8 < 
slash) {
 
13362                  } 
else if (8 * i < 
slash) {
 
13363                     mask = (uint8_t)(0xFFu << (8 * i + 8 - 
slash));
 
13365                  if ((ip & 
mask) != net) {
 
13393      if ((val.
ptr == NULL)
 
13394          || (sscanf(val.
ptr, 
"%lf%c", &
v, &mult)
 
13400              && (mult != 
','))) {
 
13405               : ((
lowercase(&mult) == 
'm') ? 1048576 : 1);
 
13410         if (matched >= 0) {
 
13435      for (i = 0; ((idx == -1) && (i < ctx->num_listening_sockets)); i++) {
 
13447   const char *host_header =
 
13453   if (host_header != NULL) {
 
13458      if (*host_header == 
'[') {
 
13459         pos = strchr(host_header, 
']');
 
13462            DEBUG_TRACE(
"%s", 
"Host name format error '[' without ']'");
 
13466         host->
ptr = host_header;
 
13467         host->
len = (size_t)(pos + 1 - host_header);
 
13470         pos = strchr(host_header, 
':');
 
13472            host->
len = (size_t)(pos - host_header);
 
13474            host->
len = strlen(host_header);
 
13476         host->
ptr = host_header;
 
13496            if ((strlen(sslhost) != host.
len)
 
13499               DEBUG_TRACE(
"Host mismatch: SNI: %s, HTTPS: %.*s",
 
13511            size_t domNameLen = strlen(domName);
 
13512            if ((domNameLen == host.
len)
 
13530                  conn->
ssl ? 
"S" : 
"",
 
13548   const char *expect_proto =
 
13552   int redirect_code = 308;
 
13559           conn, target_url, 
sizeof(target_url), expect_proto, port, NULL)
 
13563      size_t slen1 = strlen(target_url);
 
13565      if ((slen1 + slen2 + 2) < 
sizeof(target_url)) {
 
13566         target_url[slen1] = 
'?';
 
13567         memcpy(target_url + slen1 + 1,
 
13570         target_url[slen1 + slen2 + 1] = 0;
 
13593                    int is_delete_request,
 
13604   size_t urilen = strlen(
uri);
 
13635      if (!is_delete_request && (
handler == NULL)) {
 
13662   if (!phys_ctx || !dom_ctx) {
 
13672      for (tmp_rh = dom_ctx->
handlers; tmp_rh != NULL;
 
13673           tmp_rh = tmp_rh->
next) {
 
13675             && (urilen == tmp_rh->
uri_len) && !strcmp(tmp_rh->
uri, 
uri)) {
 
13676            if (!is_delete_request) {
 
13713               *lastref = tmp_rh->
next;
 
13720         lastref = &(tmp_rh->
next);
 
13722   } 
while (tmp_rh != NULL);
 
13724   if (is_delete_request) {
 
13735   if (tmp_rh == NULL) {
 
13739                          "Cannot create new request handler struct, OOM");
 
13743   if (!tmp_rh->
uri) {
 
13748                          "Cannot create new request handler struct, OOM");
 
13767   tmp_rh->
next = NULL;
 
13882   if (request_info) {
 
13883      const char *uri = request_info->
local_uri;
 
13884      size_t urilen = strlen(uri);
 
13894      for (step = 0; step < 3; step++) {
 
13896              tmp_rh = tmp_rh->
next) {
 
13902               matched = (tmp_rh->
uri_len == urilen)
 
13903                         && (strcmp(tmp_rh->
uri, 
uri) == 0);
 
13904            } 
else if (step == 1) {
 
13932                  *handler_info = tmp_rh;
 
13964#if defined(USE_WEBSOCKET) && defined(MG_EXPERIMENTAL_INTERFACES) 
13966experimental_websocket_client_data_wrapper(
struct mg_connection *conn,
 
13973   if (pcallbacks->websocket_data) {
 
13974      return pcallbacks->websocket_data(conn, bits, 
data, 
len);
 
13982experimental_websocket_client_close_wrapper(
const struct mg_connection *conn,
 
13999   if (handler_info != NULL) {
 
14017   int uri_len, ssl_index;
 
14018   int is_found = 0, is_script_resource = 0, is_websocket_request = 0,
 
14019       is_put_or_delete_request = 0, is_callback_resource = 0,
 
14020       is_template_text_file = 0;
 
14030   void *callback_data = NULL;
 
14032   void *auth_callback_data = NULL;
 
14034   time_t curtime = time(NULL);
 
14053      if (ssl_index >= 0) {
 
14063                            "Error: SSL forward not configured properly");
 
14066                         "Can not redirect to SSL, no SSL port available");
 
14121      } 
else if (i == 0) {
 
14139      const char *cors_meth_cfg =
 
14141      const char *cors_orig_cfg =
 
14143      const char *cors_cred_cfg =
 
14145      const char *cors_origin =
 
14149                                         "Access-Control-Request-Method");
 
14154      if ((cors_meth_cfg != NULL) && (*cors_meth_cfg != 0)
 
14155          && (cors_orig_cfg != NULL) && (*cors_orig_cfg != 0)
 
14156          && (cors_origin != NULL) && (cors_acrm != NULL)) {
 
14159         const char *cors_acrh =
 
14162                        "Access-Control-Request-Headers");
 
14166                   "HTTP/1.1 200 OK\r\n" 
14168                   "Access-Control-Allow-Origin: %s\r\n" 
14169                   "Access-Control-Allow-Methods: %s\r\n" 
14170                   "Content-Length: 0\r\n" 
14171                   "Connection: %s\r\n",
 
14174                   ((cors_meth_cfg[0] == 
'*') ? cors_acrm : cors_meth_cfg),
 
14177         if (cors_acrh != NULL) {
 
14179            const char *cors_hdr_cfg =
 
14182            if ((cors_hdr_cfg != NULL) && (*cors_hdr_cfg != 0)) {
 
14189                         "Access-Control-Allow-Headers: %s\r\n",
 
14190                         ((cors_hdr_cfg[0] == 
'*') ? cors_acrh
 
14194         if (cors_cred_cfg && *cors_cred_cfg) {
 
14196               "Access-Control-Allow-Credentials: %s\r\n",
 
14200         mg_printf(conn, 
"Access-Control-Max-Age: 60\r\n");
 
14213#if defined(USE_WEBSOCKET) 
14219   if (is_websocket_request) {
 
14228                           &ws_connect_handler,
 
14238      is_callback_resource = 1;
 
14239      is_script_resource = 1;
 
14242   no_callback_resource:
 
14247      is_callback_resource = 0;
 
14253                    &is_script_resource,
 
14254                    &is_websocket_request,
 
14255                    &is_put_or_delete_request,
 
14256                    &is_template_text_file);
 
14270                           &auth_callback_data,
 
14272      if (!auth_handler(conn, auth_callback_data)) {
 
14279   } 
else if (is_put_or_delete_request && !is_script_resource
 
14280              && !is_callback_resource) {
 
14284#if defined(NO_FILES) 
14296                            "%s method not allowed",
 
14301#if !defined(NO_FILES) 
14328   if (is_callback_resource) {
 
14330      if (!is_websocket_request) {
 
14331         i = callback_handler(conn, callback_data);
 
14367                          &is_script_resource,
 
14368                          &is_websocket_request,
 
14369                          &is_put_or_delete_request,
 
14370                          &is_template_text_file);
 
14371            callback_handler = NULL;
 
14382            goto no_callback_resource;
 
14385#if defined(USE_WEBSOCKET) 
14386         handle_websocket_request(conn,
 
14388                                  is_callback_resource,
 
14390                                  ws_connect_handler,
 
14401#if defined(USE_WEBSOCKET) 
14402   if (is_websocket_request) {
 
14404      if (is_script_resource) {
 
14408            handle_websocket_request(conn,
 
14428#if defined(NO_FILES) 
14443   if (is_script_resource) {
 
14450   if (is_put_or_delete_request) {
 
14472                         "%s method not allowed",
 
14485   if (
file.stat.is_directory && (uri_len > 0)
 
14486       && (ri->
local_uri[uri_len - 1] != 
'/')) {
 
14495         new_path[
len] = 
'/';
 
14496         new_path[
len + 1] = 0;
 
14498            new_path[
len + 1] = 
'?';
 
14529                         "%s method not allowed",
 
14535   if (
file.stat.is_directory) {
 
14546                            "Error: Directory listing denied");
 
14552   if (is_template_text_file) {
 
14559#if !defined(NO_CACHING) 
14574#if !defined(NO_FILESYSTEMS) 
14580#if !defined(NO_CGI) 
14581   unsigned char cgi_config_idx, inc, max;
 
14584   if (!conn || !conn->
dom_ctx) {
 
14588#if defined(USE_LUA) 
14595         handle_lsp_request(conn, path, 
file, NULL);
 
14608         mg_exec_lua_script(conn, path, NULL);
 
14617#if defined(USE_DUKTAPE) 
14623         mg_exec_duktape_script(conn, path);
 
14632#if !defined(NO_CGI) 
14635   for (cgi_config_idx = 0; cgi_config_idx < max; cgi_config_idx += inc) {
 
14664#if !defined(NO_CACHING) 
14687#if defined(USE_X_DOM_SOCKET) 
14725   unsigned int a, 
b, 
c, 
d;
 
14727   unsigned long portUL;
 
14731#if defined(USE_IPV6) 
14732   char buf[100] = {0};
 
14738   memset(so, 0, 
sizeof(*so));
 
14739   so->
lsa.
sin.sin_family = AF_INET;
 
14748              "%u.%u.%u.%u:%u%n",
 
14759      so->
lsa.
sin.sin_addr.s_addr =
 
14760          htonl((
a << 24) | (
b << 16) | (
c << 8) | 
d);
 
14761      so->
lsa.
sin.sin_port = htons((uint16_t)port);
 
14764#if defined(USE_IPV6) 
14765   } 
else if (sscanf(
vec->
ptr, 
"[%49[^]]]:%u%n", buf, &port, &
len) == 2
 
14766              && ((
size_t)len <= vec->
len)
 
14768                     AF_INET6, buf, &so->
lsa.sin6, 
sizeof(so->
lsa.sin6), 0)) {
 
14772      so->
lsa.sin6.sin6_port = htons((uint16_t)port);
 
14776   } 
else if ((
vec->
ptr[0] == 
'+')
 
14777              && (sscanf(
vec->
ptr + 1, 
"%u%n", &port, &
len)
 
14787#if defined(USE_IPV6) 
14789      so->
lsa.sin6.sin6_family = AF_INET6;
 
14790      so->
lsa.sin6.sin6_port = htons((uint16_t)port);
 
14791      *ip_version = 4 + 6;
 
14794      so->
lsa.
sin.sin_port = htons((uint16_t)port);
 
14799              && (
vec->
ptr != endptr)) {
 
14801      port = (uint16_t)portUL;
 
14803      so->
lsa.
sin.sin_port = htons((uint16_t)port);
 
14806   } 
else if ((cb = strchr(
vec->
ptr, 
':')) != NULL) {
 
14816      char hostname[256];
 
14817      size_t hostnlen = (size_t)(cb - 
vec->
ptr);
 
14819      if ((hostnlen >= 
vec->
len) || (hostnlen >= 
sizeof(hostname))) {
 
14828              AF_INET, hostname, &so->
lsa.
sin, 
sizeof(so->
lsa.
sin), 1)) {
 
14829         if (sscanf(cb + 1, 
"%u%n", &port, &
len)
 
14835            so->
lsa.
sin.sin_port = htons((uint16_t)port);
 
14836            len += (
int)(hostnlen + 1);
 
14840#if defined(USE_IPV6) 
14844                              sizeof(so->
lsa.sin6),
 
14846         if (sscanf(cb + 1, 
"%u%n", &port, &
len) == 1) {
 
14848            so->
lsa.sin6.sin6_port = htons((uint16_t)port);
 
14849            len += (
int)(hostnlen + 1);
 
14858#if defined(USE_X_DOM_SOCKET) 
14860   } 
else if (
vec->
ptr[0] == 
'x') {
 
14862      if (
vec->
len < 
sizeof(so->
lsa.sun.sun_path)) {
 
14864         so->
lsa.sun.sun_family = AF_UNIX;
 
14865         memset(so->
lsa.sun.sun_path, 0, 
sizeof(so->
lsa.sun.sun_path));
 
14886      so->
is_ssl = (ch == 
's');
 
14888      if ((ch == 
'\0') || (ch == 
's') || (ch == 
'r')) {
 
14939      int portslen = (
int)strlen(ports);
 
14940      char prevIsNumber = 0;
 
14942      for (i = 0; i < portslen; i++) {
 
14943         if (prevIsNumber && (ports[i] == 
's' || ports[i] == 
'r')) {
 
14946         if (ports[i] >= 
'0' && ports[i] <= 
'9') {
 
14962#if defined(USE_IPV6) 
14973   int portsTotal = 0;
 
14976   const char *opt_txt;
 
14977   long opt_listen_backlog;
 
14983   memset(&so, 0, 
sizeof(so));
 
14984   memset(&
usa, 0, 
sizeof(
usa));
 
14995             "%.*s: invalid port spec (entry %i). Expecting list of: %s",
 
14999             "[IP_ADDRESS:]PORT[s|r]");
 
15003#if !defined(NO_SSL) 
15007                             "Cannot add SSL socket (entry %i)",
 
15019                      (ip_version == 99) ? ( 0) : ( 6)))
 
15023                             "cannot create socket (entry %i)",
 
15038      if (setsockopt(so.
sock,
 
15040                     SO_EXCLUSIVEADDRUSE,
 
15048             "cannot set socket option SO_EXCLUSIVEADDRUSE (entry %i)",
 
15052      if (setsockopt(so.
sock,
 
15062             "cannot set socket option SO_REUSEADDR (entry %i)",
 
15067#if defined(USE_X_DOM_SOCKET) 
15068      if (ip_version == 99) {
 
15073          if (ip_version > 4) {
 
15075#if defined(USE_IPV6) 
15076         if (ip_version > 6) {
 
15077            if (so.
lsa.
sa.sa_family == AF_INET6
 
15078                && setsockopt(so.
sock,
 
15087                                   "cannot set socket option " 
15088                                   "IPV6_V6ONLY=off (entry %i)",
 
15092            if (so.
lsa.
sa.sa_family == AF_INET6
 
15093                && setsockopt(so.
sock,
 
15102                                   "cannot set socket option " 
15103                                   "IPV6_V6ONLY=on (entry %i)",
 
15115      if (so.
lsa.
sa.sa_family == AF_INET) {
 
15120                                "cannot bind to %.*s: %d (%s)",
 
15130#if defined(USE_IPV6) 
15131      else if (so.
lsa.
sa.sa_family == AF_INET6) {
 
15133         len = 
sizeof(so.
lsa.sin6);
 
15136                                "cannot bind to IPv6 %.*s: %d (%s)",
 
15147#if defined(USE_X_DOM_SOCKET) 
15148      else if (so.
lsa.
sa.sa_family == AF_UNIX) {
 
15150         len = 
sizeof(so.
lsa.sun);
 
15153                                "cannot bind to unix socket %s: %d (%s)",
 
15154                                so.
lsa.sun.sun_path,
 
15166             "cannot bind: address family not supported (entry %i)",
 
15174      opt_listen_backlog = strtol(opt_txt, NULL, 10);
 
15175      if ((opt_listen_backlog > INT_MAX) || (opt_listen_backlog < 1)) {
 
15177                             "%s value \"%s\" is invalid",
 
15185      if (listen(so.
sock, (
int)opt_listen_backlog) != 0) {
 
15188                             "cannot listen to %.*s: %d (%s)",
 
15199          || (
usa.
sa.sa_family != so.
lsa.
sa.sa_family)) {
 
15203                             "call to getsockname failed %.*s: %d (%s)",
 
15214#if defined(USE_IPV6) 
15215      if (so.
lsa.
sa.sa_family == AF_INET6) {
 
15216         so.
lsa.sin6.sin6_port = 
usa.sin6.sin6_port;
 
15223      if ((ptr = (
struct socket *)
 
15258   if (portsOk != portsTotal) {
 
15270   const char *header_value;
 
15272   if ((header_value = 
mg_get_header(conn, header)) == NULL) {
 
15275      return header_value;
 
15280#if defined(MG_EXTERNAL_FUNCTION_log_access) 
15281#include "external_log_access.inl" 
15282#elif !defined(NO_FILESYSTEMS) 
15292   const char *referer;
 
15293   const char *user_agent;
 
15295   char log_buf[4096];
 
15297   if (!conn || !conn->
dom_ctx) {
 
15304#if defined(USE_LUA) 
15305   if (conn->
phys_ctx->lua_bg_log_available) {
 
15308      lua_State *lstate = (lua_State *)ctx->lua_background_state;
 
15309      pthread_mutex_lock(&ctx->lua_bg_mutex);
 
15311      lua_getglobal(lstate, 
"log");
 
15312      prepare_lua_request_info_inner(conn, lstate);
 
15313      push_lua_response_log_data(conn, lstate);
 
15315      ret = lua_pcall(lstate,  2,  1, 0);
 
15317         int t = lua_type(lstate, -1);
 
15318         if (t == LUA_TBOOLEAN) {
 
15319            if (lua_toboolean(lstate, -1) == 0) {
 
15321               pthread_mutex_unlock(&ctx->lua_bg_mutex);
 
15325         } 
else if (t == LUA_TSTRING) {
 
15327            const char *txt = lua_tolstring(lstate, -1, &
len);
 
15328            if ((
len == 0) || (*txt == 0)) {
 
15330               pthread_mutex_unlock(&ctx->lua_bg_mutex);
 
15334            if (
len >= 
sizeof(log_buf)) {
 
15335               len = 
sizeof(log_buf) - 1;
 
15337            memcpy(log_buf, txt, 
len);
 
15341         lua_cry(conn, ret, lstate, 
"lua_background_script", 
"log");
 
15343      pthread_mutex_unlock(&ctx->lua_bg_mutex);
 
15370         strftime(date, 
sizeof(date), 
"%d/%b/%Y:%H:%M:%S %z", tm);
 
15372         mg_strlcpy(date, 
"01/Jan/1970:00:00:00 +0000", 
sizeof(date));
 
15373         date[
sizeof(date) - 1] = 
'\0';
 
15380      user_agent = 
header_val(conn, 
"User-Agent");
 
15386                  "%s - %s [%s] \"%s %s%s%s HTTP/%s\" %d %" INT64_FMT 
15417      if (fprintf(fi.
access.
fp, 
"%s\n", log_buf) < 1) {
 
15429                         "Error writing log file %s",
 
15435#error "Either enable filesystems or provide a custom log_access implementation" 
15445   int allowed, flag, matched;
 
15452      allowed = (list == NULL) ? 
'+' : 
'-';
 
15457         if ((
vec.
len > 0) && ((flag == 
'+') || (flag == 
'-'))) {
 
15464                                "%s: subnet must be [+|-]IP-addr[/x]",
 
15473      return allowed == 
'+';
 
15479#if !defined(_WIN32) && !defined(__ZEPHYR__) 
15487      const uid_t curr_uid = getuid();
 
15490      const struct passwd *to_pw = NULL;
 
15492      if ((run_as_user != NULL) && (to_pw = getpwnam(run_as_user)) == NULL) {
 
15496                             "%s: unknown user [%s]",
 
15499      } 
else if ((run_as_user == NULL) || (curr_uid == to_pw->
pw_uid)) {
 
15506         if (setgid(to_pw->
pw_gid) == -1) {
 
15508                                "%s: setgid(%s): %s",
 
15512         } 
else if (setgroups(0, NULL) == -1) {
 
15514                                "%s: setgroups(): %s",
 
15517         } 
else if (setuid(to_pw->
pw_uid) == -1) {
 
15519                                "%s: setuid(%s): %s",
 
15546   pthread_setspecific(
sTlsKey, NULL);
 
15550#if defined(USE_MBEDTLS) 
15561      dom_ctx = &(phys_ctx->
dd);
 
15570   if (dom_ctx->
ssl_ctx == NULL) {
 
15571      fprintf(stderr, 
"ssl_ctx malloc failed\n");
 
15581#elif !defined(NO_SSL) 
15586                            const char *chain);
 
15593   struct stat cert_buf;
 
15597   int should_verify_peer;
 
15605   if (chain == NULL) {
 
15613   if (stat(pem, &cert_buf) != -1) {
 
15614      t = (int64_t)cert_buf.st_mtime;
 
15621      should_verify_peer = 0;
 
15625            should_verify_peer = 1;
 
15629            should_verify_peer = 1;
 
15633      if (should_verify_peer) {
 
15643                "SSL_CTX_load_verify_locations error: %s " 
15644                "ssl_verify_peer requires setting " 
15645                "either ssl_ca_path or ssl_ca_file. Is any of them " 
15663#if defined(OPENSSL_API_1_1) 
15670       int (*func)(
SSL *),
 
15675   unsigned timeout = 1024;
 
15696   if (conn->
ssl == NULL) {
 
15698      OPENSSL_REMOVE_THREAD_STATE();
 
15701   SSL_set_app_data(conn->
ssl, (
char *)conn);
 
15703   ret = SSL_set_fd(conn->ssl, conn->client.sock);
 
15706      SSL_free(conn->ssl);
 
15708      OPENSSL_REMOVE_THREAD_STATE();
 
15712   if (client_options) {
 
15714         SSL_set_tlsext_host_name(conn->ssl, client_options->
host_name);
 
15724         timeout = (unsigned)to;
 
15731   for (i = 0; i <= timeout; i += 50) {
 
15734      ret = func(conn->ssl);
 
15736         err = SSL_get_error(conn->ssl, ret);
 
15754               pfd.fd = conn->client.sock;
 
15760                   mg_poll(&pfd, 1, 50, &(conn->phys_ctx->stop_flag));
 
15787      SSL_free(conn->ssl);
 
15789      OPENSSL_REMOVE_THREAD_STATE();
 
15802   err = ERR_get_error();
 
15803   return ((err == 0) ? 
"" : ERR_error_string(err, NULL));
 
15811   const char hexdigit[] = 
"0123456789abcdef";
 
15813   if ((memlen <= 0) || (buflen <= 0)) {
 
15816   if (buflen < (3 * memlen)) {
 
15820   for (i = 0; i < memlen; i++) {
 
15822         buf[3 * i - 1] = 
' ';
 
15824      buf[3 * i] = hexdigit[(((uint8_t *)mem)[i] >> 4) & 0xF];
 
15825      buf[3 * i + 1] = hexdigit[((uint8_t *)mem)[i] & 0xF];
 
15827   buf[3 * memlen - 1] = 0;
 
15837   X509 *cert = SSL_get_peer_certificate(conn->
ssl);
 
15839      char str_buf[1024];
 
15840      unsigned char buf[256];
 
15841      char *str_serial = NULL;
 
15844      unsigned char *tmp_buf;
 
15845      unsigned char *tmp_p;
 
15848      const EVP_MD *digest = EVP_get_digestbyname(
"sha1");
 
15851      X509_NAME *subj = X509_get_subject_name(cert);
 
15852      X509_NAME *iss = X509_get_issuer_name(cert);
 
15858      BIGNUM *serial_bn = ASN1_INTEGER_to_BN(serial, NULL);
 
15860         str_serial = BN_bn2hex(serial_bn);
 
15861         BN_free(serial_bn);
 
15867      (void)X509_NAME_oneline(subj, str_buf, (
int)
sizeof(str_buf));
 
15869      (void)X509_NAME_oneline(iss, str_buf, (
int)
sizeof(str_buf));
 
15877      ilen = i2d_X509(cert, NULL);
 
15878      tmp_buf = (ilen > 0)
 
15884         (void)i2d_X509(cert, &tmp_p);
 
15886                 tmp_buf, (
unsigned)ilen, buf, &ulen, digest, NULL)) {
 
15892      if (!
hexdump2string(buf, (
int)ulen, str_buf, (
int)
sizeof(str_buf))) {
 
15901      OPENSSL_free(str_serial);
 
15908#if defined(OPENSSL_API_1_1) 
15918      (void)pthread_mutex_lock(&
ssl_mutexes[mutex_num]);
 
15920      (void)pthread_mutex_unlock(&
ssl_mutexes[mutex_num]);
 
15926#if !defined(NO_SSL_DL) 
15931             const char *dll_name,
 
15933             int *feature_missing)
 
15944   if ((dll_handle = dlopen(dll_name, RTLD_LAZY)) == NULL) {
 
15949                  "%s: cannot load %s",
 
15956   for (fp = sw; fp->
name != NULL; fp++) {
 
15959      u.fp = (void (*)(void))dlsym(dll_handle, fp->
name);
 
15964      u.p = dlsym(dll_handle, fp->
name);
 
15970      if (u.fp == NULL) {
 
15972         if (feature_missing) {
 
15984                           "%s: %s: cannot find %s",
 
15992               size_t cur_len = strlen(ebuf);
 
15993               if (!truncated && ((ebuf_len - cur_len) > 3)) {
 
15997                              ebuf_len - cur_len - 3,
 
16002                     strcat(ebuf, 
"...");
 
16011      (void)dlclose(dll_handle);
 
16025#if defined(SSL_ALREADY_INITIALIZED) 
16037#if !defined(OPENSSL_API_1_1) && !defined(OPENSSL_API_3_0) 
16042   if (ebuf_len > 0) {
 
16046#if !defined(NO_SSL_DL) 
16056                     "%s: error loading library %s",
 
16069#if !defined(OPENSSL_API_1_1) && !defined(OPENSSL_API_3_0) 
16073   num_locks = CRYPTO_num_locks();
 
16074   if (num_locks < 0) {
 
16077   size = 
sizeof(pthread_mutex_t) * ((
size_t)(num_locks));
 
16080   if (num_locks == 0) {
 
16093                     "%s: cannot allocate mutexes: %s",
 
16101      for (i = 0; i < num_locks; i++) {
 
16107                        "%s: error initializing mutex %i of %i",
 
16122#if !defined(NO_SSL_DL) 
16127#if !defined(OPENSSL_API_1_1) 
16136#if (defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0))                     \ 
16137    && !defined(NO_SSL_DL) 
16139   OPENSSL_init_ssl(0, NULL);
 
16145   SSL_library_init();
 
16146   SSL_load_error_strings();
 
16159   if (SSL_CTX_use_certificate_file(dom_ctx->
ssl_ctx, pem, 1) == 0) {
 
16161                          "%s: cannot open certificate file %s: %s",
 
16169   if (SSL_CTX_use_PrivateKey_file(dom_ctx->
ssl_ctx, pem, 1) == 0) {
 
16171                          "%s: cannot open private key file %s: %s",
 
16178   if (SSL_CTX_check_private_key(dom_ctx->
ssl_ctx) == 0) {
 
16180                          "%s: certificate and private key do not match: %s",
 
16195      if (SSL_CTX_use_certificate_chain_file(dom_ctx->
ssl_ctx, chain) == 0) {
 
16197                             "%s: cannot use certificate chain file %s: %s",
 
16208#if defined(OPENSSL_API_1_1) 
16209static unsigned long 
16212   long unsigned ret = (
long unsigned)
SSL_OP_ALL;
 
16213   if (version_id > 0)
 
16215   if (version_id > 1)
 
16217   if (version_id > 2)
 
16219   if (version_id > 3)
 
16221   if (version_id > 4)
 
16223#if defined(SSL_OP_NO_TLSv1_3) 
16224   if (version_id > 5)
 
16233   unsigned long ret = (
unsigned long)
SSL_OP_ALL;
 
16234   if (version_id > 0)
 
16236   if (version_id > 1)
 
16238   if (version_id > 2)
 
16240   if (version_id > 3)
 
16242   if (version_id > 4)
 
16244#if defined(SSL_OP_NO_TLSv1_3) 
16245   if (version_id > 5)
 
16269      SSL_get_app_data(ssl);
 
16282#if defined(GCC_DIAGNOSTIC) 
16283#pragma GCC diagnostic push 
16284#pragma GCC diagnostic ignored "-Wcast-align" 
16290#if defined(GCC_DIAGNOSTIC) 
16291#pragma GCC diagnostic pop 
16299   if ((conn == NULL) || (conn->
phys_ctx == NULL)) {
 
16311   if ((servername == NULL) || (*servername == 0)) {
 
16312      DEBUG_TRACE(
"%s", 
"SSL connection not supporting SNI");
 
16319   DEBUG_TRACE(
"TLS connection to host %s", servername);
 
16347#if defined(USE_ALPN) 
16348static const char alpn_proto_list[] = 
"\x02h2\x08http/1.1\x08http/1.0";
 
16349static const char *alpn_proto_order_http1[] = {alpn_proto_list + 3,
 
16350                                               alpn_proto_list + 3 + 8,
 
16352#if defined(USE_HTTP2) 
16353static const char *alpn_proto_order_http2[] = {alpn_proto_list,
 
16354                                               alpn_proto_list + 3,
 
16355                                               alpn_proto_list + 3 + 8,
 
16361               const unsigned char **out,
 
16362               unsigned char *outlen,
 
16363               const unsigned char *in,
 
16364               unsigned int inlen,
 
16368   unsigned int i, j, enable_http2 = 0;
 
16369   const char **alpn_proto_order = alpn_proto_order_http1;
 
16382#if defined(USE_HTTP2) 
16383   enable_http2 = (0 == strcmp(dom_ctx->
config[ENABLE_HTTP2], 
"yes"));
 
16384   if (enable_http2) {
 
16385      alpn_proto_order = alpn_proto_order_http2;
 
16389   for (j = 0; alpn_proto_order[j] != NULL; j++) {
 
16391      const char *
alpn_proto = alpn_proto_order[j];
 
16393      for (i = 0; i < inlen; i++) {
 
16409next_protos_advertised_cb(
SSL *ssl,
 
16410                          const unsigned char **
data,
 
16415   *
data = (
const unsigned char *)alpn_proto_list;
 
16416   *
len = (
unsigned int)strlen((
const char *)
data);
 
16428   unsigned int alpn_len = (
unsigned int)strlen((
char *)alpn_proto_list);
 
16429   int ret = SSL_CTX_set_alpn_protos(dom_ctx->
ssl_ctx,
 
16430                                     (
const unsigned char *)alpn_proto_list,
 
16434                          "SSL_CTX_set_alpn_protos error: %s",
 
16438   SSL_CTX_set_alpn_select_cb(dom_ctx->
ssl_ctx,
 
16442   SSL_CTX_set_next_protos_advertised_cb(dom_ctx->
ssl_ctx,
 
16443                                         next_protos_advertised_cb,
 
16459   int should_verify_peer;
 
16460   int peer_certificate_optional;
 
16461   const char *ca_path;
 
16462   const char *ca_file;
 
16463   int use_default_verify_paths;
 
16465   struct timespec now_mt;
 
16469   int ssl_cache_timeout;
 
16471#if (defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0))                     \ 
16472    && !defined(NO_SSL_DL) 
16473   if ((dom_ctx->
ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) {
 
16475                          "SSL_CTX_new (server) error: %s",
 
16480   if ((dom_ctx->
ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
 
16482                          "SSL_CTX_new (server) error: %s",
 
16488#if defined(SSL_OP_NO_TLSv1_3) 
16489   SSL_CTX_clear_options(dom_ctx->
ssl_ctx,
 
16494   SSL_CTX_clear_options(dom_ctx->
ssl_ctx,
 
16503   SSL_CTX_set_options(dom_ctx->
ssl_ctx,
 
16507#if defined(SSL_OP_NO_RENEGOTIATION) 
16511#if !defined(NO_SSL_DL) 
16512   SSL_CTX_set_ecdh_auto(dom_ctx->
ssl_ctx, 1);
 
16530   SSL_CTX_set_tlsext_servername_callback(dom_ctx->
ssl_ctx,
 
16542   if (callback_ret < 0) {
 
16544                          "SSL callback returned error: %i",
 
16548   if (callback_ret > 0) {
 
16564   if (callback_ret < 0) {
 
16566                          "Domain SSL callback returned error: %i",
 
16570   if (callback_ret > 0) {
 
16578   clock_gettime(CLOCK_MONOTONIC, &now_mt);
 
16590   SSL_CTX_set_session_id_context(dom_ctx->
ssl_ctx,
 
16591                                  (
unsigned char *)ssl_context_id,
 
16592                                  sizeof(ssl_context_id));
 
16602   should_verify_peer = 0;
 
16603   peer_certificate_optional = 0;
 
16607         should_verify_peer = 1;
 
16612         should_verify_peer = 1;
 
16613         peer_certificate_optional = 1;
 
16617   use_default_verify_paths =
 
16622   if (should_verify_peer) {
 
16625      if (SSL_CTX_load_verify_locations(dom_ctx->
ssl_ctx, ca_file, ca_path)
 
16628                             "SSL_CTX_load_verify_locations error: %s " 
16629                             "ssl_verify_peer requires setting " 
16630                             "either ssl_ca_path or ssl_ca_file. " 
16631                             "Is any of them present in the " 
16637      if (peer_certificate_optional) {
 
16640         SSL_CTX_set_verify(dom_ctx->
ssl_ctx,
 
16646      if (use_default_verify_paths
 
16647          && (SSL_CTX_set_default_verify_paths(dom_ctx->
ssl_ctx) != 1)) {
 
16649                             "SSL_CTX_set_default_verify_paths error: %s",
 
16656         SSL_CTX_set_verify_depth(dom_ctx->
ssl_ctx, verify_depth);
 
16661      if (SSL_CTX_set_cipher_list(dom_ctx->
ssl_ctx,
 
16665                             "SSL_CTX_set_cipher_list error: %s",
 
16674   if (ssl_cache_timeout > 0) {
 
16678      SSL_CTX_set_timeout(dom_ctx->
ssl_ctx, (
long)ssl_cache_timeout);
 
16681#if defined(USE_ALPN) 
16683#if !defined(NO_SSL_DL) 
16687      init_alpn(phys_ctx, dom_ctx);
 
16712      dom_ctx = &(phys_ctx->
dd);
 
16727   if (callback_ret < 0) {
 
16730                          "external_ssl_ctx callback returned error: %i",
 
16733   } 
else if (callback_ret > 0) {
 
16754   if (callback_ret < 0) {
 
16758          "external_ssl_ctx_domain callback returned error: %i",
 
16761   } 
else if (callback_ret > 0) {
 
16782                          "Initializing SSL failed: -%s is not set",
 
16789   if (chain == NULL) {
 
16793   if ((chain != NULL) && (*chain == 0)) {
 
16810#if defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0) 
16818      CONF_modules_unload(1);
 
16828      CRYPTO_set_locking_callback(NULL);
 
16829      CRYPTO_set_id_callback(NULL);
 
16831      CONF_modules_unload(1);
 
16832      ERR_free_strings();
 
16834      CRYPTO_cleanup_all_ex_data();
 
16835      OPENSSL_REMOVE_THREAD_STATE();
 
16837      for (i = 0; i < CRYPTO_num_locks(); i++) {
 
16848#if !defined(NO_FILESYSTEMS) 
16863                             "Cannot open %s: %s",
 
16879   memset(&
sa, 0, 
sizeof(
sa));
 
16880#if defined(USE_IPV6) 
16881   sa.sin6.sin6_family = AF_INET6;
 
16883   sa.sin.sin_family = AF_INET;
 
16925#if defined(USE_SERVER_STATS) 
16926   conn->processing_time = 0;
 
16934   if ((so->
lsa.
sa.sa_family == AF_INET)
 
16935       || (so->
lsa.
sa.sa_family == AF_INET6)) {
 
16937      if (setsockopt(so->
sock,
 
16941                     sizeof(nodelay_on))
 
16952#if !defined(__ZEPHYR__) 
16960   struct linger linger;
 
16961   int error_code = 0;
 
16962   int linger_timeout = -2;
 
16963   socklen_t opt_len = 
sizeof(error_code);
 
16986      n = 
pull_inner(NULL, conn, buf, 
sizeof(buf),  1.0);
 
16995   if (linger_timeout >= 0) {
 
16998      linger.l_onoff = 1;
 
17000#if defined(_MSC_VER) 
17001#pragma warning(push) 
17002#pragma warning(disable : 4244) 
17004#if defined(GCC_DIAGNOSTIC) 
17005#pragma GCC diagnostic push 
17006#pragma GCC diagnostic ignored "-Wconversion" 
17012      linger.l_linger = (linger_timeout + 999) / 1000;
 
17014#if defined(GCC_DIAGNOSTIC) 
17015#pragma GCC diagnostic pop 
17017#if defined(_MSC_VER) 
17018#pragma warning(pop) 
17022      linger.l_onoff = 0;
 
17023      linger.l_linger = 0;
 
17026   if (linger_timeout < -1) {
 
17032                         (
char *)&error_code,
 
17042                      "%s: getsockopt(SOL_SOCKET SO_ERROR) failed: %s",
 
17046   } 
else if (error_code == WSAECONNRESET) {
 
17048   } 
else if (error_code == ECONNRESET) {
 
17063             "%s: setsockopt(SOL_SOCKET SO_LINGER(%i,%i)) failed: %s",
 
17081#if defined(USE_SERVER_STATS) 
17082   conn->conn_state = 6; 
 
17085#if defined(USE_LUA) && defined(USE_WEBSOCKET) 
17086   if (conn->lua_websocket_state) {
 
17087      lua_websocket_close(conn, conn->lua_websocket_state);
 
17088      conn->lua_websocket_state = NULL;
 
17110#if defined(USE_SERVER_STATS) 
17111   conn->conn_state = 7; 
 
17114#if defined(USE_MBEDTLS) 
17115   if (conn->
ssl != NULL) {
 
17116      mbed_ssl_close(conn->
ssl);
 
17119#elif !defined(NO_SSL) 
17120   if (conn->
ssl != NULL) {
 
17123      SSL_shutdown(conn->
ssl);
 
17124      SSL_free(conn->
ssl);
 
17125      OPENSSL_REMOVE_THREAD_STATE();
 
17130#if defined(__ZEPHYR__) 
17147#if defined(USE_SERVER_STATS) 
17148   conn->conn_state = 8; 
 
17156   if ((conn == NULL) || (conn->
phys_ctx == NULL)) {
 
17160#if defined(USE_WEBSOCKET) 
17162      if (conn->in_websocket_handling) {
 
17190#if !defined(NO_SSL) && !defined(USE_MBEDTLS)  
17198#if defined(USE_WEBSOCKET) 
17201      (void)pthread_mutex_destroy(&conn->
mutex);
 
17204      (void)pthread_mutex_destroy(&conn->
mutex);
 
17209      (void)pthread_mutex_destroy(&conn->
mutex);
 
17225   struct sockaddr *psa;
 
17228   unsigned max_req_size =
 
17232   size_t conn_size = ((
sizeof(
struct mg_connection) + 7) >> 3) << 3;
 
17233   size_t ctx_size = ((
sizeof(
struct mg_context) + 7) >> 3) << 3;
 
17237                                         conn_size + ctx_size + max_req_size);
 
17239   if (conn == NULL) {
 
17249#if defined(GCC_DIAGNOSTIC) 
17250#pragma GCC diagnostic push 
17251#pragma GCC diagnostic ignored "-Wcast-align" 
17257#if defined(GCC_DIAGNOSTIC) 
17258#pragma GCC diagnostic pop 
17261   conn->
buf = (((
char *)conn) + conn_size + ctx_size);
 
17267                       client_options->
host,
 
17268                       client_options->
port,
 
17280#if !defined(NO_SSL) && !defined(USE_MBEDTLS)  
17281#if (defined(OPENSSL_API_1_1) || defined(OPENSSL_API_3_0))                     \ 
17282    && !defined(NO_SSL_DL) 
17290                  "SSL_CTX_new error: %s",
 
17298       && (conn->
dom_ctx->
ssl_ctx = SSL_CTX_new(SSLv23_client_method()))
 
17304                  "SSL_CTX_new error: %s",
 
17314#if defined(USE_IPV6) 
17317   psa = (sa.
sa.sa_family == AF_INET)
 
17319             : (
struct sockaddr *)&(conn->
client.
rsa.sin6);
 
17328   if (getsockname(sock, psa, &
len) != 0) {
 
17330                      "%s: getsockname() failed: %s",
 
17341                  "Can not create mutex");
 
17342#if !defined(NO_SSL) && !defined(USE_MBEDTLS)  
17351#if !defined(NO_SSL) && !defined(USE_MBEDTLS)  
17369                        "Can not use SSL client certificate");
 
17383                            "SSL_CTX_load_verify_locations error: %s ",
 
17395      if (!
sslize(conn, SSL_connect, client_options)) {
 
17400                     "SSL connection error");
 
17415                         char *error_buffer,
 
17416                         size_t error_buffer_size)
 
17421                                 error_buffer_size);
 
17429                  char *error_buffer,
 
17430                  size_t error_buffer_size)
 
17433   memset(&opts, 0, 
sizeof(opts));
 
17439                                 error_buffer_size);
 
17443#if defined(MG_EXPERIMENTAL_INTERFACES) 
17445mg_connect_client2(
const char *host,
 
17446                   const char *protocol,
 
17455   if (error != NULL) {
 
17462   if ((host == NULL) || (protocol == NULL)) {
 
17469                     "Invalid parameters");
 
17481#if defined(USE_WEBSOCKET) 
17495                     "Protocol %s not supported",
 
17504#if defined(USE_WEBSOCKET) 
17511          ((error != NULL) ? error->
text : NULL),
 
17512          ((error != NULL) ? error->text_buffer_size : 0),
 
17513          (path ? path : 
""),
 
17515          experimental_websocket_client_data_wrapper,
 
17516          experimental_websocket_client_close_wrapper,
 
17523   memset(&opts, 0, 
sizeof(opts));
 
17528                                 ((error != NULL) ? error->
text : NULL),
 
17529                                 ((error != NULL) ? error->text_buffer_size
 
17535static const struct {
 
17540                         {
"https://", 8, 443},
 
17542                         {
"wss://", 6, 443},
 
17556   const char *hostend, *portbegin;
 
17558   unsigned long port;
 
17564   if ((uri[0] == 
'*') && (uri[1] == 
'\0')) {
 
17575   for (i = 0; uri[i] != 0; i++) {
 
17584   if (uri[0] == 
'/') {
 
17608         port = strtoul(portbegin + 1, &portend, 10);
 
17609         if ((portend != hostend) || (port <= 0) || !
is_valid_port(port)) {
 
17625   const char *server_domain;
 
17626   size_t server_domain_len;
 
17627   size_t request_domain_len = 0;
 
17628   unsigned long port = 0;
 
17629   int i, auth_domain_check_enabled;
 
17630   const char *hostbegin = NULL;
 
17631   const char *hostend = NULL;
 
17632   const char *portbegin;
 
17635   auth_domain_check_enabled =
 
17647         hostend = strchr(hostbegin, 
'/');
 
17651         portbegin = strchr(hostbegin, 
':');
 
17652         if ((!portbegin) || (portbegin > hostend)) {
 
17654            request_domain_len = (size_t)(hostend - hostbegin);
 
17656            port = strtoul(portbegin + 1, &portend, 10);
 
17657            if ((portend != hostend) || (port <= 0)
 
17661            request_domain_len = (size_t)(portbegin - hostbegin);
 
17688   if (auth_domain_check_enabled) {
 
17690      server_domain_len = strlen(server_domain);
 
17691      if ((server_domain_len == 0) || (hostbegin == NULL)) {
 
17694      if ((request_domain_len == server_domain_len)
 
17695          && (!memcmp(server_domain, hostbegin, server_domain_len))) {
 
17698         if (request_domain_len < (server_domain_len + 2)) {
 
17705         if (hostbegin[request_domain_len - server_domain_len - 1] != 
'.') {
 
17712             != memcmp(server_domain,
 
17713                       hostbegin + request_domain_len - server_domain_len,
 
17714                       server_domain_len)) {
 
17729   if (ebuf_len > 0) {
 
17749   clock_gettime(CLOCK_MONOTONIC, &(conn->
req_time));
 
17760                  "Invalid message size");
 
17771                  "Message too large");
 
17783                     "Malformed message");
 
17793                     "No data received");
 
17834                  "Bad request: Host mismatch");
 
17842                         "Accept-Encoding"))
 
17844       && strstr(cl, 
"gzip")) {
 
17850                         "Transfer-Encoding"))
 
17870      char *endptr = NULL;
 
17922                         "Transfer-Encoding"))
 
17941      char *endptr = NULL;
 
17987   char *save_timeout;
 
17990   if (ebuf_len > 0) {
 
18000                  "Parameter error");
 
18010   if (timeout >= 0) {
 
18011      mg_snprintf(conn, NULL, txt, 
sizeof(txt), 
"%i", timeout);
 
18014      new_timeout = NULL;
 
18027   return (ret == 0) ? -1 : +1;
 
18045   if (ebuf_len > 0) {
 
18054   if (conn != NULL) {
 
18062                     "Error sending request");
 
18074   if ((ebuf[0] != 
'\0') && (conn != NULL)) {
 
18092#if defined(USE_WEBSOCKET) 
18094static unsigned __stdcall websocket_client_thread(
void *
data)
 
18097websocket_client_thread(
void *
data)
 
18103   void *user_thread_ptr = NULL;
 
18105#if !defined(_WIN32) && !defined(__ZEPHYR__) 
18106   struct sigaction sa;
 
18109   memset(&sa, 0, 
sizeof(sa));
 
18110   sa.sa_handler = SIG_IGN;
 
18111   sigaction(SIGPIPE, &sa, NULL);
 
18127   DEBUG_TRACE(
"%s", 
"Websocket client thread exited\n");
 
18157                                 char *error_buffer,
 
18158                                 size_t error_buffer_size,
 
18160                                 const char *origin,
 
18161                                 const char *extensions,
 
18168#if defined(USE_WEBSOCKET) 
18170   static const char *magic = 
"x3JJHMbDL1EzLkh9GBhXDw==";
 
18172   const char *host = client_options->
host;
 
18175#if defined(__clang__) 
18176#pragma clang diagnostic push 
18177#pragma clang diagnostic ignored "-Wformat-nonliteral" 
18184                                 error_buffer_size);
 
18187   if (
conn == NULL) {
 
18189      if (!error_buffer[0]) {
 
18195                     "Unexpected error");
 
18200   if (origin != NULL) {
 
18201      if (extensions != NULL) {
 
18203                       "GET %s HTTP/1.1\r\n" 
18205                       "Upgrade: websocket\r\n" 
18206                       "Connection: Upgrade\r\n" 
18207                       "Sec-WebSocket-Key: %s\r\n" 
18208                       "Sec-WebSocket-Version: 13\r\n" 
18209                       "Sec-WebSocket-Extensions: %s\r\n" 
18219                       "GET %s HTTP/1.1\r\n" 
18221                       "Upgrade: websocket\r\n" 
18222                       "Connection: Upgrade\r\n" 
18223                       "Sec-WebSocket-Key: %s\r\n" 
18224                       "Sec-WebSocket-Version: 13\r\n" 
18234      if (extensions != NULL) {
 
18236                       "GET %s HTTP/1.1\r\n" 
18238                       "Upgrade: websocket\r\n" 
18239                       "Connection: Upgrade\r\n" 
18240                       "Sec-WebSocket-Key: %s\r\n" 
18241                       "Sec-WebSocket-Version: 13\r\n" 
18242                       "Sec-WebSocket-Extensions: %s\r\n" 
18250                       "GET %s HTTP/1.1\r\n" 
18252                       "Upgrade: websocket\r\n" 
18253                       "Connection: Upgrade\r\n" 
18254                       "Sec-WebSocket-Key: %s\r\n" 
18255                       "Sec-WebSocket-Version: 13\r\n" 
18268                  "Error sending request");
 
18281#if defined(__clang__) 
18282#pragma clang diagnostic pop 
18290      if (!*error_buffer) {
 
18296                     "Unexpected server reply");
 
18299      DEBUG_TRACE(
"Websocket client connect error: %s\r\n", error_buffer);
 
18306   if (!thread_data) {
 
18343                  "Websocket client connect thread could not be started\r\n");
 
18348   (void)client_options;
 
18350   (void)error_buffer;
 
18351   (void)error_buffer_size;
 
18368                            char *error_buffer,
 
18369                            size_t error_buffer_size,
 
18371                            const char *origin,
 
18377   memset(&client_options, 0, 
sizeof(client_options));
 
18397    char *error_buffer,
 
18398    size_t error_buffer_size,
 
18400    const char *origin,
 
18405   if (!client_options) {
 
18424                                       char *error_buffer,
 
18425                                       size_t error_buffer_size,
 
18427                                       const char *origin,
 
18428                                       const char *extensions,
 
18434   memset(&client_options, 0, 
sizeof(client_options));
 
18453    char *error_buffer,
 
18454    size_t error_buffer_size,
 
18456    const char *origin,
 
18457    const char *extensions,
 
18462   if (!client_options) {
 
18482   int keep_alive_enabled =
 
18485   if (!keep_alive_enabled) {
 
18496#if defined(USE_SERVER_STATS) 
18497   conn->conn_state = 2; 
 
18503         void *conn_data = NULL;
 
18520   int keep_alive, discard_len;
 
18522   const char *hostend;
 
18523   int reqerr, uri_type;
 
18525#if defined(USE_SERVER_STATS) 
18527   mg_atomic_add(&(conn->
phys_ctx->total_connections), 1);
 
18528   mg_atomic_max(&(conn->
phys_ctx->max_active_connections), mcon);
 
18531   DEBUG_TRACE(
"Start processing connection from %s",
 
18537      DEBUG_TRACE(
"calling get_request (%i times for this connection)",
 
18540#if defined(USE_SERVER_STATS) 
18541      conn->conn_state = 3; 
 
18544      if (!
get_request(conn, ebuf, 
sizeof(ebuf), &reqerr)) {
 
18560                     "Bad HTTP version: [%s]",
 
18565      if (ebuf[0] == 
'\0') {
 
18567         switch (uri_type) {
 
18603      if (ebuf[0] != 
'\0') {
 
18623                  (ebuf[0] ? ebuf : 
"none"));
 
18625      if (ebuf[0] == 
'\0') {
 
18676                    conn->
buf + discard_len,
 
18685         DEBUG_TRACE(
"internal error: data_len = %li, buf_size = %li",
 
18691   } 
while (keep_alive);
 
18693   DEBUG_TRACE(
"Done processing connection from %s (%f sec)",
 
18699#if defined(USE_SERVER_STATS) 
18706#if defined(ALTERNATIVE_QUEUE) 
18716         if (ctx->client_socks[i].in_use == 2) {
 
18718            if ((ctx->client_socks[i].in_use == 2) && !ctx->
stop_flag) {
 
18719               ctx->client_socks[i] = *sp;
 
18720               ctx->client_socks[i].in_use = 1;
 
18723               (
void)event_signal(ctx->client_wait_events[i]);
 
18743   ctx->client_socks[thread_index].in_use = 2;
 
18746   event_wait(ctx->client_wait_events[thread_index]);
 
18749   *sp = ctx->client_socks[thread_index];
 
18775   (void)thread_index;
 
18801   (void)pthread_cond_signal(&ctx->
sq_empty);
 
18820          && (queue_filled >= ctx->
sq_size)) {
 
18822#if defined(USE_SERVER_STATS) 
18823      if (queue_filled > ctx->sq_max_fill) {
 
18824         ctx->sq_max_fill = queue_filled;
 
18832   if (queue_filled < ctx->sq_size) {
 
18840#if defined(USE_SERVER_STATS) 
18841   if (queue_filled > ctx->sq_max_fill) {
 
18842      ctx->sq_max_fill = queue_filled;
 
18846   (void)pthread_cond_signal(&ctx->
sq_full);
 
18864   tls.pthread_cond_helper_mutex = CreateEvent(NULL, 
FALSE, 
FALSE, NULL);
 
18868   pthread_setspecific(
sTlsKey, &tls);
 
18882   if ((thread_index < 0)
 
18885                          "Internal error: Invalid worker index %i",
 
18894   if (conn->
buf == NULL) {
 
18897          "Out of memory: Cannot allocate buffer for worker %i",
 
18917#if defined(USE_SERVER_STATS) 
18918   conn->conn_state = 1; 
 
18929#if defined(USE_SERVER_STATS) 
18930      conn->conn_close_time = 0;
 
18956#if defined(USE_MBEDTLS) 
18958         if (mbed_ssl_accept(&(conn->
ssl),
 
18974#elif !defined(NO_SSL) 
18976         if (
sslize(conn, SSL_accept, NULL)) {
 
18986#if defined(USE_HTTP2) 
18988                && (!memcmp(tls.
alpn_proto, 
"\x02h2", 3))) {
 
18996               process_new_http2_connection(conn);
 
19041#if defined(USE_SERVER_STATS) 
19042      conn->conn_close_time = time(NULL);
 
19052   pthread_setspecific(
sTlsKey, NULL);
 
19054   CloseHandle(tls.pthread_cond_helper_mutex);
 
19056   pthread_mutex_destroy(&conn->
mutex);
 
19069#if defined(USE_SERVER_STATS) 
19070   conn->conn_state = 9; 
 
19079static unsigned __stdcall 
worker_thread(
void *thread_func_param)
 
19088#if !defined(__ZEPHYR__) 
19089   struct sigaction sa;
 
19092   memset(&sa, 0, 
sizeof(sa));
 
19093   sa.sa_handler = SIG_IGN;
 
19094   sigaction(SIGPIPE, &sa, NULL);
 
19110   socklen_t 
len = 
sizeof(so.
rsa);
 
19111#if !defined(__ZEPHYR__) 
19114   memset(&so, 0, 
sizeof(so));
 
19121                          "%s: %s is not allowed to connect",
 
19133                             "%s: getsockname() failed: %s",
 
19138#if !defined(__ZEPHYR__) 
19139      if ((so.
lsa.
sa.sa_family == AF_INET)
 
19140          || (so.
lsa.
sa.sa_family == AF_INET6)) {
 
19148         if (setsockopt(so.
sock,
 
19156                "%s: setsockopt(SOL_SOCKET SO_KEEPALIVE) failed: %s",
 
19175                "%s: setsockopt(IPPROTO_TCP TCP_NODELAY) failed: %s",
 
19198   unsigned int workerthreadcount;
 
19208   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
 
19209#elif defined(USE_MASTER_THREAD_PRIORITY) 
19210   int min_prio = sched_get_priority_min(SCHED_RR);
 
19211   int max_prio = sched_get_priority_max(SCHED_RR);
 
19212   if ((min_prio >= 0) && (max_prio >= 0)
 
19213       && ((USE_MASTER_THREAD_PRIORITY) <= max_prio)
 
19214       && ((USE_MASTER_THREAD_PRIORITY) >= min_prio)) {
 
19215      struct sched_param sched_param = {0};
 
19216      sched_param.sched_priority = (USE_MASTER_THREAD_PRIORITY);
 
19217      pthread_setschedparam(pthread_self(), SCHED_RR, &sched_param);
 
19223   tls.pthread_cond_helper_mutex = CreateEvent(NULL, 
FALSE, 
FALSE, NULL);
 
19226   pthread_setspecific(
sTlsKey, &tls);
 
19236#if defined(USE_LUA) 
19237   if (ctx->lua_background_state) {
 
19238      lua_State *lstate = (lua_State *)ctx->lua_background_state;
 
19239      pthread_mutex_lock(&ctx->lua_bg_mutex);
 
19242      lua_getglobal(lstate, 
"start");
 
19243      if (lua_type(lstate, -1) == LUA_TFUNCTION) {
 
19244         int ret = lua_pcall(lstate,  0,  0, 0);
 
19250                    "lua_background_script",
 
19254         lua_pop(lstate, 1);
 
19258      lua_getglobal(lstate, 
"log");
 
19259      if (lua_type(lstate, -1) == LUA_TFUNCTION) {
 
19260         ctx->lua_bg_log_available = 1;
 
19262      lua_pop(lstate, 1);
 
19264      pthread_mutex_unlock(&ctx->lua_bg_mutex);
 
19276         pfd[i].events = POLLIN;
 
19291                && (pfd[i].revents & POLLIN)) {
 
19305#if defined(ALTERNATIVE_QUEUE) 
19307      event_signal(ctx->client_wait_events[i]);
 
19311   pthread_cond_broadcast(&ctx->
sq_full);
 
19317   for (i = 0; i < workerthreadcount; i++) {
 
19323#if defined(USE_LUA) 
19325   if (ctx->lua_background_state) {
 
19326      lua_State *lstate = (lua_State *)ctx->lua_background_state;
 
19327      ctx->lua_bg_log_available = 0;
 
19330      pthread_mutex_lock(&ctx->lua_bg_mutex);
 
19331      lua_getglobal(lstate, 
"stop");
 
19332      if (lua_type(lstate, -1) == LUA_TFUNCTION) {
 
19333         int ret = lua_pcall(lstate,  0,  0, 0);
 
19339                    "lua_background_script",
 
19345      ctx->lua_background_state = 0;
 
19346      pthread_mutex_unlock(&ctx->lua_bg_mutex);
 
19359   CloseHandle(tls.pthread_cond_helper_mutex);
 
19361   pthread_setspecific(
sTlsKey, NULL);
 
19372static unsigned __stdcall 
master_thread(
void *thread_func_param)
 
19381#if !defined(__ZEPHYR__) 
19382   struct sigaction sa;
 
19385   memset(&sa, 0, 
sizeof(sa));
 
19386   sa.sa_handler = SIG_IGN;
 
19387   sigaction(SIGPIPE, &sa, NULL);
 
19416#if defined(ALTERNATIVE_QUEUE) 
19418   if (ctx->client_wait_events != NULL) {
 
19419      for (i = 0; (unsigned)i < ctx->cfg_worker_threads; i++) {
 
19420         event_destroy(ctx->client_wait_events[i]);
 
19422      mg_free(ctx->client_wait_events);
 
19425   (void)pthread_cond_destroy(&ctx->
sq_empty);
 
19426   (void)pthread_cond_destroy(&ctx->
sq_full);
 
19433#if defined(USE_LUA) 
19434   (void)pthread_mutex_destroy(&ctx->lua_bg_mutex);
 
19440#if defined(_MSC_VER) 
19441#pragma warning(suppress : 6001) 
19455#if defined(USE_MBEDTLS) 
19462#elif !defined(NO_SSL) 
19465      void *ssl_ctx = (
void *)ctx->
dd.
ssl_ctx;
 
19471      if (callback_ret == 0) {
 
19514#if defined(USE_TIMERS) 
19527#if defined(USE_LUA) 
19541   DWORD dwVersion = 0;
 
19542   DWORD dwMajorVersion = 0;
 
19543   DWORD dwMinorVersion = 0;
 
19545   BOOL wowRet, isWoW = 
FALSE;
 
19547#if defined(_MSC_VER) 
19548#pragma warning(push) 
19550#pragma warning(disable : 4996) 
19552   dwVersion = GetVersion();
 
19553#if defined(_MSC_VER) 
19554#pragma warning(pop) 
19557   dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
 
19558   dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
 
19559   dwBuild = ((dwVersion < 0x80000000) ? (DWORD)(HIWORD(dwVersion)) : 0);
 
19562   wowRet = IsWow64Process(GetCurrentProcess(), &isWoW);
 
19566           (
unsigned)dwMajorVersion,
 
19567           (
unsigned)dwMinorVersion,
 
19568           (wowRet ? (isWoW ? 
" (WoW64)" : 
"") : 
" (?)"));
 
19573#elif defined(__ZEPHYR__) 
19576   struct utsname 
name;
 
19590      const char **run_options = options;
 
19594      while (*run_options) {
 
19595         if (!strcmp(*run_options, optname)) {
 
19596            ports_option = run_options[1];
 
19616   const char *
name, *
value, *default_value;
 
19617   int idx, ok, workerthreadcount;
 
19620   void (*exit_callback)(
const struct mg_context *ctx) = 0;
 
19621   const char **options =
 
19622       ((init != NULL) ? (init->configuration_options) : (NULL));
 
19626   if (error != NULL) {
 
19646                     "Library uninitialized");
 
19666       (uint64_t)
get_random() ^ (uint64_t)(ptrdiff_t)(options);
 
19675   tls.pthread_cond_helper_mutex = NULL;
 
19677   pthread_setspecific(
sTlsKey, &tls);
 
19680#if !defined(ALTERNATIVE_QUEUE) 
19681   ok &= (0 == pthread_cond_init(&ctx->
sq_empty, NULL));
 
19682   ok &= (0 == pthread_cond_init(&ctx->
sq_full, NULL));
 
19686#if defined(USE_LUA) 
19690      const char *err_msg =
 
19691          "Cannot initialize thread synchronization objects";
 
19706      pthread_setspecific(
sTlsKey, NULL);
 
19710   if ((init != NULL) && (init->callbacks != NULL)) {
 
19713      exit_callback = init->callbacks->exit_context;
 
19719   ctx->
user_data = ((init != NULL) ? (init->user_data) : (NULL));
 
19723#if defined(USE_LUA) 
19728   while (options && (
name = *options++) != NULL) {
 
19736                        "Invalid configuration option: %s",
 
19740         pthread_setspecific(
sTlsKey, NULL);
 
19742      } 
else if ((
value = *options++) == NULL) {
 
19749                        "Invalid configuration option value: %s",
 
19753         pthread_setspecific(
sTlsKey, NULL);
 
19756      if (ctx->
dd.
config[idx] != NULL) {
 
19769      if ((ctx->
dd.
config[i] == NULL) && (default_value != NULL)) {
 
19785                     "Invalid configuration option value: %s",
 
19789      pthread_setspecific(
sTlsKey, NULL);
 
19795#if !defined(ALTERNATIVE_QUEUE) 
19806                     "Invalid configuration option value: %s",
 
19810      pthread_setspecific(
sTlsKey, NULL);
 
19815   if (ctx->
squeue == NULL) {
 
19817                          "Out of memory: Cannot allocate %s",
 
19824                     "Out of memory: Cannot allocate %s",
 
19828      pthread_setspecific(
sTlsKey, NULL);
 
19838      if (workerthreadcount <= 0) {
 
19848                     "Invalid configuration option value: %s",
 
19852      pthread_setspecific(
sTlsKey, NULL);
 
19857#if defined(NO_FILES) 
19865                     "Invalid configuration option value: %s",
 
19869      pthread_setspecific(
sTlsKey, NULL);
 
19876#if defined(USE_LUA) 
19878   ctx->lua_bg_log_available = 0;
 
19879   if (ctx->
dd.
config[LUA_BACKGROUND_SCRIPT] != NULL) {
 
19881      struct vec opt_vec;
 
19883      const char *sparams;
 
19885      memset(ebuf, 0, 
sizeof(ebuf));
 
19886      pthread_mutex_lock(&ctx->lua_bg_mutex);
 
19889      lua_State *state = mg_lua_context_script_prepare(
 
19890          ctx->
dd.
config[LUA_BACKGROUND_SCRIPT], ctx, ebuf, 
sizeof(ebuf));
 
19893                             "lua_background_script load error: %s",
 
19900                        "Error in script %s: %s",
 
19904         pthread_mutex_unlock(&ctx->lua_bg_mutex);
 
19907         pthread_setspecific(
sTlsKey, NULL);
 
19912      sparams = ctx->
dd.
config[LUA_BACKGROUND_SCRIPT_PARAMS];
 
19913      if (sparams && sparams[0]) {
 
19914         lua_getglobal(state, 
"mg");
 
19915         lua_pushstring(state, 
"params");
 
19916         lua_newtable(state);
 
19918         while ((sparams = 
next_option(sparams, &opt_vec, &eq_vec))
 
19921                state, opt_vec.
ptr, opt_vec.
len, eq_vec.
ptr, eq_vec.
len);
 
19925         lua_rawset(state, -3);
 
19930      state = mg_lua_context_script_run(state,
 
19931                                        ctx->
dd.
config[LUA_BACKGROUND_SCRIPT],
 
19937                             "lua_background_script start error: %s",
 
19944                        "Error in script %s: %s",
 
19948         pthread_mutex_unlock(&ctx->lua_bg_mutex);
 
19951         pthread_setspecific(
sTlsKey, NULL);
 
19956      ctx->lua_background_state = (
void *)state;
 
19957      pthread_mutex_unlock(&ctx->lua_bg_mutex);
 
19960      ctx->lua_background_state = 0;
 
19965#if !defined(NO_FILESYSTEMS) 
19967      const char *err_msg = 
"Invalid global password file";
 
19980      pthread_setspecific(
sTlsKey, NULL);
 
19985#if defined(USE_MBEDTLS) 
19986   if (!mg_sslctx_init(ctx, NULL)) {
 
19987      const char *err_msg = 
"Error initializing SSL context";
 
20000      pthread_setspecific(
sTlsKey, NULL);
 
20004#elif !defined(NO_SSL) 
20006      const char *err_msg = 
"Error initializing SSL context";
 
20019      pthread_setspecific(
sTlsKey, NULL);
 
20025      const char *err_msg = 
"Failed to setup server ports";
 
20038      pthread_setspecific(
sTlsKey, NULL);
 
20043#if !defined(_WIN32) && !defined(__ZEPHYR__) 
20045      const char *err_msg = 
"Failed to run as configured user";
 
20058      pthread_setspecific(
sTlsKey, NULL);
 
20064      const char *err_msg = 
"Failed to setup access control list";
 
20077      pthread_setspecific(
sTlsKey, NULL);
 
20087      const char *err_msg = 
"Not enough memory for worker thread ID array";
 
20099      pthread_setspecific(
sTlsKey, NULL);
 
20107      const char *err_msg =
 
20108          "Not enough memory for worker thread connection array";
 
20120      pthread_setspecific(
sTlsKey, NULL);
 
20124#if defined(ALTERNATIVE_QUEUE) 
20125   ctx->client_wait_events =
 
20127                              sizeof(ctx->client_wait_events[0]),
 
20129   if (ctx->client_wait_events == NULL) {
 
20130      const char *err_msg = 
"Not enough memory for worker event array";
 
20143      pthread_setspecific(
sTlsKey, NULL);
 
20147   ctx->client_socks =
 
20149                                      sizeof(ctx->client_socks[0]),
 
20151   if (ctx->client_socks == NULL) {
 
20152      const char *err_msg = 
"Not enough memory for worker socket array";
 
20154      mg_free(ctx->client_wait_events);
 
20166      pthread_setspecific(
sTlsKey, NULL);
 
20170   for (i = 0; (unsigned)i < ctx->cfg_worker_threads; i++) {
 
20171      ctx->client_wait_events[i] = event_create();
 
20172      if (ctx->client_wait_events[i] == 0) {
 
20173         const char *err_msg = 
"Error creating worker event %i";
 
20177            event_destroy(ctx->client_wait_events[i]);
 
20180         mg_free(ctx->client_wait_events);
 
20192         pthread_setspecific(
sTlsKey, NULL);
 
20198#if defined(USE_TIMERS) 
20199   if (timers_init(ctx) != 0) {
 
20200      const char *err_msg = 
"Error creating timers";
 
20212      pthread_setspecific(
sTlsKey, NULL);
 
20236         long error_no = (long)
ERRNO;
 
20243                                "Cannot start worker thread %i: error %ld",
 
20256                                "Cannot create threads: error %ld",
 
20265                   "Cannot create first worker thread: error %ld",
 
20269            pthread_setspecific(
sTlsKey, NULL);
 
20279   pthread_setspecific(
sTlsKey, NULL);
 
20287         const char **options)
 
20292   init.configuration_options = options;
 
20301                 const char **options,
 
20306   const char *default_value;
 
20311   if (error != NULL) {
 
20318   if ((ctx == NULL) || (options == NULL)) {
 
20325                     "Invalid parameters");
 
20337                     "Server already stopped");
 
20359   while (options && (
name = *options++) != NULL) {
 
20367                        "Invalid option: %s",
 
20372      } 
else if ((
value = *options++) == NULL) {
 
20379                        "Invalid option value: %s",
 
20385      if (new_dom->
config[idx] != NULL) {
 
20403                     "Mandatory option %s missing",
 
20413      default_value = ctx->
dd.
config[i];
 
20414      if ((new_dom->
config[i] == NULL) && (default_value != NULL)) {
 
20420   new_dom->
next = NULL;
 
20425#if defined(USE_LUA) && defined(USE_WEBSOCKET) 
20426   new_dom->shared_lua_websockets = NULL;
 
20429#if !defined(NO_SSL) && !defined(USE_MBEDTLS) 
20438                     "Initializing SSL context failed");
 
20455                             "domain %s already in use",
 
20462                        "Domain %s specified by %s is already in use",
 
20474      if (dom->
next == NULL) {
 
20475         dom->
next = new_dom;
 
20499   static const unsigned feature_set = 0
 
20503#if !defined(NO_FILES) 
20506#if !defined(NO_SSL) || defined(USE_MBEDTLS) 
20509#if !defined(NO_CGI) 
20512#if defined(USE_IPV6) 
20515#if defined(USE_WEBSOCKET) 
20518#if defined(USE_LUA) 
20521#if defined(USE_DUKTAPE) 
20524#if !defined(NO_CACHING) 
20527#if defined(USE_SERVER_STATS) 
20530#if defined(USE_ZLIB) 
20533#if defined(USE_HTTP2) 
20536#if defined(USE_X_DOM_SOCKET) 
20542#if defined(MG_LEGACY_INTERFACE) 
20545#if defined(MG_EXPERIMENTAL_INTERFACES) 
20548#if !defined(NO_RESPONSE_BUFFERING) 
20551#if defined(MEMORY_DEBUGGING) 
20555   return (feature & feature_set);
 
20562   size_t len = strlen(
src);
 
20565      if ((
size_t)(end - *dst) > 
len) {
 
20581   char *end, *append_eoobj = NULL, block[256];
 
20582   size_t system_info_length = 0;
 
20585   static const char eol[] = 
"\r\n", eoobj[] = 
"\r\n}\r\n";
 
20587   static const char eol[] = 
"\n", eoobj[] = 
"\n}\n";
 
20590   if ((buffer == NULL) || (buflen < 1)) {
 
20595      end = buffer + buflen;
 
20597   if (buflen > (
int)(
sizeof(eoobj) - 1)) {
 
20599      append_eoobj = buffer;
 
20601         end -= 
sizeof(eoobj) - 1;
 
20614                  "%s\"version\" : \"%s\"",
 
20623      DWORD dwVersion = 0;
 
20624      DWORD dwMajorVersion = 0;
 
20625      DWORD dwMinorVersion = 0;
 
20628      GetSystemInfo(&si);
 
20630#if defined(_MSC_VER) 
20631#pragma warning(push) 
20633#pragma warning(disable : 4996) 
20635      dwVersion = GetVersion();
 
20636#if defined(_MSC_VER) 
20637#pragma warning(pop) 
20640      dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
 
20641      dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
 
20647                  ",%s\"os\" : \"Windows %u.%u\"",
 
20649                  (
unsigned)dwMajorVersion,
 
20650                  (
unsigned)dwMinorVersion);
 
20657                  ",%s\"cpu\" : \"type %u, cores %u, mask %x\"",
 
20659                  (
unsigned)si.wProcessorArchitecture,
 
20660                  (
unsigned)si.dwNumberOfProcessors,
 
20661                  (
unsigned)si.dwActiveProcessorMask);
 
20663#elif defined(__ZEPHYR__) 
20668                  ",%s\"os\" : \"%s %s\"",
 
20674      struct utsname 
name;
 
20682                  ",%s\"os\" : \"%s %s (%s) - %s\"",
 
20698                  ",%s\"features\" : %lu" 
20699                  ",%s\"feature_list\" : \"Server:%s%s%s%s%s%s%s%s%s\"",
 
20715#if defined(USE_LUA) 
20720                  ",%s\"lua_version\" : \"%u (%s)\"",
 
20722                  (
unsigned)LUA_VERSION_NUM,
 
20726#if defined(USE_DUKTAPE) 
20731                  ",%s\"javascript\" : \"Duktape %u.%u.%u\"",
 
20733                  (
unsigned)DUK_VERSION / 10000,
 
20734                  ((
unsigned)DUK_VERSION / 100) % 100,
 
20735                  (
unsigned)DUK_VERSION % 100);
 
20742#if defined(BUILD_DATE) 
20743      const char *bd = BUILD_DATE;
 
20745#if defined(GCC_DIAGNOSTIC) 
20746#if GCC_VERSION >= 40900 
20747#pragma GCC diagnostic push 
20751#pragma GCC diagnostic ignored "-Wdate-time" 
20754      const char *bd = __DATE__;
 
20755#if defined(GCC_DIAGNOSTIC) 
20756#if GCC_VERSION >= 40900 
20757#pragma GCC diagnostic pop 
20763          NULL, NULL, block, 
sizeof(block), 
",%s\"build\" : \"%s\"", eol, bd);
 
20772#if defined(_MSC_VER) 
20777                  ",%s\"compiler\" : \"MSC: %u (%u)\"",
 
20779                  (
unsigned)_MSC_VER,
 
20780                  (
unsigned)_MSC_FULL_VER);
 
20782#elif defined(__MINGW64__) 
20787                  ",%s\"compiler\" : \"MinGW64: %u.%u\"",
 
20789                  (
unsigned)__MINGW64_VERSION_MAJOR,
 
20790                  (
unsigned)__MINGW64_VERSION_MINOR);
 
20796                  ",%s\"compiler\" : \"MinGW32: %u.%u\"",
 
20798                  (
unsigned)__MINGW32_MAJOR_VERSION,
 
20799                  (
unsigned)__MINGW32_MINOR_VERSION);
 
20801#elif defined(__MINGW32__) 
20806                  ",%s\"compiler\" : \"MinGW32: %u.%u\"",
 
20808                  (
unsigned)__MINGW32_MAJOR_VERSION,
 
20809                  (
unsigned)__MINGW32_MINOR_VERSION);
 
20811#elif defined(__clang__) 
20816                  ",%s\"compiler\" : \"clang: %u.%u.%u (%s)\"",
 
20820                  __clang_patchlevel__,
 
20821                  __clang_version__);
 
20823#elif defined(__GNUC__) 
20828                  ",%s\"compiler\" : \"gcc: %u.%u.%u\"",
 
20830                  (
unsigned)__GNUC__,
 
20831                  (
unsigned)__GNUC_MINOR__,
 
20832                  (
unsigned)__GNUC_PATCHLEVEL__);
 
20834#elif defined(__INTEL_COMPILER) 
20839                  ",%s\"compiler\" : \"Intel C/C++: %u\"",
 
20841                  (
unsigned)__INTEL_COMPILER);
 
20843#elif defined(__BORLANDC__) 
20848                  ",%s\"compiler\" : \"Borland C: 0x%x\"",
 
20850                  (
unsigned)__BORLANDC__);
 
20852#elif defined(__SUNPRO_C) 
20857                  ",%s\"compiler\" : \"Solaris: 0x%x\"",
 
20859                  (
unsigned)__SUNPRO_C);
 
20866                  ",%s\"compiler\" : \"other\"",
 
20879                  ",%s\"data_model\" : \"int:%u/%u/%u/%u, float:%u/%u/%u, " 
20881                  "ptr:%u, size:%u, time:%u\"",
 
20883                  (
unsigned)
sizeof(
short),
 
20884                  (
unsigned)
sizeof(
int),
 
20885                  (
unsigned)
sizeof(
long),
 
20886                  (
unsigned)
sizeof(
long long),
 
20887                  (
unsigned)
sizeof(
float),
 
20888                  (
unsigned)
sizeof(
double),
 
20889                  (
unsigned)
sizeof(
long double),
 
20890                  (
unsigned)
sizeof(
char),
 
20891                  (
unsigned)
sizeof(
wchar_t),
 
20892                  (
unsigned)
sizeof(
void *),
 
20893                  (
unsigned)
sizeof(
size_t),
 
20894                  (
unsigned)
sizeof(time_t));
 
20899   if (append_eoobj) {
 
20900      strcat(append_eoobj, eoobj);
 
20902   system_info_length += 
sizeof(eoobj) - 1;
 
20904   return (
int)system_info_length;
 
20913#if defined(USE_SERVER_STATS) 
20914   char *end, *append_eoobj = NULL, block[256];
 
20915   size_t context_info_length = 0;
 
20918   static const char eol[] = 
"\r\n", eoobj[] = 
"\r\n}\r\n";
 
20920   static const char eol[] = 
"\n", eoobj[] = 
"\n}\n";
 
20922   struct mg_memory_stat *ms = get_memory_stat((
struct mg_context *)ctx);
 
20924   if ((buffer == NULL) || (buflen < 1)) {
 
20929      end = buffer + buflen;
 
20931   if (buflen > (
int)(
sizeof(eoobj) - 1)) {
 
20933      append_eoobj = buffer;
 
20934      end -= 
sizeof(eoobj) - 1;
 
20941      int blockCount = (
int)ms->blockCount;
 
20942      int64_t totalMemUsed = ms->totalMemUsed;
 
20943      int64_t maxMemUsed = ms->maxMemUsed;
 
20944      if (totalMemUsed > maxMemUsed) {
 
20945         maxMemUsed = totalMemUsed;
 
20952                  "%s\"memory\" : {%s" 
20953                  "\"blocks\" : %i,%s" 
20971      char start_time_str[64] = {0};
 
20972      char now_str[64] = {0};
 
20974      time_t now = time(NULL);
 
20975      int64_t total_data_read, total_data_written;
 
20976      int active_connections = (
int)ctx->active_connections;
 
20977      int max_active_connections = (
int)ctx->max_active_connections;
 
20978      int total_connections = (
int)ctx->total_connections;
 
20979      if (active_connections > max_active_connections) {
 
20980         max_active_connections = active_connections;
 
20982      if (active_connections > total_connections) {
 
20983         total_connections = active_connections;
 
20991                  ",%s\"connections\" : {%s" 
20992                  "\"active\" : %i,%s" 
20993                  "\"maxActive\" : %i,%s" 
20998                  active_connections,
 
21000                  max_active_connections,
 
21007#if !defined(ALTERNATIVE_QUEUE) 
21012                  ",%s\"queue\" : {%s" 
21013                  "\"length\" : %i,%s" 
21014                  "\"filled\" : %i,%s" 
21015                  "\"maxFilled\" : %i,%s" 
21036                  ",%s\"requests\" : {%s" 
21037                  "\"total\" : %lu%s" 
21041                  (
unsigned long)ctx->total_requests,
 
21047          mg_atomic_add64((
volatile int64_t *)&ctx->total_data_read, 0);
 
21048      total_data_written =
 
21049          mg_atomic_add64((
volatile int64_t *)&ctx->total_data_written, 0);
 
21054                  ",%s\"data\" : {%s" 
21062                  total_data_written,
 
21068                      sizeof(start_time_str) - 1,
 
21076                  ",%s\"time\" : {%s" 
21077                  "\"uptime\" : %.0f,%s" 
21078                  "\"start\" : \"%s\",%s" 
21079                  "\"now\" : \"%s\"%s" 
21083                  difftime(now, start_time),
 
21093   if (append_eoobj) {
 
21094      strcat(append_eoobj, eoobj);
 
21096   context_info_length += 
sizeof(eoobj) - 1;
 
21098   return (
int)context_info_length;
 
21101   if ((buffer != NULL) && (buflen > 0)) {
 
21113   if (conn != NULL) {
 
21119#if defined(MG_EXPERIMENTAL_INTERFACES) 
21123mg_get_connection_info(
const struct mg_context *ctx,
 
21130   char *
end, *append_eoobj = NULL, block[256];
 
21131   size_t connection_info_length = 0;
 
21133   const char *state_str = 
"unknown";
 
21136   static const char eol[] = 
"\r\n", eoobj[] = 
"\r\n}\r\n";
 
21138   static const char eol[] = 
"\n", eoobj[] = 
"\n}\n";
 
21141   if ((buffer == NULL) || (buflen < 1)) {
 
21146      end = buffer + buflen;
 
21148   if (buflen > (
int)(
sizeof(eoobj) - 1)) {
 
21150      append_eoobj = buffer;
 
21151      end -= 
sizeof(eoobj) - 1;
 
21154   if ((ctx == NULL) || (idx < 0)) {
 
21169   connection_info_length += 
mg_str_append(&buffer, end, 
"{");
 
21174#if defined(USE_SERVER_STATS) 
21175   state = conn->conn_state;
 
21180      state_str = 
"undefined";
 
21183      state_str = 
"not used";
 
21186      state_str = 
"init";
 
21189      state_str = 
"ready";
 
21192      state_str = 
"processing";
 
21195      state_str = 
"processed";
 
21198      state_str = 
"to close";
 
21201      state_str = 
"closing";
 
21204      state_str = 
"closed";
 
21207      state_str = 
"done";
 
21213   if ((state >= 3) && (state < 9)) {
 
21218                  "%s\"connection\" : {%s" 
21220                  "\"protocol\" : \"%s\",%s" 
21221                  "\"addr\" : \"%s\",%s" 
21224                  "\"handled_requests\" : %u%s" 
21238      connection_info_length += 
mg_str_append(&buffer, end, block);
 
21242   if ((state >= 4) && (state < 6)) {
 
21247                  "%s%s\"request_info\" : {%s" 
21248                  "\"method\" : \"%s\",%s" 
21249                  "\"uri\" : \"%s\",%s" 
21250                  "\"query\" : %s%s%s%s" 
21252                  (connection_info_length > 1 ? 
"," : 
""),
 
21263      connection_info_length += 
mg_str_append(&buffer, end, block);
 
21267   if ((state >= 2) && (state < 9)) {
 
21268      char start_time_str[64] = {0};
 
21269      char close_time_str[64] = {0};
 
21271      time_t close_time = 0;
 
21275                      sizeof(start_time_str) - 1,
 
21277#if defined(USE_SERVER_STATS) 
21278      close_time = conn->conn_close_time;
 
21280      if (close_time != 0) {
 
21281         time_diff = difftime(close_time, start_time);
 
21283                         sizeof(close_time_str) - 1,
 
21286         time_t now = time(NULL);
 
21287         time_diff = difftime(now, start_time);
 
21288         close_time_str[0] = 0; 
 
21295                  "%s%s\"time\" : {%s" 
21296                  "\"uptime\" : %.0f,%s" 
21297                  "\"start\" : \"%s\",%s" 
21298                  "\"closed\" : \"%s\"%s" 
21300                  (connection_info_length > 1 ? 
"," : 
""),
 
21309      connection_info_length += 
mg_str_append(&buffer, end, block);
 
21318                  "%s%s\"user\" : {%s" 
21319                  "\"name\" : \"%s\",%s" 
21321                  (connection_info_length > 1 ? 
"," : 
""),
 
21326      connection_info_length += 
mg_str_append(&buffer, end, block);
 
21335                  "%s%s\"data\" : {%s" 
21339                  (connection_info_length > 1 ? 
"," : 
""),
 
21342                  conn->consumed_content,
 
21344                  conn->num_bytes_sent,
 
21346      connection_info_length += 
mg_str_append(&buffer, end, block);
 
21354               "%s%s\"state\" : \"%s\"",
 
21355               (connection_info_length > 1 ? 
"," : 
""),
 
21358   connection_info_length += 
mg_str_append(&buffer, end, block);
 
21361   if (append_eoobj) {
 
21362      strcat(append_eoobj, eoobj);
 
21364   connection_info_length += 
sizeof(eoobj) - 1;
 
21366   return (
int)connection_info_length;
 
21377   unsigned features_inited = features_to_init;
 
21390      int file_mutex_init = 1;
 
21393      int mutexattr_init = 1;
 
21398      if (key_create == 0) {
 
21402         if (file_mutex_init == 0) {
 
21405            failed = wsa = WSAStartup(MAKEWORD(2, 2), &
data);
 
21409         if (mutexattr_init == 0) {
 
21411                                               PTHREAD_MUTEX_RECURSIVE);
 
21420            (void)WSACleanup();
 
21422         if (file_mutex_init == 0) {
 
21423            (void)pthread_mutex_destroy(&global_log_file_lock);
 
21426         if (mutexattr_init == 0) {
 
21430         if (key_create == 0) {
 
21431            (void)pthread_key_delete(
sTlsKey);
 
21438#if defined(USE_LUA) 
21439      lua_init_optional_libraries();
 
21445#if (defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1)                      \ 
21446     || defined(OPENSSL_API_3_0))                                              \ 
21447    && !defined(NO_SSL) 
21449      if (!mg_openssl_initialized) {
 
21452            mg_openssl_initialized = 1;
 
21455            DEBUG_TRACE(
"Initializing SSL failed: %s", ebuf);
 
21472   return features_inited;
 
21488#if (defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1)) && !defined(NO_SSL) 
21489      if (mg_openssl_initialized) {
 
21491         mg_openssl_initialized = 0;
 
21496      (void)WSACleanup();
 
21497      (void)pthread_mutex_destroy(&global_log_file_lock);
 
21502      (void)pthread_key_delete(
sTlsKey);
 
21504#if defined(USE_LUA) 
21505      lua_exit_optional_libraries();
 
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
 
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 consume_socket(struct mg_context *ctx, struct socket *sp, int thread_index)
 
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 int modify_passwords_file(const char *fname, const char *domain, const char *user, const char *pass, const char *ha1)
 
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 mkcol(struct mg_connection *conn, const char *path)
 
static void remove_bad_file(const struct mg_connection *conn, const char *path)
 
const struct mg_option * mg_get_valid_options(void)
 
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
 
@ PROTOCOL_TYPE_WEBSOCKET
 
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)
 
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,...)
 
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 void handle_cgi_request(struct mg_connection *conn, const char *prog, unsigned char cgi_config_idx)
 
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)
 
void mg_disable_connection_keep_alive(struct mg_connection *conn)
 
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 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 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)
 
void mg_send_file(struct mg_connection *conn, const char *path)
 
static void send_authorization_request(struct mg_connection *conn, const char *realm)
 
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, unsigned char cgi_config_idx)
 
static int check_password(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 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)
 
#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 int prepare_cgi_environment(struct mg_connection *conn, const char *prog, struct cgi_environment *env, unsigned char cgi_config_idx)
 
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 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)
 
static struct mg_connection * mg_connect_client_impl(const struct mg_client_options *client_options, int use_ssl, char *ebuf, size_t ebuf_len)
 
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)
 
static int connect_socket(struct mg_context *ctx, const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len, SOCKET *sock, union usa *sa)
 
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 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 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)
 
#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 ptrdiff_t match_prefix_strlen(const char *pattern, const char *str)
 
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)
 
static const struct @143 abs_uri_protocols[]
 
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)
 
static void send_file_data(struct mg_connection *conn, struct mg_file *filep, int64_t offset, int64_t len)
 
#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)
 
static int parse_auth_header(struct mg_connection *conn, char *buf, size_t buf_size, struct ah *ah)
 
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 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_template_text)
 
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 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)
 
static int print_dir_entry(struct de *de)
 
#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 ptrdiff_t match_prefix(const char *pattern, size_t pattern_len, const char *str)
 
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 const struct @142 builtin_mime_types[]
 
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 refresh_trust(struct mg_connection *conn)
 
void * mg_get_thread_pointer(const struct mg_connection *conn)
 
static int compare_dir_entries(const void *p1, const void *p2)
 
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)
 
char static_assert_replacement[1]
 
#define ERROR_TRY_AGAIN(err)
 
static unsigned long mg_current_thread_id(void)
 
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 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 __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)
 
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)
 
@ CONNECTION_TYPE_RESPONSE
 
@ CONNECTION_TYPE_INVALID
 
@ CONNECTION_TYPE_REQUEST
 
#define PASSWORDS_FILE_NAME
 
static void close_connection(struct mg_connection *conn)
 
@ ENABLE_DIRECTORY_LISTING
 
@ ACCESS_CONTROL_ALLOW_ORIGIN
 
@ 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 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 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)
 
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_CONFIG_TYPE_DIRECTORY
 
@ MG_CONFIG_TYPE_EXT_PATTERN
 
@ MG_CONFIG_TYPE_STRING_MULTILINE
 
@ MG_CONFIG_TYPE_STRING_LIST
 
@ MG_CONFIG_TYPE_YES_NO_OPTIONAL
 
@ MG_FEATURES_X_DOMAIN_SOCKET
 
@ MG_FEATURES_COMPRESSION
 
@ 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)
 
#define PRINTF_ARGS(x, y)
 
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 *)
 
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)
 
void(off) SmallVectorTemplateBase< T
 
void init()
Inspect hardware capabilities, and load the optimal library for RooFit computations.
 
RooArgList L(Args_t &&... args)
 
double min(double x, double y)
 
struct asn1_integer ASN1_INTEGER
 
#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
 
struct x509_name X509_NAME
 
#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)
 
struct mg_connection * conn
 
struct mg_connection * conn
 
int(* init_ssl)(void *ssl_ctx, void *user_data)
 
int(* log_message)(const struct mg_connection *, const char *message)
 
void *(* init_thread)(const struct mg_context *ctx, int thread_type)
 
void(* end_request)(const struct mg_connection *, int reply_status_code)
 
int(* init_connection)(const struct mg_connection *conn, void **conn_data)
 
void(* connection_close)(const struct mg_connection *)
 
int(* http_error)(struct mg_connection *conn, int status, const char *errmsg)
 
void(* exit_context)(const struct mg_context *ctx)
 
int(* init_ssl_domain)(const char *server_domain, void *ssl_ctx, void *user_data)
 
int(* external_ssl_ctx)(void **ssl_ctx, void *user_data)
 
void(* exit_thread)(const struct mg_context *ctx, int thread_type, void *thread_pointer)
 
int(* begin_request)(struct mg_connection *)
 
int(* log_access)(const struct mg_connection *, const char *message)
 
void(* init_context)(const struct mg_context *ctx)
 
void(* connection_closed)(const struct mg_connection *)
 
int(* external_ssl_ctx_domain)(const char *server_domain, void **ssl_ctx, void *user_data)
 
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
 
pthread_t * worker_threadids
 
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
 
unsigned int num_listening_sockets
 
unsigned int max_request_size
 
unsigned int cfg_worker_threads
 
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 * default_value
 
struct mg_header http_headers[(64)]
 
const char * local_uri_raw
 
const char * request_method
 
struct mg_client_cert * client_cert
 
const char * query_string
 
const char * http_version
 
const char * acceptedWebSocketSubprotocol
 
struct mg_header http_headers[(64)]
 
const char * http_version
 
const char ** subprotocols
 
struct mg_connection * conn
 
enum ssl_func_category required
 
mg_websocket_close_handler close_handler
 
mg_websocket_data_handler data_handler
 
struct mg_connection * conn