Logo ROOT   master
Reference Guide
civetweb.c
Go to the documentation of this file.
1 /* Copyright (c) 2013-2018 the Civetweb developers
2  * Copyright (c) 2004-2013 Sergey Lyubka
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #if defined(__GNUC__) || defined(__MINGW32__)
24 #define GCC_VERSION \
25  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
26 #if GCC_VERSION >= 40500
27 /* gcc diagnostic pragmas available */
28 #define GCC_DIAGNOSTIC
29 #endif
30 #endif
31 
32 #if defined(GCC_DIAGNOSTIC)
33 /* Disable unused macros warnings - not all defines are required
34  * for all systems and all compilers. */
35 #pragma GCC diagnostic ignored "-Wunused-macros"
36 /* A padding warning is just plain useless */
37 #pragma GCC diagnostic ignored "-Wpadded"
38 #endif
39 
40 #if defined(__clang__) /* GCC does not (yet) support this pragma */
41 /* We must set some flags for the headers we include. These flags
42  * are reserved ids according to C99, so we need to disable a
43  * warning for that. */
44 #pragma GCC diagnostic push
45 #pragma GCC diagnostic ignored "-Wreserved-id-macro"
46 #endif
47 
48 #if defined(_WIN32)
49 #if !defined(_CRT_SECURE_NO_WARNINGS)
50 #define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */
51 #endif
52 #if !defined(_WIN32_WINNT) /* defined for tdm-gcc so we can use getnameinfo */
53 #define _WIN32_WINNT 0x0501
54 #endif
55 #else
56 #if !defined(_GNU_SOURCE)
57 #define _GNU_SOURCE /* for setgroups(), pthread_setname_np() */
58 #endif
59 #if defined(__linux__) && !defined(_XOPEN_SOURCE)
60 #define _XOPEN_SOURCE 600 /* For flockfile() on Linux */
61 #endif
62 #if !defined(_LARGEFILE_SOURCE)
63 #define _LARGEFILE_SOURCE /* For fseeko(), ftello() */
64 #endif
65 #if !defined(_FILE_OFFSET_BITS)
66 #define _FILE_OFFSET_BITS 64 /* Use 64-bit file offsets by default */
67 #endif
68 #if !defined(__STDC_FORMAT_MACROS)
69 #define __STDC_FORMAT_MACROS /* <inttypes.h> wants this for C++ */
70 #endif
71 #if !defined(__STDC_LIMIT_MACROS)
72 #define __STDC_LIMIT_MACROS /* C++ wants that for INT64_MAX */
73 #endif
74 #if !defined(_DARWIN_UNLIMITED_SELECT)
75 #define _DARWIN_UNLIMITED_SELECT
76 #endif
77 #if defined(__sun)
78 #define __EXTENSIONS__ /* to expose flockfile and friends in stdio.h */
79 #define __inline inline /* not recognized on older compiler versions */
80 #endif
81 #endif
82 
83 #if defined(__clang__)
84 /* Enable reserved-id-macro warning again. */
85 #pragma GCC diagnostic pop
86 #endif
87 
88 
89 #if defined(USE_LUA)
90 #define USE_TIMERS
91 #endif
92 
93 #if defined(_MSC_VER)
94 /* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */
95 #pragma warning(disable : 4306)
96 /* conditional expression is constant: introduced by FD_SET(..) */
97 #pragma warning(disable : 4127)
98 /* non-constant aggregate initializer: issued due to missing C99 support */
99 #pragma warning(disable : 4204)
100 /* padding added after data member */
101 #pragma warning(disable : 4820)
102 /* not defined as a preprocessor macro, replacing with '0' for '#if/#elif' */
103 #pragma warning(disable : 4668)
104 /* no function prototype given: converting '()' to '(void)' */
105 #pragma warning(disable : 4255)
106 /* function has been selected for automatic inline expansion */
107 #pragma warning(disable : 4711)
108 #endif
109 
110 
111 /* This code uses static_assert to check some conditions.
112  * Unfortunately some compilers still do not support it, so we have a
113  * replacement function here. */
114 #if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201100L
115 #define mg_static_assert _Static_assert
116 #elif defined(__cplusplus) && __cplusplus >= 201103L
117 #define mg_static_assert static_assert
118 #else
120 #define mg_static_assert(cond, txt) \
121  extern char static_assert_replacement[(cond) ? 1 : -1]
122 #endif
123 
124 mg_static_assert(sizeof(int) == 4 || sizeof(int) == 8,
125  "int data type size check");
126 mg_static_assert(sizeof(void *) == 4 || sizeof(void *) == 8,
127  "pointer data type size check");
128 mg_static_assert(sizeof(void *) >= sizeof(int), "data type size check");
129 
130 
131 /* Alternative queue is well tested and should be the new default */
132 #if defined(NO_ALTERNATIVE_QUEUE)
133 #if defined(ALTERNATIVE_QUEUE)
134 #error "Define ALTERNATIVE_QUEUE or NO_ALTERNATIVE_QUEUE or none, but not both"
135 #endif
136 #else
137 #define ALTERNATIVE_QUEUE
138 #endif
139 
140 
141 /* DTL -- including winsock2.h works better if lean and mean */
142 #if !defined(WIN32_LEAN_AND_MEAN)
143 #define WIN32_LEAN_AND_MEAN
144 #endif
145 
146 #if defined(__SYMBIAN32__)
147 /* According to https://en.wikipedia.org/wiki/Symbian#History,
148  * Symbian is no longer maintained since 2014-01-01.
149  * Recent versions of CivetWeb are no longer tested for Symbian.
150  * It makes no sense, to support an abandoned operating system.
151  */
152 #error "Symbian is no longer maintained. CivetWeb no longer supports Symbian."
153 #define NO_SSL /* SSL is not supported */
154 #define NO_CGI /* CGI is not supported */
155 #define PATH_MAX FILENAME_MAX
156 #endif /* __SYMBIAN32__ */
157 
158 
159 #if !defined(CIVETWEB_HEADER_INCLUDED)
160 /* Include the header file here, so the CivetWeb interface is defined for the
161  * entire implementation, including the following forward definitions. */
162 #include "civetweb.h"
163 #endif
164 
165 #if !defined(DEBUG_TRACE)
166 #if defined(DEBUG)
167 static void DEBUG_TRACE_FUNC(const char *func,
168  unsigned line,
169  PRINTF_FORMAT_STRING(const char *fmt),
170  ...) PRINTF_ARGS(3, 4);
171 
172 #define DEBUG_TRACE(fmt, ...) \
173  DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
174 
175 #define NEED_DEBUG_TRACE_FUNC
176 
177 #else
178 #define DEBUG_TRACE(fmt, ...) \
179  do { \
180  } while (0)
181 #endif /* DEBUG */
182 #endif /* DEBUG_TRACE */
183 
184 
185 #if !defined(DEBUG_ASSERT)
186 #if defined(DEBUG)
187 #define DEBUG_ASSERT(cond) \
188  do { \
189  if (!(cond)) { \
190  DEBUG_TRACE("ASSERTION FAILED: %s", #cond); \
191  exit(2); /* Exit with error */ \
192  } \
193  } while (0)
194 #else
195 #define DEBUG_ASSERT(cond)
196 #endif /* DEBUG */
197 #endif
198 
199 
200 #if defined(__GNUC__) && defined(GCC_INSTRUMENTATION)
201 void __cyg_profile_func_enter(void *this_fn, void *call_site)
202  __attribute__((no_instrument_function));
203 
204 void __cyg_profile_func_exit(void *this_fn, void *call_site)
205  __attribute__((no_instrument_function));
206 
207 void
208 __cyg_profile_func_enter(void *this_fn, void *call_site)
209 {
210  if ((void *)this_fn != (void *)printf) {
211  printf("E %p %p\n", this_fn, call_site);
212  }
213 }
214 
215 void
216 __cyg_profile_func_exit(void *this_fn, void *call_site)
217 {
218  if ((void *)this_fn != (void *)printf) {
219  printf("X %p %p\n", this_fn, call_site);
220  }
221 }
222 #endif
223 
224 
225 #if !defined(IGNORE_UNUSED_RESULT)
226 #define IGNORE_UNUSED_RESULT(a) ((void)((a) && 1))
227 #endif
228 
229 
230 #if defined(__GNUC__) || defined(__MINGW32__)
231 
232 /* GCC unused function attribute seems fundamentally broken.
233  * Several attempts to tell the compiler "THIS FUNCTION MAY BE USED
234  * OR UNUSED" for individual functions failed.
235  * Either the compiler creates an "unused-function" warning if a
236  * function is not marked with __attribute__((unused)).
237  * On the other hand, if the function is marked with this attribute,
238  * but is used, the compiler raises a completely idiotic
239  * "used-but-marked-unused" warning - and
240  * #pragma GCC diagnostic ignored "-Wused-but-marked-unused"
241  * raises error: unknown option after "#pragma GCC diagnostic".
242  * Disable this warning completely, until the GCC guys sober up
243  * again.
244  */
245 
246 #pragma GCC diagnostic ignored "-Wunused-function"
247 
248 #define FUNCTION_MAY_BE_UNUSED /* __attribute__((unused)) */
249 
250 #else
251 #define FUNCTION_MAY_BE_UNUSED
252 #endif
253 
254 
255 /* Some ANSI #includes are not available on Windows CE */
256 #if !defined(_WIN32_WCE)
257 #include <errno.h>
258 #include <fcntl.h>
259 #include <signal.h>
260 #include <sys/stat.h>
261 #include <sys/types.h>
262 #endif /* !_WIN32_WCE */
263 
264 
265 #if defined(__clang__)
266 /* When using -Weverything, clang does not accept it's own headers
267  * in a release build configuration. Disable what is too much in
268  * -Weverything. */
269 #pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
270 #endif
271 
272 #if defined(__GNUC__) || defined(__MINGW32__)
273 /* Who on earth came to the conclusion, using __DATE__ should rise
274  * an "expansion of date or time macro is not reproducible"
275  * warning. That's exactly what was intended by using this macro.
276  * Just disable this nonsense warning. */
277 
278 /* And disabling them does not work either:
279  * #pragma clang diagnostic ignored "-Wno-error=date-time"
280  * #pragma clang diagnostic ignored "-Wdate-time"
281  * So we just have to disable ALL warnings for some lines
282  * of code.
283  * This seems to be a known GCC bug, not resolved since 2012:
284  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431
285  */
286 #endif
287 
288 
289 #if defined(__MACH__) /* Apple OSX section */
290 
291 #if defined(__clang__)
292 #if (__clang_major__ == 3) && ((__clang_minor__ == 7) || (__clang_minor__ == 8))
293 /* Avoid warnings for Xcode 7. It seems it does no longer exist in Xcode 8 */
294 #pragma clang diagnostic ignored "-Wno-reserved-id-macro"
295 #pragma clang diagnostic ignored "-Wno-keyword-macro"
296 #endif
297 #endif
298 
299 #define CLOCK_MONOTONIC (1)
300 #define CLOCK_REALTIME (2)
301 
302 #include <mach/clock.h>
303 #include <mach/mach.h>
304 #include <mach/mach_time.h>
305 #include <sys/errno.h>
306 #include <sys/time.h>
307 
308 /* clock_gettime is not implemented on OSX prior to 10.12 */
309 static int
310 _civet_clock_gettime(int clk_id, struct timespec *t)
311 {
312  memset(t, 0, sizeof(*t));
313  if (clk_id == CLOCK_REALTIME) {
314  struct timeval now;
315  int rv = gettimeofday(&now, NULL);
316  if (rv) {
317  return rv;
318  }
319  t->tv_sec = now.tv_sec;
320  t->tv_nsec = now.tv_usec * 1000;
321  return 0;
322 
323  } else if (clk_id == CLOCK_MONOTONIC) {
324  static uint64_t clock_start_time = 0;
325  static mach_timebase_info_data_t timebase_ifo = {0, 0};
326 
327  uint64_t now = mach_absolute_time();
328 
329  if (clock_start_time == 0) {
330  kern_return_t mach_status = mach_timebase_info(&timebase_ifo);
331  DEBUG_ASSERT(mach_status == KERN_SUCCESS);
332 
333  /* appease "unused variable" warning for release builds */
334  (void)mach_status;
335 
336  clock_start_time = now;
337  }
338 
339  now = (uint64_t)((double)(now - clock_start_time)
340  * (double)timebase_ifo.numer
341  / (double)timebase_ifo.denom);
342 
343  t->tv_sec = now / 1000000000;
344  t->tv_nsec = now % 1000000000;
345  return 0;
346  }
347  return -1; /* EINVAL - Clock ID is unknown */
348 }
349 
350 /* if clock_gettime is declared, then __CLOCK_AVAILABILITY will be defined */
351 #if defined(__CLOCK_AVAILABILITY)
352 /* If we compiled with Mac OSX 10.12 or later, then clock_gettime will be
353  * declared but it may be NULL at runtime. So we need to check before using
354  * it. */
355 static int
356 _civet_safe_clock_gettime(int clk_id, struct timespec *t)
357 {
358  if (clock_gettime) {
359  return clock_gettime(clk_id, t);
360  }
361  return _civet_clock_gettime(clk_id, t);
362 }
363 #define clock_gettime _civet_safe_clock_gettime
364 #else
365 #define clock_gettime _civet_clock_gettime
366 #endif
367 
368 #endif
369 
370 
371 #include <ctype.h>
372 #include <limits.h>
373 #include <stdarg.h>
374 #include <stddef.h>
375 #include <stdint.h>
376 #include <stdio.h>
377 #include <stdlib.h>
378 #include <string.h>
379 #include <time.h>
380 
381 /********************************************************************/
382 /* CivetWeb configuration defines */
383 /********************************************************************/
384 
385 /* Maximum number of threads that can be configured.
386  * The number of threads actually created depends on the "num_threads"
387  * configuration parameter, but this is the upper limit. */
388 #if !defined(MAX_WORKER_THREADS)
389 #define MAX_WORKER_THREADS (1024 * 64) /* in threads (count) */
390 #endif
391 
392 /* Timeout interval for select/poll calls.
393  * The timeouts depend on "*_timeout_ms" configuration values, but long
394  * timeouts are split into timouts as small as SOCKET_TIMEOUT_QUANTUM.
395  * This reduces the time required to stop the server. */
396 #if !defined(SOCKET_TIMEOUT_QUANTUM)
397 #define SOCKET_TIMEOUT_QUANTUM (2000) /* in ms */
398 #endif
399 
400 /* Do not try to compress files smaller than this limit. */
401 #if !defined(MG_FILE_COMPRESSION_SIZE_LIMIT)
402 #define MG_FILE_COMPRESSION_SIZE_LIMIT (1024) /* in bytes */
403 #endif
404 
405 #if !defined(PASSWORDS_FILE_NAME)
406 #define PASSWORDS_FILE_NAME ".htpasswd"
407 #endif
408 
409 /* Initial buffer size for all CGI environment variables. In case there is
410  * not enough space, another block is allocated. */
411 #if !defined(CGI_ENVIRONMENT_SIZE)
412 #define CGI_ENVIRONMENT_SIZE (4096) /* in bytes */
413 #endif
414 
415 /* Maximum number of environment variables. */
416 #if !defined(MAX_CGI_ENVIR_VARS)
417 #define MAX_CGI_ENVIR_VARS (256) /* in variables (count) */
418 #endif
419 
420 /* General purpose buffer size. */
421 #if !defined(MG_BUF_LEN) /* in bytes */
422 #define MG_BUF_LEN (1024 * 8)
423 #endif
424 
425 /* Size of the accepted socket queue (in case the old queue implementation
426  * is used). */
427 #if !defined(MGSQLEN)
428 #define MGSQLEN (20) /* count */
429 #endif
430 
431 
432 /********************************************************************/
433 
434 /* Helper makros */
435 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
436 
437 /* Standard defines */
438 #if !defined(INT64_MAX)
439 #define INT64_MAX (9223372036854775807)
440 #endif
441 
442 #define SHUTDOWN_RD (0)
443 #define SHUTDOWN_WR (1)
444 #define SHUTDOWN_BOTH (2)
445 
447  "worker threads must be a positive number");
448 
449 mg_static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8,
450  "size_t data type size check");
451 
452 #if defined(_WIN32) /* WINDOWS include block */
453 #include <windows.h>
454 #include <winsock2.h> /* DTL add for SO_EXCLUSIVE */
455 #include <ws2tcpip.h>
456 
457 typedef const char *SOCK_OPT_TYPE;
458 
459 #if !defined(PATH_MAX)
460 #define W_PATH_MAX (MAX_PATH)
461 /* at most three UTF-8 chars per wchar_t */
462 #define PATH_MAX (W_PATH_MAX * 3)
463 #else
464 #define W_PATH_MAX ((PATH_MAX + 2) / 3)
465 #endif
466 
467 mg_static_assert(PATH_MAX >= 1, "path length must be a positive number");
468 
469 #if !defined(_IN_PORT_T)
470 #if !defined(in_port_t)
471 #define in_port_t u_short
472 #endif
473 #endif
474 
475 #if !defined(_WIN32_WCE)
476 #include <direct.h>
477 #include <io.h>
478 #include <process.h>
479 #else /* _WIN32_WCE */
480 #define NO_CGI /* WinCE has no pipes */
481 #define NO_POPEN /* WinCE has no popen */
482 
483 typedef long off_t;
484 
485 #define errno ((int)(GetLastError()))
486 #define strerror(x) (_ultoa(x, (char *)_alloca(sizeof(x) * 3), 10))
487 #endif /* _WIN32_WCE */
488 
489 #define MAKEUQUAD(lo, hi) \
490  ((uint64_t)(((uint32_t)(lo)) | ((uint64_t)((uint32_t)(hi))) << 32))
491 #define RATE_DIFF (10000000) /* 100 nsecs */
492 #define EPOCH_DIFF (MAKEUQUAD(0xd53e8000, 0x019db1de))
493 #define SYS2UNIX_TIME(lo, hi) \
494  ((time_t)((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF))
495 
496 /* Visual Studio 6 does not know __func__ or __FUNCTION__
497  * The rest of MS compilers use __FUNCTION__, not C99 __func__
498  * Also use _strtoui64 on modern M$ compilers */
499 #if defined(_MSC_VER)
500 #if (_MSC_VER < 1300)
501 #define STRX(x) #x
502 #define STR(x) STRX(x)
503 #define __func__ __FILE__ ":" STR(__LINE__)
504 #define strtoull(x, y, z) ((unsigned __int64)_atoi64(x))
505 #define strtoll(x, y, z) (_atoi64(x))
506 #else
507 #define __func__ __FUNCTION__
508 #define strtoull(x, y, z) (_strtoui64(x, y, z))
509 #define strtoll(x, y, z) (_strtoi64(x, y, z))
510 #endif
511 #endif /* _MSC_VER */
512 
513 #define ERRNO ((int)(GetLastError()))
514 #define NO_SOCKLEN_T
515 
516 #if defined(_WIN64) || defined(__MINGW64__)
517 #if !defined(SSL_LIB)
518 #define SSL_LIB "ssleay64.dll"
519 #endif
520 #if !defined(CRYPTO_LIB)
521 #define CRYPTO_LIB "libeay64.dll"
522 #endif
523 #else
524 #if !defined(SSL_LIB)
525 #define SSL_LIB "ssleay32.dll"
526 #endif
527 #if !defined(CRYPTO_LIB)
528 #define CRYPTO_LIB "libeay32.dll"
529 #endif
530 #endif
531 
532 #define O_NONBLOCK (0)
533 #if !defined(W_OK)
534 #define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */
535 #endif
536 #if !defined(EWOULDBLOCK)
537 #define EWOULDBLOCK WSAEWOULDBLOCK
538 #endif /* !EWOULDBLOCK */
539 #define _POSIX_
540 #define INT64_FMT "I64d"
541 #define UINT64_FMT "I64u"
542 
543 #define WINCDECL __cdecl
544 #define vsnprintf_impl _vsnprintf
545 #define access _access
546 #define mg_sleep(x) (Sleep(x))
547 
548 #define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
549 #if !defined(popen)
550 #define popen(x, y) (_popen(x, y))
551 #endif
552 #if !defined(pclose)
553 #define pclose(x) (_pclose(x))
554 #endif
555 #define close(x) (_close(x))
556 #define dlsym(x, y) (GetProcAddress((HINSTANCE)(x), (y)))
557 #define RTLD_LAZY (0)
558 #define fseeko(x, y, z) ((_lseeki64(_fileno(x), (y), (z)) == -1) ? -1 : 0)
559 #define fdopen(x, y) (_fdopen((x), (y)))
560 #define write(x, y, z) (_write((x), (y), (unsigned)z))
561 #define read(x, y, z) (_read((x), (y), (unsigned)z))
562 #define flockfile(x) (EnterCriticalSection(&global_log_file_lock))
563 #define funlockfile(x) (LeaveCriticalSection(&global_log_file_lock))
564 #define sleep(x) (Sleep((x)*1000))
565 #define rmdir(x) (_rmdir(x))
566 #if defined(_WIN64) || !defined(__MINGW32__)
567 /* Only MinGW 32 bit is missing this function */
568 #define timegm(x) (_mkgmtime(x))
569 #else
570 time_t timegm(struct tm *tm);
571 #define NEED_TIMEGM
572 #endif
573 
574 
575 #if !defined(fileno)
576 #define fileno(x) (_fileno(x))
577 #endif /* !fileno MINGW #defines fileno */
578 
579 typedef HANDLE pthread_mutex_t;
580 typedef DWORD pthread_key_t;
581 typedef HANDLE pthread_t;
582 typedef struct {
583  CRITICAL_SECTION threadIdSec;
584  struct mg_workerTLS *waiting_thread; /* The chain of threads */
586 
587 #if !defined(__clockid_t_defined)
588 typedef DWORD clockid_t;
589 #endif
590 #if !defined(CLOCK_MONOTONIC)
591 #define CLOCK_MONOTONIC (1)
592 #endif
593 #if !defined(CLOCK_REALTIME)
594 #define CLOCK_REALTIME (2)
595 #endif
596 #if !defined(CLOCK_THREAD)
597 #define CLOCK_THREAD (3)
598 #endif
599 #if !defined(CLOCK_PROCESS)
600 #define CLOCK_PROCESS (4)
601 #endif
602 
603 
604 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
605 #define _TIMESPEC_DEFINED
606 #endif
607 #if !defined(_TIMESPEC_DEFINED)
608 struct timespec {
609  time_t tv_sec; /* seconds */
610  long tv_nsec; /* nanoseconds */
611 };
612 #endif
613 
614 #if !defined(WIN_PTHREADS_TIME_H)
615 #define MUST_IMPLEMENT_CLOCK_GETTIME
616 #endif
617 
618 #if defined(MUST_IMPLEMENT_CLOCK_GETTIME)
619 #define clock_gettime mg_clock_gettime
620 static int
621 clock_gettime(clockid_t clk_id, struct timespec *tp)
622 {
623  FILETIME ft;
624  ULARGE_INTEGER li, li2;
625  BOOL ok = FALSE;
626  double d;
627  static double perfcnt_per_sec = 0.0;
628  static BOOL initialized = FALSE;
629 
630  if (!initialized) {
631  QueryPerformanceFrequency((LARGE_INTEGER *)&li);
632  perfcnt_per_sec = 1.0 / li.QuadPart;
633  initialized = TRUE;
634  }
635 
636  if (tp) {
637  memset(tp, 0, sizeof(*tp));
638 
639  if (clk_id == CLOCK_REALTIME) {
640 
641  /* BEGIN: CLOCK_REALTIME = wall clock (date and time) */
642  GetSystemTimeAsFileTime(&ft);
643  li.LowPart = ft.dwLowDateTime;
644  li.HighPart = ft.dwHighDateTime;
645  li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */
646  tp->tv_sec = (time_t)(li.QuadPart / 10000000);
647  tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
648  ok = TRUE;
649  /* END: CLOCK_REALTIME */
650 
651  } else if (clk_id == CLOCK_MONOTONIC) {
652 
653  /* BEGIN: CLOCK_MONOTONIC = stopwatch (time differences) */
654  QueryPerformanceCounter((LARGE_INTEGER *)&li);
655  d = li.QuadPart * perfcnt_per_sec;
656  tp->tv_sec = (time_t)d;
657  d -= (double)tp->tv_sec;
658  tp->tv_nsec = (long)(d * 1.0E9);
659  ok = TRUE;
660  /* END: CLOCK_MONOTONIC */
661 
662  } else if (clk_id == CLOCK_THREAD) {
663 
664  /* BEGIN: CLOCK_THREAD = CPU usage of thread */
665  FILETIME t_create, t_exit, t_kernel, t_user;
666  if (GetThreadTimes(GetCurrentThread(),
667  &t_create,
668  &t_exit,
669  &t_kernel,
670  &t_user)) {
671  li.LowPart = t_user.dwLowDateTime;
672  li.HighPart = t_user.dwHighDateTime;
673  li2.LowPart = t_kernel.dwLowDateTime;
674  li2.HighPart = t_kernel.dwHighDateTime;
675  li.QuadPart += li2.QuadPart;
676  tp->tv_sec = (time_t)(li.QuadPart / 10000000);
677  tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
678  ok = TRUE;
679  }
680  /* END: CLOCK_THREAD */
681 
682  } else if (clk_id == CLOCK_PROCESS) {
683 
684  /* BEGIN: CLOCK_PROCESS = CPU usage of process */
685  FILETIME t_create, t_exit, t_kernel, t_user;
686  if (GetProcessTimes(GetCurrentProcess(),
687  &t_create,
688  &t_exit,
689  &t_kernel,
690  &t_user)) {
691  li.LowPart = t_user.dwLowDateTime;
692  li.HighPart = t_user.dwHighDateTime;
693  li2.LowPart = t_kernel.dwLowDateTime;
694  li2.HighPart = t_kernel.dwHighDateTime;
695  li.QuadPart += li2.QuadPart;
696  tp->tv_sec = (time_t)(li.QuadPart / 10000000);
697  tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
698  ok = TRUE;
699  }
700  /* END: CLOCK_PROCESS */
701 
702  } else {
703 
704  /* BEGIN: unknown clock */
705  /* ok = FALSE; already set by init */
706  /* END: unknown clock */
707  }
708  }
709 
710  return ok ? 0 : -1;
711 }
712 #endif
713 
714 
715 #define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */
716 
717 static int pthread_mutex_lock(pthread_mutex_t *);
718 static int pthread_mutex_unlock(pthread_mutex_t *);
719 static void path_to_unicode(const struct mg_connection *conn,
720  const char *path,
721  wchar_t *wbuf,
722  size_t wbuf_len);
723 
724 /* All file operations need to be rewritten to solve #246. */
725 
726 struct mg_file;
727 
728 static const char *
729 mg_fgets(char *buf, size_t size, struct mg_file *filep, char **p);
730 
731 
732 /* POSIX dirent interface */
733 struct dirent {
734  char d_name[PATH_MAX];
735 };
736 
737 typedef struct DIR {
738  HANDLE handle;
739  WIN32_FIND_DATAW info;
740  struct dirent result;
741 } DIR;
742 
743 #if defined(_WIN32)
744 #if !defined(HAVE_POLL)
745 struct pollfd {
746  SOCKET fd;
747  short events;
748  short revents;
749 };
750 #endif
751 #endif
752 
753 /* Mark required libraries */
754 #if defined(_MSC_VER)
755 #pragma comment(lib, "Ws2_32.lib")
756 #endif
757 
758 #else /* defined(_WIN32) - WINDOWS vs UNIX include block */
759 
760 #include <arpa/inet.h>
761 #include <inttypes.h>
762 #include <netdb.h>
763 #include <netinet/in.h>
764 #include <netinet/tcp.h>
765 #include <stdint.h>
766 #include <sys/poll.h>
767 #include <sys/socket.h>
768 #include <sys/time.h>
769 #include <sys/utsname.h>
770 #include <sys/wait.h>
771 typedef const void *SOCK_OPT_TYPE;
772 
773 #if defined(ANDROID)
774 typedef unsigned short int in_port_t;
775 #endif
776 
777 #include <dirent.h>
778 #include <grp.h>
779 #include <pwd.h>
780 #include <unistd.h>
781 #define vsnprintf_impl vsnprintf
782 
783 #if !defined(NO_SSL_DL) && !defined(NO_SSL)
784 #include <dlfcn.h>
785 #endif
786 #include <pthread.h>
787 #if defined(__MACH__)
788 #define SSL_LIB "libssl.dylib"
789 #define CRYPTO_LIB "libcrypto.dylib"
790 #else
791 #if !defined(SSL_LIB)
792 #define SSL_LIB "libssl.so"
793 #endif
794 #if !defined(CRYPTO_LIB)
795 #define CRYPTO_LIB "libcrypto.so"
796 #endif
797 #endif
798 #if !defined(O_BINARY)
799 #define O_BINARY (0)
800 #endif /* O_BINARY */
801 #define closesocket(a) (close(a))
802 #define mg_mkdir(conn, path, mode) (mkdir(path, mode))
803 #define mg_remove(conn, x) (remove(x))
804 #define mg_sleep(x) (usleep((x)*1000))
805 #define mg_opendir(conn, x) (opendir(x))
806 #define mg_closedir(x) (closedir(x))
807 #define mg_readdir(x) (readdir(x))
808 #define ERRNO (errno)
809 #define INVALID_SOCKET (-1)
810 #define INT64_FMT PRId64
811 #define UINT64_FMT PRIu64
812 typedef int SOCKET;
813 #define WINCDECL
814 
815 #if defined(__hpux)
816 /* HPUX 11 does not have monotonic, fall back to realtime */
817 #if !defined(CLOCK_MONOTONIC)
818 #define CLOCK_MONOTONIC CLOCK_REALTIME
819 #endif
820 
821 /* HPUX defines socklen_t incorrectly as size_t which is 64bit on
822  * Itanium. Without defining _XOPEN_SOURCE or _XOPEN_SOURCE_EXTENDED
823  * the prototypes use int* rather than socklen_t* which matches the
824  * actual library expectation. When called with the wrong size arg
825  * accept() returns a zero client inet addr and check_acl() always
826  * fails. Since socklen_t is widely used below, just force replace
827  * their typedef with int. - DTL
828  */
829 #define socklen_t int
830 #endif /* hpux */
831 
832 #endif /* defined(_WIN32) - WINDOWS vs UNIX include block */
833 
834 /* Maximum queue length for pending connections. This value is passed as
835  * parameter to the "listen" socket call. */
836 #if !defined(SOMAXCONN)
837 /* This symbol may be defined in winsock2.h so this must after that include */
838 #define SOMAXCONN (100) /* in pending connections (count) */
839 #endif
840 
841 /* In case our C library is missing "timegm", provide an implementation */
842 #if defined(NEED_TIMEGM)
843 static inline int
844 is_leap(int y)
845 {
846  return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
847 }
848 
849 static inline int
850 count_leap(int y)
851 {
852  return (y - 1969) / 4 - (y - 1901) / 100 + (y - 1601) / 400;
853 }
854 
855 time_t
856 timegm(struct tm *tm)
857 {
858  static const unsigned short ydays[] = {
859  0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
860  int year = tm->tm_year + 1900;
861  int mon = tm->tm_mon;
862  int mday = tm->tm_mday - 1;
863  int hour = tm->tm_hour;
864  int min = tm->tm_min;
865  int sec = tm->tm_sec;
866 
867  if (year < 1970 || mon < 0 || mon > 11 || mday < 0
868  || (mday >= ydays[mon + 1] - ydays[mon]
869  + (mon == 1 && is_leap(year) ? 1 : 0))
870  || hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || sec > 60)
871  return -1;
872 
873  time_t res = year - 1970;
874  res *= 365;
875  res += mday;
876  res += ydays[mon] + (mon > 1 && is_leap(year) ? 1 : 0);
877  res += count_leap(year);
878 
879  res *= 24;
880  res += hour;
881  res *= 60;
882  res += min;
883  res *= 60;
884  res += sec;
885  return res;
886 }
887 #endif /* NEED_TIMEGM */
888 
889 
890 /* va_copy should always be a macro, C99 and C++11 - DTL */
891 #if !defined(va_copy)
892 #define va_copy(x, y) ((x) = (y))
893 #endif
894 
895 
896 #if defined(_WIN32)
897 /* Create substitutes for POSIX functions in Win32. */
898 
899 #if defined(GCC_DIAGNOSTIC)
900 /* Show no warning in case system functions are not used. */
901 #pragma GCC diagnostic push
902 #pragma GCC diagnostic ignored "-Wunused-function"
903 #endif
904 
905 
906 static CRITICAL_SECTION global_log_file_lock;
907 
909 static DWORD
910 pthread_self(void)
911 {
912  return GetCurrentThreadId();
913 }
914 
915 
917 static int
918 pthread_key_create(
919  pthread_key_t *key,
920  void (*_ignored)(void *) /* destructor not supported for Windows */
921 )
922 {
923  (void)_ignored;
924 
925  if ((key != 0)) {
926  *key = TlsAlloc();
927  return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1;
928  }
929  return -2;
930 }
931 
932 
934 static int
935 pthread_key_delete(pthread_key_t key)
936 {
937  return TlsFree(key) ? 0 : 1;
938 }
939 
940 
942 static int
943 pthread_setspecific(pthread_key_t key, void *value)
944 {
945  return TlsSetValue(key, value) ? 0 : 1;
946 }
947 
948 
950 static void *
951 pthread_getspecific(pthread_key_t key)
952 {
953  return TlsGetValue(key);
954 }
955 
956 #if defined(GCC_DIAGNOSTIC)
957 /* Enable unused function warning again */
958 #pragma GCC diagnostic pop
959 #endif
960 
961 static struct pthread_mutex_undefined_struct *pthread_mutex_attr = NULL;
962 #else
963 static pthread_mutexattr_t pthread_mutex_attr;
964 #endif /* _WIN32 */
965 
966 
967 #if defined(_WIN32_WCE)
968 /* Create substitutes for POSIX functions in Win32. */
969 
970 #if defined(GCC_DIAGNOSTIC)
971 /* Show no warning in case system functions are not used. */
972 #pragma GCC diagnostic push
973 #pragma GCC diagnostic ignored "-Wunused-function"
974 #endif
975 
976 
978 static time_t
979 time(time_t *ptime)
980 {
981  time_t t;
982  SYSTEMTIME st;
983  FILETIME ft;
984 
985  GetSystemTime(&st);
986  SystemTimeToFileTime(&st, &ft);
987  t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime);
988 
989  if (ptime != NULL) {
990  *ptime = t;
991  }
992 
993  return t;
994 }
995 
996 
998 static struct tm *
999 localtime_s(const time_t *ptime, struct tm *ptm)
1000 {
1001  int64_t t = ((int64_t)*ptime) * RATE_DIFF + EPOCH_DIFF;
1002  FILETIME ft, lft;
1003  SYSTEMTIME st;
1004  TIME_ZONE_INFORMATION tzinfo;
1005 
1006  if (ptm == NULL) {
1007  return NULL;
1008  }
1009 
1010  *(int64_t *)&ft = t;
1011  FileTimeToLocalFileTime(&ft, &lft);
1012  FileTimeToSystemTime(&lft, &st);
1013  ptm->tm_year = st.wYear - 1900;
1014  ptm->tm_mon = st.wMonth - 1;
1015  ptm->tm_wday = st.wDayOfWeek;
1016  ptm->tm_mday = st.wDay;
1017  ptm->tm_hour = st.wHour;
1018  ptm->tm_min = st.wMinute;
1019  ptm->tm_sec = st.wSecond;
1020  ptm->tm_yday = 0; /* hope nobody uses this */
1021  ptm->tm_isdst =
1022  (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT) ? 1 : 0;
1023 
1024  return ptm;
1025 }
1026 
1027 
1029 static struct tm *
1030 gmtime_s(const time_t *ptime, struct tm *ptm)
1031 {
1032  /* FIXME(lsm): fix this. */
1033  return localtime_s(ptime, ptm);
1034 }
1035 
1036 
1037 static int mg_atomic_inc(volatile int *addr);
1038 static struct tm tm_array[MAX_WORKER_THREADS];
1039 static int tm_index = 0;
1040 
1041 
1043 static struct tm *
1044 localtime(const time_t *ptime)
1045 {
1046  int i = mg_atomic_inc(&tm_index) % (sizeof(tm_array) / sizeof(tm_array[0]));
1047  return localtime_s(ptime, tm_array + i);
1048 }
1049 
1050 
1052 static struct tm *
1053 gmtime(const time_t *ptime)
1054 {
1055  int i = mg_atomic_inc(&tm_index) % ARRAY_SIZE(tm_array);
1056  return gmtime_s(ptime, tm_array + i);
1057 }
1058 
1059 
1061 static size_t
1062 strftime(char *dst, size_t dst_size, const char *fmt, const struct tm *tm)
1063 {
1064  /* TODO: (void)mg_snprintf(NULL, dst, dst_size, "implement strftime()
1065  * for WinCE"); */
1066  return 0;
1067 }
1068 
1069 #define _beginthreadex(psec, stack, func, prm, flags, ptid) \
1070  (uintptr_t) CreateThread(psec, stack, func, prm, flags, ptid)
1071 
1072 #define remove(f) mg_remove(NULL, f)
1073 
1074 
1076 static int
1077 rename(const char *a, const char *b)
1078 {
1079  wchar_t wa[W_PATH_MAX];
1080  wchar_t wb[W_PATH_MAX];
1081  path_to_unicode(NULL, a, wa, ARRAY_SIZE(wa));
1082  path_to_unicode(NULL, b, wb, ARRAY_SIZE(wb));
1083 
1084  return MoveFileW(wa, wb) ? 0 : -1;
1085 }
1086 
1087 
1088 struct stat {
1089  int64_t st_size;
1090  time_t st_mtime;
1091 };
1092 
1093 
1095 static int
1096 stat(const char *name, struct stat *st)
1097 {
1098  wchar_t wbuf[W_PATH_MAX];
1099  WIN32_FILE_ATTRIBUTE_DATA attr;
1100  time_t creation_time, write_time;
1101 
1102  path_to_unicode(NULL, name, wbuf, ARRAY_SIZE(wbuf));
1103  memset(&attr, 0, sizeof(attr));
1104 
1105  GetFileAttributesExW(wbuf, GetFileExInfoStandard, &attr);
1106  st->st_size =
1107  (((int64_t)attr.nFileSizeHigh) << 32) + (int64_t)attr.nFileSizeLow;
1108 
1109  write_time = SYS2UNIX_TIME(attr.ftLastWriteTime.dwLowDateTime,
1110  attr.ftLastWriteTime.dwHighDateTime);
1111  creation_time = SYS2UNIX_TIME(attr.ftCreationTime.dwLowDateTime,
1112  attr.ftCreationTime.dwHighDateTime);
1113 
1114  if (creation_time > write_time) {
1115  st->st_mtime = creation_time;
1116  } else {
1117  st->st_mtime = write_time;
1118  }
1119  return 0;
1120 }
1121 
1122 #define access(x, a) 1 /* not required anyway */
1123 
1124 /* WinCE-TODO: define stat, remove, rename, _rmdir, _lseeki64 */
1125 /* Values from errno.h in Windows SDK (Visual Studio). */
1126 #define EEXIST 17
1127 #define EACCES 13
1128 #define ENOENT 2
1129 
1130 #if defined(GCC_DIAGNOSTIC)
1131 /* Enable unused function warning again */
1132 #pragma GCC diagnostic pop
1133 #endif
1134 
1135 #endif /* defined(_WIN32_WCE) */
1136 
1137 
1138 #if defined(GCC_DIAGNOSTIC)
1139 /* Show no warning in case system functions are not used. */
1140 #pragma GCC diagnostic push
1141 #pragma GCC diagnostic ignored "-Wunused-function"
1142 #endif /* defined(GCC_DIAGNOSTIC) */
1143 #if defined(__clang__)
1144 /* Show no warning in case system functions are not used. */
1145 #pragma clang diagnostic push
1146 #pragma clang diagnostic ignored "-Wunused-function"
1147 #endif
1148 
1149 static pthread_mutex_t global_lock_mutex;
1150 
1151 
1152 #if defined(_WIN32)
1153 /* Forward declaration for Windows */
1155 static int pthread_mutex_lock(pthread_mutex_t *mutex);
1156 
1158 static int pthread_mutex_unlock(pthread_mutex_t *mutex);
1159 #endif
1160 
1161 
1163 static void
1165 {
1166  (void)pthread_mutex_lock(&global_lock_mutex);
1167 }
1168 
1169 
1171 static void
1173 {
1174  (void)pthread_mutex_unlock(&global_lock_mutex);
1175 }
1176 
1177 
1179 static int
1180 mg_atomic_inc(volatile int *addr)
1181 {
1182  int ret;
1183 #if defined(_WIN32) && !defined(NO_ATOMICS)
1184  /* Depending on the SDK, this function uses either
1185  * (volatile unsigned int *) or (volatile LONG *),
1186  * so whatever you use, the other SDK is likely to raise a warning. */
1187  ret = InterlockedIncrement((volatile long *)addr);
1188 #elif defined(__GNUC__) \
1189  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1190  && !defined(NO_ATOMICS)
1191  ret = __sync_add_and_fetch(addr, 1);
1192 #else
1193  mg_global_lock();
1194  ret = (++(*addr));
1195  mg_global_unlock();
1196 #endif
1197  return ret;
1198 }
1199 
1200 
1202 static int
1203 mg_atomic_dec(volatile int *addr)
1204 {
1205  int ret;
1206 #if defined(_WIN32) && !defined(NO_ATOMICS)
1207  /* Depending on the SDK, this function uses either
1208  * (volatile unsigned int *) or (volatile LONG *),
1209  * so whatever you use, the other SDK is likely to raise a warning. */
1210  ret = InterlockedDecrement((volatile long *)addr);
1211 #elif defined(__GNUC__) \
1212  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1213  && !defined(NO_ATOMICS)
1214  ret = __sync_sub_and_fetch(addr, 1);
1215 #else
1216  mg_global_lock();
1217  ret = (--(*addr));
1218  mg_global_unlock();
1219 #endif
1220  return ret;
1221 }
1222 
1223 
1224 #if defined(USE_SERVER_STATS)
1225 static int64_t
1226 mg_atomic_add(volatile int64_t *addr, int64_t value)
1227 {
1228  int64_t ret;
1229 #if defined(_WIN64) && !defined(NO_ATOMICS)
1230  ret = InterlockedAdd64(addr, value);
1231 #elif defined(__GNUC__) \
1232  && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) \
1233  && !defined(NO_ATOMICS)
1234  ret = __sync_add_and_fetch(addr, value);
1235 #else
1236  mg_global_lock();
1237  *addr += value;
1238  ret = (*addr);
1239  mg_global_unlock();
1240 #endif
1241  return ret;
1242 }
1243 #endif
1244 
1245 
1246 #if defined(GCC_DIAGNOSTIC)
1247 /* Show no warning in case system functions are not used. */
1248 #pragma GCC diagnostic pop
1249 #endif /* defined(GCC_DIAGNOSTIC) */
1250 #if defined(__clang__)
1251 /* Show no warning in case system functions are not used. */
1252 #pragma clang diagnostic pop
1253 #endif
1254 
1255 
1256 #if defined(USE_SERVER_STATS)
1257 
1258 struct mg_memory_stat {
1259  volatile int64_t totalMemUsed;
1260  volatile int64_t maxMemUsed;
1261  volatile int blockCount;
1262 };
1263 
1264 
1265 static struct mg_memory_stat *get_memory_stat(struct mg_context *ctx);
1266 
1267 
1268 static void *
1269 mg_malloc_ex(size_t size,
1270  struct mg_context *ctx,
1271  const char *file,
1272  unsigned line)
1273 {
1274  void *data = malloc(size + 2 * sizeof(uintptr_t));
1275  void *memory = 0;
1276  struct mg_memory_stat *mstat = get_memory_stat(ctx);
1277 
1278 #if defined(MEMORY_DEBUGGING)
1279  char mallocStr[256];
1280 #else
1281  (void)file;
1282  (void)line;
1283 #endif
1284 
1285  if (data) {
1286  int64_t mmem = mg_atomic_add(&mstat->totalMemUsed, (int64_t)size);
1287  if (mmem > mstat->maxMemUsed) {
1288  /* could use atomic compare exchange, but this
1289  * seems overkill for statistics data */
1290  mstat->maxMemUsed = mmem;
1291  }
1292 
1293  mg_atomic_inc(&mstat->blockCount);
1294  ((uintptr_t *)data)[0] = size;
1295  ((uintptr_t *)data)[1] = (uintptr_t)mstat;
1296  memory = (void *)(((char *)data) + 2 * sizeof(uintptr_t));
1297  }
1298 
1299 #if defined(MEMORY_DEBUGGING)
1300  sprintf(mallocStr,
1301  "MEM: %p %5lu alloc %7lu %4lu --- %s:%u\n",
1302  memory,
1303  (unsigned long)size,
1304  (unsigned long)mstat->totalMemUsed,
1305  (unsigned long)mstat->blockCount,
1306  file,
1307  line);
1308 #if defined(_WIN32)
1309  OutputDebugStringA(mallocStr);
1310 #else
1311  DEBUG_TRACE("%s", mallocStr);
1312 #endif
1313 #endif
1314 
1315  return memory;
1316 }
1317 
1318 
1319 static void *
1320 mg_calloc_ex(size_t count,
1321  size_t size,
1322  struct mg_context *ctx,
1323  const char *file,
1324  unsigned line)
1325 {
1326  void *data = mg_malloc_ex(size * count, ctx, file, line);
1327 
1328  if (data) {
1329  memset(data, 0, size * count);
1330  }
1331  return data;
1332 }
1333 
1334 
1335 static void
1336 mg_free_ex(void *memory, const char *file, unsigned line)
1337 {
1338  void *data = (void *)(((char *)memory) - 2 * sizeof(uintptr_t));
1339 
1340 
1341 #if defined(MEMORY_DEBUGGING)
1342  char mallocStr[256];
1343 #else
1344  (void)file;
1345  (void)line;
1346 #endif
1347 
1348  if (memory) {
1349  uintptr_t size = ((uintptr_t *)data)[0];
1350  struct mg_memory_stat *mstat =
1351  (struct mg_memory_stat *)(((uintptr_t *)data)[1]);
1352  mg_atomic_add(&mstat->totalMemUsed, -(int64_t)size);
1353  mg_atomic_dec(&mstat->blockCount);
1354 #if defined(MEMORY_DEBUGGING)
1355  sprintf(mallocStr,
1356  "MEM: %p %5lu free %7lu %4lu --- %s:%u\n",
1357  memory,
1358  (unsigned long)size,
1359  (unsigned long)mstat->totalMemUsed,
1360  (unsigned long)mstat->blockCount,
1361  file,
1362  line);
1363 #if defined(_WIN32)
1364  OutputDebugStringA(mallocStr);
1365 #else
1366  DEBUG_TRACE("%s", mallocStr);
1367 #endif
1368 #endif
1369  free(data);
1370  }
1371 }
1372 
1373 
1374 static void *
1375 mg_realloc_ex(void *memory,
1376  size_t newsize,
1377  struct mg_context *ctx,
1378  const char *file,
1379  unsigned line)
1380 {
1381  void *data;
1382  void *_realloc;
1383  uintptr_t oldsize;
1384 
1385 #if defined(MEMORY_DEBUGGING)
1386  char mallocStr[256];
1387 #else
1388  (void)file;
1389  (void)line;
1390 #endif
1391 
1392  if (newsize) {
1393  if (memory) {
1394  /* Reallocate existing block */
1395  struct mg_memory_stat *mstat;
1396  data = (void *)(((char *)memory) - 2 * sizeof(uintptr_t));
1397  oldsize = ((uintptr_t *)data)[0];
1398  mstat = (struct mg_memory_stat *)((uintptr_t *)data)[1];
1399  _realloc = realloc(data, newsize + 2 * sizeof(uintptr_t));
1400  if (_realloc) {
1401  data = _realloc;
1402  mg_atomic_add(&mstat->totalMemUsed, -(int64_t)oldsize);
1403 #if defined(MEMORY_DEBUGGING)
1404  sprintf(mallocStr,
1405  "MEM: %p %5lu r-free %7lu %4lu --- %s:%u\n",
1406  memory,
1407  (unsigned long)oldsize,
1408  (unsigned long)mstat->totalMemUsed,
1409  (unsigned long)mstat->blockCount,
1410  file,
1411  line);
1412 #if defined(_WIN32)
1413  OutputDebugStringA(mallocStr);
1414 #else
1415  DEBUG_TRACE("%s", mallocStr);
1416 #endif
1417 #endif
1418  mg_atomic_add(&mstat->totalMemUsed, (int64_t)newsize);
1419 #if defined(MEMORY_DEBUGGING)
1420  sprintf(mallocStr,
1421  "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n",
1422  memory,
1423  (unsigned long)newsize,
1424  (unsigned long)mstat->totalMemUsed,
1425  (unsigned long)mstat->blockCount,
1426  file,
1427  line);
1428 #if defined(_WIN32)
1429  OutputDebugStringA(mallocStr);
1430 #else
1431  DEBUG_TRACE("%s", mallocStr);
1432 #endif
1433 #endif
1434  *(uintptr_t *)data = newsize;
1435  data = (void *)(((char *)data) + 2 * sizeof(uintptr_t));
1436  } else {
1437 #if defined(MEMORY_DEBUGGING)
1438 #if defined(_WIN32)
1439  OutputDebugStringA("MEM: realloc failed\n");
1440 #else
1441  DEBUG_TRACE("%s", "MEM: realloc failed\n");
1442 #endif
1443 #endif
1444  return _realloc;
1445  }
1446  } else {
1447  /* Allocate new block */
1448  data = mg_malloc_ex(newsize, ctx, file, line);
1449  }
1450  } else {
1451  /* Free existing block */
1452  data = 0;
1453  mg_free_ex(memory, file, line);
1454  }
1455 
1456  return data;
1457 }
1458 
1459 #define mg_malloc(a) mg_malloc_ex(a, NULL, __FILE__, __LINE__)
1460 #define mg_calloc(a, b) mg_calloc_ex(a, b, NULL, __FILE__, __LINE__)
1461 #define mg_realloc(a, b) mg_realloc_ex(a, b, NULL, __FILE__, __LINE__)
1462 #define mg_free(a) mg_free_ex(a, __FILE__, __LINE__)
1463 
1464 #define mg_malloc_ctx(a, c) mg_malloc_ex(a, c, __FILE__, __LINE__)
1465 #define mg_calloc_ctx(a, b, c) mg_calloc_ex(a, b, c, __FILE__, __LINE__)
1466 #define mg_realloc_ctx(a, b, c) mg_realloc_ex(a, b, c, __FILE__, __LINE__)
1467 
1468 #else /* USE_SERVER_STATS */
1469 
1470 static __inline void *
1471 mg_malloc(size_t a)
1472 {
1473  return malloc(a);
1474 }
1475 
1476 static __inline void *
1477 mg_calloc(size_t a, size_t b)
1478 {
1479  return calloc(a, b);
1480 }
1481 
1482 static __inline void *
1483 mg_realloc(void *a, size_t b)
1484 {
1485  return realloc(a, b);
1486 }
1487 
1488 static __inline void
1489 mg_free(void *a)
1490 {
1491  free(a);
1492 }
1493 
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)
1498 
1499 #endif /* USE_SERVER_STATS */
1500 
1501 
1502 static void mg_vsnprintf(const struct mg_connection *conn,
1503  int *truncated,
1504  char *buf,
1505  size_t buflen,
1506  const char *fmt,
1507  va_list ap);
1508 
1509 static void mg_snprintf(const struct mg_connection *conn,
1510  int *truncated,
1511  char *buf,
1512  size_t buflen,
1513  PRINTF_FORMAT_STRING(const char *fmt),
1514  ...) PRINTF_ARGS(5, 6);
1515 
1516 /* This following lines are just meant as a reminder to use the mg-functions
1517  * for memory management */
1518 #if defined(malloc)
1519 #undef malloc
1520 #endif
1521 #if defined(calloc)
1522 #undef calloc
1523 #endif
1524 #if defined(realloc)
1525 #undef realloc
1526 #endif
1527 #if defined(free)
1528 #undef free
1529 #endif
1530 #if defined(snprintf)
1531 #undef snprintf
1532 #endif
1533 #if defined(vsnprintf)
1534 #undef vsnprintf
1535 #endif
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
1541 #if defined(_WIN32)
1542 /* vsnprintf must not be used in any system,
1543  * but this define only works well for Windows. */
1544 #define vsnprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_vsnprintf
1545 #endif
1546 
1547 
1548 /* mg_init_library counter */
1549 static int mg_init_library_called = 0;
1550 
1551 #if !defined(NO_SSL)
1552 static int mg_ssl_initialized = 0;
1553 #endif
1554 
1555 static pthread_key_t sTlsKey; /* Thread local storage index */
1556 static int thread_idx_max = 0;
1557 
1558 #if defined(MG_LEGACY_INTERFACE)
1559 #define MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE
1560 #endif
1561 
1562 struct mg_workerTLS {
1563  int is_master;
1564  unsigned long thread_idx;
1565 #if defined(_WIN32)
1566  HANDLE pthread_cond_helper_mutex;
1567  struct mg_workerTLS *next_waiting_thread;
1568 #endif
1569 #if defined(MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE)
1570  char txtbuf[4];
1571 #endif
1572 };
1573 
1574 
1575 #if defined(GCC_DIAGNOSTIC)
1576 /* Show no warning in case system functions are not used. */
1577 #pragma GCC diagnostic push
1578 #pragma GCC diagnostic ignored "-Wunused-function"
1579 #endif /* defined(GCC_DIAGNOSTIC) */
1580 #if defined(__clang__)
1581 /* Show no warning in case system functions are not used. */
1582 #pragma clang diagnostic push
1583 #pragma clang diagnostic ignored "-Wunused-function"
1584 #endif
1585 
1586 
1587 /* Get a unique thread ID as unsigned long, independent from the data type
1588  * of thread IDs defined by the operating system API.
1589  * If two calls to mg_current_thread_id return the same value, they calls
1590  * are done from the same thread. If they return different values, they are
1591  * done from different threads. (Provided this function is used in the same
1592  * process context and threads are not repeatedly created and deleted, but
1593  * CivetWeb does not do that).
1594  * This function must match the signature required for SSL id callbacks:
1595  * CRYPTO_set_id_callback
1596  */
1598 static unsigned long
1600 {
1601 #if defined(_WIN32)
1602  return GetCurrentThreadId();
1603 #else
1604 
1605 #if defined(__clang__)
1606 #pragma clang diagnostic push
1607 #pragma clang diagnostic ignored "-Wunreachable-code"
1608 /* For every compiler, either "sizeof(pthread_t) > sizeof(unsigned long)"
1609  * or not, so one of the two conditions will be unreachable by construction.
1610  * Unfortunately the C standard does not define a way to check this at
1611  * compile time, since the #if preprocessor conditions can not use the sizeof
1612  * operator as an argument. */
1613 #endif
1614 
1615  if (sizeof(pthread_t) > sizeof(unsigned long)) {
1616  /* This is the problematic case for CRYPTO_set_id_callback:
1617  * The OS pthread_t can not be cast to unsigned long. */
1618  struct mg_workerTLS *tls =
1619  (struct mg_workerTLS *)pthread_getspecific(sTlsKey);
1620  if (tls == NULL) {
1621  /* SSL called from an unknown thread: Create some thread index.
1622  */
1623  tls = (struct mg_workerTLS *)mg_malloc(sizeof(struct mg_workerTLS));
1624  tls->is_master = -2; /* -2 means "3rd party thread" */
1625  tls->thread_idx = (unsigned)mg_atomic_inc(&thread_idx_max);
1626  pthread_setspecific(sTlsKey, tls);
1627  }
1628  return tls->thread_idx;
1629  } else {
1630  /* pthread_t may be any data type, so a simple cast to unsigned long
1631  * can rise a warning/error, depending on the platform.
1632  * Here memcpy is used as an anything-to-anything cast. */
1633  unsigned long ret = 0;
1634  pthread_t t = pthread_self();
1635  memcpy(&ret, &t, sizeof(pthread_t));
1636  return ret;
1637  }
1638 
1639 #if defined(__clang__)
1640 #pragma clang diagnostic pop
1641 #endif
1642 
1643 #endif
1644 }
1645 
1646 
1648 static uint64_t
1650 {
1651  struct timespec tsnow;
1652  clock_gettime(CLOCK_REALTIME, &tsnow);
1653  return (((uint64_t)tsnow.tv_sec) * 1000000000) + (uint64_t)tsnow.tv_nsec;
1654 }
1655 
1656 
1657 #if defined(GCC_DIAGNOSTIC)
1658 /* Show no warning in case system functions are not used. */
1659 #pragma GCC diagnostic pop
1660 #endif /* defined(GCC_DIAGNOSTIC) */
1661 #if defined(__clang__)
1662 /* Show no warning in case system functions are not used. */
1663 #pragma clang diagnostic pop
1664 #endif
1665 
1666 
1667 #if defined(NEED_DEBUG_TRACE_FUNC)
1668 static void
1669 DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...)
1670 {
1671  va_list args;
1672  uint64_t nsnow;
1673  static uint64_t nslast;
1674  struct timespec tsnow;
1675 
1676  /* Get some operating system independent thread id */
1677  unsigned long thread_id = mg_current_thread_id();
1678 
1679  clock_gettime(CLOCK_REALTIME, &tsnow);
1680  nsnow = ((uint64_t)tsnow.tv_sec) * ((uint64_t)1000000000)
1681  + ((uint64_t)tsnow.tv_nsec);
1682 
1683  if (!nslast) {
1684  nslast = nsnow;
1685  }
1686 
1687  flockfile(stdout);
1688  printf("*** %lu.%09lu %12" INT64_FMT " %lu %s:%u: ",
1689  (unsigned long)tsnow.tv_sec,
1690  (unsigned long)tsnow.tv_nsec,
1691  nsnow - nslast,
1692  thread_id,
1693  func,
1694  line);
1695  va_start(args, fmt);
1696  vprintf(fmt, args);
1697  va_end(args);
1698  putchar('\n');
1699  fflush(stdout);
1700  funlockfile(stdout);
1701  nslast = nsnow;
1702 }
1703 #endif /* NEED_DEBUG_TRACE_FUNC */
1704 
1705 
1706 #define MD5_STATIC static
1707 #include "md5.inl"
1708 
1709 /* Darwin prior to 7.0 and Win32 do not have socklen_t */
1710 #if defined(NO_SOCKLEN_T)
1711 typedef int socklen_t;
1712 #endif /* NO_SOCKLEN_T */
1713 
1714 #define IP_ADDR_STR_LEN (50) /* IPv6 hex string is 46 chars */
1715 
1716 #if !defined(MSG_NOSIGNAL)
1717 #define MSG_NOSIGNAL (0)
1718 #endif
1719 
1720 
1721 #if defined(NO_SSL)
1722 typedef struct SSL SSL; /* dummy for SSL argument to push/pull */
1723 typedef struct SSL_CTX SSL_CTX;
1724 #else
1725 #if defined(NO_SSL_DL)
1726 #include <openssl/bn.h>
1727 #include <openssl/conf.h>
1728 #include <openssl/crypto.h>
1729 #include <openssl/dh.h>
1730 #include <openssl/engine.h>
1731 #include <openssl/err.h>
1732 #include <openssl/opensslv.h>
1733 #include <openssl/pem.h>
1734 #include <openssl/ssl.h>
1735 #include <openssl/tls1.h>
1736 #include <openssl/x509.h>
1737 
1738 #if defined(WOLFSSL_VERSION)
1739 /* Additional defines for WolfSSL, see
1740  * https://github.com/civetweb/civetweb/issues/583 */
1741 #include "wolfssl_extras.inl"
1742 #endif
1743 
1744 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
1745 /* If OpenSSL headers are included, automatically select the API version */
1746 #if !defined(OPENSSL_API_1_1)
1747 #define OPENSSL_API_1_1
1748 #endif
1749 #define OPENSSL_REMOVE_THREAD_STATE()
1750 #else
1751 #define OPENSSL_REMOVE_THREAD_STATE() ERR_remove_thread_state(NULL)
1752 #endif
1753 
1754 #else
1755 
1756 /* SSL loaded dynamically from DLL.
1757  * I put the prototypes here to be independent from OpenSSL source
1758  * installation. */
1759 
1760 typedef struct ssl_st SSL;
1761 typedef struct ssl_method_st SSL_METHOD;
1762 typedef struct ssl_ctx_st SSL_CTX;
1763 typedef struct x509_store_ctx_st X509_STORE_CTX;
1764 typedef struct x509_name X509_NAME;
1765 typedef struct asn1_integer ASN1_INTEGER;
1766 typedef struct bignum BIGNUM;
1767 typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS;
1768 typedef struct evp_md EVP_MD;
1769 typedef struct x509 X509;
1770 
1771 
1772 #define SSL_CTRL_OPTIONS (32)
1773 #define SSL_CTRL_CLEAR_OPTIONS (77)
1774 #define SSL_CTRL_SET_ECDH_AUTO (94)
1775 
1776 #define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0x00100000L
1777 #define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L
1778 #define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L
1779 
1780 #define SSL_VERIFY_NONE (0)
1781 #define SSL_VERIFY_PEER (1)
1782 #define SSL_VERIFY_FAIL_IF_NO_PEER_CERT (2)
1783 #define SSL_VERIFY_CLIENT_ONCE (4)
1784 #define SSL_OP_ALL ((long)(0x80000BFFUL))
1785 #define SSL_OP_NO_SSLv2 (0x01000000L)
1786 #define SSL_OP_NO_SSLv3 (0x02000000L)
1787 #define SSL_OP_NO_TLSv1 (0x04000000L)
1788 #define SSL_OP_NO_TLSv1_2 (0x08000000L)
1789 #define SSL_OP_NO_TLSv1_1 (0x10000000L)
1790 #define SSL_OP_SINGLE_DH_USE (0x00100000L)
1791 #define SSL_OP_CIPHER_SERVER_PREFERENCE (0x00400000L)
1792 #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (0x00010000L)
1793 #define SSL_OP_NO_COMPRESSION (0x00020000L)
1794 
1795 #define SSL_CB_HANDSHAKE_START (0x10)
1796 #define SSL_CB_HANDSHAKE_DONE (0x20)
1797 
1798 #define SSL_ERROR_NONE (0)
1799 #define SSL_ERROR_SSL (1)
1800 #define SSL_ERROR_WANT_READ (2)
1801 #define SSL_ERROR_WANT_WRITE (3)
1802 #define SSL_ERROR_WANT_X509_LOOKUP (4)
1803 #define SSL_ERROR_SYSCALL (5) /* see errno */
1804 #define SSL_ERROR_ZERO_RETURN (6)
1805 #define SSL_ERROR_WANT_CONNECT (7)
1806 #define SSL_ERROR_WANT_ACCEPT (8)
1807 
1808 #define TLSEXT_TYPE_server_name (0)
1809 #define TLSEXT_NAMETYPE_host_name (0)
1810 #define SSL_TLSEXT_ERR_OK (0)
1811 #define SSL_TLSEXT_ERR_ALERT_WARNING (1)
1812 #define SSL_TLSEXT_ERR_ALERT_FATAL (2)
1813 #define SSL_TLSEXT_ERR_NOACK (3)
1814 
1815 struct ssl_func {
1816  const char *name; /* SSL function name */
1817  void (*ptr)(void); /* Function pointer */
1818 };
1819 
1820 
1821 #if defined(OPENSSL_API_1_1)
1822 
1823 #define SSL_free (*(void (*)(SSL *))ssl_sw[0].ptr)
1824 #define SSL_accept (*(int (*)(SSL *))ssl_sw[1].ptr)
1825 #define SSL_connect (*(int (*)(SSL *))ssl_sw[2].ptr)
1826 #define SSL_read (*(int (*)(SSL *, void *, int))ssl_sw[3].ptr)
1827 #define SSL_write (*(int (*)(SSL *, const void *, int))ssl_sw[4].ptr)
1828 #define SSL_get_error (*(int (*)(SSL *, int))ssl_sw[5].ptr)
1829 #define SSL_set_fd (*(int (*)(SSL *, SOCKET))ssl_sw[6].ptr)
1830 #define SSL_new (*(SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
1831 #define SSL_CTX_new (*(SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
1832 #define TLS_server_method (*(SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
1833 #define OPENSSL_init_ssl \
1834  (*(int (*)(uint64_t opts, \
1835  const OPENSSL_INIT_SETTINGS *settings))ssl_sw[10] \
1836  .ptr)
1837 #define SSL_CTX_use_PrivateKey_file \
1838  (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[11].ptr)
1839 #define SSL_CTX_use_certificate_file \
1840  (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[12].ptr)
1841 #define SSL_CTX_set_default_passwd_cb \
1842  (*(void (*)(SSL_CTX *, mg_callback_t))ssl_sw[13].ptr)
1843 #define SSL_CTX_free (*(void (*)(SSL_CTX *))ssl_sw[14].ptr)
1844 #define SSL_CTX_use_certificate_chain_file \
1845  (*(int (*)(SSL_CTX *, const char *))ssl_sw[15].ptr)
1846 #define TLS_client_method (*(SSL_METHOD * (*)(void)) ssl_sw[16].ptr)
1847 #define SSL_pending (*(int (*)(SSL *))ssl_sw[17].ptr)
1848 #define SSL_CTX_set_verify \
1849  (*(void (*)(SSL_CTX *, \
1850  int, \
1851  int (*verify_callback)(int, X509_STORE_CTX *)))ssl_sw[18] \
1852  .ptr)
1853 #define SSL_shutdown (*(int (*)(SSL *))ssl_sw[19].ptr)
1854 #define SSL_CTX_load_verify_locations \
1855  (*(int (*)(SSL_CTX *, const char *, const char *))ssl_sw[20].ptr)
1856 #define SSL_CTX_set_default_verify_paths (*(int (*)(SSL_CTX *))ssl_sw[21].ptr)
1857 #define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))ssl_sw[22].ptr)
1858 #define SSL_get_peer_certificate (*(X509 * (*)(SSL *)) ssl_sw[23].ptr)
1859 #define SSL_get_version (*(const char *(*)(SSL *))ssl_sw[24].ptr)
1860 #define SSL_get_current_cipher (*(SSL_CIPHER * (*)(SSL *)) ssl_sw[25].ptr)
1861 #define SSL_CIPHER_get_name \
1862  (*(const char *(*)(const SSL_CIPHER *))ssl_sw[26].ptr)
1863 #define SSL_CTX_check_private_key (*(int (*)(SSL_CTX *))ssl_sw[27].ptr)
1864 #define SSL_CTX_set_session_id_context \
1865  (*(int (*)(SSL_CTX *, const unsigned char *, unsigned int))ssl_sw[28].ptr)
1866 #define SSL_CTX_ctrl (*(long (*)(SSL_CTX *, int, long, void *))ssl_sw[29].ptr)
1867 #define SSL_CTX_set_cipher_list \
1868  (*(int (*)(SSL_CTX *, const char *))ssl_sw[30].ptr)
1869 #define SSL_CTX_set_options \
1870  (*(unsigned long (*)(SSL_CTX *, unsigned long))ssl_sw[31].ptr)
1871 #define SSL_CTX_set_info_callback \
1872  (*(void (*)(SSL_CTX * ctx, void (*callback)(const SSL *, int, int))) \
1873  ssl_sw[32] \
1874  .ptr)
1875 #define SSL_get_ex_data (*(char *(*)(const SSL *, int))ssl_sw[33].ptr)
1876 #define SSL_set_ex_data (*(void (*)(SSL *, int, char *))ssl_sw[34].ptr)
1877 #define SSL_CTX_callback_ctrl \
1878  (*(long (*)(SSL_CTX *, int, void (*)(void)))ssl_sw[35].ptr)
1879 #define SSL_get_servername \
1880  (*(const char *(*)(const SSL *, int type))ssl_sw[36].ptr)
1881 #define SSL_set_SSL_CTX (*(SSL_CTX * (*)(SSL *, SSL_CTX *)) ssl_sw[37].ptr)
1882 #define SSL_ctrl (*(long (*)(SSL *, int, long, void *))ssl_sw[38].ptr)
1883 
1884 #define SSL_CTX_clear_options(ctx, op) \
1885  SSL_CTX_ctrl((ctx), SSL_CTRL_CLEAR_OPTIONS, (op), NULL)
1886 #define SSL_CTX_set_ecdh_auto(ctx, onoff) \
1887  SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, onoff, NULL)
1888 
1889 #define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53
1890 #define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54
1891 #define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
1892 #define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
1893  SSL_CTX_callback_ctrl(ctx, \
1894  SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, \
1895  (void (*)(void))cb)
1896 #define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
1897  SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG, 0, (void *)arg)
1898 #define SSL_set_tlsext_host_name(ctx, arg) \
1899  SSL_ctrl(ctx, SSL_CTRL_SET_TLSEXT_HOSTNAME, 0, (void *)arg)
1900 
1901 #define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
1902 #define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
1903 
1904 #define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)arg))
1905 #define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
1906 
1907 #define ERR_get_error (*(unsigned long (*)(void))crypto_sw[0].ptr)
1908 #define ERR_error_string (*(char *(*)(unsigned long, char *))crypto_sw[1].ptr)
1909 #define CONF_modules_unload (*(void (*)(int))crypto_sw[2].ptr)
1910 #define X509_free (*(void (*)(X509 *))crypto_sw[3].ptr)
1911 #define X509_get_subject_name (*(X509_NAME * (*)(X509 *)) crypto_sw[4].ptr)
1912 #define X509_get_issuer_name (*(X509_NAME * (*)(X509 *)) crypto_sw[5].ptr)
1913 #define X509_NAME_oneline \
1914  (*(char *(*)(X509_NAME *, char *, int))crypto_sw[6].ptr)
1915 #define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *)) crypto_sw[7].ptr)
1916 #define EVP_get_digestbyname \
1917  (*(const EVP_MD *(*)(const char *))crypto_sw[8].ptr)
1918 #define EVP_Digest \
1919  (*(int (*)( \
1920  const void *, size_t, void *, unsigned int *, const EVP_MD *, void *)) \
1921  crypto_sw[9] \
1922  .ptr)
1923 #define i2d_X509 (*(int (*)(X509 *, unsigned char **))crypto_sw[10].ptr)
1924 #define BN_bn2hex (*(char *(*)(const BIGNUM *a))crypto_sw[11].ptr)
1925 #define ASN1_INTEGER_to_BN \
1926  (*(BIGNUM * (*)(const ASN1_INTEGER *ai, BIGNUM *bn)) crypto_sw[12].ptr)
1927 #define BN_free (*(void (*)(const BIGNUM *a))crypto_sw[13].ptr)
1928 #define CRYPTO_free (*(void (*)(void *addr))crypto_sw[14].ptr)
1929 
1930 #define OPENSSL_free(a) CRYPTO_free(a)
1931 
1932 #define OPENSSL_REMOVE_THREAD_STATE()
1933 
1934 /* init_ssl_ctx() function updates this array.
1935  * It loads SSL library dynamically and changes NULLs to the actual addresses
1936  * of respective functions. The macros above (like SSL_connect()) are really
1937  * just calling these functions indirectly via the pointer. */
1938 static struct ssl_func ssl_sw[] = {{"SSL_free", NULL},
1939  {"SSL_accept", NULL},
1940  {"SSL_connect", NULL},
1941  {"SSL_read", NULL},
1942  {"SSL_write", NULL},
1943  {"SSL_get_error", NULL},
1944  {"SSL_set_fd", NULL},
1945  {"SSL_new", NULL},
1946  {"SSL_CTX_new", NULL},
1947  {"TLS_server_method", NULL},
1948  {"OPENSSL_init_ssl", NULL},
1949  {"SSL_CTX_use_PrivateKey_file", NULL},
1950  {"SSL_CTX_use_certificate_file", NULL},
1951  {"SSL_CTX_set_default_passwd_cb", NULL},
1952  {"SSL_CTX_free", NULL},
1953  {"SSL_CTX_use_certificate_chain_file", NULL},
1954  {"TLS_client_method", NULL},
1955  {"SSL_pending", NULL},
1956  {"SSL_CTX_set_verify", NULL},
1957  {"SSL_shutdown", NULL},
1958  {"SSL_CTX_load_verify_locations", NULL},
1959  {"SSL_CTX_set_default_verify_paths", NULL},
1960  {"SSL_CTX_set_verify_depth", NULL},
1961  {"SSL_get_peer_certificate", NULL},
1962  {"SSL_get_version", NULL},
1963  {"SSL_get_current_cipher", NULL},
1964  {"SSL_CIPHER_get_name", NULL},
1965  {"SSL_CTX_check_private_key", NULL},
1966  {"SSL_CTX_set_session_id_context", NULL},
1967  {"SSL_CTX_ctrl", NULL},
1968  {"SSL_CTX_set_cipher_list", NULL},
1969  {"SSL_CTX_set_options", NULL},
1970  {"SSL_CTX_set_info_callback", NULL},
1971  {"SSL_get_ex_data", NULL},
1972  {"SSL_set_ex_data", NULL},
1973  {"SSL_CTX_callback_ctrl", NULL},
1974  {"SSL_get_servername", NULL},
1975  {"SSL_set_SSL_CTX", NULL},
1976  {"SSL_ctrl", NULL},
1977  {NULL, NULL}};
1978 
1979 
1980 /* Similar array as ssl_sw. These functions could be located in different
1981  * lib. */
1982 static struct ssl_func crypto_sw[] = {{"ERR_get_error", NULL},
1983  {"ERR_error_string", NULL},
1984  {"CONF_modules_unload", NULL},
1985  {"X509_free", NULL},
1986  {"X509_get_subject_name", NULL},
1987  {"X509_get_issuer_name", NULL},
1988  {"X509_NAME_oneline", NULL},
1989  {"X509_get_serialNumber", NULL},
1990  {"EVP_get_digestbyname", NULL},
1991  {"EVP_Digest", NULL},
1992  {"i2d_X509", NULL},
1993  {"BN_bn2hex", NULL},
1994  {"ASN1_INTEGER_to_BN", NULL},
1995  {"BN_free", NULL},
1996  {"CRYPTO_free", NULL},
1997  {NULL, NULL}};
1998 #else
1999 
2000 #define SSL_free (*(void (*)(SSL *))ssl_sw[0].ptr)
2001 #define SSL_accept (*(int (*)(SSL *))ssl_sw[1].ptr)
2002 #define SSL_connect (*(int (*)(SSL *))ssl_sw[2].ptr)
2003 #define SSL_read (*(int (*)(SSL *, void *, int))ssl_sw[3].ptr)
2004 #define SSL_write (*(int (*)(SSL *, const void *, int))ssl_sw[4].ptr)
2005 #define SSL_get_error (*(int (*)(SSL *, int))ssl_sw[5].ptr)
2006 #define SSL_set_fd (*(int (*)(SSL *, SOCKET))ssl_sw[6].ptr)
2007 #define SSL_new (*(SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
2008 #define SSL_CTX_new (*(SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
2009 #define SSLv23_server_method (*(SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
2010 #define SSL_library_init (*(int (*)(void))ssl_sw[10].ptr)
2011 #define SSL_CTX_use_PrivateKey_file \
2012  (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[11].ptr)
2013 #define SSL_CTX_use_certificate_file \
2014  (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[12].ptr)
2015 #define SSL_CTX_set_default_passwd_cb \
2016  (*(void (*)(SSL_CTX *, mg_callback_t))ssl_sw[13].ptr)
2017 #define SSL_CTX_free (*(void (*)(SSL_CTX *))ssl_sw[14].ptr)
2018 #define SSL_load_error_strings (*(void (*)(void))ssl_sw[15].ptr)
2019 #define SSL_CTX_use_certificate_chain_file \
2020  (*(int (*)(SSL_CTX *, const char *))ssl_sw[16].ptr)
2021 #define SSLv23_client_method (*(SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
2022 #define SSL_pending (*(int (*)(SSL *))ssl_sw[18].ptr)
2023 #define SSL_CTX_set_verify \
2024  (*(void (*)(SSL_CTX *, \
2025  int, \
2026  int (*verify_callback)(int, X509_STORE_CTX *)))ssl_sw[19] \
2027  .ptr)
2028 #define SSL_shutdown (*(int (*)(SSL *))ssl_sw[20].ptr)
2029 #define SSL_CTX_load_verify_locations \
2030  (*(int (*)(SSL_CTX *, const char *, const char *))ssl_sw[21].ptr)
2031 #define SSL_CTX_set_default_verify_paths (*(int (*)(SSL_CTX *))ssl_sw[22].ptr)
2032 #define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))ssl_sw[23].ptr)
2033 #define SSL_get_peer_certificate (*(X509 * (*)(SSL *)) ssl_sw[24].ptr)
2034 #define SSL_get_version (*(const char *(*)(SSL *))ssl_sw[25].ptr)
2035 #define SSL_get_current_cipher (*(SSL_CIPHER * (*)(SSL *)) ssl_sw[26].ptr)
2036 #define SSL_CIPHER_get_name \
2037  (*(const char *(*)(const SSL_CIPHER *))ssl_sw[27].ptr)
2038 #define SSL_CTX_check_private_key (*(int (*)(SSL_CTX *))ssl_sw[28].ptr)
2039 #define SSL_CTX_set_session_id_context \
2040  (*(int (*)(SSL_CTX *, const unsigned char *, unsigned int))ssl_sw[29].ptr)
2041 #define SSL_CTX_ctrl (*(long (*)(SSL_CTX *, int, long, void *))ssl_sw[30].ptr)
2042 #define SSL_CTX_set_cipher_list \
2043  (*(int (*)(SSL_CTX *, const char *))ssl_sw[31].ptr)
2044 #define SSL_CTX_set_info_callback \
2045  (*(void (*)(SSL_CTX *, void (*callback)(const SSL *, int, int)))ssl_sw[32] \
2046  .ptr)
2047 #define SSL_get_ex_data (*(char *(*)(const SSL *, int))ssl_sw[33].ptr)
2048 #define SSL_set_ex_data (*(void (*)(SSL *, int, char *))ssl_sw[34].ptr)
2049 #define SSL_CTX_callback_ctrl \
2050  (*(long (*)(SSL_CTX *, int, void (*)(void)))ssl_sw[35].ptr)
2051 #define SSL_get_servername \
2052  (*(const char *(*)(const SSL *, int type))ssl_sw[36].ptr)
2053 #define SSL_set_SSL_CTX (*(SSL_CTX * (*)(SSL *, SSL_CTX *)) ssl_sw[37].ptr)
2054 #define SSL_ctrl (*(long (*)(SSL *, int, long, void *))ssl_sw[38].ptr)
2055 
2056 #define SSL_CTX_set_options(ctx, op) \
2057  SSL_CTX_ctrl((ctx), SSL_CTRL_OPTIONS, (op), NULL)
2058 #define SSL_CTX_clear_options(ctx, op) \
2059  SSL_CTX_ctrl((ctx), SSL_CTRL_CLEAR_OPTIONS, (op), NULL)
2060 #define SSL_CTX_set_ecdh_auto(ctx, onoff) \
2061  SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, onoff, NULL)
2062 
2063 #define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53
2064 #define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54
2065 #define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
2066 #define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
2067  SSL_CTX_callback_ctrl(ctx, \
2068  SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, \
2069  (void (*)(void))cb)
2070 #define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
2071  SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG, 0, (void *)arg)
2072 #define SSL_set_tlsext_host_name(ctx, arg) \
2073  SSL_ctrl(ctx, SSL_CTRL_SET_TLSEXT_HOSTNAME, 0, (void *)arg)
2074 
2075 #define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
2076 #define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
2077 
2078 #define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)arg))
2079 #define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
2080 
2081 #define CRYPTO_num_locks (*(int (*)(void))crypto_sw[0].ptr)
2082 #define CRYPTO_set_locking_callback \
2083  (*(void (*)(void (*)(int, int, const char *, int)))crypto_sw[1].ptr)
2084 #define CRYPTO_set_id_callback \
2085  (*(void (*)(unsigned long (*)(void)))crypto_sw[2].ptr)
2086 #define ERR_get_error (*(unsigned long (*)(void))crypto_sw[3].ptr)
2087 #define ERR_error_string (*(char *(*)(unsigned long, char *))crypto_sw[4].ptr)
2088 #define ERR_remove_state (*(void (*)(unsigned long))crypto_sw[5].ptr)
2089 #define ERR_free_strings (*(void (*)(void))crypto_sw[6].ptr)
2090 #define ENGINE_cleanup (*(void (*)(void))crypto_sw[7].ptr)
2091 #define CONF_modules_unload (*(void (*)(int))crypto_sw[8].ptr)
2092 #define CRYPTO_cleanup_all_ex_data (*(void (*)(void))crypto_sw[9].ptr)
2093 #define EVP_cleanup (*(void (*)(void))crypto_sw[10].ptr)
2094 #define X509_free (*(void (*)(X509 *))crypto_sw[11].ptr)
2095 #define X509_get_subject_name (*(X509_NAME * (*)(X509 *)) crypto_sw[12].ptr)
2096 #define X509_get_issuer_name (*(X509_NAME * (*)(X509 *)) crypto_sw[13].ptr)
2097 #define X509_NAME_oneline \
2098  (*(char *(*)(X509_NAME *, char *, int))crypto_sw[14].ptr)
2099 #define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *)) crypto_sw[15].ptr)
2100 #define i2c_ASN1_INTEGER \
2101  (*(int (*)(ASN1_INTEGER *, unsigned char **))crypto_sw[16].ptr)
2102 #define EVP_get_digestbyname \
2103  (*(const EVP_MD *(*)(const char *))crypto_sw[17].ptr)
2104 #define EVP_Digest \
2105  (*(int (*)( \
2106  const void *, size_t, void *, unsigned int *, const EVP_MD *, void *)) \
2107  crypto_sw[18] \
2108  .ptr)
2109 #define i2d_X509 (*(int (*)(X509 *, unsigned char **))crypto_sw[19].ptr)
2110 #define BN_bn2hex (*(char *(*)(const BIGNUM *a))crypto_sw[20].ptr)
2111 #define ASN1_INTEGER_to_BN \
2112  (*(BIGNUM * (*)(const ASN1_INTEGER *ai, BIGNUM *bn)) crypto_sw[21].ptr)
2113 #define BN_free (*(void (*)(const BIGNUM *a))crypto_sw[22].ptr)
2114 #define CRYPTO_free (*(void (*)(void *addr))crypto_sw[23].ptr)
2115 
2116 #define OPENSSL_free(a) CRYPTO_free(a)
2117 
2118 /* use here ERR_remove_state,
2119  * while on some platforms function is not included into library due to
2120  * deprication */
2121 #define OPENSSL_REMOVE_THREAD_STATE() ERR_remove_state(0)
2122 
2123 /* init_ssl_ctx() function updates this array.
2124  * It loads SSL library dynamically and changes NULLs to the actual addresses
2125  * of respective functions. The macros above (like SSL_connect()) are really
2126  * just calling these functions indirectly via the pointer. */
2127 static struct ssl_func ssl_sw[] = {{"SSL_free", NULL},
2128  {"SSL_accept", NULL},
2129  {"SSL_connect", NULL},
2130  {"SSL_read", NULL},
2131  {"SSL_write", NULL},
2132  {"SSL_get_error", NULL},
2133  {"SSL_set_fd", NULL},
2134  {"SSL_new", NULL},
2135  {"SSL_CTX_new", NULL},
2136  {"SSLv23_server_method", NULL},
2137  {"SSL_library_init", NULL},
2138  {"SSL_CTX_use_PrivateKey_file", NULL},
2139  {"SSL_CTX_use_certificate_file", NULL},
2140  {"SSL_CTX_set_default_passwd_cb", NULL},
2141  {"SSL_CTX_free", NULL},
2142  {"SSL_load_error_strings", NULL},
2143  {"SSL_CTX_use_certificate_chain_file", NULL},
2144  {"SSLv23_client_method", NULL},
2145  {"SSL_pending", NULL},
2146  {"SSL_CTX_set_verify", NULL},
2147  {"SSL_shutdown", NULL},
2148  {"SSL_CTX_load_verify_locations", NULL},
2149  {"SSL_CTX_set_default_verify_paths", NULL},
2150  {"SSL_CTX_set_verify_depth", NULL},
2151  {"SSL_get_peer_certificate", NULL},
2152  {"SSL_get_version", NULL},
2153  {"SSL_get_current_cipher", NULL},
2154  {"SSL_CIPHER_get_name", NULL},
2155  {"SSL_CTX_check_private_key", NULL},
2156  {"SSL_CTX_set_session_id_context", NULL},
2157  {"SSL_CTX_ctrl", NULL},
2158  {"SSL_CTX_set_cipher_list", NULL},
2159  {"SSL_CTX_set_info_callback", NULL},
2160  {"SSL_get_ex_data", NULL},
2161  {"SSL_set_ex_data", NULL},
2162  {"SSL_CTX_callback_ctrl", NULL},
2163  {"SSL_get_servername", NULL},
2164  {"SSL_set_SSL_CTX", NULL},
2165  {"SSL_ctrl", NULL},
2166  {NULL, NULL}};
2167 
2168 
2169 /* Similar array as ssl_sw. These functions could be located in different
2170  * lib. */
2171 static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL},
2172  {"CRYPTO_set_locking_callback", NULL},
2173  {"CRYPTO_set_id_callback", NULL},
2174  {"ERR_get_error", NULL},
2175  {"ERR_error_string", NULL},
2176  {"ERR_remove_state", NULL},
2177  {"ERR_free_strings", NULL},
2178  {"ENGINE_cleanup", NULL},
2179  {"CONF_modules_unload", NULL},
2180  {"CRYPTO_cleanup_all_ex_data", NULL},
2181  {"EVP_cleanup", NULL},
2182  {"X509_free", NULL},
2183  {"X509_get_subject_name", NULL},
2184  {"X509_get_issuer_name", NULL},
2185  {"X509_NAME_oneline", NULL},
2186  {"X509_get_serialNumber", NULL},
2187  {"i2c_ASN1_INTEGER", NULL},
2188  {"EVP_get_digestbyname", NULL},
2189  {"EVP_Digest", NULL},
2190  {"i2d_X509", NULL},
2191  {"BN_bn2hex", NULL},
2192  {"ASN1_INTEGER_to_BN", NULL},
2193  {"BN_free", NULL},
2194  {"CRYPTO_free", NULL},
2195  {NULL, NULL}};
2196 #endif /* OPENSSL_API_1_1 */
2197 #endif /* NO_SSL_DL */
2198 #endif /* NO_SSL */
2199 
2200 
2201 #if !defined(NO_CACHING)
2202 static const char *month_names[] = {"Jan",
2203  "Feb",
2204  "Mar",
2205  "Apr",
2206  "May",
2207  "Jun",
2208  "Jul",
2209  "Aug",
2210  "Sep",
2211  "Oct",
2212  "Nov",
2213  "Dec"};
2214 #endif /* !NO_CACHING */
2215 
2216 /* Unified socket address. For IPv6 support, add IPv6 address structure in
2217  * the
2218  * union u. */
2219 union usa {
2220  struct sockaddr sa;
2221  struct sockaddr_in sin;
2222 #if defined(USE_IPV6)
2223  struct sockaddr_in6 sin6;
2224 #endif
2225 };
2226 
2227 /* Describes a string (chunk of memory). */
2228 struct vec {
2229  const char *ptr;
2230  size_t len;
2231 };
2232 
2233 struct mg_file_stat {
2234  /* File properties filled by mg_stat: */
2235  uint64_t size;
2236  time_t last_modified;
2237  int is_directory; /* Set to 1 if mg_stat is called for a directory */
2238  int is_gzipped; /* Set to 1 if the content is gzipped, in which
2239  * case we need a "Content-Eencoding: gzip" header */
2240  int location; /* 0 = nowhere, 1 = on disk, 2 = in memory */
2241 };
2242 
2243 struct mg_file_in_memory {
2244  char *p;
2245  uint32_t pos;
2246  char mode;
2247 };
2248 
2249 struct mg_file_access {
2250  /* File properties filled by mg_fopen: */
2251  FILE *fp;
2252 #if defined(MG_USE_OPEN_FILE)
2253  /* TODO (low): Remove obsolete "file in memory" implementation.
2254  * In an "early 2017" discussion at Google groups
2255  * https://groups.google.com/forum/#!topic/civetweb/h9HT4CmeYqI
2256  * we decided to get rid of this feature (after some fade-out
2257  * phase). */
2258  const char *membuf;
2259 #endif
2260 };
2261 
2262 struct mg_file {
2263  struct mg_file_stat stat;
2264  struct mg_file_access access;
2265 };
2266 
2267 #if defined(MG_USE_OPEN_FILE)
2268 
2269 #define STRUCT_FILE_INITIALIZER \
2270  { \
2271  {(uint64_t)0, (time_t)0, 0, 0, 0}, \
2272  { \
2273  (FILE *)NULL, (const char *)NULL \
2274  } \
2275  }
2276 
2277 #else
2278 
2279 #define STRUCT_FILE_INITIALIZER \
2280  { \
2281  {(uint64_t)0, (time_t)0, 0, 0, 0}, \
2282  { \
2283  (FILE *)NULL \
2284  } \
2285  }
2286 
2287 #endif
2288 
2289 
2290 /* Describes listening socket, or socket which was accept()-ed by the master
2291  * thread and queued for future handling by the worker thread. */
2292 struct socket {
2293  SOCKET sock; /* Listening socket */
2294  union usa lsa; /* Local socket address */
2295  union usa rsa; /* Remote socket address */
2296  unsigned char is_ssl; /* Is port SSL-ed */
2297  unsigned char ssl_redir; /* Is port supposed to redirect everything to SSL
2298  * port */
2299  unsigned char in_use; /* Is valid */
2300 };
2301 
2302 
2303 /* Enum const for all options must be in sync with
2304  * static struct mg_option config_options[]
2305  * This is tested in the unit test (test/private.c)
2306  * "Private Config Options"
2307  */
2308 enum {
2309  /* Once for each server */
2313  CONFIG_TCP_NODELAY, /* Prepended CONFIG_ to avoid conflict with the
2314  * socket option typedef TCP_NODELAY. */
2317 #if defined(__linux__)
2318  ALLOW_SENDFILE_CALL,
2319 #endif
2320 #if defined(_WIN32)
2321  CASE_SENSITIVE_FILES,
2322 #endif
2329 #if defined(USE_WEBSOCKET)
2330  WEBSOCKET_TIMEOUT,
2331  ENABLE_WEBSOCKET_PING_PONG,
2332 #endif
2334 #if defined(USE_LUA)
2335  LUA_BACKGROUND_SCRIPT,
2336  LUA_BACKGROUND_SCRIPT_PARAMS,
2337 #endif
2338 #if defined(USE_TIMERS)
2339  CGI_TIMEOUT,
2340 #endif
2341 
2342  /* Once for each domain */
2369 
2370 #if defined(USE_LUA)
2371  LUA_PRELOAD_FILE,
2372  LUA_SCRIPT_EXTENSIONS,
2373  LUA_SERVER_PAGE_EXTENSIONS,
2374 #if defined(MG_EXPERIMENTAL_INTERFACES)
2375  LUA_DEBUG_PARAMS,
2376 #endif
2377 #endif
2378 #if defined(USE_DUKTAPE)
2379  DUKTAPE_SCRIPT_EXTENSIONS,
2380 #endif
2381 
2382 #if defined(USE_WEBSOCKET)
2383  WEBSOCKET_ROOT,
2384 #endif
2385 #if defined(USE_LUA) && defined(USE_WEBSOCKET)
2386  LUA_WEBSOCKET_EXTENSIONS,
2387 #endif
2388 
2393 #if !defined(NO_CACHING)
2395 #endif
2396 #if !defined(NO_SSL)
2398 #endif
2401 
2403 };
2404 
2405 
2406 /* Config option name, config types, default value.
2407  * Must be in the same order as the enum const above.
2408  */
2409 static const struct mg_option config_options[] = {
2410 
2411  /* Once for each server */
2412  {"listening_ports", MG_CONFIG_TYPE_STRING_LIST, "8080"},
2413  {"num_threads", MG_CONFIG_TYPE_NUMBER, "50"},
2414  {"run_as_user", MG_CONFIG_TYPE_STRING, NULL},
2415  {"tcp_nodelay", MG_CONFIG_TYPE_NUMBER, "0"},
2416  {"max_request_size", MG_CONFIG_TYPE_NUMBER, "16384"},
2417  {"linger_timeout_ms", MG_CONFIG_TYPE_NUMBER, NULL},
2418 #if defined(__linux__)
2419  {"allow_sendfile_call", MG_CONFIG_TYPE_BOOLEAN, "yes"},
2420 #endif
2421 #if defined(_WIN32)
2422  {"case_sensitive", MG_CONFIG_TYPE_BOOLEAN, "no"},
2423 #endif
2424  {"throttle", MG_CONFIG_TYPE_STRING_LIST, NULL},
2425  {"access_log_file", MG_CONFIG_TYPE_FILE, NULL},
2426  {"error_log_file", MG_CONFIG_TYPE_FILE, NULL},
2427  {"enable_keep_alive", MG_CONFIG_TYPE_BOOLEAN, "no"},
2428  {"request_timeout_ms", MG_CONFIG_TYPE_NUMBER, "30000"},
2429  {"keep_alive_timeout_ms", MG_CONFIG_TYPE_NUMBER, "500"},
2430 #if defined(USE_WEBSOCKET)
2431  {"websocket_timeout_ms", MG_CONFIG_TYPE_NUMBER, NULL},
2432  {"enable_websocket_ping_pong", MG_CONFIG_TYPE_BOOLEAN, "no"},
2433 #endif
2434  {"decode_url", MG_CONFIG_TYPE_BOOLEAN, "yes"},
2435 #if defined(USE_LUA)
2436  {"lua_background_script", MG_CONFIG_TYPE_FILE, NULL},
2437  {"lua_background_script_params", MG_CONFIG_TYPE_STRING_LIST, NULL},
2438 #endif
2439 #if defined(USE_TIMERS)
2440  {"cgi_timeout_ms", MG_CONFIG_TYPE_NUMBER, NULL},
2441 #endif
2442 
2443  /* Once for each domain */
2444  {"document_root", MG_CONFIG_TYPE_DIRECTORY, NULL},
2445  {"cgi_pattern", MG_CONFIG_TYPE_EXT_PATTERN, "**.cgi$|**.pl$|**.php$"},
2446  {"cgi_environment", MG_CONFIG_TYPE_STRING_LIST, NULL},
2447  {"put_delete_auth_file", MG_CONFIG_TYPE_FILE, NULL},
2448  {"cgi_interpreter", MG_CONFIG_TYPE_FILE, NULL},
2449  {"protect_uri", MG_CONFIG_TYPE_STRING_LIST, NULL},
2450  {"authentication_domain", MG_CONFIG_TYPE_STRING, "mydomain.com"},
2451  {"enable_auth_domain_check", MG_CONFIG_TYPE_BOOLEAN, "yes"},
2452  {"ssi_pattern", MG_CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$"},
2453  {"enable_directory_listing", MG_CONFIG_TYPE_BOOLEAN, "yes"},
2454  {"global_auth_file", MG_CONFIG_TYPE_FILE, NULL},
2455  {"index_files",
2457 #if defined(USE_LUA)
2458  "index.xhtml,index.html,index.htm,"
2459  "index.lp,index.lsp,index.lua,index.cgi,"
2460  "index.shtml,index.php"},
2461 #else
2462  "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"},
2463 #endif
2464  {"access_control_list", MG_CONFIG_TYPE_STRING_LIST, NULL},
2465  {"extra_mime_types", MG_CONFIG_TYPE_STRING_LIST, NULL},
2466  {"ssl_certificate", MG_CONFIG_TYPE_FILE, NULL},
2467  {"ssl_certificate_chain", MG_CONFIG_TYPE_FILE, NULL},
2468  {"url_rewrite_patterns", MG_CONFIG_TYPE_STRING_LIST, NULL},
2469  {"hide_files_patterns", MG_CONFIG_TYPE_EXT_PATTERN, NULL},
2470 
2471  {"ssl_verify_peer", MG_CONFIG_TYPE_YES_NO_OPTIONAL, "no"},
2472 
2473  {"ssl_ca_path", MG_CONFIG_TYPE_DIRECTORY, NULL},
2474  {"ssl_ca_file", MG_CONFIG_TYPE_FILE, NULL},
2475  {"ssl_verify_depth", MG_CONFIG_TYPE_NUMBER, "9"},
2476  {"ssl_default_verify_paths", MG_CONFIG_TYPE_BOOLEAN, "yes"},
2477  {"ssl_cipher_list", MG_CONFIG_TYPE_STRING, NULL},
2478  {"ssl_protocol_version", MG_CONFIG_TYPE_NUMBER, "0"},
2479  {"ssl_short_trust", MG_CONFIG_TYPE_BOOLEAN, "no"},
2480 
2481 #if defined(USE_LUA)
2482  {"lua_preload_file", MG_CONFIG_TYPE_FILE, NULL},
2483  {"lua_script_pattern", MG_CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
2484  {"lua_server_page_pattern", MG_CONFIG_TYPE_EXT_PATTERN, "**.lp$|**.lsp$"},
2485 #if defined(MG_EXPERIMENTAL_INTERFACES)
2486  {"lua_debug", MG_CONFIG_TYPE_STRING, NULL},
2487 #endif
2488 #endif
2489 #if defined(USE_DUKTAPE)
2490  /* The support for duktape is still in alpha version state.
2491  * The name of this config option might change. */
2492  {"duktape_script_pattern", MG_CONFIG_TYPE_EXT_PATTERN, "**.ssjs$"},
2493 #endif
2494 
2495 #if defined(USE_WEBSOCKET)
2496  {"websocket_root", MG_CONFIG_TYPE_DIRECTORY, NULL},
2497 #endif
2498 #if defined(USE_LUA) && defined(USE_WEBSOCKET)
2499  {"lua_websocket_pattern", MG_CONFIG_TYPE_EXT_PATTERN, "**.lua$"},
2500 #endif
2501  {"access_control_allow_origin", MG_CONFIG_TYPE_STRING, "*"},
2502  {"access_control_allow_methods", MG_CONFIG_TYPE_STRING, "*"},
2503  {"access_control_allow_headers", MG_CONFIG_TYPE_STRING, "*"},
2504  {"error_pages", MG_CONFIG_TYPE_DIRECTORY, NULL},
2505 #if !defined(NO_CACHING)
2506  {"static_file_max_age", MG_CONFIG_TYPE_NUMBER, "3600"},
2507 #endif
2508 #if !defined(NO_SSL)
2509  {"strict_transport_security_max_age", MG_CONFIG_TYPE_NUMBER, NULL},
2510 #endif
2511  {"additional_header", MG_CONFIG_TYPE_STRING_MULTILINE, NULL},
2512  {"allow_index_script_resource", MG_CONFIG_TYPE_BOOLEAN, "no"},
2513 
2514  {NULL, MG_CONFIG_TYPE_UNKNOWN, NULL}};
2515 
2516 
2517 /* Check if the config_options and the corresponding enum have compatible
2518  * sizes. */
2519 mg_static_assert((sizeof(config_options) / sizeof(config_options[0]))
2520  == (NUM_OPTIONS + 1),
2521  "config_options and enum not sync");
2522 
2523 
2525 
2526 
2527 struct mg_handler_info {
2528  /* Name/Pattern of the URI. */
2529  char *uri;
2530  size_t uri_len;
2531 
2532  /* handler type */
2533  int handler_type;
2534 
2535  /* Handler for http/https or authorization requests. */
2536  mg_request_handler handler;
2537  unsigned int refcount;
2538  pthread_mutex_t refcount_mutex; /* Protects refcount */
2540  refcount_cond; /* Signaled when handler refcount is decremented */
2541 
2542  /* Handler for ws/wss (websocket) requests. */
2543  mg_websocket_connect_handler connect_handler;
2544  mg_websocket_ready_handler ready_handler;
2545  mg_websocket_data_handler data_handler;
2546  mg_websocket_close_handler close_handler;
2547 
2548  /* accepted subprotocols for ws/wss requests. */
2550 
2551  /* Handler for authorization requests */
2552  mg_authorization_handler auth_handler;
2553 
2554  /* User supplied argument for the handler function. */
2555  void *cbdata;
2556 
2557  /* next handler in a linked list */
2558  struct mg_handler_info *next;
2559 };
2560 
2561 
2562 enum {
2567 };
2568 
2569 
2570 struct mg_domain_context {
2571  SSL_CTX *ssl_ctx; /* SSL context */
2572  char *config[NUM_OPTIONS]; /* Civetweb configuration parameters */
2573  struct mg_handler_info *handlers; /* linked list of uri handlers */
2574 
2575  /* Server nonce */
2576  uint64_t auth_nonce_mask; /* Mask for all nonce values */
2577  unsigned long nonce_count; /* Used nonces, used for authentication */
2578 
2579 #if defined(USE_LUA) && defined(USE_WEBSOCKET)
2580  /* linked list of shared lua websockets */
2581  struct mg_shared_lua_websocket_list *shared_lua_websockets;
2582 #endif
2583 
2584  /* Linked list of domains */
2585  struct mg_domain_context *next;
2586 };
2587 
2588 
2589 struct mg_context {
2590 
2591  /* Part 1 - Physical context:
2592  * This holds threads, ports, timeouts, ...
2593  * set for the entire server, independent from the
2594  * addressed hostname.
2595  */
2596 
2597  /* Connection related */
2598  int context_type; /* See CONTEXT_* above */
2599 
2600  struct socket *listening_sockets;
2601  struct pollfd *listening_socket_fds;
2602  unsigned int num_listening_sockets;
2603 
2604  struct mg_connection *worker_connections; /* The connection struct, pre-
2605  * allocated for each worker */
2606 
2607 #if defined(USE_SERVER_STATS)
2608  int active_connections;
2609  int max_connections;
2610  int64_t total_connections;
2611  int64_t total_requests;
2612  int64_t total_data_read;
2613  int64_t total_data_written;
2614 #endif
2615 
2616  /* Thread related */
2617  volatile int stop_flag; /* Should we stop event loop */
2618  pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */
2619 
2620  pthread_t masterthreadid; /* The master thread ID */
2621  unsigned int
2622  cfg_worker_threads; /* The number of configured worker threads. */
2623  pthread_t *worker_threadids; /* The worker thread IDs */
2624 
2625 /* Connection to thread dispatching */
2626 #if defined(ALTERNATIVE_QUEUE)
2627  struct socket *client_socks;
2628  void **client_wait_events;
2629 #else
2630  struct socket queue[MGSQLEN]; /* Accepted sockets */
2631  volatile int sq_head; /* Head of the socket queue */
2632  volatile int sq_tail; /* Tail of the socket queue */
2633  pthread_cond_t sq_full; /* Signaled when socket is produced */
2634  pthread_cond_t sq_empty; /* Signaled when socket is consumed */
2635 #endif
2636 
2637  /* Memory related */
2638  unsigned int max_request_size; /* The max request size */
2639 
2640 #if defined(USE_SERVER_STATS)
2641  struct mg_memory_stat ctx_memory;
2642 #endif
2643 
2644  /* Operating system related */
2645  char *systemName; /* What operating system is running */
2646  time_t start_time; /* Server start time, used for authentication
2647  * and for diagnstics. */
2648 
2649 #if defined(USE_TIMERS)
2650  struct ttimers *timers;
2651 #endif
2652 
2653 /* Lua specific: Background operations and shared websockets */
2654 #if defined(USE_LUA)
2655  void *lua_background_state;
2656 #endif
2657 
2658  /* Server nonce */
2659  pthread_mutex_t nonce_mutex; /* Protects nonce_count */
2660 
2661  /* Server callbacks */
2662  struct mg_callbacks callbacks; /* User-defined callback function */
2663  void *user_data; /* User-defined data */
2664 
2665  /* Part 2 - Logical domain:
2666  * This holds hostname, TLS certificate, document root, ...
2667  * set for a domain hosted at the server.
2668  * There may be multiple domains hosted at one physical server.
2669  * The default domain "dd" is the first element of a list of
2670  * domains.
2671  */
2672  struct mg_domain_context dd; /* default domain */
2673 };
2674 
2675 
2676 #if defined(USE_SERVER_STATS)
2677 static struct mg_memory_stat mg_common_memory = {0, 0, 0};
2678 
2679 static struct mg_memory_stat *
2680 get_memory_stat(struct mg_context *ctx)
2681 {
2682  if (ctx) {
2683  return &(ctx->ctx_memory);
2684  }
2685  return &mg_common_memory;
2686 }
2687 #endif
2688 
2689 enum {
2693 };
2694 
2695 struct mg_connection {
2696  int connection_type; /* see CONNECTION_TYPE_* above */
2697 
2698  struct mg_request_info request_info;
2699  struct mg_response_info response_info;
2700 
2701  struct mg_context *phys_ctx;
2702  struct mg_domain_context *dom_ctx;
2703 
2704 #if defined(USE_SERVER_STATS)
2705  int conn_state; /* 0 = undef, numerical value may change in different
2706  * versions. For the current definition, see
2707  * mg_get_connection_info_impl */
2708 #endif
2709 
2710  const char *host; /* Host (HTTP/1.1 header or SNI) */
2711  SSL *ssl; /* SSL descriptor */
2712  SSL_CTX *client_ssl_ctx; /* SSL context for client connections */
2713  struct socket client; /* Connected client */
2714  time_t conn_birth_time; /* Time (wall clock) when connection was
2715  * established */
2716  struct timespec req_time; /* Time (since system start) when the request
2717  * was received */
2718  int64_t num_bytes_sent; /* Total bytes sent to client */
2719  int64_t content_len; /* Content-Length header value */
2720  int64_t consumed_content; /* How many bytes of content have been read */
2721  int is_chunked; /* Transfer-Encoding is chunked:
2722  * 0 = not chunked,
2723  * 1 = chunked, do data read yet,
2724  * 2 = chunked, some data read,
2725  * 3 = chunked, all data read
2726  */
2727  size_t chunk_remainder; /* Unread data from the last chunk */
2728  char *buf; /* Buffer for received data */
2729  char *path_info; /* PATH_INFO part of the URL */
2730 
2731  int must_close; /* 1 if connection must be closed */
2732  int accept_gzip; /* 1 if gzip encoding is accepted */
2733  int in_error_handler; /* 1 if in handler for user defined error
2734  * pages */
2735 #if defined(USE_WEBSOCKET)
2736  int in_websocket_handling; /* 1 if in read_websocket */
2737 #endif
2738  int handled_requests; /* Number of requests handled by this connection
2739  */
2740  int buf_size; /* Buffer size */
2741  int request_len; /* Size of the request + headers in a buffer */
2742  int data_len; /* Total size of data in a buffer */
2743  int status_code; /* HTTP reply status code, e.g. 200 */
2744  int throttle; /* Throttling, bytes/sec. <= 0 means no
2745  * throttle */
2746 
2747  time_t last_throttle_time; /* Last time throttled data was sent */
2748  int64_t last_throttle_bytes; /* Bytes sent this second */
2749  pthread_mutex_t mutex; /* Used by mg_(un)lock_connection to ensure
2750  * atomic transmissions for websockets */
2751 #if defined(USE_LUA) && defined(USE_WEBSOCKET)
2752  void *lua_websocket_state; /* Lua_State for a websocket connection */
2753 #endif
2754 
2755  int thread_index; /* Thread index within ctx */
2756 };
2757 
2758 
2759 /* Directory entry */
2760 struct de {
2761  struct mg_connection *conn;
2762  char *file_name;
2763  struct mg_file_stat file;
2764 };
2765 
2766 
2767 #if defined(USE_WEBSOCKET)
2768 static int is_websocket_protocol(const struct mg_connection *conn);
2769 #else
2770 #define is_websocket_protocol(conn) (0)
2771 #endif
2772 
2773 
2774 #define mg_cry_internal(conn, fmt, ...) \
2775  mg_cry_internal_wrap(conn, __func__, __LINE__, fmt, __VA_ARGS__)
2776 
2777 static void mg_cry_internal_wrap(const struct mg_connection *conn,
2778  const char *func,
2779  unsigned line,
2780  const char *fmt,
2781  ...) PRINTF_ARGS(4, 5);
2782 
2783 
2784 #if !defined(NO_THREAD_NAME)
2785 #if defined(_WIN32) && defined(_MSC_VER)
2786 /* Set the thread name for debugging purposes in Visual Studio
2787  * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
2788  */
2789 #pragma pack(push, 8)
2790 typedef struct tagTHREADNAME_INFO {
2791  DWORD dwType; /* Must be 0x1000. */
2792  LPCSTR szName; /* Pointer to name (in user addr space). */
2793  DWORD dwThreadID; /* Thread ID (-1=caller thread). */
2794  DWORD dwFlags; /* Reserved for future use, must be zero. */
2795 } THREADNAME_INFO;
2796 #pragma pack(pop)
2797 
2798 #elif defined(__linux__)
2799 
2800 #include <sys/prctl.h>
2801 #include <sys/sendfile.h>
2802 #if defined(ALTERNATIVE_QUEUE)
2803 #include <sys/eventfd.h>
2804 #endif /* ALTERNATIVE_QUEUE */
2805 
2806 
2807 #if defined(ALTERNATIVE_QUEUE)
2808 
2809 static void *
2810 event_create(void)
2811 {
2812  int evhdl = eventfd(0, EFD_CLOEXEC);
2813  int *ret;
2814 
2815  if (evhdl == -1) {
2816  /* Linux uses -1 on error, Windows NULL. */
2817  /* However, Linux does not return 0 on success either. */
2818  return 0;
2819  }
2820 
2821  ret = (int *)mg_malloc(sizeof(int));
2822  if (ret) {
2823  *ret = evhdl;
2824  } else {
2825  (void)close(evhdl);
2826  }
2827 
2828  return (void *)ret;
2829 }
2830 
2831 
2832 static int
2833 event_wait(void *eventhdl)
2834 {
2835  uint64_t u;
2836  int evhdl, s;
2837 
2838  if (!eventhdl) {
2839  /* error */
2840  return 0;
2841  }
2842  evhdl = *(int *)eventhdl;
2843 
2844  s = (int)read(evhdl, &u, sizeof(u));
2845  if (s != sizeof(u)) {
2846  /* error */
2847  return 0;
2848  }
2849  (void)u; /* the value is not required */
2850  return 1;
2851 }
2852 
2853 
2854 static int
2855 event_signal(void *eventhdl)
2856 {
2857  uint64_t u = 1;
2858  int evhdl, s;
2859 
2860  if (!eventhdl) {
2861  /* error */
2862  return 0;
2863  }
2864  evhdl = *(int *)eventhdl;
2865 
2866  s = (int)write(evhdl, &u, sizeof(u));
2867  if (s != sizeof(u)) {
2868  /* error */
2869  return 0;
2870  }
2871  return 1;
2872 }
2873 
2874 
2875 static void
2876 event_destroy(void *eventhdl)
2877 {
2878  int evhdl;
2879 
2880  if (!eventhdl) {
2881  /* error */
2882  return;
2883  }
2884  evhdl = *(int *)eventhdl;
2885 
2886  close(evhdl);
2887  mg_free(eventhdl);
2888 }
2889 
2890 
2891 #endif
2892 
2893 #endif
2894 
2895 
2896 #if !defined(__linux__) && !defined(_WIN32) && defined(ALTERNATIVE_QUEUE)
2897 
2898 struct posix_event {
2899  pthread_mutex_t mutex;
2900  pthread_cond_t cond;
2901 };
2902 
2903 
2904 static void *
2906 {
2907  struct posix_event *ret = mg_malloc(sizeof(struct posix_event));
2908  if (ret == 0) {
2909  /* out of memory */
2910  return 0;
2911  }
2912  if (0 != pthread_mutex_init(&(ret->mutex), NULL)) {
2913  /* pthread mutex not available */
2914  mg_free(ret);
2915  return 0;
2916  }
2917  if (0 != pthread_cond_init(&(ret->cond), NULL)) {
2918  /* pthread cond not available */
2919  pthread_mutex_destroy(&(ret->mutex));
2920  mg_free(ret);
2921  return 0;
2922  }
2923  return (void *)ret;
2924 }
2925 
2926 
2927 static int
2928 event_wait(void *eventhdl)
2929 {
2930  struct posix_event *ev = (struct posix_event *)eventhdl;
2931  pthread_mutex_lock(&(ev->mutex));
2932  pthread_cond_wait(&(ev->cond), &(ev->mutex));
2933  pthread_mutex_unlock(&(ev->mutex));
2934  return 1;
2935 }
2936 
2937 
2938 static int
2939 event_signal(void *eventhdl)
2940 {
2941  struct posix_event *ev = (struct posix_event *)eventhdl;
2942  pthread_mutex_lock(&(ev->mutex));
2943  pthread_cond_signal(&(ev->cond));
2944  pthread_mutex_unlock(&(ev->mutex));
2945  return 1;
2946 }
2947 
2948 
2949 static void
2950 event_destroy(void *eventhdl)
2951 {
2952  struct posix_event *ev = (struct posix_event *)eventhdl;
2953  pthread_cond_destroy(&(ev->cond));
2954  pthread_mutex_destroy(&(ev->mutex));
2955  mg_free(ev);
2956 }
2957 #endif
2958 
2959 
2960 static void
2962 {
2963  char threadName[16 + 1]; /* 16 = Max. thread length in Linux/OSX/.. */
2964 
2965  mg_snprintf(
2966  NULL, NULL, threadName, sizeof(threadName), "civetweb-%s", name);
2967 
2968 #if defined(_WIN32)
2969 #if defined(_MSC_VER)
2970  /* Windows and Visual Studio Compiler */
2971  __try {
2972  THREADNAME_INFO info;
2973  info.dwType = 0x1000;
2974  info.szName = threadName;
2975  info.dwThreadID = ~0U;
2976  info.dwFlags = 0;
2977 
2978  RaiseException(0x406D1388,
2979  0,
2980  sizeof(info) / sizeof(ULONG_PTR),
2981  (ULONG_PTR *)&info);
2982  } __except (EXCEPTION_EXECUTE_HANDLER) {
2983  }
2984 #elif defined(__MINGW32__)
2985 /* No option known to set thread name for MinGW */
2986 #endif
2987 #elif defined(_GNU_SOURCE) && defined(__GLIBC__) \
2988  && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12)))
2989 /* pthread_setname_np first appeared in glibc in version 2.12*/
2990 #if defined(__MACH__)
2991  /* OS X only current thread name can be changed */
2992  (void)pthread_setname_np(threadName);
2993 #else
2994  (void)pthread_setname_np(pthread_self(), threadName);
2995 #endif
2996 #elif defined(__linux__)
2997  /* on linux we can use the old prctl function */
2998  (void)prctl(PR_SET_NAME, threadName, 0, 0, 0);
2999 #endif
3000 }
3001 #else /* !defined(NO_THREAD_NAME) */
3002 void
3003 mg_set_thread_name(const char *threadName)
3004 {
3005 }
3006 #endif
3007 
3008 
3009 #if defined(MG_LEGACY_INTERFACE)
3010 const char **
3011 mg_get_valid_option_names(void)
3012 {
3013  /* This function is deprecated. Use mg_get_valid_options instead. */
3014  static const char
3015  *data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0};
3016  int i;
3017 
3018  for (i = 0; config_options[i].name != NULL; i++) {
3019  data[i * 2] = config_options[i].name;
3020  data[i * 2 + 1] = config_options[i].default_value;
3021  }
3022 
3023  return data;
3024 }
3025 #endif
3026 
3027 
3028 const struct mg_option *
3030 {
3031  return config_options;
3032 }
3033 
3034 
3035 /* Do not open file (used in is_file_in_memory) */
3036 #define MG_FOPEN_MODE_NONE (0)
3037 
3038 /* Open file for read only access */
3039 #define MG_FOPEN_MODE_READ (1)
3040 
3041 /* Open file for writing, create and overwrite */
3042 #define MG_FOPEN_MODE_WRITE (2)
3043 
3044 /* Open file for writing, create and append */
3045 #define MG_FOPEN_MODE_APPEND (4)
3046 
3047 
3048 /* If a file is in memory, set all "stat" members and the membuf pointer of
3049  * output filep and return 1, otherwise return 0 and don't modify anything.
3050  */
3051 static int
3052 open_file_in_memory(const struct mg_connection *conn,
3053  const char *path,
3054  struct mg_file *filep,
3055  int mode)
3056 {
3057 #if defined(MG_USE_OPEN_FILE)
3058 
3059  size_t size = 0;
3060  const char *buf = NULL;
3061  if (!conn) {
3062  return 0;
3063  }
3064 
3065  if ((mode != MG_FOPEN_MODE_NONE) && (mode != MG_FOPEN_MODE_READ)) {
3066  return 0;
3067  }
3068 
3069  if (conn->phys_ctx->callbacks.open_file) {
3070  buf = conn->phys_ctx->callbacks.open_file(conn, path, &size);
3071  if (buf != NULL) {
3072  if (filep == NULL) {
3073  /* This is a file in memory, but we cannot store the
3074  * properties
3075  * now.
3076  * Called from "is_file_in_memory" function. */
3077  return 1;
3078  }
3079 
3080  /* NOTE: override filep->size only on success. Otherwise, it
3081  * might
3082  * break constructs like if (!mg_stat() || !mg_fopen()) ... */
3083  filep->access.membuf = buf;
3084  filep->access.fp = NULL;
3085 
3086  /* Size was set by the callback */
3087  filep->stat.size = size;
3088 
3089  /* Assume the data may change during runtime by setting
3090  * last_modified = now */
3091  filep->stat.last_modified = time(NULL);
3092 
3093  filep->stat.is_directory = 0;
3094  filep->stat.is_gzipped = 0;
3095  }
3096  }
3097 
3098  return (buf != NULL);
3099 
3100 #else
3101  (void)conn;
3102  (void)path;
3103  (void)filep;
3104  (void)mode;
3105 
3106  return 0;
3107 
3108 #endif
3109 }
3110 
3111 
3112 static int
3113 is_file_in_memory(const struct mg_connection *conn, const char *path)
3114 {
3115  return open_file_in_memory(conn, path, NULL, MG_FOPEN_MODE_NONE);
3116 }
3117 
3118 
3119 static int
3120 is_file_opened(const struct mg_file_access *fileacc)
3121 {
3122  if (!fileacc) {
3123  return 0;
3124  }
3125 
3126 #if defined(MG_USE_OPEN_FILE)
3127  return (fileacc->membuf != NULL) || (fileacc->fp != NULL);
3128 #else
3129  return (fileacc->fp != NULL);
3130 #endif
3131 }
3132 
3133 
3134 static int mg_stat(const struct mg_connection *conn,
3135  const char *path,
3136  struct mg_file_stat *filep);
3137 
3138 
3139 /* mg_fopen will open a file either in memory or on the disk.
3140  * The input parameter path is a string in UTF-8 encoding.
3141  * The input parameter mode is MG_FOPEN_MODE_*
3142  * On success, either fp or membuf will be set in the output
3143  * struct file. All status members will also be set.
3144  * The function returns 1 on success, 0 on error. */
3145 static int
3146 mg_fopen(const struct mg_connection *conn,
3147  const char *path,
3148  int mode,
3149  struct mg_file *filep)
3150 {
3151  int found;
3152 
3153  if (!filep) {
3154  return 0;
3155  }
3156  filep->access.fp = NULL;
3157 #if defined(MG_USE_OPEN_FILE)
3158  filep->access.membuf = NULL;
3159 #endif
3160 
3161  if (!is_file_in_memory(conn, path)) {
3162 
3163  /* filep is initialized in mg_stat: all fields with memset to,
3164  * some fields like size and modification date with values */
3165  found = mg_stat(conn, path, &(filep->stat));
3166 
3167  if ((mode == MG_FOPEN_MODE_READ) && (!found)) {
3168  /* file does not exist and will not be created */
3169  return 0;
3170  }
3171 
3172 #if defined(_WIN32)
3173  {
3174  wchar_t wbuf[W_PATH_MAX];
3175  path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf));
3176  switch (mode) {
3177  case MG_FOPEN_MODE_READ:
3178  filep->access.fp = _wfopen(wbuf, L"rb");
3179  break;
3180  case MG_FOPEN_MODE_WRITE:
3181  filep->access.fp = _wfopen(wbuf, L"wb");
3182  break;
3183  case MG_FOPEN_MODE_APPEND:
3184  filep->access.fp = _wfopen(wbuf, L"ab");
3185  break;
3186  }
3187  }
3188 #else
3189  /* Linux et al already use unicode. No need to convert. */
3190  switch (mode) {
3191  case MG_FOPEN_MODE_READ:
3192  filep->access.fp = fopen(path, "r");
3193  break;
3194  case MG_FOPEN_MODE_WRITE:
3195  filep->access.fp = fopen(path, "w");
3196  break;
3197  case MG_FOPEN_MODE_APPEND:
3198  filep->access.fp = fopen(path, "a");
3199  break;
3200  }
3201 
3202 #endif
3203  if (!found) {
3204  /* File did not exist before fopen was called.
3205  * Maybe it has been created now. Get stat info
3206  * like creation time now. */
3207  found = mg_stat(conn, path, &(filep->stat));
3208  (void)found;
3209  }
3210 
3211  /* file is on disk */
3212  return (filep->access.fp != NULL);
3213 
3214  } else {
3215 #if defined(MG_USE_OPEN_FILE)
3216  /* is_file_in_memory returned true */
3217  if (open_file_in_memory(conn, path, filep, mode)) {
3218  /* file is in memory */
3219  return (filep->access.membuf != NULL);
3220  }
3221 #endif
3222  }
3223 
3224  /* Open failed */
3225  return 0;
3226 }
3227 
3228 
3229 /* return 0 on success, just like fclose */
3230 static int
3231 mg_fclose(struct mg_file_access *fileacc)
3232 {
3233  int ret = -1;
3234  if (fileacc != NULL) {
3235  if (fileacc->fp != NULL) {
3236  ret = fclose(fileacc->fp);
3237 #if defined(MG_USE_OPEN_FILE)
3238  } else if (fileacc->membuf != NULL) {
3239  ret = 0;
3240 #endif
3241  }
3242  /* reset all members of fileacc */
3243  memset(fileacc, 0, sizeof(*fileacc));
3244  }
3245  return ret;
3246 }
3247 
3248 
3249 static void
3250 mg_strlcpy(register char *dst, register const char *src, size_t n)
3251 {
3252  for (; *src != '\0' && n > 1; n--) {
3253  *dst++ = *src++;
3254  }
3255  *dst = '\0';
3256 }
3257 
3258 
3259 static int
3260 lowercase(const char *s)
3261 {
3262  return tolower(*(const unsigned char *)s);
3263 }
3264 
3265 
3266 int
3267 mg_strncasecmp(const char *s1, const char *s2, size_t len)
3268 {
3269  int diff = 0;
3270 
3271  if (len > 0) {
3272  do {
3273  diff = lowercase(s1++) - lowercase(s2++);
3274  } while (diff == 0 && s1[-1] != '\0' && --len > 0);
3275  }
3276 
3277  return diff;
3278 }
3279 
3280 
3281 int
3282 mg_strcasecmp(const char *s1, const char *s2)
3283 {
3284  int diff;
3285 
3286  do {
3287  diff = lowercase(s1++) - lowercase(s2++);
3288  } while (diff == 0 && s1[-1] != '\0');
3289 
3290  return diff;
3291 }
3292 
3293 
3294 static char *
3295 mg_strndup_ctx(const char *ptr, size_t len, struct mg_context *ctx)
3296 {
3297  char *p;
3298  (void)ctx; /* Avoid Visual Studio warning if USE_SERVER_STATS is not
3299  * defined */
3300 
3301  if ((p = (char *)mg_malloc_ctx(len + 1, ctx)) != NULL) {
3302  mg_strlcpy(p, ptr, len + 1);
3303  }
3304 
3305  return p;
3306 }
3307 
3308 
3309 static char *
3310 mg_strdup_ctx(const char *str, struct mg_context *ctx)
3311 {
3312  return mg_strndup_ctx(str, strlen(str), ctx);
3313 }
3314 
3315 static char *
3316 mg_strdup(const char *str)
3317 {
3318  return mg_strndup_ctx(str, strlen(str), NULL);
3319 }
3320 
3321 
3322 static const char *
3323 mg_strcasestr(const char *big_str, const char *small_str)
3324 {
3325  size_t i, big_len = strlen(big_str), small_len = strlen(small_str);
3326 
3327  if (big_len >= small_len) {
3328  for (i = 0; i <= (big_len - small_len); i++) {
3329  if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) {
3330  return big_str + i;
3331  }
3332  }
3333  }
3334 
3335  return NULL;
3336 }
3337 
3338 
3339 /* Return null terminated string of given maximum length.
3340  * Report errors if length is exceeded. */
3341 static void
3342 mg_vsnprintf(const struct mg_connection *conn,
3343  int *truncated,
3344  char *buf,
3345  size_t buflen,
3346  const char *fmt,
3347  va_list ap)
3348 {
3349  int n, ok;
3350 
3351  if (buflen == 0) {
3352  if (truncated) {
3353  *truncated = 1;
3354  }
3355  return;
3356  }
3357 
3358 #if defined(__clang__)
3359 #pragma clang diagnostic push
3360 #pragma clang diagnostic ignored "-Wformat-nonliteral"
3361 /* Using fmt as a non-literal is intended here, since it is mostly called
3362  * indirectly by mg_snprintf */
3363 #endif
3364 
3365  n = (int)vsnprintf_impl(buf, buflen, fmt, ap);
3366  ok = (n >= 0) && ((size_t)n < buflen);
3367 
3368 #if defined(__clang__)
3369 #pragma clang diagnostic pop
3370 #endif
3371 
3372  if (ok) {
3373  if (truncated) {
3374  *truncated = 0;
3375  }
3376  } else {
3377  if (truncated) {
3378  *truncated = 1;
3379  }
3380  mg_cry_internal(conn,
3381  "truncating vsnprintf buffer: [%.*s]",
3382  (int)((buflen > 200) ? 200 : (buflen - 1)),
3383  buf);
3384  n = (int)buflen - 1;
3385  }
3386  buf[n] = '\0';
3387 }
3388 
3389 
3390 static void
3391 mg_snprintf(const struct mg_connection *conn,
3392  int *truncated,
3393  char *buf,
3394  size_t buflen,
3395  const char *fmt,
3396  ...)
3397 {
3398  va_list ap;
3399 
3400  va_start(ap, fmt);
3401  mg_vsnprintf(conn, truncated, buf, buflen, fmt, ap);
3402  va_end(ap);
3403 }
3404 
3405 
3406 static int
3408 {
3409  int i;
3410 
3411  for (i = 0; config_options[i].name != NULL; i++) {
3412  if (strcmp(config_options[i].name, name) == 0) {
3413  return i;
3414  }
3415  }
3416  return -1;
3417 }
3418 
3419 
3420 const char *
3421 mg_get_option(const struct mg_context *ctx, const char *name)
3422 {
3423  int i;
3424  if ((i = get_option_index(name)) == -1) {
3425  return NULL;
3426  } else if (!ctx || ctx->dd.config[i] == NULL) {
3427  return "";
3428  } else {
3429  return ctx->dd.config[i];
3430  }
3431 }
3432 
3433 #define mg_get_option DO_NOT_USE_THIS_FUNCTION_INTERNALLY__access_directly
3434 
3435 struct mg_context *
3436 mg_get_context(const struct mg_connection *conn)
3437 {
3438  return (conn == NULL) ? (struct mg_context *)NULL : (conn->phys_ctx);
3439 }
3440 
3441 
3442 void *
3443 mg_get_user_data(const struct mg_context *ctx)
3444 {
3445  return (ctx == NULL) ? NULL : ctx->user_data;
3446 }
3447 
3448 
3449 void
3450 mg_set_user_connection_data(struct mg_connection *conn, void *data)
3451 {
3452  if (conn != NULL) {
3453  conn->request_info.conn_data = data;
3454  }
3455 }
3456 
3457 
3458 void *
3459 mg_get_user_connection_data(const struct mg_connection *conn)
3460 {
3461  if (conn != NULL) {
3462  return conn->request_info.conn_data;
3463  }
3464  return NULL;
3465 }
3466 
3467 
3468 #if defined(MG_LEGACY_INTERFACE)
3469 /* Deprecated: Use mg_get_server_ports instead. */
3470 size_t
3471 mg_get_ports(const struct mg_context *ctx, size_t size, int *ports, int *ssl)
3472 {
3473  size_t i;
3474  if (!ctx) {
3475  return 0;
3476  }
3477  for (i = 0; i < size && i < ctx->num_listening_sockets; i++) {
3478  ssl[i] = ctx->listening_sockets[i].is_ssl;
3479  ports[i] =
3480 #if defined(USE_IPV6)
3481  (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET6)
3482  ? ntohs(ctx->listening_sockets[i].lsa.sin6.sin6_port)
3483  :
3484 #endif
3485  ntohs(ctx->listening_sockets[i].lsa.sin.sin_port);
3486  }
3487  return i;
3488 }
3489 #endif
3490 
3491 
3492 int
3493 mg_get_server_ports(const struct mg_context *ctx,
3494  int size,
3495  struct mg_server_ports *ports)
3496 {
3497  int i, cnt = 0;
3498 
3499  if (size <= 0) {
3500  return -1;
3501  }
3502  memset(ports, 0, sizeof(*ports) * (size_t)size);
3503  if (!ctx) {
3504  return -1;
3505  }
3506  if (!ctx->listening_sockets) {
3507  return -1;
3508  }
3509 
3510  for (i = 0; (i < size) && (i < (int)ctx->num_listening_sockets); i++) {
3511 
3512  ports[cnt].port =
3513 #if defined(USE_IPV6)
3514  (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET6)
3515  ? ntohs(ctx->listening_sockets[i].lsa.sin6.sin6_port)
3516  :
3517 #endif
3518  ntohs(ctx->listening_sockets[i].lsa.sin.sin_port);
3519  ports[cnt].is_ssl = ctx->listening_sockets[i].is_ssl;
3520  ports[cnt].is_redirect = ctx->listening_sockets[i].ssl_redir;
3521 
3522  if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET) {
3523  /* IPv4 */
3524  ports[cnt].protocol = 1;
3525  cnt++;
3526  } else if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET6) {
3527  /* IPv6 */
3528  ports[cnt].protocol = 3;
3529  cnt++;
3530  }
3531  }
3532 
3533  return cnt;
3534 }
3535 
3536 
3537 static void
3538 sockaddr_to_string(char *buf, size_t len, const union usa *usa)
3539 {
3540  buf[0] = '\0';
3541 
3542  if (!usa) {
3543  return;
3544  }
3545 
3546  if (usa->sa.sa_family == AF_INET) {
3547  getnameinfo(&usa->sa,
3548  sizeof(usa->sin),
3549  buf,
3550  (unsigned)len,
3551  NULL,
3552  0,
3553  NI_NUMERICHOST);
3554  }
3555 #if defined(USE_IPV6)
3556  else if (usa->sa.sa_family == AF_INET6) {
3557  getnameinfo(&usa->sa,
3558  sizeof(usa->sin6),
3559  buf,
3560  (unsigned)len,
3561  NULL,
3562  0,
3563  NI_NUMERICHOST);
3564  }
3565 #endif
3566 }
3567 
3568 
3569 /* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be
3570  * included in all responses other than 100, 101, 5xx. */
3571 static void
3572 gmt_time_string(char *buf, size_t buf_len, time_t *t)
3573 {
3574 #if !defined(REENTRANT_TIME)
3575  struct tm *tm;
3576 
3577  tm = ((t != NULL) ? gmtime(t) : NULL);
3578  if (tm != NULL) {
3579 #else
3580  struct tm _tm;
3581  struct tm *tm = &_tm;
3582 
3583  if (t != NULL) {
3584  gmtime_r(t, tm);
3585 #endif
3586  strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm);
3587  } else {
3588  mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len);
3589  buf[buf_len - 1] = '\0';
3590  }
3591 }
3592 
3593 
3594 /* difftime for struct timespec. Return value is in seconds. */
3595 static double
3596 mg_difftimespec(const struct timespec *ts_now, const struct timespec *ts_before)
3597 {
3598  return (double)(ts_now->tv_nsec - ts_before->tv_nsec) * 1.0E-9
3599  + (double)(ts_now->tv_sec - ts_before->tv_sec);
3600 }
3601 
3602 
3603 #if defined(MG_EXTERNAL_FUNCTION_mg_cry_internal_impl)
3604 static void mg_cry_internal_impl(const struct mg_connection *conn,
3605  const char *func,
3606  unsigned line,
3607  const char *fmt,
3608  va_list ap);
3609 #include "external_mg_cry_internal_impl.inl"
3610 #else
3611 
3612 /* Print error message to the opened error log stream. */
3613 static void
3614 mg_cry_internal_impl(const struct mg_connection *conn,
3615  const char *func,
3616  unsigned line,
3617  const char *fmt,
3618  va_list ap)
3619 {
3620  char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN];
3621  struct mg_file fi;
3622  time_t timestamp;
3623 
3624  /* Unused, in the RELEASE build */
3625  (void)func;
3626  (void)line;
3627 
3628 #if defined(GCC_DIAGNOSTIC)
3629 #pragma GCC diagnostic push
3630 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
3631 #endif
3632 
3633  IGNORE_UNUSED_RESULT(vsnprintf_impl(buf, sizeof(buf), fmt, ap));
3634 
3635 #if defined(GCC_DIAGNOSTIC)
3636 #pragma GCC diagnostic pop
3637 #endif
3638 
3639  buf[sizeof(buf) - 1] = 0;
3640 
3641  DEBUG_TRACE("mg_cry called from %s:%u: %s", func, line, buf);
3642 
3643  if (!conn) {
3644  puts(buf);
3645  return;
3646  }
3647 
3648  /* Do not lock when getting the callback value, here and below.
3649  * I suppose this is fine, since function cannot disappear in the
3650  * same way string option can. */
3651  if ((conn->phys_ctx->callbacks.log_message == NULL)
3652  || (conn->phys_ctx->callbacks.log_message(conn, buf) == 0)) {
3653 
3654  if (conn->dom_ctx->config[ERROR_LOG_FILE] != NULL) {
3655  if (mg_fopen(conn,
3656  conn->dom_ctx->config[ERROR_LOG_FILE],
3658  &fi)
3659  == 0) {
3660  fi.access.fp = NULL;
3661  }
3662  } else {
3663  fi.access.fp = NULL;
3664  }
3665 
3666  if (fi.access.fp != NULL) {
3667  flockfile(fi.access.fp);
3668  timestamp = time(NULL);
3669 
3670  sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
3671  fprintf(fi.access.fp,
3672  "[%010lu] [error] [client %s] ",
3673  (unsigned long)timestamp,
3674  src_addr);
3675 
3676  if (conn->request_info.request_method != NULL) {
3677  fprintf(fi.access.fp,
3678  "%s %s: ",
3679  conn->request_info.request_method,
3680  conn->request_info.request_uri
3681  ? conn->request_info.request_uri
3682  : "");
3683  }
3684 
3685  fprintf(fi.access.fp, "%s", buf);
3686  fputc('\n', fi.access.fp);
3687  fflush(fi.access.fp);
3688  funlockfile(fi.access.fp);
3689  (void)mg_fclose(&fi.access); /* Ignore errors. We can't call
3690  * mg_cry here anyway ;-) */
3691  }
3692  }
3693 }
3694 
3695 #endif /* Externally provided function */
3696 
3697 
3698 static void
3699 mg_cry_internal_wrap(const struct mg_connection *conn,
3700  const char *func,
3701  unsigned line,
3702  const char *fmt,
3703  ...)
3704 {
3705  va_list ap;
3706  va_start(ap, fmt);
3707  mg_cry_internal_impl(conn, func, line, fmt, ap);
3708  va_end(ap);
3709 }
3710 
3711 
3712 void
3713 mg_cry(const struct mg_connection *conn, const char *fmt, ...)
3714 {
3715  va_list ap;
3716  va_start(ap, fmt);
3717  mg_cry_internal_impl(conn, "user", 0, fmt, ap);
3718  va_end(ap);
3719 }
3720 
3721 
3722 #define mg_cry DO_NOT_USE_THIS_FUNCTION__USE_mg_cry_internal
3723 
3724 
3725 /* Return fake connection structure. Used for logging, if connection
3726  * is not applicable at the moment of logging. */
3727 static struct mg_connection *
3728 fc(struct mg_context *ctx)
3729 {
3730  static struct mg_connection fake_connection;
3731  fake_connection.phys_ctx = ctx;
3732  fake_connection.dom_ctx = &(ctx->dd);
3733  return &fake_connection;
3734 }
3735 
3736 
3737 const char *
3739 {
3740  return CIVETWEB_VERSION;
3741 }
3742 
3743 
3744 const struct mg_request_info *
3745 mg_get_request_info(const struct mg_connection *conn)
3746 {
3747  if (!conn) {
3748  return NULL;
3749  }
3750 #if defined(MG_ALLOW_USING_GET_REQUEST_INFO_FOR_RESPONSE)
3751  if (conn->connection_type == CONNECTION_TYPE_RESPONSE) {
3752  char txt[16];
3753  struct mg_workerTLS *tls =
3754  (struct mg_workerTLS *)pthread_getspecific(sTlsKey);
3755 
3756  sprintf(txt, "%03i", conn->response_info.status_code);
3757  if (strlen(txt) == 3) {
3758  memcpy(tls->txtbuf, txt, 4);
3759  } else {
3760  strcpy(tls->txtbuf, "ERR");
3761  }
3762 
3763  ((struct mg_connection *)conn)->request_info.local_uri =
3764  ((struct mg_connection *)conn)->request_info.request_uri =
3765  tls->txtbuf; /* use thread safe buffer */
3766 
3767  ((struct mg_connection *)conn)->request_info.num_headers =
3768  conn->response_info.num_headers;
3769  memcpy(((struct mg_connection *)conn)->request_info.http_headers,
3770  conn->response_info.http_headers,
3771  sizeof(conn->response_info.http_headers));
3772  } else
3773 #endif
3774  if (conn->connection_type != CONNECTION_TYPE_REQUEST) {
3775  return NULL;
3776  }
3777  return &conn->request_info;
3778 }
3779 
3780 
3781 const struct mg_response_info *
3782 mg_get_response_info(const struct mg_connection *conn)
3783 {
3784  if (!conn) {
3785  return NULL;
3786  }
3787  if (conn->connection_type != CONNECTION_TYPE_RESPONSE) {
3788  return NULL;
3789  }
3790  return &conn->response_info;
3791 }
3792 
3793 
3794 static const char *
3795 get_proto_name(const struct mg_connection *conn)
3796 {
3797 #if defined(__clang__)
3798 #pragma clang diagnostic push
3799 #pragma clang diagnostic ignored "-Wunreachable-code"
3800 /* Depending on USE_WEBSOCKET and NO_SSL, some oft the protocols might be
3801  * not supported. Clang raises an "unreachable code" warning for parts of ?:
3802  * unreachable, but splitting into four different #ifdef clauses here is more
3803  * complicated.
3804  */
3805 #endif
3806 
3807  const struct mg_request_info *ri = &conn->request_info;
3808 
3809  const char *proto =
3810  (is_websocket_protocol(conn) ? (ri->is_ssl ? "wss" : "ws")
3811  : (ri->is_ssl ? "https" : "http"));
3812 
3813  return proto;
3814 
3815 #if defined(__clang__)
3816 #pragma clang diagnostic pop
3817 #endif
3818 }
3819 
3820 
3821 int
3822 mg_get_request_link(const struct mg_connection *conn, char *buf, size_t buflen)
3823 {
3824  if ((buflen < 1) || (buf == 0) || (conn == 0)) {
3825  return -1;
3826  } else {
3827 
3828  int truncated = 0;
3829  const struct mg_request_info *ri = &conn->request_info;
3830 
3831  const char *proto = get_proto_name(conn);
3832 
3833  if (ri->local_uri == NULL) {
3834  return -1;
3835  }
3836 
3837  if ((ri->request_uri != NULL)
3838  && (0 != strcmp(ri->local_uri, ri->request_uri))) {
3839  /* The request uri is different from the local uri.
3840  * This is usually if an absolute URI, including server
3841  * name has been provided. */
3842  mg_snprintf(conn,
3843  &truncated,
3844  buf,
3845  buflen,
3846  "%s://%s",
3847  proto,
3848  ri->request_uri);
3849  if (truncated) {
3850  return -1;
3851  }
3852  return 0;
3853 
3854  } else {
3855 
3856  /* The common case is a relative URI, so we have to
3857  * construct an absolute URI from server name and port */
3858 
3859 #if defined(USE_IPV6)
3860  int is_ipv6 = (conn->client.lsa.sa.sa_family == AF_INET6);
3861  int port = is_ipv6 ? htons(conn->client.lsa.sin6.sin6_port)
3862  : htons(conn->client.lsa.sin.sin_port);
3863 #else
3864  int port = htons(conn->client.lsa.sin.sin_port);
3865 #endif
3866  int def_port = ri->is_ssl ? 443 : 80;
3867  int auth_domain_check_enabled =
3868  conn->dom_ctx->config[ENABLE_AUTH_DOMAIN_CHECK]
3869  && (!mg_strcasecmp(
3870  conn->dom_ctx->config[ENABLE_AUTH_DOMAIN_CHECK], "yes"));
3871  const char *server_domain =
3872  conn->dom_ctx->config[AUTHENTICATION_DOMAIN];
3873 
3874  char portstr[16];
3875  char server_ip[48];
3876 
3877  if (port != def_port) {
3878  sprintf(portstr, ":%u", (unsigned)port);
3879  } else {
3880  portstr[0] = 0;
3881  }
3882 
3883  if (!auth_domain_check_enabled || !server_domain) {
3884 
3885  sockaddr_to_string(server_ip,
3886  sizeof(server_ip),
3887  &conn->client.lsa);
3888 
3889  server_domain = server_ip;
3890  }
3891 
3892  mg_snprintf(conn,
3893  &truncated,
3894  buf,
3895  buflen,
3896  "%s://%s%s%s",
3897  proto,
3898  server_domain,
3899  portstr,
3900  ri->local_uri);
3901  if (truncated) {
3902  return -1;
3903  }
3904  return 0;
3905  }
3906  }
3907 }
3908 
3909 /* Skip the characters until one of the delimiters characters found.
3910  * 0-terminate resulting word. Skip the delimiter and following whitespaces.
3911  * Advance pointer to buffer to the next word. Return found 0-terminated
3912  * word.
3913  * Delimiters can be quoted with quotechar. */
3914 static char *
3915 skip_quoted(char **buf,
3916  const char *delimiters,
3917  const char *whitespace,
3918  char quotechar)
3919 {
3920  char *p, *begin_word, *end_word, *end_whitespace;
3921 
3922  begin_word = *buf;
3923  end_word = begin_word + strcspn(begin_word, delimiters);
3924 
3925  /* Check for quotechar */
3926  if (end_word > begin_word) {
3927  p = end_word - 1;
3928  while (*p == quotechar) {
3929  /* While the delimiter is quoted, look for the next delimiter.
3930  */
3931  /* This happens, e.g., in calls from parse_auth_header,
3932  * if the user name contains a " character. */
3933 
3934  /* If there is anything beyond end_word, copy it. */
3935  if (*end_word != '\0') {
3936  size_t end_off = strcspn(end_word + 1, delimiters);
3937  memmove(p, end_word, end_off + 1);
3938  p += end_off; /* p must correspond to end_word - 1 */
3939  end_word += end_off + 1;
3940  } else {
3941  *p = '\0';
3942  break;
3943  }
3944  }
3945  for (p++; p < end_word; p++) {
3946  *p = '\0';
3947  }
3948  }
3949 
3950  if (*end_word == '\0') {
3951  *buf = end_word;
3952  } else {
3953 
3954 #if defined(GCC_DIAGNOSTIC)
3955 /* Disable spurious conversion warning for GCC */
3956 #pragma GCC diagnostic push
3957 #pragma GCC diagnostic ignored "-Wsign-conversion"
3958 #endif /* defined(GCC_DIAGNOSTIC) */
3959 
3960  end_whitespace = end_word + strspn(&end_word[1], whitespace) + 1;
3961 
3962 #if defined(GCC_DIAGNOSTIC)
3963 #pragma GCC diagnostic pop
3964 #endif /* defined(GCC_DIAGNOSTIC) */
3965 
3966  for (p = end_word; p < end_whitespace; p++) {
3967  *p = '\0';
3968  }
3969 
3970  *buf = end_whitespace;
3971  }
3972 
3973  return begin_word;
3974 }
3975 
3976 
3977 /* Return HTTP header value, or NULL if not found. */
3978 static const char *
3979 get_header(const struct mg_header *hdr, int num_hdr, const char *name)
3980 {
3981  int i;
3982  for (i = 0; i < num_hdr; i++) {
3983  if (!mg_strcasecmp(name, hdr[i].name)) {
3984  return hdr[i].value;
3985  }
3986  }
3987 
3988  return NULL;
3989 }
3990 
3991 
3992 #if defined(USE_WEBSOCKET)
3993 /* Retrieve requested HTTP header multiple values, and return the number of
3994  * found occurrences */
3995 static int
3996 get_req_headers(const struct mg_request_info *ri,
3997  const char *name,
3998  const char **output,
3999  int output_max_size)
4000 {
4001  int i;
4002  int cnt = 0;
4003  if (ri) {
4004  for (i = 0; i < ri->num_headers && cnt < output_max_size; i++) {
4005  if (!mg_strcasecmp(name, ri->http_headers[i].name)) {
4006  output[cnt++] = ri->http_headers[i].value;
4007  }
4008  }
4009  }
4010  return cnt;
4011 }
4012 #endif
4013 
4014 
4015 const char *
4016 mg_get_header(const struct mg_connection *conn, const char *name)
4017 {
4018  if (!conn) {
4019  return NULL;
4020  }
4021 
4022  if (conn->connection_type == CONNECTION_TYPE_REQUEST) {
4023  return get_header(conn->request_info.http_headers,
4024  conn->request_info.num_headers,
4025  name);
4026  }
4027  if (conn->connection_type == CONNECTION_TYPE_RESPONSE) {
4028  return get_header(conn->response_info.http_headers,
4029  conn->response_info.num_headers,
4030  name);
4031  }
4032  return NULL;
4033 }
4034 
4035 
4036 static const char *
4037 get_http_version(const struct mg_connection *conn)
4038 {
4039  if (!conn) {
4040  return NULL;
4041  }
4042 
4043  if (conn->connection_type == CONNECTION_TYPE_REQUEST) {
4044  return conn->request_info.http_version;
4045  }
4046  if (conn->connection_type == CONNECTION_TYPE_RESPONSE) {
4047  return conn->response_info.http_version;
4048  }
4049  return NULL;
4050 }
4051 
4052 
4053 /* A helper function for traversing a comma separated list of values.
4054  * It returns a list pointer shifted to the next value, or NULL if the end
4055  * of the list found.
4056  * Value is stored in val vector. If value has form "x=y", then eq_val
4057  * vector is initialized to point to the "y" part, and val vector length
4058  * is adjusted to point only to "x". */
4059 static const char *
4060 next_option(const char *list, struct vec *val, struct vec *eq_val)
4061 {
4062  int end;
4063 
4064 reparse:
4065  if (val == NULL || list == NULL || *list == '\0') {
4066  /* End of the list */
4067  return NULL;
4068  }
4069 
4070  /* Skip over leading LWS */
4071  while (*list == ' ' || *list == '\t')
4072  list++;
4073 
4074  val->ptr = list;
4075  if ((list = strchr(val->ptr, ',')) != NULL) {
4076  /* Comma found. Store length and shift the list ptr */
4077  val->len = ((size_t)(list - val->ptr));
4078  list++;
4079  } else {
4080  /* This value is the last one */
4081  list = val->ptr + strlen(val->ptr);
4082  val->len = ((size_t)(list - val->ptr));
4083  }
4084 
4085  /* Adjust length for trailing LWS */
4086  end = (int)val->len - 1;
4087  while (end >= 0 && ((val->ptr[end] == ' ') || (val->ptr[end] == '\t')))
4088  end--;
4089  val->len = (size_t)(end + 1);
4090 
4091  if (val->len == 0) {
4092  /* Ignore any empty entries. */
4093  goto reparse;
4094  }
4095 
4096  if (eq_val != NULL) {
4097  /* Value has form "x=y", adjust pointers and lengths
4098  * so that val points to "x", and eq_val points to "y". */
4099  eq_val->len = 0;
4100  eq_val->ptr = (const char *)memchr(val->ptr, '=', val->len);
4101  if (eq_val->ptr != NULL) {
4102  eq_val->ptr++; /* Skip over '=' character */
4103  eq_val->len = ((size_t)(val->ptr - eq_val->ptr)) + val->len;
4104  val->len = ((size_t)(eq_val->ptr - val->ptr)) - 1;
4105  }
4106  }
4107 
4108  return list;
4109 }
4110 
4111 
4112 /* A helper function for checking if a comma separated list of values
4113  * contains
4114  * the given option (case insensitvely).
4115  * 'header' can be NULL, in which case false is returned. */
4116 static int
4117 header_has_option(const char *header, const char *option)
4118 {
4119  struct vec opt_vec;
4120  struct vec eq_vec;
4121 
4122  DEBUG_ASSERT(option != NULL);
4123  DEBUG_ASSERT(option[0] != '\0');
4124 
4125  while ((header = next_option(header, &opt_vec, &eq_vec)) != NULL) {
4126  if (mg_strncasecmp(option, opt_vec.ptr, opt_vec.len) == 0)
4127  return 1;
4128  }
4129 
4130  return 0;
4131 }
4132 
4133 
4134 /* Perform case-insensitive match of string against pattern */
4135 static ptrdiff_t
4136 match_prefix(const char *pattern, size_t pattern_len, const char *str)
4137 {
4138  const char *or_str;
4139  ptrdiff_t i, j, len, res;
4140 
4141  if ((or_str = (const char *)memchr(pattern, '|', pattern_len)) != NULL) {
4142  res = match_prefix(pattern, (size_t)(or_str - pattern), str);
4143  return (res > 0) ? res
4144  : match_prefix(or_str + 1,
4145  (size_t)((pattern + pattern_len)
4146  - (or_str + 1)),
4147  str);
4148  }
4149 
4150  for (i = 0, j = 0; (i < (ptrdiff_t)pattern_len); i++, j++) {
4151  if ((pattern[i] == '?') && (str[j] != '\0')) {
4152  continue;
4153  } else if (pattern[i] == '$') {
4154  return (str[j] == '\0') ? j : -1;
4155  } else if (pattern[i] == '*') {
4156  i++;
4157  if (pattern[i] == '*') {
4158  i++;
4159  len = strlen(str + j);
4160  } else {
4161  len = strcspn(str + j, "/");
4162  }
4163  if (i == (ptrdiff_t)pattern_len) {
4164  return j + len;
4165  }
4166  do {
4167  res = match_prefix(pattern + i, pattern_len - i, str + j + len);
4168  } while (res == -1 && len-- > 0);
4169  return (res == -1) ? -1 : j + res + len;
4170  } else if (lowercase(&pattern[i]) != lowercase(&str[j])) {
4171  return -1;
4172  }
4173  }
4174  return (ptrdiff_t)j;
4175 }
4176 
4177 
4178 /* HTTP 1.1 assumes keep alive if "Connection:" header is not set
4179  * This function must tolerate situations when connection info is not
4180  * set up, for example if request parsing failed. */
4181 static int
4182 should_keep_alive(const struct mg_connection *conn)
4183 {
4184  const char *http_version;
4185  const char *header;
4186 
4187  /* First satisfy needs of the server */
4188  if ((conn == NULL) || conn->must_close) {
4189  /* Close, if civetweb framework needs to close */
4190  return 0;
4191  }
4192 
4193  if (mg_strcasecmp(conn->dom_ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0) {
4194  /* Close, if keep alive is not enabled */
4195  return 0;
4196  }
4197 
4198  /* Check explicit wish of the client */
4199  header = mg_get_header(conn, "Connection");
4200  if (header) {
4201  /* If there is a connection header from the client, obey */
4202  if (header_has_option(header, "keep-alive")) {
4203  return 1;
4204  }
4205  return 0;
4206  }
4207 
4208  /* Use default of the standard */
4209  http_version = get_http_version(conn);
4210  if (http_version && (0 == strcmp(http_version, "1.1"))) {
4211  /* HTTP 1.1 default is keep alive */
4212  return 1;
4213  }
4214 
4215  /* HTTP 1.0 (and earlier) default is to close the connection */
4216  return 0;
4217 }
4218 
4219 
4220 static int
4221 should_decode_url(const struct mg_connection *conn)
4222 {
4223  if (!conn || !conn->dom_ctx) {
4224  return 0;
4225  }
4226 
4227  return (mg_strcasecmp(conn->dom_ctx->config[DECODE_URL], "yes") == 0);
4228 }
4229 
4230 
4231 static const char *
4232 suggest_connection_header(const struct mg_connection *conn)
4233 {
4234  return should_keep_alive(conn) ? "keep-alive" : "close";
4235 }
4236 
4237 
4238 static int
4239 send_no_cache_header(struct mg_connection *conn)
4240 {
4241  /* Send all current and obsolete cache opt-out directives. */
4242  return mg_printf(conn,
4243  "Cache-Control: no-cache, no-store, "
4244  "must-revalidate, private, max-age=0\r\n"
4245  "Pragma: no-cache\r\n"
4246  "Expires: 0\r\n");
4247 }
4248 
4249 
4250 static int
4251 send_static_cache_header(struct mg_connection *conn)
4252 {
4253 #if !defined(NO_CACHING)
4254  /* Read the server config to check how long a file may be cached.
4255  * The configuration is in seconds. */
4256  int max_age = atoi(conn->dom_ctx->config[STATIC_FILE_MAX_AGE]);
4257  if (max_age <= 0) {
4258  /* 0 means "do not cache". All values <0 are reserved
4259  * and may be used differently in the future. */
4260  /* If a file should not be cached, do not only send
4261  * max-age=0, but also pragmas and Expires headers. */
4262  return send_no_cache_header(conn);
4263  }
4264 
4265  /* Use "Cache-Control: max-age" instead of "Expires" header.
4266  * Reason: see https://www.mnot.net/blog/2007/05/15/expires_max-age */
4267  /* See also https://www.mnot.net/cache_docs/ */
4268  /* According to RFC 2616, Section 14.21, caching times should not exceed
4269  * one year. A year with 365 days corresponds to 31536000 seconds, a
4270  * leap
4271  * year to 31622400 seconds. For the moment, we just send whatever has
4272  * been configured, still the behavior for >1 year should be considered
4273  * as undefined. */
4274  return mg_printf(conn, "Cache-Control: max-age=%u\r\n", (unsigned)max_age);
4275 #else /* NO_CACHING */
4276  return send_no_cache_header(conn);
4277 #endif /* !NO_CACHING */
4278 }
4279 
4280 
4281 static int
4282 send_additional_header(struct mg_connection *conn)
4283 {
4284  int i = 0;
4285  const char *header = conn->dom_ctx->config[ADDITIONAL_HEADER];
4286 
4287 #if !defined(NO_SSL)
4288  if (conn->dom_ctx->config[STRICT_HTTPS_MAX_AGE]) {
4289  int max_age = atoi(conn->dom_ctx->config[STRICT_HTTPS_MAX_AGE]);
4290  if (max_age >= 0) {
4291  i += mg_printf(conn,
4292  "Strict-Transport-Security: max-age=%u\r\n",
4293  (unsigned)max_age);
4294  }
4295  }
4296 #endif
4297 
4298  if (header && header[0]) {
4299  i += mg_printf(conn, "%s\r\n", header);
4300  }
4301 
4302  return i;
4303 }
4304 
4305 
4306 static void handle_file_based_request(struct mg_connection *conn,
4307  const char *path,
4308  struct mg_file *filep);
4309 
4310 
4311 const char *
4312 mg_get_response_code_text(const struct mg_connection *conn, int response_code)
4313 {
4314  /* See IANA HTTP status code assignment:
4315  * http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
4316  */
4317 
4318  switch (response_code) {
4319  /* RFC2616 Section 10.1 - Informational 1xx */
4320  case 100:
4321  return "Continue"; /* RFC2616 Section 10.1.1 */
4322  case 101:
4323  return "Switching Protocols"; /* RFC2616 Section 10.1.2 */
4324  case 102:
4325  return "Processing"; /* RFC2518 Section 10.1 */
4326 
4327  /* RFC2616 Section 10.2 - Successful 2xx */
4328  case 200:
4329  return "OK"; /* RFC2616 Section 10.2.1 */
4330  case 201:
4331  return "Created"; /* RFC2616 Section 10.2.2 */
4332  case 202:
4333  return "Accepted"; /* RFC2616 Section 10.2.3 */
4334  case 203:
4335  return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */
4336  case 204:
4337  return "No Content"; /* RFC2616 Section 10.2.5 */
4338  case 205:
4339  return "Reset Content"; /* RFC2616 Section 10.2.6 */
4340  case 206:
4341  return "Partial Content"; /* RFC2616 Section 10.2.7 */
4342  case 207:
4343  return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1
4344  */
4345  case 208:
4346  return "Already Reported"; /* RFC5842 Section 7.1 */
4347 
4348  case 226:
4349  return "IM used"; /* RFC3229 Section 10.4.1 */
4350 
4351  /* RFC2616 Section 10.3 - Redirection 3xx */
4352  case 300:
4353  return "Multiple Choices"; /* RFC2616 Section 10.3.1 */
4354  case 301:
4355  return "Moved Permanently"; /* RFC2616 Section 10.3.2 */
4356  case 302:
4357  return "Found"; /* RFC2616 Section 10.3.3 */
4358  case 303:
4359  return "See Other"; /* RFC2616 Section 10.3.4 */
4360  case 304:
4361  return "Not Modified"; /* RFC2616 Section 10.3.5 */
4362  case 305:
4363  return "Use Proxy"; /* RFC2616 Section 10.3.6 */
4364  case 307:
4365  return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */
4366  case 308:
4367  return "Permanent Redirect"; /* RFC7238 Section 3 */
4368 
4369  /* RFC2616 Section 10.4 - Client Error 4xx */
4370  case 400:
4371  return "Bad Request"; /* RFC2616 Section 10.4.1 */
4372  case 401:
4373  return "Unauthorized"; /* RFC2616 Section 10.4.2 */
4374  case 402:
4375  return "Payment Required"; /* RFC2616 Section 10.4.3 */
4376  case 403:
4377  return "Forbidden"; /* RFC2616 Section 10.4.4 */
4378  case 404:
4379  return "Not Found"; /* RFC2616 Section 10.4.5 */
4380  case 405:
4381  return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */
4382  case 406:
4383  return "Not Acceptable"; /* RFC2616 Section 10.4.7 */
4384  case 407:
4385  return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */
4386  case 408:
4387  return "Request Time-out"; /* RFC2616 Section 10.4.9 */
4388  case 409:
4389  return "Conflict"; /* RFC2616 Section 10.4.10 */
4390  case 410:
4391  return "Gone"; /* RFC2616 Section 10.4.11 */
4392  case 411:
4393  return "Length Required"; /* RFC2616 Section 10.4.12 */
4394  case 412:
4395  return "Precondition Failed"; /* RFC2616 Section 10.4.13 */
4396  case 413:
4397  return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */
4398  case 414:
4399  return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */
4400  case 415:
4401  return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */
4402  case 416:
4403  return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17
4404  */
4405  case 417:
4406  return "Expectation Failed"; /* RFC2616 Section 10.4.18 */
4407 
4408  case 421:
4409  return "Misdirected Request"; /* RFC7540 Section 9.1.2 */
4410  case 422:
4411  return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918
4412  * Section 11.2 */
4413  case 423:
4414  return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */
4415  case 424:
4416  return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918
4417  * Section 11.4 */
4418 
4419  case 426:
4420  return "Upgrade Required"; /* RFC 2817 Section 4 */
4421 
4422  case 428:
4423  return "Precondition Required"; /* RFC 6585, Section 3 */
4424  case 429:
4425  return "Too Many Requests"; /* RFC 6585, Section 4 */
4426 
4427  case 431:
4428  return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */
4429 
4430  case 451:
4431  return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05,
4432  * Section 3 */
4433 
4434  /* RFC2616 Section 10.5 - Server Error 5xx */
4435  case 500:
4436  return "Internal Server Error"; /* RFC2616 Section 10.5.1 */
4437  case 501:
4438  return "Not Implemented"; /* RFC2616 Section 10.5.2 */
4439  case 502:
4440  return "Bad Gateway"; /* RFC2616 Section 10.5.3 */
4441  case 503:
4442  return "Service Unavailable"; /* RFC2616 Section 10.5.4 */
4443  case 504:
4444  return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */
4445  case 505:
4446  return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */
4447  case 506:
4448  return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */
4449  case 507:
4450  return "Insufficient Storage"; /* RFC2518 Section 10.6, RFC4918
4451  * Section 11.5 */
4452  case 508:
4453  return "Loop Detected"; /* RFC5842 Section 7.1 */
4454 
4455  case 510:
4456  return "Not Extended"; /* RFC 2774, Section 7 */
4457  case 511:
4458  return "Network Authentication Required"; /* RFC 6585, Section 6 */
4459 
4460  /* Other status codes, not shown in the IANA HTTP status code
4461  * assignment.
4462  * E.g., "de facto" standards due to common use, ... */
4463  case 418:
4464  return "I am a teapot"; /* RFC2324 Section 2.3.2 */
4465  case 419:
4466  return "Authentication Timeout"; /* common use */
4467  case 420:
4468  return "Enhance Your Calm"; /* common use */
4469  case 440:
4470  return "Login Timeout"; /* common use */
4471  case 509:
4472  return "Bandwidth Limit Exceeded"; /* common use */
4473 
4474  default:
4475  /* This error code is unknown. This should not happen. */
4476  if (conn) {
4477  mg_cry_internal(conn,
4478  "Unknown HTTP response code: %u",
4479  response_code);
4480  }
4481 
4482  /* Return at least a category according to RFC 2616 Section 10. */
4483  if (response_code >= 100 && response_code < 200) {
4484  /* Unknown informational status code */
4485  return "Information";
4486  }
4487  if (response_code >= 200 && response_code < 300) {
4488  /* Unknown success code */
4489  return "Success";
4490  }
4491  if (response_code >= 300 && response_code < 400) {
4492  /* Unknown redirection code */
4493  return "Redirection";
4494  }
4495  if (response_code >= 400 && response_code < 500) {
4496  /* Unknown request error code */
4497  return "Client Error";
4498  }
4499  if (response_code >= 500 && response_code < 600) {
4500  /* Unknown server error code */
4501  return "Server Error";
4502  }
4503 
4504  /* Response code not even within reasonable range */
4505  return "";
4506  }
4507 }
4508 
4509 
4510 static int
4511 mg_send_http_error_impl(struct mg_connection *conn,
4512  int status,
4513  const char *fmt,
4514  va_list args)
4515 {
4516  char errmsg_buf[MG_BUF_LEN];
4517  char path_buf[PATH_MAX];
4518  va_list ap;
4519  int len, i, page_handler_found, scope, truncated, has_body;
4520  char date[64];
4521  time_t curtime = time(NULL);
4522  const char *error_handler = NULL;
4523  struct mg_file error_page_file = STRUCT_FILE_INITIALIZER;
4524  const char *error_page_file_ext, *tstr;
4525  int handled_by_callback = 0;
4526 
4527  const char *status_text = mg_get_response_code_text(conn, status);
4528 
4529  if ((conn == NULL) || (fmt == NULL)) {
4530  return -2;
4531  }
4532 
4533  /* Set status (for log) */
4534  conn->status_code = status;
4535 
4536  /* Errors 1xx, 204 and 304 MUST NOT send a body */
4537  has_body = ((status > 199) && (status != 204) && (status != 304));
4538 
4539  /* Prepare message in buf, if required */
4540  if (has_body
4541  || (!conn->in_error_handler
4542  && (conn->phys_ctx->callbacks.http_error != NULL))) {
4543  /* Store error message in errmsg_buf */
4544  va_copy(ap, args);
4545  mg_vsnprintf(conn, NULL, errmsg_buf, sizeof(errmsg_buf), fmt, ap);
4546  va_end(ap);
4547  /* In a debug build, print all html errors */
4548  DEBUG_TRACE("Error %i - [%s]", status, errmsg_buf);
4549  }
4550 
4551  /* If there is a http_error callback, call it.
4552  * But don't do it recursively, if callback calls mg_send_http_error again.
4553  */
4554  if (!conn->in_error_handler
4555  && (conn->phys_ctx->callbacks.http_error != NULL)) {
4556  /* Mark in_error_handler to avoid recursion and call user callback. */
4557  conn->in_error_handler = 1;
4558  handled_by_callback =
4559  (conn->phys_ctx->callbacks.http_error(conn, status, errmsg_buf)
4560  == 0);
4561  conn->in_error_handler = 0;
4562  }
4563 
4564  if (!handled_by_callback) {
4565  /* Check for recursion */
4566  if (conn->in_error_handler) {
4567  DEBUG_TRACE(
4568  "Recursion when handling error %u - fall back to default",
4569  status);
4570  } else {
4571  /* Send user defined error pages, if defined */
4572  error_handler = conn->dom_ctx->config[ERROR_PAGES];
4573  error_page_file_ext = conn->dom_ctx->config[INDEX_FILES];
4574  page_handler_found = 0;
4575 
4576  if (error_handler != NULL) {
4577  for (scope = 1; (scope <= 3) && !page_handler_found; scope++) {
4578  switch (scope) {
4579  case 1: /* Handler for specific error, e.g. 404 error */
4580  mg_snprintf(conn,
4581  &truncated,
4582  path_buf,
4583  sizeof(path_buf) - 32,
4584  "%serror%03u.",
4585  error_handler,
4586  status);
4587  break;
4588  case 2: /* Handler for error group, e.g., 5xx error
4589  * handler
4590  * for all server errors (500-599) */
4591  mg_snprintf(conn,
4592  &truncated,
4593  path_buf,
4594  sizeof(path_buf) - 32,
4595  "%serror%01uxx.",
4596  error_handler,
4597  status / 100);
4598  break;
4599  default: /* Handler for all errors */
4600  mg_snprintf(conn,
4601  &truncated,
4602  path_buf,
4603  sizeof(path_buf) - 32,
4604  "%serror.",
4605  error_handler);
4606  break;
4607  }
4608 
4609  /* String truncation in buf may only occur if
4610  * error_handler is too long. This string is
4611  * from the config, not from a client. */
4612  (void)truncated;
4613 
4614  len = (int)strlen(path_buf);
4615 
4616  tstr = strchr(error_page_file_ext, '.');
4617 
4618  while (tstr) {
4619  for (i = 1;
4620  (i < 32) && (tstr[i] != 0) && (tstr[i] != ',');
4621  i++) {
4622  /* buffer overrun is not possible here, since
4623  * (i < 32) && (len < sizeof(path_buf) - 32)
4624  * ==> (i + len) < sizeof(path_buf) */
4625  path_buf[len + i - 1] = tstr[i];
4626  }
4627  /* buffer overrun is not possible here, since
4628  * (i <= 32) && (len < sizeof(path_buf) - 32)
4629  * ==> (i + len) <= sizeof(path_buf) */
4630  path_buf[len + i - 1] = 0;
4631 
4632  if (mg_stat(conn, path_buf, &error_page_file.stat)) {
4633  DEBUG_TRACE("Check error page %s - found",
4634  path_buf);
4635  page_handler_found = 1;
4636  break;
4637  }
4638  DEBUG_TRACE("Check error page %s - not found",
4639  path_buf);
4640 
4641  tstr = strchr(tstr + i, '.');
4642  }
4643  }
4644  }
4645 
4646  if (page_handler_found) {
4647  conn->in_error_handler = 1;
4648  handle_file_based_request(conn, path_buf, &error_page_file);
4649  conn->in_error_handler = 0;
4650  return 0;
4651  }
4652  }
4653 
4654  /* No custom error page. Send default error page. */
4655  gmt_time_string(date, sizeof(date), &curtime);
4656 
4657  conn->must_close = 1;
4658  mg_printf(conn, "HTTP/1.1 %d %s\r\n", status, status_text);
4659  send_no_cache_header(conn);
4660  send_additional_header(conn);
4661  if (has_body) {
4662  mg_printf(conn,
4663  "%s",
4664  "Content-Type: text/plain; charset=utf-8\r\n");
4665  }
4666  mg_printf(conn,
4667  "Date: %s\r\n"
4668  "Connection: close\r\n\r\n",
4669  date);
4670 
4671  /* HTTP responses 1xx, 204 and 304 MUST NOT send a body */
4672  if (has_body) {
4673  /* For other errors, send a generic error message. */
4674  mg_printf(conn, "Error %d: %s\n", status, status_text);
4675  mg_write(conn, errmsg_buf, strlen(errmsg_buf));
4676 
4677  } else {
4678  /* No body allowed. Close the connection. */
4679  DEBUG_TRACE("Error %i", status);
4680  }
4681  }
4682  return 0;
4683 }
4684 
4685 
4686 int
4687 mg_send_http_error(struct mg_connection *conn, int status, const char *fmt, ...)
4688 {
4689  va_list ap;
4690  int ret;
4691 
4692  va_start(ap, fmt);
4693  ret = mg_send_http_error_impl(conn, status, fmt, ap);
4694  va_end(ap);
4695 
4696  return ret;
4697 }
4698 
4699 
4700 int
4701 mg_send_http_ok(struct mg_connection *conn,
4702  const char *mime_type,
4703  long long content_length)
4704 {
4705  char date[64];
4706  time_t curtime = time(NULL);
4707 
4708  if ((mime_type == NULL) || (*mime_type == 0)) {
4709  /* Parameter error */
4710  return -2;
4711  }
4712 
4713  gmt_time_string(date, sizeof(date), &curtime);
4714 
4715  mg_printf(conn,
4716  "HTTP/1.1 200 OK\r\n"
4717  "Content-Type: %s\r\n"
4718  "Date: %s\r\n"
4719  "Connection: %s\r\n",
4720  mime_type,
4721  date,
4723 
4724  send_no_cache_header(conn);
4725  send_additional_header(conn);
4726  if (content_length < 0) {
4727  mg_printf(conn, "Transfer-Encoding: chunked\r\n\r\n");
4728  } else {
4729  mg_printf(conn,
4730  "Content-Length: %" UINT64_FMT "\r\n\r\n",
4731  (uint64_t)content_length);
4732  }
4733 
4734  return 0;
4735 }
4736 
4737 
4738 int
4739 mg_send_http_redirect(struct mg_connection *conn,
4740  const char *target_url,
4741  int redirect_code)
4742 {
4743  /* Send a 30x redirect response.
4744  *
4745  * Redirect types (status codes):
4746  *
4747  * Status | Perm/Temp | Method | Version
4748  * 301 | permanent | POST->GET undefined | HTTP/1.0
4749  * 302 | temporary | POST->GET undefined | HTTP/1.0
4750  * 303 | temporary | always use GET | HTTP/1.1
4751  * 307 | temporary | always keep method | HTTP/1.1
4752  * 308 | permanent | always keep method | HTTP/1.1
4753  */
4754  const char *redirect_text;
4755  int ret;
4756  size_t content_len = 0;
4757  char reply[MG_BUF_LEN];
4758 
4759  /* In case redirect_code=0, use 307. */
4760  if (redirect_code == 0) {
4761  redirect_code = 307;
4762  }
4763 
4764  /* In case redirect_code is none of the above, return error. */
4765  if ((redirect_code != 301) && (redirect_code != 302)
4766  && (redirect_code != 303) && (redirect_code != 307)
4767  && (redirect_code != 308)) {
4768  /* Parameter error */
4769  return -2;
4770  }
4771 
4772  /* Get proper text for response code */
4773  redirect_text = mg_get_response_code_text(conn, redirect_code);
4774 
4775  /* If target_url is not defined, redirect to "/". */
4776  if ((target_url == NULL) || (*target_url == 0)) {
4777  target_url = "/";
4778  }
4779 
4780 #if defined(MG_SEND_REDIRECT_BODY)
4781  /* TODO: condition name? */
4782 
4783  /* Prepare a response body with a hyperlink.
4784  *
4785  * According to RFC2616 (and RFC1945 before):
4786  * Unless the request method was HEAD, the entity of the
4787  * response SHOULD contain a short hypertext note with a hyperlink to
4788  * the new URI(s).
4789  *
4790  * However, this response body is not useful in M2M communication.
4791  * Probably the original reason in the RFC was, clients not supporting
4792  * a 30x HTTP redirect could still show the HTML page and let the user
4793  * press the link. Since current browsers support 30x HTTP, the additional
4794  * HTML body does not seem to make sense anymore.
4795  *
4796  * The new RFC7231 (Section 6.4) does no longer recommend it ("SHOULD"),
4797  * but it only notes:
4798  * The server's response payload usually contains a short
4799  * hypertext note with a hyperlink to the new URI(s).
4800  *
4801  * Deactivated by default. If you need the 30x body, set the define.
4802  */
4803  mg_snprintf(
4804  conn,
4805  NULL /* ignore truncation */,
4806  reply,
4807  sizeof(reply),
4808  "<html><head>%s</head><body><a href=\"%s\">%s</a></body></html>",
4809  redirect_text,
4810  target_url,
4811  target_url);
4812  content_len = strlen(reply);
4813 #else
4814  reply[0] = 0;
4815 #endif
4816 
4817  /* Do not send any additional header. For all other options,
4818  * including caching, there are suitable defaults. */
4819  ret = mg_printf(conn,
4820  "HTTP/1.1 %i %s\r\n"
4821  "Location: %s\r\n"
4822  "Content-Length: %u\r\n"
4823  "Connection: %s\r\n\r\n",
4824  redirect_code,
4825  redirect_text,
4826  target_url,
4827  (unsigned int)content_len,
4829 
4830  /* Send response body */
4831  if (ret > 0) {
4832  /* ... unless it is a HEAD request */
4833  if (0 != strcmp(conn->request_info.request_method, "HEAD")) {
4834  ret = mg_write(conn, reply, content_len);
4835  }
4836  }
4837 
4838  return (ret > 0) ? ret : -1;
4839 }
4840 
4841 
4842 #if defined(_WIN32)
4843 /* Create substitutes for POSIX functions in Win32. */
4844 
4845 #if defined(GCC_DIAGNOSTIC)
4846 /* Show no warning in case system functions are not used. */
4847 #pragma GCC diagnostic push
4848 #pragma GCC diagnostic ignored "-Wunused-function"
4849 #endif
4850 
4851 
4853 static int
4854 pthread_mutex_init(pthread_mutex_t *mutex, void *unused)
4855 {
4856  (void)unused;
4857  *mutex = CreateMutex(NULL, FALSE, NULL);
4858  return (*mutex == NULL) ? -1 : 0;
4859 }
4860 
4862 static int
4863 pthread_mutex_destroy(pthread_mutex_t *mutex)
4864 {
4865  return (CloseHandle(*mutex) == 0) ? -1 : 0;
4866 }
4867 
4868 
4870 static int
4871 pthread_mutex_lock(pthread_mutex_t *mutex)
4872 {
4873  return (WaitForSingleObject(*mutex, (DWORD)INFINITE) == WAIT_OBJECT_0) ? 0
4874  : -1;
4875 }
4876 
4877 
4878 #if defined(ENABLE_UNUSED_PTHREAD_FUNCTIONS)
4880 static int
4881 pthread_mutex_trylock(pthread_mutex_t *mutex)
4882 {
4883  switch (WaitForSingleObject(*mutex, 0)) {
4884  case WAIT_OBJECT_0:
4885  return 0;
4886  case WAIT_TIMEOUT:
4887  return -2; /* EBUSY */
4888  }
4889  return -1;
4890 }
4891 #endif
4892 
4893 
4895 static int
4896 pthread_mutex_unlock(pthread_mutex_t *mutex)
4897 {
4898  return (ReleaseMutex(*mutex) == 0) ? -1 : 0;
4899 }
4900 
4901 
4903 static int
4904 pthread_cond_init(pthread_cond_t *cv, const void *unused)
4905 {
4906  (void)unused;
4907  InitializeCriticalSection(&cv->threadIdSec);
4908  cv->waiting_thread = NULL;
4909  return 0;
4910 }
4911 
4912 
4914 static int
4915 pthread_cond_timedwait(pthread_cond_t *cv,
4916  pthread_mutex_t *mutex,
4917  FUNCTION_MAY_BE_UNUSED const struct timespec *abstime)
4918 {
4919  struct mg_workerTLS **ptls,
4920  *tls = (struct mg_workerTLS *)pthread_getspecific(sTlsKey);
4921  int ok;
4922  int64_t nsnow, nswaitabs, nswaitrel;
4923  DWORD mswaitrel;
4924 
4925  EnterCriticalSection(&cv->threadIdSec);
4926  /* Add this thread to cv's waiting list */
4927  ptls = &cv->waiting_thread;
4928  for (; *ptls != NULL; ptls = &(*ptls)->next_waiting_thread)
4929  ;
4930  tls->next_waiting_thread = NULL;
4931  *ptls = tls;
4932  LeaveCriticalSection(&cv->threadIdSec);
4933 
4934  if (abstime) {
4935  nsnow = mg_get_current_time_ns();
4936  nswaitabs =
4937  (((int64_t)abstime->tv_sec) * 1000000000) + abstime->tv_nsec;
4938  nswaitrel = nswaitabs - nsnow;
4939  if (nswaitrel < 0) {
4940  nswaitrel = 0;
4941  }
4942  mswaitrel = (DWORD)(nswaitrel / 1000000);
4943  } else {
4944  mswaitrel = (DWORD)INFINITE;
4945  }
4946 
4947  pthread_mutex_unlock(mutex);
4948  ok = (WAIT_OBJECT_0
4949  == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
4950  if (!ok) {
4951  ok = 1;
4952  EnterCriticalSection(&cv->threadIdSec);
4953  ptls = &cv->waiting_thread;
4954  for (; *ptls != NULL; ptls = &(*ptls)->next_waiting_thread) {
4955  if (*ptls == tls) {
4956  *ptls = tls->next_waiting_thread;
4957  ok = 0;
4958  break;
4959  }
4960  }
4961  LeaveCriticalSection(&cv->threadIdSec);
4962  if (ok) {
4963  WaitForSingleObject(tls->pthread_cond_helper_mutex,
4964  (DWORD)INFINITE);
4965  }
4966  }
4967  /* This thread has been removed from cv's waiting list */
4968  pthread_mutex_lock(mutex);
4969 
4970  return ok ? 0 : -1;
4971 }
4972 
4973 
4975 static int
4976 pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
4977 {
4978  return pthread_cond_timedwait(cv, mutex, NULL);
4979 }
4980 
4981 
4983 static int
4984 pthread_cond_signal(pthread_cond_t *cv)
4985 {
4986  HANDLE wkup = NULL;
4987  BOOL ok = FALSE;
4988 
4989  EnterCriticalSection(&cv->threadIdSec);
4990  if (cv->waiting_thread) {
4991  wkup = cv->waiting_thread->pthread_cond_helper_mutex;
4992  cv->waiting_thread = cv->waiting_thread->next_waiting_thread;
4993 
4994  ok = SetEvent(wkup);
4995  DEBUG_ASSERT(ok);
4996  }
4997  LeaveCriticalSection(&cv->threadIdSec);
4998 
4999  return ok ? 0 : 1;
5000 }
5001 
5002 
5004 static int
5005 pthread_cond_broadcast(pthread_cond_t *cv)
5006 {
5007  EnterCriticalSection(&cv->threadIdSec);
5008  while (cv->waiting_thread) {
5009  pthread_cond_signal(cv);
5010  }
5011  LeaveCriticalSection(&cv->threadIdSec);
5012 
5013  return 0;
5014 }
5015 
5016 
5018 static int
5019 pthread_cond_destroy(pthread_cond_t *cv)
5020 {
5021  EnterCriticalSection(&cv->threadIdSec);
5022  DEBUG_ASSERT(cv->waiting_thread == NULL);
5023  LeaveCriticalSection(&cv->threadIdSec);
5024  DeleteCriticalSection(&cv->threadIdSec);
5025 
5026  return 0;
5027 }
5028 
5029 
5030 #if defined(ALTERNATIVE_QUEUE)
5032 static void *
5033 event_create(void)
5034 {
5035  return (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
5036 }
5037 
5038 
5040 static int
5041 event_wait(void *eventhdl)
5042 {
5043  int res = WaitForSingleObject((HANDLE)eventhdl, (DWORD)INFINITE);
5044  return (res == WAIT_OBJECT_0);
5045 }
5046 
5047 
5049 static int
5050 event_signal(void *eventhdl)
5051 {
5052  return (int)SetEvent((HANDLE)eventhdl);
5053 }
5054 
5055 
5057 static void
5058 event_destroy(void *eventhdl)
5059 {
5060  CloseHandle((HANDLE)eventhdl);
5061 }
5062 #endif
5063 
5064 
5065 #if defined(GCC_DIAGNOSTIC)
5066 /* Enable unused function warning again */
5067 #pragma GCC diagnostic pop
5068 #endif
5069 
5070 
5071 /* For Windows, change all slashes to backslashes in path names. */
5072 static void
5073 change_slashes_to_backslashes(char *path)
5074 {
5075  int i;
5076 
5077  for (i = 0; path[i] != '\0'; i++) {
5078  if (path[i] == '/') {
5079  path[i] = '\\';
5080  }
5081 
5082  /* remove double backslash (check i > 0 to preserve UNC paths,
5083  * like \\server\file.txt) */
5084  if ((path[i] == '\\') && (i > 0)) {
5085  while ((path[i + 1] == '\\') || (path[i + 1] == '/')) {
5086  (void)memmove(path + i + 1, path + i + 2, strlen(path + i + 1));
5087  }
5088  }
5089  }
5090 }
5091 
5092 
5093 static int
5094 mg_wcscasecmp(const wchar_t *s1, const wchar_t *s2)
5095 {
5096  int diff;
5097 
5098  do {
5099  diff = tolower(*s1) - tolower(*s2);
5100  s1++;
5101  s2++;
5102  } while ((diff == 0) && (s1[-1] != '\0'));
5103 
5104  return diff;
5105 }
5106 
5107 
5108 /* Encode 'path' which is assumed UTF-8 string, into UNICODE string.
5109  * wbuf and wbuf_len is a target buffer and its length. */
5110 static void
5111 path_to_unicode(const struct mg_connection *conn,
5112  const char *path,
5113  wchar_t *wbuf,
5114  size_t wbuf_len)
5115 {
5116  char buf[PATH_MAX], buf2[PATH_MAX];
5117  wchar_t wbuf2[W_PATH_MAX + 1];
5118  DWORD long_len, err;
5119  int (*fcompare)(const wchar_t *, const wchar_t *) = mg_wcscasecmp;
5120 
5121  mg_strlcpy(buf, path, sizeof(buf));
5122  change_slashes_to_backslashes(buf);
5123 
5124  /* Convert to Unicode and back. If doubly-converted string does not
5125  * match the original, something is fishy, reject. */
5126  memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
5127  MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int)wbuf_len);
5128  WideCharToMultiByte(
5129  CP_UTF8, 0, wbuf, (int)wbuf_len, buf2, sizeof(buf2), NULL, NULL);
5130  if (strcmp(buf, buf2) != 0) {
5131  wbuf[0] = L'\0';
5132  }
5133 
5134  /* Windows file systems are not case sensitive, but you can still use
5135  * uppercase and lowercase letters (on all modern file systems).
5136  * The server can check if the URI uses the same upper/lowercase
5137  * letters an the file system, effectively making Windows servers
5138  * case sensitive (like Linux servers are). It is still not possible
5139  * to use two files with the same name in different cases on Windows
5140  * (like /a and /A) - this would be possible in Linux.
5141  * As a default, Windows is not case sensitive, but the case sensitive
5142  * file name check can be activated by an additional configuration. */
5143  if (conn) {
5144  if (conn->dom_ctx->config[CASE_SENSITIVE_FILES]
5145  && !mg_strcasecmp(conn->dom_ctx->config[CASE_SENSITIVE_FILES],
5146  "yes")) {
5147  /* Use case sensitive compare function */
5148  fcompare = wcscmp;
5149  }
5150  }
5151  (void)conn; /* conn is currently unused */
5152 
5153 #if !defined(_WIN32_WCE)
5154  /* Only accept a full file path, not a Windows short (8.3) path. */
5155  memset(wbuf2, 0, ARRAY_SIZE(wbuf2) * sizeof(wchar_t));
5156  long_len = GetLongPathNameW(wbuf, wbuf2, ARRAY_SIZE(wbuf2) - 1);
5157  if (long_len == 0) {
5158  err = GetLastError();
5159  if (err == ERROR_FILE_NOT_FOUND) {
5160  /* File does not exist. This is not always a problem here. */
5161  return;
5162  }
5163  }
5164  if ((long_len >= ARRAY_SIZE(wbuf2)) || (fcompare(wbuf, wbuf2) != 0)) {
5165  /* Short name is used. */
5166  wbuf[0] = L'\0';
5167  }
5168 #else
5169  (void)long_len;
5170  (void)wbuf2;
5171  (void)err;
5172 
5173  if (strchr(path, '~')) {
5174  wbuf[0] = L'\0';
5175  }
5176 #endif
5177 }
5178 
5179 
5180 /* Windows happily opens files with some garbage at the end of file name.
5181  * For example, fopen("a.cgi ", "r") on Windows successfully opens
5182  * "a.cgi", despite one would expect an error back.
5183  * This function returns non-0 if path ends with some garbage. */
5184 static int
5185 path_cannot_disclose_cgi(const char *path)
5186 {
5187  static const char *allowed_last_characters = "_-";
5188  int last = path[strlen(path) - 1];
5189  return isalnum(last) || strchr(allowed_last_characters, last) != NULL;
5190 }
5191 
5192 
5193 static int
5194 mg_stat(const struct mg_connection *conn,
5195  const char *path,
5196  struct mg_file_stat *filep)
5197 {
5198  wchar_t wbuf[W_PATH_MAX];
5199  WIN32_FILE_ATTRIBUTE_DATA info;
5200  time_t creation_time;
5201 
5202  if (!filep) {
5203  return 0;
5204  }
5205  memset(filep, 0, sizeof(*filep));
5206 
5207  if (conn && is_file_in_memory(conn, path)) {
5208  /* filep->is_directory = 0; filep->gzipped = 0; .. already done by
5209  * memset */
5210 
5211  /* Quick fix (for 1.9.x): */
5212  /* mg_stat must fill all fields, also for files in memory */
5213  struct mg_file tmp_file = STRUCT_FILE_INITIALIZER;
5214  open_file_in_memory(conn, path, &tmp_file, MG_FOPEN_MODE_NONE);
5215  filep->size = tmp_file.stat.size;
5216  filep->location = 2;
5217  /* TODO: for 1.10: restructure how files in memory are handled */
5218 
5219  /* The "file in memory" feature is a candidate for deletion.
5220  * Please join the discussion at
5221  * https://groups.google.com/forum/#!topic/civetweb/h9HT4CmeYqI
5222  */
5223 
5224  filep->last_modified = time(NULL); /* TODO */
5225  /* last_modified = now ... assumes the file may change during
5226  * runtime,
5227  * so every mg_fopen call may return different data */
5228  /* last_modified = conn->phys_ctx.start_time;
5229  * May be used it the data does not change during runtime. This
5230  * allows
5231  * browser caching. Since we do not know, we have to assume the file
5232  * in memory may change. */
5233  return 1;
5234  }
5235 
5236  path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf));
5237  if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
5238  filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
5239  filep->last_modified =
5240  SYS2UNIX_TIME(info.ftLastWriteTime.dwLowDateTime,
5241  info.ftLastWriteTime.dwHighDateTime);
5242 
5243  /* On Windows, the file creation time can be higher than the
5244  * modification time, e.g. when a file is copied.
5245  * Since the Last-Modified timestamp is used for caching
5246  * it should be based on the most recent timestamp. */
5247  creation_time = SYS2UNIX_TIME(info.ftCreationTime.dwLowDateTime,
5248  info.ftCreationTime.dwHighDateTime);
5249  if (creation_time > filep->last_modified) {
5250  filep->last_modified = creation_time;
5251  }
5252 
5253  filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
5254  /* If file name is fishy, reset the file structure and return
5255  * error.
5256  * Note it is important to reset, not just return the error, cause
5257  * functions like is_file_opened() check the struct. */
5258  if (!filep->is_directory && !path_cannot_disclose_cgi(path)) {
5259  memset(filep, 0, sizeof(*filep));
5260  return 0;
5261  }
5262 
5263  return 1;
5264  }
5265 
5266  return 0;
5267 }
5268 
5269 
5270 static int
5271 mg_remove(const struct mg_connection *conn, const char *path)
5272 {
5273  wchar_t wbuf[W_PATH_MAX];
5274  path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf));
5275  return DeleteFileW(wbuf) ? 0 : -1;
5276 }
5277 
5278 
5279 static int
5280 mg_mkdir(const struct mg_connection *conn, const char *path, int mode)
5281 {
5282  wchar_t wbuf[W_PATH_MAX];
5283  (void)mode;
5284  path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf));
5285  return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
5286 }
5287 
5288 
5289 /* Create substitutes for POSIX functions in Win32. */
5290 
5291 #if defined(GCC_DIAGNOSTIC)
5292 /* Show no warning in case system functions are not used. */
5293 #pragma GCC diagnostic push
5294 #pragma GCC diagnostic ignored "-Wunused-function"
5295 #endif
5296 
5297 
5298 /* Implementation of POSIX opendir/closedir/readdir for Windows. */
5300 static DIR *
5301 mg_opendir(const struct mg_connection *conn, const char *name)
5302 {
5303  DIR *dir = NULL;
5304  wchar_t wpath[W_PATH_MAX];
5305  DWORD attrs;
5306 
5307  if (name == NULL) {
5308  SetLastError(ERROR_BAD_ARGUMENTS);
5309  } else if ((dir = (DIR *)mg_malloc(sizeof(*dir))) == NULL) {
5310  SetLastError(ERROR_NOT_ENOUGH_MEMORY);
5311  } else {
5312  path_to_unicode(conn, name, wpath, ARRAY_SIZE(wpath));
5313  attrs = GetFileAttributesW(wpath);
5314  if ((wcslen(wpath) + 2 < ARRAY_SIZE(wpath)) && (attrs != 0xFFFFFFFF)
5315  && ((attrs & FILE_ATTRIBUTE_DIRECTORY) != 0)) {
5316  (void)wcscat(wpath, L"\\*");
5317  dir->handle = FindFirstFileW(wpath, &dir->info);
5318  dir->result.d_name[0] = '\0';
5319  } else {
5320  mg_free(dir);
5321  dir = NULL;
5322  }
5323  }
5324 
5325  return dir;
5326 }
5327 
5328 
5330 static int
5331 mg_closedir(DIR *dir)
5332 {
5333  int result = 0;
5334 
5335  if (dir != NULL) {
5336  if (dir->handle != INVALID_HANDLE_VALUE)
5337  result = FindClose(dir->handle) ? 0 : -1;
5338 
5339  mg_free(dir);
5340  } else {
5341  result = -1;
5342  SetLastError(ERROR_BAD_ARGUMENTS);
5343  }
5344 
5345  return result;
5346 }
5347 
5348 
5350 static struct dirent *
5351 mg_readdir(DIR *dir)
5352 {
5353  struct dirent *result = 0;
5354 
5355  if (dir) {
5356  if (dir->handle != INVALID_HANDLE_VALUE) {
5357  result = &dir->result;
5358  (void)WideCharToMultiByte(CP_UTF8,
5359  0,
5360  dir->info.cFileName,
5361  -1,
5362  result->d_name,
5363  sizeof(result->d_name),
5364  NULL,
5365  NULL);
5366 
5367  if (!FindNextFileW(dir->handle, &dir->info)) {
5368  (void)FindClose(dir->handle);
5369  dir->handle = INVALID_HANDLE_VALUE;
5370  }
5371 
5372  } else {
5373  SetLastError(ERROR_FILE_NOT_FOUND);
5374  }
5375  } else {
5376  SetLastError(ERROR_BAD_ARGUMENTS);
5377  }
5378 
5379  return result;
5380 }
5381 
5382 
5383 #if !defined(HAVE_POLL)
5384 #define POLLIN (1) /* Data ready - read will not block. */
5385 #define POLLPRI (2) /* Priority data ready. */
5386 #define POLLOUT (4) /* Send queue not full - write will not block. */
5387 
5389 static int
5390 poll(struct pollfd *pfd, unsigned int n, int milliseconds)
5391 {
5392  struct timeval tv;
5393  fd_set rset;
5394  fd_set wset;
5395  unsigned int i;
5396  int result;
5397  SOCKET maxfd = 0;
5398 
5399  memset(&tv, 0, sizeof(tv));
5400  tv.tv_sec = milliseconds / 1000;
5401  tv.tv_usec = (milliseconds % 1000) * 1000;
5402  FD_ZERO(&rset);
5403  FD_ZERO(&wset);
5404 
5405  for (i = 0; i < n; i++) {
5406  if (pfd[i].events & POLLIN) {
5407  FD_SET((SOCKET)pfd[i].fd, &rset);
5408  } else if (pfd[i].events & POLLOUT) {
5409  FD_SET((SOCKET)pfd[i].fd, &wset);
5410  }
5411  pfd[i].revents = 0;
5412 
5413  if (pfd[i].fd > maxfd) {
5414  maxfd = pfd[i].fd;
5415  }
5416  }
5417 
5418  if ((result = select((int)maxfd + 1, &rset, &wset, NULL, &tv)) > 0) {
5419  for (i = 0; i < n; i++) {
5420  if (FD_ISSET(pfd[i].fd, &rset)) {
5421  pfd[i].revents |= POLLIN;
5422  }
5423  if (FD_ISSET(pfd[i].fd, &wset)) {
5424  pfd[i].revents |= POLLOUT;
5425  }
5426  }
5427  }
5428 
5429  /* We should subtract the time used in select from remaining
5430  * "milliseconds", in particular if called from mg_poll with a
5431  * timeout quantum.
5432  * Unfortunately, the remaining time is not stored in "tv" in all
5433  * implementations, so the result in "tv" must be considered undefined.
5434  * See http://man7.org/linux/man-pages/man2/select.2.html */
5435 
5436  return result;
5437 }
5438 #endif /* HAVE_POLL */
5439 
5440 
5441 #if defined(GCC_DIAGNOSTIC)
5442 /* Enable unused function warning again */
5443 #pragma GCC diagnostic pop
5444 #endif
5445 
5446 
5447 static void
5448 set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */)
5449 {
5450  (void)conn; /* Unused. */
5451 #if defined(_WIN32_WCE)
5452  (void)sock;
5453 #else
5454  (void)SetHandleInformation((HANDLE)(intptr_t)sock, HANDLE_FLAG_INHERIT, 0);
5455 #endif
5456 }
5457 
5458 
5459 int
5461 {
5462 #if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
5463  /* Compile-time option to control stack size, e.g.
5464  * -DUSE_STACK_SIZE=16384
5465  */
5466  return ((_beginthread((void(__cdecl *)(void *))f, USE_STACK_SIZE, p)
5467  == ((uintptr_t)(-1L)))
5468  ? -1
5469  : 0);
5470 #else
5471  return (
5472  (_beginthread((void(__cdecl *)(void *))f, 0, p) == ((uintptr_t)(-1L)))
5473  ? -1
5474  : 0);
5475 #endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
5476 }
5477 
5478 
5479 /* Start a thread storing the thread context. */
5480 static int
5481 mg_start_thread_with_id(unsigned(__stdcall *f)(void *),
5482  void *p,
5483  pthread_t *threadidptr)
5484 {
5485  uintptr_t uip;
5486  HANDLE threadhandle;
5487  int result = -1;
5488 
5489  uip = _beginthreadex(NULL, 0, (unsigned(__stdcall *)(void *))f, p, 0, NULL);
5490  threadhandle = (HANDLE)uip;
5491  if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
5492  *threadidptr = threadhandle;
5493  result = 0;
5494  }
5495 
5496  return result;
5497 }
5498 
5499 
5500 /* Wait for a thread to finish. */
5501 static int
5502 mg_join_thread(pthread_t threadid)
5503 {
5504  int result;
5505  DWORD dwevent;
5506 
5507  result = -1;
5508  dwevent = WaitForSingleObject(threadid, (DWORD)INFINITE);
5509  if (dwevent == WAIT_FAILED) {
5510  DEBUG_TRACE("WaitForSingleObject() failed, error %d", ERRNO);
5511  } else {
5512  if (dwevent == WAIT_OBJECT_0) {
5513  CloseHandle(threadid);
5514  result = 0;
5515  }
5516  }
5517 
5518  return result;
5519 }
5520 
5521 #if !defined(NO_SSL_DL) && !defined(NO_SSL)
5522 /* If SSL is loaded dynamically, dlopen/dlclose is required. */
5523 /* Create substitutes for POSIX functions in Win32. */
5524 
5525 #if defined(GCC_DIAGNOSTIC)
5526 /* Show no warning in case system functions are not used. */
5527 #pragma GCC diagnostic push
5528 #pragma GCC diagnostic ignored "-Wunused-function"
5529 #endif
5530 
5531 
5533 static HANDLE
5534 dlopen(const char *dll_name, int flags)
5535 {
5536  wchar_t wbuf[W_PATH_MAX];
5537  (void)flags;
5538  path_to_unicode(NULL, dll_name, wbuf, ARRAY_SIZE(wbuf));
5539  return LoadLibraryW(wbuf);
5540 }
5541 
5542 
5544 static int
5545 dlclose(void *handle)
5546 {
5547  int result;
5548 
5549  if (FreeLibrary((HMODULE)handle) != 0) {
5550  result = 0;
5551  } else {
5552  result = -1;
5553  }
5554 
5555  return result;
5556 }
5557 
5558 
5559 #if defined(GCC_DIAGNOSTIC)
5560 /* Enable unused function warning again */
5561 #pragma GCC diagnostic pop
5562 #endif
5563 
5564 #endif
5565 
5566 
5567 #if !defined(NO_CGI)
5568 #define SIGKILL (0)
5569 
5570 
5571 static int
5572 kill(pid_t pid, int sig_num)
5573 {
5574  (void)TerminateProcess((HANDLE)pid, (UINT)sig_num);
5575  (void)CloseHandle((HANDLE)pid);
5576  return 0;
5577 }
5578 
5579 
5580 #if !defined(WNOHANG)
5581 #define WNOHANG (1)
5582 #endif
5583 
5584 
5585 static pid_t
5586 waitpid(pid_t pid, int *status, int flags)
5587 {
5588  DWORD timeout = INFINITE;
5589  DWORD waitres;
5590 
5591  (void)status; /* Currently not used by any client here */
5592 
5593  if ((flags | WNOHANG) == WNOHANG) {
5594  timeout = 0;
5595  }
5596 
5597  waitres = WaitForSingleObject((HANDLE)pid, timeout);
5598  if (waitres == WAIT_OBJECT_0) {
5599  return pid;
5600  }
5601  if (waitres == WAIT_TIMEOUT) {
5602  return 0;
5603  }
5604  return (pid_t)-1;
5605 }
5606 
5607 
5608 static void
5609 trim_trailing_whitespaces(char *s)
5610 {
5611  char *e = s + strlen(s) - 1;
5612  while ((e > s) && isspace(*(unsigned char *)e)) {
5613  *e-- = '\0';
5614  }
5615 }
5616 
5617 
5618 static pid_t
5619 spawn_process(struct mg_connection *conn,
5620  const char *prog,
5621  char *envblk,
5622  char *envp[],
5623  int fdin[2],
5624  int fdout[2],
5625  int fderr[2],
5626  const char *dir)
5627 {
5628  HANDLE me;
5629  char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
5630  cmdline[PATH_MAX], buf[PATH_MAX];
5631  int truncated;
5632  struct mg_file file = STRUCT_FILE_INITIALIZER;
5633  STARTUPINFOA si;
5634  PROCESS_INFORMATION pi = {0};
5635 
5636  (void)envp;
5637 
5638  memset(&si, 0, sizeof(si));
5639  si.cb = sizeof(si);
5640 
5641  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5642  si.wShowWindow = SW_HIDE;
5643 
5644  me = GetCurrentProcess();
5645  DuplicateHandle(me,
5646  (HANDLE)_get_osfhandle(fdin[0]),
5647  me,
5648  &si.hStdInput,
5649  0,
5650  TRUE,
5651  DUPLICATE_SAME_ACCESS);
5652  DuplicateHandle(me,
5653  (HANDLE)_get_osfhandle(fdout[1]),
5654  me,
5655  &si.hStdOutput,
5656  0,
5657  TRUE,
5658  DUPLICATE_SAME_ACCESS);
5659  DuplicateHandle(me,
5660  (HANDLE)_get_osfhandle(fderr[1]),
5661  me,
5662  &si.hStdError,
5663  0,
5664  TRUE,
5665  DUPLICATE_SAME_ACCESS);
5666 
5667  /* Mark handles that should not be inherited. See
5668  * https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx
5669  */
5670  SetHandleInformation((HANDLE)_get_osfhandle(fdin[1]),
5671  HANDLE_FLAG_INHERIT,
5672  0);
5673  SetHandleInformation((HANDLE)_get_osfhandle(fdout[0]),
5674  HANDLE_FLAG_INHERIT,
5675  0);
5676  SetHandleInformation((HANDLE)_get_osfhandle(fderr[0]),
5677  HANDLE_FLAG_INHERIT,
5678  0);
5679 
5680  /* If CGI file is a script, try to read the interpreter line */
5681  interp = conn->dom_ctx->config[CGI_INTERPRETER];
5682  if (interp == NULL) {
5683  buf[0] = buf[1] = '\0';
5684 
5685  /* Read the first line of the script into the buffer */
5686  mg_snprintf(
5687  conn, &truncated, cmdline, sizeof(cmdline), "%s/%s", dir, prog);
5688 
5689  if (truncated) {
5690  pi.hProcess = (pid_t)-1;
5691  goto spawn_cleanup;
5692  }
5693 
5694  if (mg_fopen(conn, cmdline, MG_FOPEN_MODE_READ, &file)) {
5695 #if defined(MG_USE_OPEN_FILE)
5696  p = (char *)file.access.membuf;
5697 #else
5698  p = (char *)NULL;
5699 #endif
5700  mg_fgets(buf, sizeof(buf), &file, &p);
5701  (void)mg_fclose(&file.access); /* ignore error on read only file */
5702  buf[sizeof(buf) - 1] = '\0';
5703  }
5704 
5705  if ((buf[0] == '#') && (buf[1] == '!')) {
5706  trim_trailing_whitespaces(buf + 2);
5707  } else {
5708  buf[2] = '\0';
5709  }
5710  interp = buf + 2;
5711  }
5712 
5713  if (interp[0] != '\0') {
5714  GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL);
5715  interp = full_interp;
5716  }
5717  GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
5718 
5719  if (interp[0] != '\0') {
5720  mg_snprintf(conn,
5721  &truncated,
5722  cmdline,
5723  sizeof(cmdline),
5724  "\"%s\" \"%s\\%s\"",
5725  interp,
5726  full_dir,
5727  prog);
5728  } else {
5729  mg_snprintf(conn,
5730  &truncated,
5731  cmdline,
5732  sizeof(cmdline),
5733  "\"%s\\%s\"",
5734  full_dir,
5735  prog);
5736  }
5737 
5738  if (truncated) {
5739  pi.hProcess = (pid_t)-1;
5740  goto spawn_cleanup;
5741  }
5742 
5743  DEBUG_TRACE("Running [%s]", cmdline);
5744  if (CreateProcessA(NULL,
5745  cmdline,
5746  NULL,
5747  NULL,
5748  TRUE,
5749  CREATE_NEW_PROCESS_GROUP,
5750  envblk,
5751  NULL,
5752  &si,
5753  &pi)
5754  == 0) {
5756  conn, "%s: CreateProcess(%s): %ld", __func__, cmdline, (long)ERRNO);
5757  pi.hProcess = (pid_t)-1;
5758  /* goto spawn_cleanup; */
5759  }
5760 
5761 spawn_cleanup:
5762  (void)CloseHandle(si.hStdOutput);
5763  (void)CloseHandle(si.hStdError);
5764  (void)CloseHandle(si.hStdInput);
5765  if (pi.hThread != NULL) {
5766  (void)CloseHandle(pi.hThread);
5767  }
5768 
5769  return (pid_t)pi.hProcess;
5770 }
5771 #endif /* !NO_CGI */
5772 
5773 
5774 static int
5776 {
5777  unsigned long non_blocking = 0;
5778  return ioctlsocket(sock, (long)FIONBIO, &non_blocking);
5779 }
5780 
5781 static int
5783 {
5784  unsigned long non_blocking = 1;
5785  return ioctlsocket(sock, (long)FIONBIO, &non_blocking);
5786 }
5787 
5788 #else
5789 
5790 static int
5791 mg_stat(const struct mg_connection *conn,
5792  const char *path,
5793  struct mg_file_stat *filep)
5794 {
5795  struct stat st;
5796  if (!filep) {
5797  return 0;
5798  }
5799  memset(filep, 0, sizeof(*filep));
5800 
5801  if (conn && is_file_in_memory(conn, path)) {
5802 
5803  /* Quick fix (for 1.9.x): */
5804  /* mg_stat must fill all fields, also for files in memory */
5805  struct mg_file tmp_file = STRUCT_FILE_INITIALIZER;
5806  open_file_in_memory(conn, path, &tmp_file, MG_FOPEN_MODE_NONE);
5807  filep->size = tmp_file.stat.size;
5808  filep->last_modified = time(NULL);
5809  filep->location = 2;
5810  /* TODO: remove legacy "files in memory" feature */
5811 
5812  return 1;
5813  }
5814 
5815  if (0 == stat(path, &st)) {
5816  filep->size = (uint64_t)(st.st_size);
5817  filep->last_modified = st.st_mtime;
5818  filep->is_directory = S_ISDIR(st.st_mode);
5819  return 1;
5820  }
5821 
5822  return 0;
5823 }
5824 
5825 
5826 static void
5827 set_close_on_exec(SOCKET fd, struct mg_connection *conn /* may be null */)
5828 {
5829  if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
5830  if (conn) {
5831  mg_cry_internal(conn,
5832  "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s",
5833  __func__,
5834  strerror(ERRNO));
5835  }
5836  }
5837 }
5838 
5839 
5840 int
5842 {
5843  pthread_t thread_id;
5844  pthread_attr_t attr;
5845  int result;
5846 
5847  (void)pthread_attr_init(&attr);
5848  (void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
5849 
5850 #if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
5851  /* Compile-time option to control stack size,
5852  * e.g. -DUSE_STACK_SIZE=16384 */
5853  (void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
5854 #endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */
5855 
5856  result = pthread_create(&thread_id, &attr, func, param);
5857  pthread_attr_destroy(&attr);
5858 
5859  return result;
5860 }
5861 
5862 
5863 /* Start a thread storing the thread context. */
5864 static int
5866  void *param,
5867  pthread_t *threadidptr)
5868 {
5869  pthread_t thread_id;
5870  pthread_attr_t attr;
5871  int result;
5872 
5873  (void)pthread_attr_init(&attr);
5874 
5875 #if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1)
5876  /* Compile-time option to control stack size,
5877  * e.g. -DUSE_STACK_SIZE=16384 */
5878  (void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE);
5879 #endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */
5880 
5881  result = pthread_create(&thread_id, &attr, func, param);
5882  pthread_attr_destroy(&attr);
5883  if ((result == 0) && (threadidptr != NULL)) {
5884  *threadidptr = thread_id;
5885  }
5886  return result;
5887 }
5888 
5889 
5890 /* Wait for a thread to finish. */
5891 static int
5892 mg_join_thread(pthread_t threadid)
5893 {
5894  int result;
5895 
5896  result = pthread_join(threadid, NULL);
5897  return result;
5898 }
5899 
5900 
5901 #if !defined(NO_CGI)
5902 static pid_t
5903 spawn_process(struct mg_connection *conn,
5904  const char *prog,
5905  char *envblk,
5906  char *envp[],
5907  int fdin[2],
5908  int fdout[2],
5909  int fderr[2],
5910  const char *dir)
5911 {
5912  pid_t pid;
5913  const char *interp;
5914 
5915  (void)envblk;
5916 
5917  if (conn == NULL) {
5918  return 0;
5919  }
5920 
5921  if ((pid = fork()) == -1) {
5922  /* Parent */
5923  mg_send_http_error(conn,
5924  500,
5925  "Error: Creating CGI process\nfork(): %s",
5926  strerror(ERRNO));
5927  } else if (pid == 0) {
5928  /* Child */
5929  if (chdir(dir) != 0) {
5931  conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
5932  } else if (dup2(fdin[0], 0) == -1) {
5933  mg_cry_internal(conn,
5934  "%s: dup2(%d, 0): %s",
5935  __func__,
5936  fdin[0],
5937  strerror(ERRNO));
5938  } else if (dup2(fdout[1], 1) == -1) {
5939  mg_cry_internal(conn,
5940  "%s: dup2(%d, 1): %s",
5941  __func__,
5942  fdout[1],
5943  strerror(ERRNO));
5944  } else if (dup2(fderr[1], 2) == -1) {
5945  mg_cry_internal(conn,
5946  "%s: dup2(%d, 2): %s",
5947  __func__,
5948  fderr[1],
5949  strerror(ERRNO));
5950  } else {
5951  /* Keep stderr and stdout in two different pipes.
5952  * Stdout will be sent back to the client,
5953  * stderr should go into a server error log. */
5954  (void)close(fdin[0]);
5955  (void)close(fdout[1]);
5956  (void)close(fderr[1]);
5957 
5958  /* Close write end fdin and read end fdout and fderr */
5959  (void)close(fdin[1]);
5960  (void)close(fdout[0]);
5961  (void)close(fderr[0]);
5962 
5963  /* After exec, all signal handlers are restored to their default
5964  * values, with one exception of SIGCHLD. According to
5965  * POSIX.1-2001 and Linux's implementation, SIGCHLD's handler
5966  * will leave unchanged after exec if it was set to be ignored.
5967  * Restore it to default action. */
5968  signal(SIGCHLD, SIG_DFL);
5969 
5970  interp = conn->dom_ctx->config[CGI_INTERPRETER];
5971  if (interp == NULL) {
5972  (void)execle(prog, prog, NULL, envp);
5973  mg_cry_internal(conn,
5974  "%s: execle(%s): %s",
5975  __func__,
5976  prog,
5977  strerror(ERRNO));
5978  } else {
5979  (void)execle(interp, interp, prog, NULL, envp);
5980  mg_cry_internal(conn,
5981  "%s: execle(%s %s): %s",
5982  __func__,
5983  interp,
5984  prog,
5985  strerror(ERRNO));
5986  }
5987  }
5988  exit(EXIT_FAILURE);
5989  }
5990 
5991  return pid;
5992 }
5993 #endif /* !NO_CGI */
5994 
5995 
5996 static int
5998 {
5999  int flags = fcntl(sock, F_GETFL, 0);
6000  if (flags < 0) {
6001  return -1;
6002  }
6003 
6004  if (fcntl(sock, F_SETFL, (flags | O_NONBLOCK)) < 0) {
6005  return -1;
6006  }
6007  return 0;
6008 }
6009 
6010 static int
6012 {
6013  int flags = fcntl(sock, F_GETFL, 0);
6014  if (flags < 0) {
6015  return -1;
6016  }
6017 
6018  if (fcntl(sock, F_SETFL, flags & (~(int)(O_NONBLOCK))) < 0) {
6019  return -1;
6020  }
6021  return 0;
6022 }
6023 #endif /* _WIN32 / else */
6024 
6025 /* End of initial operating system specific define block. */
6026 
6027 
6028 /* Get a random number (independent of C rand function) */
6029 static uint64_t
6031 {
6032  static uint64_t lfsr = 0; /* Linear feedback shift register */
6033  static uint64_t lcg = 0; /* Linear congruential generator */
6034  uint64_t now = mg_get_current_time_ns();
6035 
6036  if (lfsr == 0) {
6037  /* lfsr will be only 0 if has not been initialized,
6038  * so this code is called only once. */
6039  lfsr = mg_get_current_time_ns();
6040  lcg = mg_get_current_time_ns();
6041  } else {
6042  /* Get the next step of both random number generators. */
6043  lfsr = (lfsr >> 1)
6044  | ((((lfsr >> 0) ^ (lfsr >> 1) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1)
6045  << 63);
6046  lcg = lcg * 6364136223846793005LL + 1442695040888963407LL;
6047  }
6048 
6049  /* Combining two pseudo-random number generators and a high resolution
6050  * part
6051  * of the current server time will make it hard (impossible?) to guess
6052  * the
6053  * next number. */
6054  return (lfsr ^ lcg ^ now);
6055 }
6056 
6057 
6058 static int
6059 mg_poll(struct pollfd *pfd,
6060  unsigned int n,
6061  int milliseconds,
6062  volatile int *stop_server)
6063 {
6064  /* Call poll, but only for a maximum time of a few seconds.
6065  * This will allow to stop the server after some seconds, instead
6066  * of having to wait for a long socket timeout. */
6067  int ms_now = SOCKET_TIMEOUT_QUANTUM; /* Sleep quantum in ms */
6068 
6069  do {
6070  int result;
6071 
6072  if (*stop_server) {
6073  /* Shut down signal */
6074  return -2;
6075  }
6076 
6077  if ((milliseconds >= 0) && (milliseconds < ms_now)) {
6078  ms_now = milliseconds;
6079  }
6080 
6081  result = poll(pfd, n, ms_now);
6082  if (result != 0) {
6083  /* Poll returned either success (1) or error (-1).
6084  * Forward both to the caller. */
6085  return result;
6086  }
6087 
6088  /* Poll returned timeout (0). */
6089  if (milliseconds > 0) {
6090  milliseconds -= ms_now;
6091  }
6092 
6093  } while (milliseconds != 0);
6094 
6095  /* timeout: return 0 */
6096  return 0;
6097 }
6098 
6099 
6100 /* Write data to the IO channel - opened file descriptor, socket or SSL
6101  * descriptor.
6102  * Return value:
6103  * >=0 .. number of bytes successfully written
6104  * -1 .. timeout
6105  * -2 .. error
6106  */
6107 static int
6108 push_inner(struct mg_context *ctx,
6109  FILE *fp,
6110  SOCKET sock,
6111  SSL *ssl,
6112  const char *buf,
6113  int len,
6114  double timeout)
6115 {
6116  uint64_t start = 0, now = 0, timeout_ns = 0;
6117  int n, err;
6118  unsigned ms_wait = SOCKET_TIMEOUT_QUANTUM; /* Sleep quantum in ms */
6119 
6120 #if defined(_WIN32)
6121  typedef int len_t;
6122 #else
6123  typedef size_t len_t;
6124 #endif
6125 
6126  if (timeout > 0) {
6127  now = mg_get_current_time_ns();
6128  start = now;
6129  timeout_ns = (uint64_t)(timeout * 1.0E9);
6130  }
6131 
6132  if (ctx == NULL) {
6133  return -2;
6134  }
6135 
6136 #if defined(NO_SSL)
6137  if (ssl) {
6138  return -2;
6139  }
6140 #endif
6141 
6142  /* Try to read until it succeeds, fails, times out, or the server
6143  * shuts down. */
6144  for (;;) {
6145 
6146 #if !defined(NO_SSL)
6147  if (ssl != NULL) {
6148  n = SSL_write(ssl, buf, len);
6149  if (n <= 0) {
6150  err = SSL_get_error(ssl, n);
6151  if ((err == SSL_ERROR_SYSCALL) && (n == -1)) {
6152  err = ERRNO;
6153  } else if ((err == SSL_ERROR_WANT_READ)
6154  || (err == SSL_ERROR_WANT_WRITE)) {
6155  n = 0;
6156  } else {
6157  DEBUG_TRACE("SSL_write() failed, error %d", err);
6158  return -2;
6159  }
6160  } else {
6161  err = 0;
6162  }
6163  } else
6164 #endif
6165  if (fp != NULL) {
6166  n = (int)fwrite(buf, 1, (size_t)len, fp);
6167  if (ferror(fp)) {
6168  n = -1;
6169  err = ERRNO;
6170  } else {
6171  err = 0;
6172  }
6173  } else {
6174  n = (int)send(sock, buf, (len_t)len, MSG_NOSIGNAL);
6175  err = (n < 0) ? ERRNO : 0;
6176 #if defined(_WIN32)
6177  if (err == WSAEWOULDBLOCK) {
6178  err = 0;
6179  n = 0;
6180  }
6181 #else
6182  if (err == EWOULDBLOCK) {
6183  err = 0;
6184  n = 0;
6185  }
6186 #endif
6187  if (n < 0) {
6188  /* shutdown of the socket at client side */
6189  return -2;
6190  }
6191  }
6192 
6193  if (ctx->stop_flag) {
6194  return -2;
6195  }
6196 
6197  if ((n > 0) || ((n == 0) && (len == 0))) {
6198  /* some data has been read, or no data was requested */
6199  return n;
6200  }
6201  if (n < 0) {
6202  /* socket error - check errno */
6203  DEBUG_TRACE("send() failed, error %d", err);
6204 
6205  /* TODO (mid): error handling depending on the error code.
6206  * These codes are different between Windows and Linux.
6207  * Currently there is no problem with failing send calls,
6208  * if there is a reproducible situation, it should be
6209  * investigated in detail.
6210  */
6211  return -2;
6212  }
6213 
6214  /* Only in case n=0 (timeout), repeat calling the write function */
6215 
6216  /* If send failed, wait before retry */
6217  if (fp != NULL) {
6218  /* For files, just wait a fixed time.
6219  * Maybe it helps, maybe not. */
6220  mg_sleep(5);
6221  } else {
6222  /* For sockets, wait for the socket using poll */
6223  struct pollfd pfd[1];
6224  int pollres;
6225 
6226  pfd[0].fd = sock;
6227  pfd[0].events = POLLOUT;
6228  pollres = mg_poll(pfd, 1, (int)(ms_wait), &(ctx->stop_flag));
6229  if (ctx->stop_flag) {
6230  return -2;
6231  }
6232  if (pollres > 0) {
6233  continue;
6234  }
6235  }
6236 
6237  if (timeout > 0) {
6238  now = mg_get_current_time_ns();
6239  if ((now - start) > timeout_ns) {
6240  /* Timeout */
6241  break;
6242  }
6243  }
6244  }
6245 
6246  (void)err; /* Avoid unused warning if NO_SSL is set and DEBUG_TRACE is not
6247  used */
6248 
6249  return -1;
6250 }
6251 
6252 
6253 static int64_t
6254 push_all(struct mg_context *ctx,
6255  FILE *fp,
6256  SOCKET sock,
6257  SSL *ssl,
6258  const char *buf,
6259  int64_t len)
6260 {
6261  double timeout = -1.0;
6262  int64_t n, nwritten = 0;
6263 
6264  if (ctx == NULL) {
6265  return -1;
6266  }
6267 
6268  if (ctx->dd.config[REQUEST_TIMEOUT]) {
6269  timeout = atoi(ctx->dd.config[REQUEST_TIMEOUT]) / 1000.0;
6270  }
6271 
6272  while ((len > 0) && (ctx->stop_flag == 0)) {
6273  n = push_inner(ctx, fp, sock, ssl, buf + nwritten, (int)len, timeout);
6274  if (n < 0) {
6275  if (nwritten == 0) {
6276  nwritten = n; /* Propagate the error */
6277  }
6278  break;
6279  } else if (n == 0) {
6280  break; /* No more data to write */
6281  } else {
6282  nwritten += n;
6283  len -= n;
6284  }
6285  }
6286 
6287  return nwritten;
6288 }
6289 
6290 
6291 /* Read from IO channel - opened file descriptor, socket, or SSL descriptor.
6292  * Return value:
6293  * >=0 .. number of bytes successfully read
6294  * -1 .. timeout
6295  * -2 .. error
6296  */
6297 static int
6298 pull_inner(FILE *fp,
6299  struct mg_connection *conn,
6300  char *buf,
6301  int len,
6302  double timeout)
6303 {
6304  int nread, err = 0;
6305 
6306 #if defined(_WIN32)
6307  typedef int len_t;
6308 #else
6309  typedef size_t len_t;
6310 #endif
6311 #if !defined(NO_SSL)
6312  int ssl_pending;
6313 #endif
6314 
6315  /* We need an additional wait loop around this, because in some cases
6316  * with TLSwe may get data from the socket but not from SSL_read.
6317  * In this case we need to repeat at least once.
6318  */
6319 
6320  if (fp != NULL) {
6321 #if !defined(_WIN32_WCE)
6322  /* Use read() instead of fread(), because if we're reading from the
6323  * CGI pipe, fread() may block until IO buffer is filled up. We
6324  * cannot afford to block and must pass all read bytes immediately
6325  * to the client. */
6326  nread = (int)read(fileno(fp), buf, (size_t)len);
6327 #else
6328  /* WinCE does not support CGI pipes */
6329  nread = (int)fread(buf, 1, (size_t)len, fp);
6330 #endif
6331  err = (nread < 0) ? ERRNO : 0;
6332  if ((nread == 0) && (len > 0)) {
6333  /* Should get data, but got EOL */
6334  return -2;
6335  }
6336 
6337 #if !defined(NO_SSL)
6338  } else if ((conn->ssl != NULL)
6339  && ((ssl_pending = SSL_pending(conn->ssl)) > 0)) {
6340  /* We already know there is no more data buffered in conn->buf
6341  * but there is more available in the SSL layer. So don't poll
6342  * conn->client.sock yet. */
6343  if (ssl_pending > len) {
6344  ssl_pending = len;
6345  }
6346  nread = SSL_read(conn->ssl, buf, ssl_pending);
6347  if (nread <= 0) {
6348  err = SSL_get_error(conn->ssl, nread);
6349  if ((err == SSL_ERROR_SYSCALL) && (nread == -1)) {
6350  err = ERRNO;
6351  } else if ((err == SSL_ERROR_WANT_READ)
6352  || (err == SSL_ERROR_WANT_WRITE)) {
6353  nread = 0;
6354  } else {
6355  DEBUG_TRACE("SSL_read() failed, error %d", err);
6356  return -1;
6357  }
6358  } else {
6359  err = 0;
6360  }
6361 
6362  } else if (conn->ssl != NULL) {
6363 
6364  struct pollfd pfd[1];
6365  int pollres;
6366 
6367  pfd[0].fd = conn->client.sock;
6368  pfd[0].events = POLLIN;
6369  pollres = mg_poll(pfd,
6370  1,
6371  (int)(timeout * 1000.0),
6372  &(conn->phys_ctx->stop_flag));
6373  if (conn->phys_ctx->stop_flag) {
6374  return -2;
6375  }
6376  if (pollres > 0) {
6377  nread = SSL_read(conn->ssl, buf, len);
6378  if (nread <= 0) {
6379  err = SSL_get_error(conn->ssl, nread);
6380  if ((err == SSL_ERROR_SYSCALL) && (nread == -1)) {
6381  err = ERRNO;
6382  } else if ((err == SSL_ERROR_WANT_READ)
6383  || (err == SSL_ERROR_WANT_WRITE)) {
6384  nread = 0;
6385  } else {
6386  DEBUG_TRACE("SSL_read() failed, error %d", err);
6387  return -2;
6388  }
6389  } else {
6390  err = 0;
6391  }
6392 
6393  } else if (pollres < 0) {
6394  /* Error */
6395  return -2;
6396  } else {
6397  /* pollres = 0 means timeout */
6398  nread = 0;
6399  }
6400 #endif
6401 
6402  } else {
6403  struct pollfd pfd[1];
6404  int pollres;
6405 
6406  pfd[0].fd = conn->client.sock;
6407  pfd[0].events = POLLIN;
6408  pollres = mg_poll(pfd,
6409  1,
6410  (int)(timeout * 1000.0),
6411  &(conn->phys_ctx->stop_flag));
6412  if (conn->phys_ctx->stop_flag) {
6413  return -2;
6414  }
6415  if (pollres > 0) {
6416  nread = (int)recv(conn->client.sock, buf, (len_t)len, 0);
6417  err = (nread < 0) ? ERRNO : 0;
6418  if (nread <= 0) {
6419  /* shutdown of the socket at client side */
6420  return -2;
6421  }
6422  } else if (pollres < 0) {
6423  /* error callint poll */
6424  return -2;
6425  } else {
6426  /* pollres = 0 means timeout */
6427  nread = 0;
6428  }
6429  }
6430 
6431  if (conn->phys_ctx->stop_flag) {
6432  return -2;
6433  }
6434 
6435  if ((nread > 0) || ((nread == 0) && (len == 0))) {
6436  /* some data has been read, or no data was requested */
6437  return nread;
6438  }
6439 
6440  if (nread < 0) {
6441 /* socket error - check errno */
6442 #if defined(_WIN32)
6443  if (err == WSAEWOULDBLOCK) {
6444  /* TODO (low): check if this is still required */
6445  /* standard case if called from close_socket_gracefully */
6446  return -2;
6447  } else if (err == WSAETIMEDOUT) {
6448  /* TODO (low): check if this is still required */
6449  /* timeout is handled by the while loop */
6450  return 0;
6451  } else if (err == WSAECONNABORTED) {
6452  /* See https://www.chilkatsoft.com/p/p_299.asp */
6453  return -2;
6454  } else {
6455  DEBUG_TRACE("recv() failed, error %d", err);
6456  return -2;
6457  }
6458 #else
6459  /* TODO: POSIX returns either EAGAIN or EWOULDBLOCK in both cases,
6460  * if the timeout is reached and if the socket was set to non-
6461  * blocking in close_socket_gracefully, so we can not distinguish
6462  * here. We have to wait for the timeout in both cases for now.
6463  */
6464  if ((err == EAGAIN) || (err == EWOULDBLOCK) || (err == EINTR)) {
6465  /* TODO (low): check if this is still required */
6466  /* EAGAIN/EWOULDBLOCK:
6467  * standard case if called from close_socket_gracefully
6468  * => should return -1 */
6469  /* or timeout occurred
6470  * => the code must stay in the while loop */
6471 
6472  /* EINTR can be generated on a socket with a timeout set even
6473  * when SA_RESTART is effective for all relevant signals
6474  * (see signal(7)).
6475  * => stay in the while loop */
6476  } else {
6477  DEBUG_TRACE("recv() failed, error %d", err);
6478  return -2;
6479  }
6480 #endif
6481  }
6482 
6483  /* Timeout occurred, but no data available. */
6484  return -1;
6485 }
6486 
6487 
6488 static int
6489 pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
6490 {
6491  int n, nread = 0;
6492  double timeout = -1.0;
6493  uint64_t start_time = 0, now = 0, timeout_ns = 0;
6494 
6495  if (conn->dom_ctx->config[REQUEST_TIMEOUT]) {
6496  timeout = atoi(conn->dom_ctx->config[REQUEST_TIMEOUT]) / 1000.0;
6497  }
6498  if (timeout >= 0.0) {
6499  start_time = mg_get_current_time_ns();
6500  timeout_ns = (uint64_t)(timeout * 1.0E9);
6501  }
6502 
6503  while ((len > 0) && (conn->phys_ctx->stop_flag == 0)) {
6504  n = pull_inner(fp, conn, buf + nread, len, timeout);
6505  if (n == -2) {
6506  if (nread == 0) {
6507  nread = -1; /* Propagate the error */
6508  }
6509  break;
6510  } else if (n == -1) {
6511  /* timeout */
6512  if (timeout >= 0.0) {
6513  now = mg_get_current_time_ns();
6514  if ((now - start_time) <= timeout_ns) {
6515  continue;
6516  }
6517  }
6518  break;
6519  } else if (n == 0) {
6520  break; /* No more data to read */
6521  } else {
6522  conn->consumed_content += n;
6523  nread += n;
6524  len -= n;
6525  }
6526  }
6527 
6528  return nread;
6529 }
6530 
6531 
6532 static void
6533 discard_unread_request_data(struct mg_connection *conn)
6534 {
6535  char buf[MG_BUF_LEN];
6536  size_t to_read;
6537  int nread;
6538 
6539  if (conn == NULL) {
6540  return;
6541  }
6542 
6543  to_read = sizeof(buf);
6544 
6545  if (conn->is_chunked) {
6546  /* Chunked encoding: 3=chunk read completely
6547  * completely */
6548  while (conn->is_chunked != 3) {
6549  nread = mg_read(conn, buf, to_read);
6550  if (nread <= 0) {
6551  break;
6552  }
6553  }
6554 
6555  } else {
6556  /* Not chunked: content length is known */
6557  while (conn->consumed_content < conn->content_len) {
6558  if (to_read
6559  > (size_t)(conn->content_len - conn->consumed_content)) {
6560  to_read = (size_t)(conn->content_len - conn->consumed_content);
6561  }
6562 
6563  nread = mg_read(conn, buf, to_read);
6564  if (nread <= 0) {
6565  break;
6566  }
6567  }
6568  }
6569 }
6570 
6571 
6572 static int
6573 mg_read_inner(struct mg_connection *conn, void *buf, size_t len)
6574 {
6575  int64_t n, buffered_len, nread;
6576  int64_t len64 =
6577  (int64_t)((len > INT_MAX) ? INT_MAX : len); /* since the return value is
6578  * int, we may not read more
6579  * bytes */
6580  const char *body;
6581 
6582  if (conn == NULL) {
6583  return 0;
6584  }
6585 
6586  /* If Content-Length is not set for a request with body data
6587  * (e.g., a PUT or POST request), we do not know in advance
6588  * how much data should be read. */
6589  if (conn->consumed_content == 0) {
6590  if (conn->is_chunked == 1) {
6591  conn->content_len = len64;
6592  conn->is_chunked = 2;
6593  } else if (conn->content_len == -1) {
6594  /* The body data is completed when the connection
6595  * is closed. */
6596  conn->content_len = INT64_MAX;
6597  conn->must_close = 1;
6598  }
6599  }
6600 
6601  nread = 0;
6602  if (conn->consumed_content < conn->content_len) {
6603  /* Adjust number of bytes to read. */
6604  int64_t left_to_read = conn->content_len - conn->consumed_content;
6605  if (left_to_read < len64) {
6606  /* Do not read more than the total content length of the
6607  * request.
6608  */
6609  len64 = left_to_read;
6610  }
6611 
6612  /* Return buffered data */
6613  buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len
6614  - conn->consumed_content;
6615  if (buffered_len > 0) {
6616  if (len64 < buffered_len) {
6617  buffered_len = len64;
6618  }
6619  body = conn->buf + conn->request_len + conn->consumed_content;
6620  memcpy(buf, body, (size_t)buffered_len);
6621  len64 -= buffered_len;
6622  conn->consumed_content += buffered_len;
6623  nread += buffered_len;
6624  buf = (char *)buf + buffered_len;
6625  }
6626 
6627  /* We have returned all buffered data. Read new data from the remote
6628  * socket.
6629  */
6630  if ((n = pull_all(NULL, conn, (char *)buf, (int)len64)) >= 0) {
6631  nread += n;
6632  } else {
6633  nread = ((nread > 0) ? nread : n);
6634  }
6635  }
6636  return (int)nread;
6637 }
6638 
6639 
6640 static char
6641 mg_getc(struct mg_connection *conn)
6642 {
6643  char c;
6644  if (conn == NULL) {
6645  return 0;
6646  }
6647  if (mg_read_inner(conn, &c, 1) <= 0) {
6648  return (char)0;
6649  }
6650  return c;
6651 }
6652 
6653 
6654 int
6655 mg_read(struct mg_connection *conn, void *buf, size_t len)
6656 {
6657  if (len > INT_MAX) {
6658  len = INT_MAX;
6659  }
6660 
6661  if (conn == NULL) {
6662  return 0;
6663  }
6664 
6665  if (conn->is_chunked) {
6666  size_t all_read = 0;
6667 
6668  while (len > 0) {
6669  if (conn->is_chunked == 3) {
6670  /* No more data left to read */
6671  return 0;
6672  }
6673 
6674  if (conn->chunk_remainder) {
6675  /* copy from the remainder of the last received chunk */
6676  long read_ret;
6677  size_t read_now =
6678  ((conn->chunk_remainder > len) ? (len)
6679  : (conn->chunk_remainder));
6680 
6681  conn->content_len += (int)read_now;
6682  read_ret =
6683  mg_read_inner(conn, (char *)buf + all_read, read_now);
6684 
6685  if (read_ret < 1) {
6686  /* read error */
6687  return -1;
6688  }
6689 
6690  all_read += (size_t)read_ret;
6691  conn->chunk_remainder -= (size_t)read_ret;
6692  len -= (size_t)read_ret;
6693 
6694  if (conn->chunk_remainder == 0) {
6695  /* Add data bytes in the current chunk have been read,
6696  * so we are expecting \r\n now. */
6697  char x1, x2;
6698  conn->content_len += 2;
6699  x1 = mg_getc(conn);
6700  x2 = mg_getc(conn);
6701  if ((x1 != '\r') || (x2 != '\n')) {
6702  /* Protocol violation */
6703  return -1;
6704  }
6705  }
6706 
6707  } else {
6708  /* fetch a new chunk */
6709  int i = 0;
6710  char lenbuf[64];
6711  char *end = 0;
6712  unsigned long chunkSize = 0;
6713 
6714  for (i = 0; i < ((int)sizeof(lenbuf) - 1); i++) {
6715  conn->content_len++;
6716  lenbuf[i] = mg_getc(conn);
6717  if ((i > 0) && (lenbuf[i] == '\r')
6718  && (lenbuf[i - 1] != '\r')) {
6719  continue;
6720  }
6721  if ((i > 1) && (lenbuf[i] == '\n')
6722  && (lenbuf[i - 1] == '\r')) {
6723  lenbuf[i + 1] = 0;
6724  chunkSize = strtoul(lenbuf, &end, 16);
6725  if (chunkSize == 0) {
6726  /* regular end of content */
6727  conn->is_chunked = 3;
6728  }
6729  break;
6730  }
6731  if (!isxdigit(lenbuf[i])) {
6732  /* illegal character for chunk length */
6733  return -1;
6734  }
6735  }
6736  if ((end == NULL) || (*end != '\r')) {
6737  /* chunksize not set correctly */
6738  return -1;
6739  }
6740  if (chunkSize == 0) {
6741  break;
6742  }
6743 
6744