31#if !defined(_CRT_SECURE_NO_WARNINGS)
32#define _CRT_SECURE_NO_WARNINGS
36#define _XOPEN_SOURCE 600
38#if !defined(_LARGEFILE_SOURCE)
39#define _LARGEFILE_SOURCE
41#define __STDC_FORMAT_MACROS
42#define __STDC_LIMIT_MACROS
47#pragma warning (disable : 4127)
49#pragma warning (disable : 4204)
54#ifdef WIN32_LEAN_AND_MEAN
55#undef WIN32_LEAN_AND_MEAN
58#if defined(__SYMBIAN32__)
61#define PATH_MAX FILENAME_MAX
82#if defined(_WIN32) && !defined(__SYMBIAN32__)
84#define _WIN32_WINNT 0x0400
88#define PATH_MAX MAX_PATH
100#define errno GetLastError()
101#define strerror(x) _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
104#define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
105 ((uint64_t)((uint32_t)(hi))) << 32))
106#define RATE_DIFF 10000000
107#define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
108#define SYS2UNIX_TIME(lo, hi) \
109 (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
114#if defined(_MSC_VER) && _MSC_VER < 1300
116#define STR(x) STRX(x)
117#define __func__ __FILE__ ":" STR(__LINE__)
118#define strtoull(x, y, z) (unsigned __int64) _atoi64(x)
119#define strtoll(x, y, z) _atoi64(x)
121#define __func__ __FUNCTION__
122#define strtoull(x, y, z) _strtoui64(x, y, z)
123#define strtoll(x, y, z) _strtoi64(x, y, z)
126#define ERRNO GetLastError()
128#define SSL_LIB "ssleay32.dll"
129#define CRYPTO_LIB "libeay32.dll"
131#if !defined(EWOULDBLOCK)
132#define EWOULDBLOCK WSAEWOULDBLOCK
135#define INT64_FMT "I64d"
137#define WINCDECL __cdecl
139#define snprintf _snprintf
140#define vsnprintf _vsnprintf
141#define mg_sleep(x) Sleep(x)
143#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
145#define popen(x, y) _popen(x, y)
148#define pclose(x) _pclose(x)
150#define close(x) _close(x)
151#define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
153#define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
154#define fdopen(x, y) _fdopen((x), (y))
155#define write(x, y, z) _write((x), (y), (unsigned) z)
156#define read(x, y, z) _read((x), (y), (unsigned) z)
158#define funlockfile(x)
159#define sleep(x) Sleep((x) * 1000)
160#define rmdir(x) _rmdir(x)
163#define va_copy(x, y) x = y
167#define fileno(x) _fileno(x)
179#if defined(HAVE_STDINT)
186#define INT64_MAX 9223372036854775807
212#pragma comment(lib, "Ws2_32.lib")
217#include <sys/socket.h>
219#include <netinet/in.h>
220#include <arpa/inet.h>
229#if !defined(NO_SSL_DL) && !defined(NO_SSL)
234#define SSL_LIB "libssl.dylib"
235#define CRYPTO_LIB "libcrypto.dylib"
238#define SSL_LIB "libssl.so"
240#if !defined(CRYPTO_LIB)
241#define CRYPTO_LIB "libcrypto.so"
247#define closesocket(a) close(a)
248#define mg_mkdir(x, y) mkdir(x, y)
249#define mg_remove(x) remove(x)
250#define mg_sleep(x) usleep((x) * 1000)
252#define INVALID_SOCKET (-1)
253#define INT64_FMT PRId64
261#define MONGOOSE_VERSION "4.2"
262#define PASSWORDS_FILE_NAME ".htpasswd"
263#define CGI_ENVIRONMENT_SIZE 4096
264#define MAX_CGI_ENVIR_VARS 64
265#define MG_BUF_LEN 8192
266#define MAX_REQUEST_SIZE 16384
267#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
271#define DEBUG_TRACE(x)
274#define DEBUG_TRACE(x) do { \
276 printf("*** %lu.%p.%s.%d: ", \
277 (unsigned long) time(NULL), (void *) pthread_self(), \
278 __func__, __LINE__); \
282 funlockfile(stdout); \
285#define DEBUG_TRACE(x)
293#define _DARWIN_UNLIMITED_SELECT
295#define IP_ADDR_STR_LEN 50
297#if !defined(MSG_NOSIGNAL)
298#define MSG_NOSIGNAL 0
301#if !defined(SOMAXCONN)
305#if !defined(PATH_MAX)
315#if !defined(EXTRA_HTTP_HEADERS)
316#define EXTRA_HTTP_HEADERS ""
321#if defined(NO_SSL_DL)
322#include <openssl/ssl.h>
323#include <openssl/err.h>
332#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L
335#define SSL_OP_SINGLE_ECDH_USE 0x00080000L
337#define SSL_OP_SINGLE_DH_USE 0x00100000L
339#define SSL_OP_NO_SSLv2 0x01000000L
340#define SSL_OP_NO_SSLv3 0x02000000L
341#define SSL_OP_NO_TLSv1 0x04000000L
342#define SSL_OP_NO_TLSv1_2 0x08000000L
343#define SSL_OP_NO_TLSv1_1 0x10000000L
347#define NID_X9_62_prime256v1 415
349#define SSL_CTRL_SET_TMP_RSA 2
350#define SSL_CTRL_SET_TMP_DH 3
351#define SSL_CTRL_SET_TMP_ECDH 4
352#define SSL_CTRL_SET_TMP_RSA_CB 5
353#define SSL_CTRL_SET_TMP_DH_CB 6
354#define SSL_CTRL_SET_TMP_ECDH_CB 7
356#define SSL_CTRL_OPTIONS 32
358#define SSL_CTX_set_options(ctx,op) SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
359#define SSL_CTX_clear_options(ctx,op) SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
360#define SSL_CTX_get_options(ctx) SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
362#define SSL_CTX_set_tmp_dh(ctx,dh) SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
363#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
370#define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
371#define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
372#define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
373#define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
374#define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
375#define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
376#define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
377#define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
378#define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
379#define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
380#define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
381#define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
382 const char *, int)) ssl_sw[11].ptr)
383#define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
384 const char *, int)) ssl_sw[12].ptr)
385#define SSL_CTX_set_default_passwd_cb \
386 (* (void (*)(SSL_CTX *, mg_event_handler_t)) ssl_sw[13].ptr)
387#define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
388#define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
389#define SSL_CTX_use_certificate_chain_file \
390 (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
391#define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
392#define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
393#define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
394#define SSL_shutdown (* (int (*)(SSL *)) ssl_sw[20].ptr)
395#define SSL_CTX_ctrl (* (int (*)(SSL_CTX *ctx, int cmd, long larg, void *parg)) ssl_sw[21].ptr)
396#define SSL_CTX_set_cipher_list (* (int (*)(SSL_CTX *ctx, const char *str)) ssl_sw[22].ptr)
397#define EC_KEY_new_by_curve_name (* (EC_KEY* (*)(int nid)) ssl_sw[23].ptr)
398#define EC_KEY_free (* (int (*)(EC_KEY *)) ssl_sw[24].ptr)
399#define SSL_get_cipher_list (* (const char* (*)(const SSL*, int)) ssl_sw[25].ptr)
401#define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
402#define CRYPTO_set_locking_callback \
403 (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
404#define CRYPTO_set_id_callback \
405 (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
406#define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
407#define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
434#define STRUCT_FILE_INITIALIZER { 0, 0, 0, 0 }
518#include "lua_5.2.1.h"
533static void mg_strlcpy(
register char *dst,
register const char *src,
size_t n) {
534 for (; *src !=
'\0' &&
n > 1;
n--) {
541 return tolower(* (
const unsigned char *) s);
550 }
while (
diff == 0 &&
s1[-1] !=
'\0' && --len > 0);
560 }
while (
diff == 0 &&
s1[-1] !=
'\0');
606 }
else if (
n >= (
int)
buflen) {
686 for (
i = 0;
i <
ri->num_headers;
i++)
688 return ri->http_headers[
i].value;
750 if (pattern[
i] ==
'?' &&
str[
j] !=
'\0') {
752 }
else if (pattern[
i] ==
'$') {
753 return str[
j] ==
'\0' ?
j : -1;
754 }
else if (pattern[
i] ==
'*') {
756 if (pattern[
i] ==
'*') {
767 }
while (
res == -1 && len-- > 0);
768 return res == -1 ? -1 :
j +
res + len;
778 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
779 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
800 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
827 "cgi_pattern",
"**.cgi$|**.pl$|**.php$",
828 "cgi_environment",
NULL,
829 "put_delete_auth_file",
NULL,
830 "cgi_interpreter",
NULL,
832 "authentication_domain",
"mydomain.com",
833 "ssi_pattern",
"**.shtml$|**.shtm$",
835 "access_log_file",
NULL,
836 "enable_directory_listing",
"yes",
837 "error_log_file",
NULL,
838 "global_auth_file",
NULL,
840 "index.html,index.htm,index.cgi,index.shtml,index.php,index.lp",
841 "enable_keep_alive",
"no",
842 "access_control_list",
NULL,
843 "extra_mime_types",
NULL,
844 "listening_ports",
"8080",
845 "document_root",
NULL,
846 "ssl_certificate",
NULL,
849 "url_rewrite_patterns",
NULL,
850 "hide_files_patterns",
NULL,
851 "request_timeout_ms",
"30000",
881 static const int n = 1;
882 return ((
char *) &
n)[0] == 0;
889 unsigned char in[64];
898 t = (
uint32_t) ((
unsigned) buf[3] << 8 | buf[2]) << 16 |
899 ((
unsigned) buf[1] << 8 | buf[0]);
906#define F1(x, y, z) (z ^ (x & (y ^ z)))
907#define F2(x, y, z) F1(z, x, y)
908#define F3(x, y, z) (x ^ y ^ z)
909#define F4(x, y, z) (y ^ (x | ~z))
911#define MD5STEP(f, w, x, y, z, data, s) \
912 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
917 ctx->
buf[0] = 0x67452301;
918 ctx->
buf[1] = 0xefcdab89;
919 ctx->
buf[2] = 0x98badcfe;
920 ctx->
buf[3] = 0x10325476;
1014 ctx->
bits[1] += len >> 29;
1016 t = (t >> 3) & 0x3f;
1019 unsigned char *p = (
unsigned char *) ctx->
in + t;
1065 a[14] = ctx->
bits[0];
1066 a[15] = ctx->
bits[1];
1071 memset((
char *) ctx, 0,
sizeof(*ctx));
1079static void bin2str(
char *
to,
const unsigned char *p,
size_t len) {
1080 static const char *
hex =
"0123456789abcdef";
1082 for (; len--; p++) {
1083 *
to++ =
hex[p[0] >> 4];
1084 *
to++ =
hex[p[0] & 0x0f];
1091 unsigned char hash[16];
1111 const char *nonce,
const char *nc,
const char *cnonce,
1112 const char *qop,
const char *
response) {
1132 ":", cnonce,
":", qop,
":",
ha2,
NULL);
1156 for (p = path,
e = p +
strlen(p) - 1;
e > p;
e--)
1174 size_t buf_size,
struct ah *
ah) {
1191 while (
isspace(* (
unsigned char *) s)) {
1205 if (*
name ==
'\0') {
1293 "HTTP/1.1 401 Unauthorized\r\n"
1294 "Content-Length: 0\r\n"
1295 "WWW-Authenticate: Digest qop=\"auth\", "
1296 "realm=\"%s\", nonce=\"%lu\"\r\n\r\n",
1298 (
unsigned long) time(
NULL));
1315 const char *user,
const char *
pass) {
1345 if (
sscanf(line,
"%[^:]:%[^:]:%*s",
u,
d) != 2) {
1385 return *mutex ==
NULL ? -1 : 0;
1404 return cv->signal !=
NULL &&
cv->broadcast !=
NULL ? 0 : -1;
1432 for (
i = 0; path[
i] !=
'\0';
i++) {
1436 if (path[
i] ==
'\\' &&
i > 0)
1437 while (path[
i + 1] ==
'\\' || path[
i + 1] ==
'/')
1439 path +
i + 2,
strlen(path +
i + 1));
1462#if defined(_WIN32_WCE)
1492 ptm->tm_year =
st.wYear - 1900;
1493 ptm->tm_mon =
st.wMonth - 1;
1494 ptm->tm_wday =
st.wDayOfWeek;
1495 ptm->tm_mday =
st.wDay;
1496 ptm->tm_hour =
st.wHour;
1497 ptm->tm_min =
st.wMinute;
1498 ptm->tm_sec =
st.wSecond;
1512 const struct tm *
tm) {
1532 filep->modification_time = 0;
1537 info.ftLastWriteTime.dwLowDateTime,
1538 info.ftLastWriteTime.dwHighDateTime);
1548 return filep->modification_time != 0;
1583 if (
attrs != 0xFFFFFFFF &&
1587 dir->result.d_name[0] =
'\0';
1602 result =
FindClose(dir->handle) ? 0 : -1;
1614 struct dirent *result = 0;
1618 result = &dir->result;
1620 dir->info.cFileName, -1, result->d_name,
1621 sizeof(result->d_name),
NULL,
NULL);
1649 for (
i = 0;
i <
n;
i++) {
1659 for (
i = 0;
i <
n;
i++) {
1695 while (
e > s &&
isspace(* (
unsigned char *)
e)) {
1702 int fdout,
const char *dir) {
1728 buf[0] = buf[1] =
'\0';
1735 buf[
sizeof(buf) - 1] =
'\0';
1738 if (buf[0] ==
'#' && buf[1] ==
'!') {
1758 cry(conn,
"%s: CreateProcess(%s): %ld",
1772 unsigned long on = 1;
1782 if (
stat(path, &
st) == 0) {
1784 filep->modification_time =
st.st_mtime;
1810#if USE_STACK_SIZE > 1
1824 int fdout,
const char *dir) {
1830 if ((pid =
fork()) == -1) {
1833 }
else if (pid == 0) {
1835 if (
chdir(dir) != 0) {
1896 if (len > (
int) size &&
1897 (size = len + 1) > 0 &&
1913 len =
mg_write(conn, buf, (
size_t) len);
1915 if (buf !=
mem && buf !=
NULL) {
1935 len =
mg_printf(conn,
"%X\r\n%s\r\n", len, buf);
1938 if (buf !=
mem && buf !=
NULL) {
1949#if !defined(NO_SSL_DL)
1956 {
"SSL_accept",
NULL},
1957 {
"SSL_connect",
NULL},
1959 {
"SSL_write",
NULL},
1960 {
"SSL_get_error",
NULL},
1961 {
"SSL_set_fd",
NULL},
1963 {
"SSL_CTX_new",
NULL},
1964 {
"SSLv23_server_method",
NULL},
1965 {
"SSL_library_init",
NULL},
1966 {
"SSL_CTX_use_PrivateKey_file",
NULL},
1967 {
"SSL_CTX_use_certificate_file",
NULL},
1968 {
"SSL_CTX_set_default_passwd_cb",
NULL},
1969 {
"SSL_CTX_free",
NULL},
1970 {
"SSL_load_error_strings",
NULL},
1971 {
"SSL_CTX_use_certificate_chain_file",
NULL},
1972 {
"SSLv23_client_method",
NULL},
1973 {
"SSL_pending",
NULL},
1974 {
"SSL_CTX_set_verify",
NULL},
1975 {
"SSL_shutdown",
NULL},
1976 {
"SSL_CTX_ctrl",
NULL},
1977 {
"SSL_CTX_set_cipher_list",
NULL},
1978 {
"EC_KEY_new_by_curve_name",
NULL},
1979 {
"EC_KEY_free",
NULL},
1980 {
"SSL_get_cipher_list",
NULL},
1986 {
"CRYPTO_num_locks",
NULL},
1987 {
"CRYPTO_set_locking_callback",
NULL},
1988 {
"CRYPTO_set_id_callback",
NULL},
1989 {
"ERR_get_error",
NULL},
1990 {
"ERR_error_string",
NULL},
2000 func(conn->
ssl) == 1;
2026#if !defined(NO_SSL_DL)
2074#if !defined(NO_SSL_DL)
2121#ifdef OPENSSL_EC_NAMED_CURVE
2139#warning Very old openssl, no EC_KEY, no ECDH for modern criptography!
2162 cry(
fc(ctx),
"%s: openssl \"modern cryptography\" ECDH ciphers not available",
__func__);
2166 const char*
cipher_list =
"ALL:!RC4:!DES-CBC-SHA:!DES:!DES-CBC3-SHA:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW";
2170 cipher_list =
"ALL:!AECDH:!RC4:!DES-CBC-SHA:!DES:!AES128-SHA+RSA:!AES256-SHA+RSA:!DES-CBC3-SHA:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW";
2241 sin.sin_addr = * (
struct in_addr *)
he->h_addr_list[0];
2242 if (connect(sock, (
struct sockaddr *) &sin,
sizeof(sin)) != 0) {
2274 conn->
buf = (
char *) (conn + 1);
2294 const char *fmt, ...) {
2306 if (
ebuf[0] !=
'\0' && conn !=
NULL) {
2345#if defined(USE_IPV6)
2347 (
void *) &
usa->
sin.sin_addr :
2348 (
void *) &
usa->sin6.sin6_addr,
buf, len);
2349#elif defined(_WIN32)
2377 timestamp = time(
NULL);
2380 fprintf(
fp,
"[%010lu] [error] [client %s] ", (
unsigned long) timestamp,
2410 (header ==
NULL && http_version &&
strcmp(http_version,
"1.1"))) {
2421 const char *
reason,
const char *fmt, ...) {
2442 "Content-Length: %d\r\n"
2458 while (sent < len) {
2490 if (len <= 0)
return 0;
2497 }
else if (conn->
ssl !=
NULL) {
2518 }
else if (
n == 0) {
2609#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
2613 isxdigit(* (
const unsigned char *) (src +
i + 1)) &&
2614 isxdigit(* (
const unsigned char *) (src +
i + 2))) {
2615 a =
tolower(* (
const unsigned char *) (src +
i + 1));
2616 b =
tolower(* (
const unsigned char *) (src +
i + 2));
2633 const char *p, *
e, *s;
2649 for (p =
data; p + name_len <
e; p++) {
2650 if ((p ==
data || p[-1] ==
'&') && p[name_len] ==
'=' &&
2657 s = (
const char *)
memchr(p,
'&', (
size_t)(
e - p));
2680 const char *s, *p, *
end;
2681 int name_len, len = -1;
2694 if (s[name_len] ==
'=') {
2700 if (*s ==
'"' && p[-1] ==
'"' && p > s + 1) {
2803 if (!
isprint(* (
const unsigned char *) &buf[
i]) && buf[
i] !=
'\r' &&
2804 buf[
i] !=
'\n' && * (
const unsigned char *) &buf[
i] < 128) {
2806 }
else if (buf[
i] ==
'\n' &&
i + 1 <
buf_len && buf[
i + 1] ==
'\n') {
2808 }
else if (buf[
i] ==
'\n' &&
i + 2 <
buf_len && buf[
i + 1] ==
'\r' &&
2809 buf[
i + 2] ==
'\n') {
2822 while (*s !=
'\0') {
2824 if (s[-1] ==
'/' || s[-1] ==
'\\') {
2826 while (s[0] !=
'\0') {
2827 if (s[0] ==
'/' || s[0] ==
'\\') {
2829 }
else if (s[0] ==
'.' && s[1] ==
'.') {
2840static const struct {
2845 {
".html", 5,
"text/html"},
2846 {
".htm", 4,
"text/html"},
2847 {
".shtm", 5,
"text/html"},
2848 {
".shtml", 6,
"text/html"},
2849 {
".css", 4,
"text/css"},
2850 {
".js", 3,
"application/x-javascript"},
2851 {
".ico", 4,
"image/x-icon"},
2852 {
".gif", 4,
"image/gif"},
2853 {
".jpg", 4,
"image/jpeg"},
2854 {
".jpeg", 5,
"image/jpeg"},
2855 {
".png", 4,
"image/png"},
2856 {
".svg", 4,
"image/svg+xml"},
2857 {
".txt", 4,
"text/plain"},
2858 {
".torrent", 8,
"application/x-bittorrent"},
2859 {
".wav", 4,
"audio/x-wav"},
2860 {
".mp3", 4,
"audio/x-mp3"},
2861 {
".mid", 4,
"audio/mid"},
2862 {
".m3u", 4,
"audio/x-mpegurl"},
2863 {
".ogg", 4,
"application/ogg"},
2864 {
".ram", 4,
"audio/x-pn-realaudio"},
2865 {
".xml", 4,
"text/xml"},
2866 {
".json", 5,
"text/json"},
2867 {
".xslt", 5,
"application/xml"},
2868 {
".xsl", 4,
"application/xml"},
2869 {
".ra", 3,
"audio/x-pn-realaudio"},
2870 {
".doc", 4,
"application/msword"},
2871 {
".exe", 4,
"application/octet-stream"},
2872 {
".zip", 4,
"application/x-zip-compressed"},
2873 {
".xls", 4,
"application/excel"},
2874 {
".tgz", 4,
"application/x-tar-gz"},
2875 {
".tar", 4,
"application/x-tar"},
2876 {
".gz", 3,
"application/x-gunzip"},
2877 {
".arj", 4,
"application/x-arj-compressed"},
2878 {
".rar", 4,
"application/x-arj-compressed"},
2879 {
".rtf", 4,
"application/rtf"},
2880 {
".pdf", 4,
"application/pdf"},
2881 {
".swf", 4,
"application/x-shockwave-flash"},
2882 {
".mpg", 4,
"video/mpeg"},
2883 {
".webm", 5,
"video/webm"},
2884 {
".mpeg", 5,
"video/mpeg"},
2885 {
".mov", 4,
"video/quicktime"},
2886 {
".mp4", 4,
"video/mp4"},
2887 {
".m4v", 4,
"video/x-m4v"},
2888 {
".asf", 4,
"video/x-ms-asf"},
2889 {
".avi", 4,
"video/x-msvideo"},
2890 {
".bmp", 4,
"image/bmp"},
2891 {
".ttf", 4,
"application/x-font-ttf"},
2909 return "text/plain";
2917 const char *
list, *ext;
2940 static const char *
hex =
"0123456789abcdef";
2943 for (; *src !=
'\0' && dst <
end; src++, dst++) {
2944 if (
isalnum(*(
const unsigned char *) src) ||
2947 }
else if (dst + 2 <
end) {
2949 dst[1] =
hex[(* (
const unsigned char *) src) >> 4];
2950 dst[2] =
hex[(* (
const unsigned char *) src) & 0xf];
2963 mg_snprintf(size,
sizeof(size),
"%s",
"[DIRECTORY]");
2977 "%.1fG", (
double)
de->
file.
size / 1073741824);
2984 "<tr><td><a href=\"%s%s%s\">%s%s</a></td>"
2985 "<td> %s</td><td> %s</td></tr>\n",
2994 const struct de *a = (
const struct de *)
p1, *b = (
const struct de *)
p2;
2998 if (query_string ==
NULL) {
2999 query_string =
"na";
3006 }
else if (*query_string ==
'n') {
3008 }
else if (*query_string ==
's') {
3010 a->
file.
size > b->file.size ? 1 : -1;
3011 }
else if (*query_string ==
'd') {
3027 void *
data,
void (*cb)(
struct de *,
void *)) {
3046 mg_snprintf(path,
sizeof(path),
"%s%c%s", dir,
'/',
dp->d_name);
3082 mg_snprintf(path,
sizeof(path),
"%s%c%s", dir,
'/',
dp->d_name);
3126 if (
dsd->entries ==
NULL ||
dsd->num_entries >=
dsd->arr_size) {
3129 sizeof(
dsd->entries[0]));
3133 dsd->num_entries = 0;
3158 "HTTP/1.1 200 OK\r\n"
3159 "Transfer-Encoding: Chunked\r\n"
3160 "Content-Type: text/html; charset=utf-8\r\n\r\n");
3163 "<html><head><title>Index of %s</title>"
3164 "<style>th {text-align: left;}</style></head>"
3165 "<body><h1>Index of %s</h1><pre><table cellpadding=\"0\">"
3166 "<tr><th><a href=\"?n%c\">Name</a></th>"
3167 "<th><a href=\"?d%c\">Modified</a></th>"
3168 "<th><a href=\"?s%c\">Size</a></th></tr>"
3169 "<tr><td colspan=\"3\"><hr></td></tr>",
3175 "<tr><td><a href=\"%s%s\">%s</a></td>"
3176 "<td> %s</td><td> %s</td></tr>\n",
3182 for (
i = 0;
i <
data.num_entries;
i++) {
3184 free(
data.entries[
i].file_name);
3189 "</table></body></html>");
3239 (
unsigned long)
filep->modification_time,
filep->size);
3253 const char *msg =
"OK", *
hdr;
3270 if (
filep->gzipped) {
3273 encoding =
"Content-Encoding: gzip\r\n";
3288 r1 >= 0 &&
r2 >= 0) {
3291 if (
filep->gzipped) {
3293 "range requests in gzipped files are not supported");
3297 cl =
n == 2 ? (
r2 > cl ? cl :
r2) -
r1 + 1: cl -
r1;
3299 "Content-Range: bytes "
3303 msg =
"Partial Content";
3313 "HTTP/1.1 %d %s\r\n"
3315 "Last-Modified: %s\r\n"
3317 "Content-Type: %.*s\r\n"
3319 "Connection: %s\r\n"
3320 "Accept-Ranges: bytes\r\n"
3349 ri->http_headers[
i].value =
skip(buf,
"\r\n");
3350 if (
ri->http_headers[
i].name[0] ==
'\0')
3352 ri->num_headers =
i + 1;
3357 return !
strcmp(method,
"GET") || !
strcmp(method,
"POST") ||
3358 !
strcmp(method,
"HEAD") || !
strcmp(method,
"CONNECT") ||
3360 !
strcmp(method,
"OPTIONS") || !
strcmp(method,
"PROPFIND")
3361 || !
strcmp(method,
"MKCOL")
3372 ri->remote_user =
ri->request_method =
ri->uri =
ri->http_version =
NULL;
3373 ri->num_headers = 0;
3378 while (*buf !=
'\0' &&
isspace(* (
unsigned char *) buf)) {
3381 ri->request_method =
skip(&buf,
" ");
3382 ri->uri =
skip(&buf,
" ");
3383 ri->http_version =
skip(&buf,
"\r\n");
3393 ri->http_version += 5;
3408 int request_len,
n = 0;
3420 return request_len <= 0 &&
n <= 0 ? -1 : request_len;
3437 while (
n > 0 && path[
n - 1] ==
'/') {
3483 const char *
expect, *body;
3497 (
void)
mg_printf(conn,
"%s",
"HTTP/1.1 100 Continue\r\n\r\n");
3596 const char *s, *
slash;
3611 addenv(
blk,
"%s",
"GATEWAY_INTERFACE=CGI/1.1");
3612 addenv(
blk,
"%s",
"SERVER_PROTOCOL=HTTP/1.1");
3613 addenv(
blk,
"%s",
"REDIRECT_STATUS=200");
3618 addenv(
blk,
"REQUEST_METHOD=%s",
ri->request_method);
3622 ri->query_string ==
NULL ?
"" :
"?",
3623 ri->query_string ==
NULL ?
"" :
ri->query_string);
3645 if (
ri->query_string !=
NULL) {
3668 if ((s =
getenv(
"ProgramFiles(x86)")) !=
NULL) {
3671 if ((s =
getenv(
"CommonProgramFiles(x86)")) !=
NULL) {
3672 addenv(
blk,
"CommonProgramFiles(x86)=%s", s);
3682 if (
ri->remote_user !=
NULL) {
3688 for (
i = 0;
i <
ri->num_headers;
i++) {
3690 ri->http_headers[
i].name,
ri->http_headers[
i].value);
3693 for (; *p !=
'=' && *p !=
'\0'; p++) {
3707 blk->buf[
blk->len++] =
'\0';
3710 assert(
blk->len > 0);
3711 assert(
blk->len < (
int)
sizeof(
blk->buf));
3732 dir[0] =
'.', dir[1] =
'\0';
3743 if (pid == (
pid_t) -1) {
3793 "CGI program sent malformed or too big (>%u bytes) "
3794 "HTTP headers: [%.*s]",
3795 (
unsigned)
sizeof(
buf), data_len,
buf);
3823 for (
i = 0;
i <
ri.num_headers;
i++) {
3825 ri.http_headers[
i].name,
ri.http_headers[
i].value);
3837 if (pid != (
pid_t) -1) {
3840 if (
fdin[0] != -1) {
3843 if (
fdout[1] != -1) {
3849 }
else if (
fdin[1] != -1) {
3855 }
else if (
fdout[0] != -1) {
3870 for (s = p = path + 2; (p =
strchr(s,
'/')) !=
NULL; s = ++p) {
3872 if (len >= (
int)
sizeof(buf)) {
3920 }
else if (
rc == -1) {
3947 }
else if (
rc == -1) {
3965 mg_printf(conn,
"HTTP/1.1 %d OK\r\nContent-Length: 0\r\n\r\n",
3997 cry(conn,
"Bad SSI #include: [%s]", tag);
4002 cry(conn,
"Cannot open SSI #include: [%s]: fopen(%s): %s",
4016#if !defined(NO_POPEN)
4021 if (
sscanf(tag,
" \"%[^\"]\"", cmd) != 1) {
4022 cry(conn,
"Bad SSI #exec: [%s]", tag);
4038 cry(conn,
"SSI #include level is too deep (%s)", path);
4048 assert(len <= (
int)
sizeof(buf));
4049 if (len < 6 ||
memcmp(buf,
"<!--#", 5) != 0) {
4053 if (!
memcmp(buf + 5,
"include", 7)) {
4055#if !defined(NO_POPEN)
4056 }
else if (!
memcmp(buf + 5,
"exec", 4)) {
4060 cry(conn,
"%s: unknown SSI " "command: \"%s\"", path, buf);
4065 if (len == 5 &&
memcmp(buf,
"<!--#", 5) != 0) {
4068 }
else if (len == (
int)
sizeof(buf) - 2) {
4069 cry(conn,
"%s: SSI tag is too large", path);
4072 buf[len++] =
ch & 0xff;
4073 }
else if (
ch ==
'<') {
4079 buf[len++] =
ch & 0xff;
4081 buf[len++] =
ch & 0xff;
4082 if (len == (
int)
sizeof(buf)) {
4108 "Content-Type: %.*s\r\n"
4109 "Connection: close\r\n\r\n",
4117 static const char reply[] =
"HTTP/1.1 200 OK\r\n"
4118 "Allow: GET, POST, HEAD, CONNECT, PUT, DELETE, OPTIONS, PROPFIND, MKCOL\r\n"
4132 "<d:href>%s</d:href>"
4135 "<d:resourcetype>%s</d:resourcetype>"
4136 "<d:getcontentlength>%" INT64_FMT "</d:getcontentlength>"
4137 "<d:getlastmodified>%s</d:getlastmodified>"
4139 "<d:status>HTTP/1.1 200 OK</d:status>"
4143 filep->is_directory ?
"<d:collection/>" :
"",
4164 mg_printf(conn,
"HTTP/1.1 207 Multi-Status\r\n"
4165 "Connection: close\r\n"
4166 "Content-Type: text/xml; charset=utf-8\r\n\r\n");
4169 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
4170 "<d:multistatus xmlns:d='DAV:'>\n");
4176 if (
filep->is_directory &&
4185#if defined(USE_WEBSOCKET)
4191#include "solarisfixes.h"
4196#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
4207#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
4208 ^block->l[(i+2)&15]^block->l[i&15],1))
4209#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(block, i)+0x5A827999+rol(v,5);w=rol(w,30);
4210#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
4211#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
4212#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
4213#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
4218 unsigned char buffer[64];
4231 R0(a,b,
c,
d,
e, 0);
R0(
e,a,b,
c,
d, 1);
R0(
d,
e,a,b,
c, 2);
R0(
c,
d,
e,a,b, 3);
4232 R0(b,
c,
d,
e,a, 4);
R0(a,b,
c,
d,
e, 5);
R0(
e,a,b,
c,
d, 6);
R0(
d,
e,a,b,
c, 7);
4233 R0(
c,
d,
e,a,b, 8);
R0(b,
c,
d,
e,a, 9);
R0(a,b,
c,
d,
e,10);
R0(
e,a,b,
c,
d,11);
4234 R0(
d,
e,a,b,
c,12);
R0(
c,
d,
e,a,b,13);
R0(b,
c,
d,
e,a,14);
R0(a,b,
c,
d,
e,15);
4235 R1(
e,a,b,
c,
d,16);
R1(
d,
e,a,b,
c,17);
R1(
c,
d,
e,a,b,18);
R1(b,
c,
d,
e,a,19);
4236 R2(a,b,
c,
d,
e,20);
R2(
e,a,b,
c,
d,21);
R2(
d,
e,a,b,
c,22);
R2(
c,
d,
e,a,b,23);
4237 R2(b,
c,
d,
e,a,24);
R2(a,b,
c,
d,
e,25);
R2(
e,a,b,
c,
d,26);
R2(
d,
e,a,b,
c,27);
4238 R2(
c,
d,
e,a,b,28);
R2(b,
c,
d,
e,a,29);
R2(a,b,
c,
d,
e,30);
R2(
e,a,b,
c,
d,31);
4239 R2(
d,
e,a,b,
c,32);
R2(
c,
d,
e,a,b,33);
R2(b,
c,
d,
e,a,34);
R2(a,b,
c,
d,
e,35);
4240 R2(
e,a,b,
c,
d,36);
R2(
d,
e,a,b,
c,37);
R2(
c,
d,
e,a,b,38);
R2(b,
c,
d,
e,a,39);
4241 R3(a,b,
c,
d,
e,40);
R3(
e,a,b,
c,
d,41);
R3(
d,
e,a,b,
c,42);
R3(
c,
d,
e,a,b,43);
4242 R3(b,
c,
d,
e,a,44);
R3(a,b,
c,
d,
e,45);
R3(
e,a,b,
c,
d,46);
R3(
d,
e,a,b,
c,47);
4243 R3(
c,
d,
e,a,b,48);
R3(b,
c,
d,
e,a,49);
R3(a,b,
c,
d,
e,50);
R3(
e,a,b,
c,
d,51);
4244 R3(
d,
e,a,b,
c,52);
R3(
c,
d,
e,a,b,53);
R3(b,
c,
d,
e,a,54);
R3(a,b,
c,
d,
e,55);
4245 R3(
e,a,b,
c,
d,56);
R3(
d,
e,a,b,
c,57);
R3(
c,
d,
e,a,b,58);
R3(b,
c,
d,
e,a,59);
4246 R4(a,b,
c,
d,
e,60);
R4(
e,a,b,
c,
d,61);
R4(
d,
e,a,b,
c,62);
R4(
c,
d,
e,a,b,63);
4247 R4(b,
c,
d,
e,a,64);
R4(a,b,
c,
d,
e,65);
R4(
e,a,b,
c,
d,66);
R4(
d,
e,a,b,
c,67);
4248 R4(
c,
d,
e,a,b,68);
R4(b,
c,
d,
e,a,69);
R4(a,b,
c,
d,
e,70);
R4(
e,a,b,
c,
d,71);
4249 R4(
d,
e,a,b,
c,72);
R4(
c,
d,
e,a,b,73);
R4(b,
c,
d,
e,a,74);
R4(a,b,
c,
d,
e,75);
4250 R4(
e,a,b,
c,
d,76);
R4(
d,
e,a,b,
c,77);
R4(
c,
d,
e,a,b,78);
R4(b,
c,
d,
e,a,79);
4256 a = b =
c =
d =
e = 0;
4261 context->state[0] = 0x67452301;
4262 context->state[1] = 0xEFCDAB89;
4263 context->state[2] = 0x98BADCFE;
4264 context->state[3] = 0x10325476;
4265 context->state[4] = 0xC3D2E1F0;
4266 context->count[0] = context->count[1] = 0;
4273 j = context->count[0];
4274 if ((context->count[0] += len << 3) <
j)
4275 context->count[1]++;
4276 context->count[1] += (len>>29);
4278 if ((
j + len) > 63) {
4281 for ( ;
i + 63 < len;
i += 64) {
4294 for (
i = 0;
i < 8;
i++) {
4296 >> ((3-(
i & 3)) * 8) ) & 255);
4300 while ((context->count[0] & 504) != 448) {
4305 for (
i = 0;
i < 20;
i++) {
4307 ((context->state[
i>>2] >> ((3-(
i & 3)) * 8) ) & 255);
4309 memset(context,
'\0',
sizeof(*context));
4315 static const char *
b64 =
4316 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4324 dst[
j++] =
b64[a >> 2];
4325 dst[
j++] =
b64[((a & 3) << 4) | (b >> 4)];
4327 dst[
j++] =
b64[(b & 15) << 2 | (
c >> 6)];
4330 dst[
j++] =
b64[
c & 63];
4333 while (
j % 4 != 0) {
4340 static const char *
magic =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
4351 "HTTP/1.1 101 Switching Protocols\r\n"
4352 "Upgrade: websocket\r\n"
4353 "Connection: Upgrade\r\n"
4354 "Sec-WebSocket-Accept: ",
b64_sha,
"\r\n\r\n");
4361 unsigned char *buf = (
unsigned char *) conn->
buf + conn->
request_len;
4382 }
else if (len == 126 && body_len >= 4 +
mask_len) {
4384 data_len = ((((
int) buf[2]) << 8) + buf[3]);
4385 }
else if (body_len >= 10 +
mask_len) {
4424 memmove(buf, buf + len, body_len - len);
4430 for (
i = 0;
i < data_len;
i++) {
4431 (*data)[
i] ^=
mask[
i % 4];
4450 const char *
data,
size_t data_len) {
4451 unsigned char *copy;
4455 if ((copy = (
unsigned char *)
malloc(data_len + 10)) ==
NULL) {
4459 copy[0] = 0x80 + (
opcode & 0x0f);
4462 if (data_len < 126) {
4467 }
else if (data_len <= 0xFFFF) {
4493 return n >= 0 &&
n <= 255;
4497 int n, a, b,
c,
d,
slash = 32, len = 0;
4520 if (
sscanf(
val.ptr,
"%lf%c", &v, &mult) < 1 || v < 0 ||
4528 if ((remote_ip &
mask) ==
net) {
4546 char *buf,
fname[1024], boundary[100], *s;
4568 "boundary=")) ==
NULL ||
4571 boundary[0] ==
'\0') {
4575 boundary_len =
strlen(boundary);
4576 bl = boundary_len + 4;
4606 if (buf[
i] ==
'\r' && buf[
i + 1] ==
'\n') {
4607 buf[
i] = buf[
i + 1] =
'\0';
4610 sscanf(&buf[
j],
"Content-Disposition: %*s %*s filename=\"%1023[^\"]",
4617 if (
fname[0] ==
'\0') {
4648 if (!
memcmp(&buf[
i],
"\r\n--", 4) &&
4649 !
memcmp(&buf[
i + 4], boundary, boundary_len)) {
4706 mg_printf(conn,
"HTTP/1.1 302 Found\r\nLocation: https://%s:%d%s\r\n\r\n",
4764 }
else if (!
strcmp(
ri->request_method,
"OPTIONS")) {
4771 }
else if (!
strcmp(
ri->request_method,
"PUT")) {
4773 }
else if (!
strcmp(
ri->request_method,
"MKCOL")) {
4775 }
else if (!
strcmp(
ri->request_method,
"DELETE")) {
4781 mg_printf(conn,
"HTTP/1.1 301 Moved Permanently\r\n"
4782 "Location: %s/\r\n\r\n",
ri->uri);
4783 }
else if (!
strcmp(
ri->request_method,
"PROPFIND")) {
4791 "Directory listing denied");
4801 if (
strcmp(
ri->request_method,
"POST") &&
4802 strcmp(
ri->request_method,
"HEAD") &&
4803 strcmp(
ri->request_method,
"GET")) {
4805 "Method %s is not implemented",
ri->request_method);
4830 return port > 0 && port < 0xffff;
4837 unsigned int a, b,
c,
d,
ch, port;
4839#if defined(USE_IPV6)
4849 if (
sscanf(
vec->
ptr,
"%u.%u.%u.%u:%u%n", &a, &b, &
c, &
d, &port, &len) == 5) {
4851 so->lsa.sin.sin_addr.s_addr =
htonl((a << 24) | (b << 16) | (
c << 8) |
d);
4853#if defined(USE_IPV6)
4855 }
else if (
sscanf(
vec->
ptr,
"[%49[^]]]:%d%n", buf, &port, &len) == 2 &&
4861 }
else if (
sscanf(
vec->
ptr,
"%u%n", &port, &len) == 1) {
4869 so->is_ssl =
ch ==
's';
4870 so->ssl_redir =
ch ==
'r';
4874 (
ch ==
'\0' ||
ch ==
's' ||
ch ==
'r' ||
ch ==
',');
4880#if defined(USE_IPV6)
4888 cry(
fc(ctx),
"%s: %.*s: invalid port spec. Expecting list of: %s",
4892 cry(
fc(ctx),
"Cannot add SSL socket, is -ssl_certificate option set?");
4899 (
void *) &
on,
sizeof(
on)) != 0 ||
4903 sizeof(
off)) != 0) ||
4906 sizeof(
so.lsa.sin) :
sizeof(
so.lsa)) != 0 ||
4963 ri->request_method ?
ri->request_method :
"-",
4964 ri->uri ?
ri->uri :
"-",
ri->http_version,
4988 if ((
flag !=
'+' &&
flag !=
'-') ||
4990 cry(
fc(ctx),
"%s: subnet must be [+|-]x.x.x.x[/x]",
__func__);
4994 if (
net == (remote_ip &
mask)) {
5013 }
else if (
setgid(
pw->pw_gid) == -1) {
5015 }
else if (
setuid(
pw->pw_uid) == -1) {
5110 return uri[0] ==
'/' || (uri[0] ==
'*' && uri[1] ==
'\0');
5147 return ebuf[0] ==
'\0';
5168 }
else if (
strcmp(
ri->http_version,
"1.0") &&
5174 if (
ebuf[0] ==
'\0') {
5179 if (
ri->remote_user !=
NULL) {
5180 free((
void *)
ri->remote_user);
5202 }
while (keep_alive);
5241 cry(
fc(
ctx),
"%s",
"Cannot create new connection struct, OOM");
5244 conn->
buf = (
char *) (conn + 1);
5365#if defined(ISSUE_317)
5461#if defined(_WIN32) && !defined(__SYMBIAN32__)
5473#if defined(_WIN32) && !defined(__SYMBIAN32__)
5488 cry(
fc(ctx),
"Invalid option: %s",
name);
5492 cry(
fc(ctx),
"%s: option value cannot be NULL",
name);
5497 cry(
fc(ctx),
"warning: %s: duplicate option",
name);
5527#if !defined(_WIN32) && !defined(__SYMBIAN32__)
5544 cry(
fc(ctx),
"Cannot start worker thread: %ld", (
long)
ERRNO);
5563#define munmap(x, y) UnmapViewOfFile(x)
5564#define MAP_FAILED NULL
5565#define MAP_PRIVATE 0
5568#include <sys/mman.h>
5571static const char *
LUASOCKET =
"luasocket";
5627 size_t len, sent = 0;
5634 while (sent < len) {
5635 if ((
n =
send(sock, buf + sent, len - sent, 0)) <= 0) {
5671 return luaL_error(
L,
"connect(host,port,is_ssl): invalid parameter given.");
5700 for (
i = 0;
i < len;
i++) {
5701 if (p[
i] ==
'\n')
lines++;
5702 if (p[
i] ==
'<' && p[
i + 1] ==
'?') {
5703 for (
j =
i + 1;
j < len ;
j++) {
5705 if (p[
j] ==
'?' && p[
j + 1] ==
'>') {
5760 if (len <= 0)
return 0;
5800#ifdef USE_LUA_SQLITE3
5811 if (conn ==
NULL)
return;
5835 for (
i = 0;
i <
ri->num_headers;
i++) {
5844 luaL_dostring(
L,
"mg.onerror = function(e) mg.write('\\nLua error:\\n', "
5845 "debug.traceback(e, 1)) end");
5894 const char *fmt, ...) {
5931 error =
lsp(conn, path, p,
filep->size,
L);
int mg_modify_passwords_file(const char *fname, const char *domain, const char *user, const char *pass)
int mg_websocket_read(struct mg_connection *, int *bits, char **data)
void *(* mg_thread_func_t)(void *)
void mg_close_connection(struct mg_connection *conn)
int mg_websocket_write(struct mg_connection *conn, int opcode, const char *data, size_t data_len)
#define PRINTF_FORMAT_STRING(s)
const char * mg_get_option(const struct mg_context *ctx, const char *name)
const char * mg_get_header(const struct mg_connection *conn, const char *name)
int mg_get_var(const char *data, size_t data_len, const char *name, char *dst, size_t dst_len)
int mg_start_thread(mg_thread_func_t func, void *param)
const char * request_method
struct mg_request_info * request_info
struct mg_connection * conn
char * mg_md5(char buf[33],...)
const char * query_string
struct mg_context * mg_start(const char **options, mg_event_handler_t func, void *user_data)
int mg_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
#define PRINTF_ARGS(x, y)
int mg_write(struct mg_connection *conn, const void *buf, int len)
const char * mg_get_builtin_mime_type(const char *path)
const char ** mg_get_valid_option_names(void)
FILE * mg_upload(struct mg_connection *conn, const char *destination_dir, char *path, int path_len)
void mg_send_file(struct mg_connection *conn, const char *path)
const char * http_version
int mg_get_cookie(const char *cookie_header, const char *var_name, char *dst, size_t dst_size)
void mg_stop(struct mg_context *ctx)
int(* mg_event_handler_t)(struct mg_event *event)
void mg_websocket_handshake(struct mg_connection *)
const char * mg_version(void)
int mg_read(struct mg_connection *conn, void *buf, int len)
int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap)
int mg_printf(struct mg_connection *conn, const char *fmt,...)
void base64_encode(char *s, char *d)
MidasHistoryInterface * mh
static std::string remove(const std::string s, char c)
static int is_put_or_delete_request(const struct mg_connection *conn)
static void process_new_connection(struct mg_connection *conn)
static int mg_strncasecmp(const char *s1, const char *s2, size_t len)
static int is_authorized_for_put(struct mg_connection *conn)
static void sockaddr_to_string(char *buf, size_t len, const union usa *usa)
#define MD5STEP(f, w, x, y, z, data, s)
static int consume_socket(struct mg_context *ctx, struct socket *sp)
static int check_authorization(struct mg_connection *conn, const char *path)
static void mkcol(struct mg_connection *conn, const char *path)
static int check_acl(struct mg_context *ctx, uint32_t remote_ip)
static int64_t left_to_read(const struct mg_connection *conn)
static int set_non_blocking_mode(SOCKET sock)
static void ssl_locking_callback(int mode, int mutex_num, const char *file, int line)
static int set_ports_option(struct mg_context *ctx)
static void put_file(struct mg_connection *conn, const char *path)
static int set_uid_option(struct mg_context *ctx)
static void do_ssi_exec(struct mg_connection *conn, char *tag)
static void mg_strlcpy(register char *dst, register const char *src, size_t n)
void mg_url_encode(const char *src, char *dst, size_t dst_len)
static int set_sock_timeout(SOCKET sock, int milliseconds)
static int set_gpass_option(struct mg_context *ctx)
static int mg_strcasecmp(const char *s1, const char *s2)
static void * realloc2(void *ptr, size_t size)
static void send_http_error(struct mg_connection *, int, const char *, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(4
static int set_throttle(const char *spec, uint32_t remote_ip, const char *uri)
static void uninitialize_ssl(struct mg_context *ctx)
static int num_leap_years(int year)
static int WINCDECL compare_dir_entries(const void *p1, const void *p2)
static int should_keep_alive(const struct mg_connection *conn)
static SOCKET conn2(const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len)
static void handle_file_request(struct mg_connection *conn, const char *path, struct file *filep)
static const char * ssl_error(void)
static int must_hide_file(struct mg_connection *conn, const char *path)
static int parse_net(const char *spec, uint32_t *net, uint32_t *mask)
static int substitute_index_file(struct mg_connection *conn, char *path, size_t path_len, struct file *filep)
static void close_all_listening_sockets(struct mg_context *ctx)
static void prepare_cgi_environment(struct mg_connection *conn, const char *prog, struct cgi_env_block *blk)
static int check_password(const char *method, const char *ha1, const char *uri, const char *nonce, const char *nc, const char *cnonce, const char *qop, const char *response)
static const char * get_header(const struct mg_request_info *ri, const char *name)
static int mg_chunked_printf(struct mg_connection *conn, const char *fmt,...)
static void print_dav_dir_entry(struct de *de, void *data)
static void dir_scan_callback(struct de *de, void *data)
static void remove_double_dots_and_double_slashes(char *s)
static void reset_per_request_attributes(struct mg_connection *conn)
static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap)
static pthread_mutex_t * ssl_mutexes
static int is_not_modified(const struct mg_connection *conn, const struct file *filep)
static int get_option_index(const char *name)
static void print_props(struct mg_connection *conn, const char *uri, struct file *filep)
static void handle_propfind(struct mg_connection *conn, const char *path, struct file *filep)
static char * mg_strdup(const char *str)
static void accept_new_connection(const struct socket *listener, struct mg_context *ctx)
#define CGI_ENVIRONMENT_SIZE
static void MD5Final(unsigned char digest[16], MD5_CTX *ctx)
static int put_dir(const char *path)
struct mg_connection * mg_download(const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len, const char *fmt,...)
static void parse_http_headers(char **buf, struct mg_request_info *ri)
static void get_mime_type(struct mg_context *ctx, const char *path, struct vec *vec)
static void MD5Transform(uint32_t buf[4], uint32_t const in[16])
static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
static char * skip_quoted(char **buf, const char *delimiters, const char *whitespace, char quotechar)
static FILE * open_auth_file(struct mg_connection *conn, const char *path)
static char * skip(char **buf, const char *delimiters)
static int forward_body_data(struct mg_connection *conn, FILE *fp, SOCKET sock, SSL *ssl)
static int set_ssl_option(struct mg_context *ctx)
static int sslize(struct mg_connection *conn, SSL_CTX *s, int(*func)(SSL *))
static void MD5Update(MD5_CTX *ctx, unsigned char const *buf, unsigned len)
static void set_close_on_exec(int fd)
#define ARRAY_SIZE(array)
static int get_first_ssl_listener_index(const struct mg_context *ctx)
static void log_header(const struct mg_connection *conn, const char *header, FILE *fp)
static uint32_t get_remote_ip(const struct mg_connection *conn)
static void handle_directory_request(struct mg_connection *conn, const char *dir)
static void gmt_time_string(char *buf, size_t buf_len, time_t *t)
static const char * mg_strcasestr(const char *big_str, const char *small_str)
static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
static const char * config_options[]
static void send_file_data(struct mg_connection *conn, FILE *fp, int64_t offset, int64_t len)
static int authorize(struct mg_connection *conn, FILE *fp)
static void bin2str(char *to, const unsigned char *p, size_t len)
static void byteReverse(unsigned char *buf, unsigned longs)
static void handle_options_request(struct mg_connection *conn)
static int is_valid_uri(const char *uri)
static const char * next_option(const char *list, struct vec *val, struct vec *eq_val)
static const char * suggest_connection_header(const struct mg_connection *conn)
#define EXTRA_HTTP_HEADERS
static time_t parse_date_string(const char *datetime)
static void do_ssi_include(struct mg_connection *conn, const char *ssi, char *tag, int include_level)
static int read_request(FILE *fp, struct mg_connection *conn, char *buf, int bufsiz, int *nread)
static void handle_ssi_file_request(struct mg_connection *conn, const char *path)
static void MD5Init(MD5_CTX *ctx)
static int lowercase(const char *s)
static int parse_range_header(const char *header, int64_t *a, int64_t *b)
static pid_t spawn_process(struct mg_connection *conn, const char *prog, char *envblk, char *envp[], int fdin, int fdout, const char *dir)
static void handle_delete_request(struct mg_connection *conn, const char *path)
#define MAX_CGI_ENVIR_VARS
static int parse_auth_header(struct mg_connection *conn, char *buf, size_t buf_size, struct ah *ah)
static void * master_thread(void *thread_func_param)
@ ENABLE_DIRECTORY_LISTING
@ PUT_DELETE_PASSWORDS_FILE
struct mg_connection * mg_connect(const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len)
static void fclose_on_exec(FILE *fp)
static void construct_etag(char *buf, size_t buf_len, const struct file *filep)
static int mg_stat(const char *path, struct file *filep)
static void send_ssi_file(struct mg_connection *, const char *, FILE *, int)
static void print_dir_entry(const struct de *de)
static int scan_directory(struct mg_connection *conn, const char *dir, void *data, void(*cb)(struct de *, void *))
static void produce_socket(struct mg_context *ctx, const struct socket *sp)
static void send_authorization_request(struct mg_connection *conn)
static void free_context(struct mg_context *ctx)
static int convert_uri_to_file_name(struct mg_connection *conn, char *buf, size_t buf_len, struct file *filep)
static unsigned long ssl_id_callback(void)
static int parse_port_string(const struct vec *vec, struct socket *so)
static const char * month_names[]
static char * addenv(struct cgi_env_block *block, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
static const struct @22 builtin_mime_types[]
static int match_prefix(const char *pattern, int pattern_len, const char *str)
static void handle_request(struct mg_connection *conn)
struct MD5Context MD5_CTX
static int is_big_endian(void)
static int remove_directory(struct mg_connection *conn, const char *dir)
static int get_request_len(const char *buf, int buf_len)
static int mg_vsnprintf(char *buf, size_t buflen, const char *fmt, va_list ap)
static void handle_cgi_request(struct mg_connection *conn, const char *prog)
static void static void static int getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len)
static int mg_snprintf(char *buf, size_t buflen, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(3
static struct mg_connection * fc(struct mg_context *ctx)
static void * worker_thread(void *thread_func_param)
static FILE * mg_fopen(const char *path, const char *mode)
static void static void cry(struct mg_connection *conn, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
static void close_socket_gracefully(struct mg_connection *conn)
static int call_user(int type, struct mg_connection *conn, void *p)
static int parse_http_message(char *buf, int len, struct mg_request_info *ri)
static char * mg_strndup(const char *ptr, size_t len)
static const char * http_500_error
static int set_acl_option(struct mg_context *ctx)
static int get_month_index(const char *s)
static int is_valid_port(unsigned int port)
#define PASSWORDS_FILE_NAME
static void log_access(const struct mg_connection *conn)
static void close_connection(struct mg_connection *conn)
static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
static void redirect_to_https_port(struct mg_connection *conn, int ssl_index)
#define STRUCT_FILE_INITIALIZER
static int is_valid_http_method(const char *method)
char * inet_ntoa(struct in_addr n)
const char * inet_ntop(int af, const void *src, char *dst, socklen_t size)
int inet_pton(int af, const char *src, void *dst)
#define R1(v, w, x, y, z, i)
static int left(const struct frozen *f)
#define R2(v, w, x, y, z, i)
#define R0(v, w, x, y, z, i)
static int expect(struct frozen *f, const char *s, int len, enum json_type t)
#define R3(v, w, x, y, z, i)
static uint32_t blk0(union char64long16 *block, int i)
#define R4(v, w, x, y, z, i)
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
char * vars[MAX_CGI_ENVIR_VARS]
struct mg_connection * conn
char buf[CGI_ENVIRONMENT_SIZE]
struct mg_connection * conn
time_t last_throttle_time
struct mg_request_info request_info
int64_t last_throttle_bytes
int num_listening_sockets
mg_event_handler_t event_handler
struct socket * listening_sockets
struct socket queue[MGSQLEN]
char * config[NUM_OPTIONS]
static te_expr * list(state *s)