915 {
916 ctx->buf[0] = 0x67452301;
917 ctx->buf[1] = 0xefcdab89;
918 ctx->buf[2] = 0x98badcfe;
919 ctx->buf[3] = 0x10325476;
920
921 ctx->bits[0] = 0;
922 ctx->bits[1] = 0;
923}
924
927
928 a = buf[0];
929 b = buf[1];
932
949
966
983
1000
1001 buf[0] += a;
1002 buf[1] += b;
1005}
1006
1007static void MD5Update(
MD5_CTX *ctx,
unsigned char const *buf,
unsigned len) {
1009
1013 ctx->
bits[1] += len >> 29;
1014
1015 t = (t >> 3) & 0
x3f;
1016
1017 if (t) {
1018 unsigned char *p = (
unsigned char *) ctx->
in + t;
1019
1020 t = 64 - t;
1021 if (len < t) {
1023 return;
1024 }
1028 buf += t;
1029 len -= t;
1030 }
1031
1032 while (len >= 64) {
1036 buf += 64;
1037 len -= 64;
1038 }
1039
1041}
1042
1045 unsigned char *p;
1047
1049
1051 *p++ = 0x80;
1058 } else {
1060 }
1062
1064 a[14] = ctx->
bits[0];
1065 a[15] = ctx->
bits[1];
1066
1070 memset((
char *) ctx, 0,
sizeof(*ctx));
1071}
1072#endif
1073
1074
1075
1076
1077
1078static void bin2str(
char *
to,
const unsigned char *p,
size_t len) {
1079 static const char *
hex =
"0123456789abcdef";
1080
1081 for (; len--; p++) {
1082 *
to++ =
hex[p[0] >> 4];
1083 *
to++ =
hex[p[0] & 0x0f];
1084 }
1086}
1087
1088
1089char *
mg_md5(
char buf[33], ...) {
1090 unsigned char hash[16];
1091 const char *p;
1094
1096
1100 }
1102
1105 return buf;
1106}
1107
1108
1110 const char *nonce, const char *nc, const char *cnonce,
1111 const char *qop,
const char *
response) {
1113
1114
1117 return 0;
1118 }
1119
1120
1121
1122 if (
1124
1125 ) {
1126 return 0;
1127 }
1128
1131 ":", cnonce,
":", qop,
":",
ha2,
NULL);
1132
1134}
1135
1136
1137
1143
1145
1147
1148
1153 } else {
1154
1155 for (p = path,
e = p +
strlen(p) - 1;
e > p;
e--)
1157 break;
1161 }
1162
1164}
1165
1166
1169};
1170
1171
1173 size_t buf_size,
struct ah *
ah) {
1176
1180 return 0;
1181 }
1182
1183
1185 s = buf;
1186
1187
1188 for (;;) {
1189
1190 while (
isspace(* (
unsigned char *) s)) {
1191 s++;
1192 }
1194
1195 if (s[0] == '\"') {
1196 s++;
1198 if (s[0] == ',') {
1199 s++;
1200 }
1201 } else {
1203 }
1204 if (*
name ==
'\0') {
1205 break;
1206 }
1207
1222 }
1223 }
1224
1225
1228 } else {
1229 return 0;
1230 }
1231
1232 return 1;
1233}
1234
1235
1239
1241 return 0;
1242 }
1243
1244
1247 continue;
1248 }
1249
1254 }
1255
1256 return 0;
1257}
1258
1259
1266
1273 break;
1274 }
1275 }
1276
1279 }
1280
1284 }
1285
1287}
1288
1292 "HTTP/1.1 401 Unauthorized\r\n"
1293 "Content-Length: 0\r\n"
1294 "WWW-Authenticate: Digest qop=\"auth\", "
1295 "realm=\"%s\", nonce=\"%lu\"\r\n\r\n",
1297 (
unsigned long) time(
NULL));
1298}
1299
1303 int ret = 0;
1304
1308 }
1309
1310 return ret;
1311}
1312
1314 const char *user,
const char *
pass) {
1318
1321
1322
1325 }
1326
1328
1329
1332 }
1333
1334
1336 return 0;
1339 return 0;
1340 }
1341
1342
1344 if (
sscanf(line,
"%[^:]:%[^:]:%*s",
u,
d) != 2) {
1345 continue;
1346 }
1347
1353 }
1354 } else {
1356 }
1357 }
1358
1359
1363 }
1364
1365
1368
1369
1372
1373 return 1;
1374}
1375
1376#if defined(_WIN32)
1379}
1380
1384 return *mutex ==
NULL ? -1 : 0;
1385}
1386
1389}
1390
1393}
1394
1397}
1398
1403 return cv->signal !=
NULL &&
cv->broadcast !=
NULL ? 0 : -1;
1404}
1405
1411}
1412
1415}
1416
1418
1419
1421}
1422
1425}
1426
1427
1430
1431 for (
i = 0; path[
i] !=
'\0';
i++) {
1434
1435 if (path[
i] ==
'\\' &&
i > 0)
1436 while (path[
i + 1] ==
'\\' || path[
i + 1] ==
'/')
1438 path +
i + 2,
strlen(path +
i + 1));
1439 }
1440}
1441
1442
1443
1446
1449
1450
1451
1458 }
1459}
1460
1461#if defined(_WIN32_WCE)
1466
1470
1473 }
1474
1475 return t;
1476}
1477
1483
1486 }
1487
1491 ptm->tm_year =
st.wYear - 1900;
1492 ptm->tm_mon =
st.wMonth - 1;
1493 ptm->tm_wday =
st.wDayOfWeek;
1494 ptm->tm_mday =
st.wDay;
1495 ptm->tm_hour =
st.wHour;
1496 ptm->tm_min =
st.wMinute;
1497 ptm->tm_sec =
st.wSecond;
1501
1503}
1504
1506
1508}
1509
1511 const struct tm *
tm) {
1513 return 0;
1514}
1515#endif
1516
1517
1518
1519
1520
1525}
1526
1530
1531 filep->modification_time = 0;
1536 info.ftLastWriteTime.dwLowDateTime,
1537 info.ftLastWriteTime.dwHighDateTime);
1539
1540
1541
1544 }
1545 }
1546
1547 return filep->modification_time != 0;
1548}
1549
1554}
1555
1559
1563
1565
1567}
1568
1569
1574
1579 } else {
1586 dir->result.d_name[0] = '\0';
1587 } else {
1588 free(dir);
1590 }
1591 }
1592
1593 return dir;
1594}
1595
1597 int result = 0;
1598
1601 result =
FindClose(dir->handle) ? 0 : -1;
1602
1603 free(dir);
1604 } else {
1605 result = -1;
1607 }
1608
1609 return result;
1610}
1611
1613 struct dirent *result = 0;
1614
1615 if (dir) {
1617 result = &dir->result;
1619 dir->info.cFileName, -1, result->d_name,
1620 sizeof(result->d_name),
NULL,
NULL);
1621
1625 }
1626
1627 } else {
1629 }
1630 } else {
1632 }
1633
1634 return result;
1635}
1636
1637#ifndef HAVE_POLL
1643
1647
1648 for (
i = 0;
i <
n;
i++) {
1651
1654 }
1655 }
1656
1658 for (
i = 0;
i <
n;
i++) {
1661 }
1662 }
1663 }
1664
1665 return result;
1666}
1667#endif
1668
1671}
1672
1675}
1676
1682}
1683
1684#if !defined(NO_CGI)
1685#define SIGKILL 0
1689 return 0;
1690}
1691
1694 while (
e > s &&
isspace(* (
unsigned char *)
e)) {
1696 }
1697}
1698
1701 int fdout,
const char *dir) {
1708
1710
1713
1714
1717
1723
1724
1727 buf[0] = buf[1] = '\0';
1728
1729
1734 buf[sizeof(buf) - 1] = '\0';
1735 }
1736
1737 if (buf[0] == '#' && buf[1] == '!') {
1739 } else {
1740 buf[2] = '\0';
1741 }
1743 }
1744
1748 }
1750
1753
1757 cry(conn,
"%s: CreateProcess(%s): %ld",
1760 }
1761
1765
1767}
1768#endif
1769
1771 unsigned long on = 1;
1773}
1774#endif
1775
1776#if !defined(_WIN32)
1779
1781 if (
stat(path, &
st) == 0) {
1783 filep->modification_time =
st.st_mtime;
1785
1786
1787
1788
1791 }
1792 }
1793
1795}
1796
1799}
1800
1804 int result;
1805
1808
1809#if USE_STACK_SIZE > 1
1810
1812#endif
1813
1816
1817 return result;
1818}
1819
1820#ifndef NO_CGI
1823 int fdout,
const char *dir) {
1826
1828
1829 if ((pid =
fork()) == -1) {
1830
1832 } else if (pid == 0) {
1833
1834 if (
chdir(dir) != 0) {
1840 } else {
1841
1842
1845
1846
1847
1848
1849
1851
1856 } else {
1860 }
1861 }
1863 }
1864
1865 return pid;
1866}
1867#endif
1868
1870 int flags;
1871
1874
1875 return 0;
1876}
1877#endif
1878
1879
1880
1881
1882
1885 int len;
1886
1887
1888
1889
1890
1891
1894
1895 if (len > (int) size &&
1896 (size = len + 1) > 0 &&
1898 len = -1;
1899 } else {
1902 }
1903
1904 return len;
1905}
1906
1909 int len;
1910
1912 len =
mg_write(conn, buf, (
size_t) len);
1913 }
1914 if (buf !=
mem && buf !=
NULL) {
1915 free(buf);
1916 }
1917
1918 return len;
1919}
1920
1925}
1926
1929 int len;
1930
1934 len =
mg_printf(conn,
"%X\r\n%s\r\n", len, buf);
1935 }
1936
1937 if (buf !=
mem && buf !=
NULL) {
1938 free(buf);
1939 }
1940
1941 return len;
1942}
1943
1944
1945
1946#if !defined(NO_SSL)
1947
1948#if !defined(NO_SSL_DL)
1949
1950
1951
1952
1955 {
"SSL_accept",
NULL},
1956 {
"SSL_connect",
NULL},
1958 {
"SSL_write",
NULL},
1959 {
"SSL_get_error",
NULL},
1960 {
"SSL_set_fd",
NULL},
1962 {
"SSL_CTX_new",
NULL},
1963 {
"SSLv23_server_method",
NULL},
1964 {
"SSL_library_init",
NULL},
1965 {
"SSL_CTX_use_PrivateKey_file",
NULL},
1966 {
"SSL_CTX_use_certificate_file",
NULL},
1967 {
"SSL_CTX_set_default_passwd_cb",
NULL},
1968 {
"SSL_CTX_free",
NULL},
1969 {
"SSL_load_error_strings",
NULL},
1970 {
"SSL_CTX_use_certificate_chain_file",
NULL},
1971 {
"SSLv23_client_method",
NULL},
1972 {
"SSL_pending",
NULL},
1973 {
"SSL_CTX_set_verify",
NULL},
1974 {
"SSL_shutdown",
NULL},
1975 {
"SSL_CTX_ctrl",
NULL},
1976 {
"SSL_CTX_set_cipher_list",
NULL},
1977 {
"EC_KEY_new_by_curve_name",
NULL},
1978 {
"EC_KEY_free",
NULL},
1979 {
"SSL_get_cipher_list",
NULL},
1981};
1982
1983
1985 {
"CRYPTO_num_locks",
NULL},
1986 {
"CRYPTO_set_locking_callback",
NULL},
1987 {
"CRYPTO_set_id_callback",
NULL},
1988 {
"ERR_get_error",
NULL},
1989 {
"ERR_error_string",
NULL},
1991};
1992#endif
1993
1995
1999 func(conn->
ssl) == 1;
2000}
2001
2002
2004 unsigned long err;
2007}
2008
2010 int line) {
2013
2016 } else {
2018 }
2019}
2020
2023}
2024
2025#if !defined(NO_SSL_DL)
2031
2034 return 0;
2035 }
2036
2038#ifdef _WIN32
2039
2041#else
2042
2043
2045#endif
2048 return 0;
2049 } else {
2051 }
2052 }
2053
2054 return 1;
2055}
2056#endif
2057
2058
2064
2065
2066
2068
2069
2070 return 1;
2071 }
2072
2073#if !defined(NO_SSL_DL)
2076 return 0;
2077 }
2078#endif
2079
2080
2083
2086 return 0;
2087 }
2088
2091
2092#if 0
2093 {
2094
2095
2096
2097
2098
2099
2100
2101
2108 } else {
2109
2110 }
2112
2113 }
2115
2116 }
2117 }
2118#endif
2119
2120#ifdef OPENSSL_EC_NAMED_CURVE
2121 {
2122
2123
2124
2125
2129 } else {
2132 }
2135 }
2136 }
2137#else
2138#warning Very old openssl, no EC_KEY, no ECDH for modern criptography!
2139#endif
2140
2143
2144
2145
2146 {
2152 break;
2153
2156 }
2158 }
2159
2161 cry(
fc(ctx),
"%s: openssl \"modern cryptography\" ECDH ciphers not available",
__func__);
2162 }
2163
2164
2165 const char*
cipher_list =
"ALL:!RC4:!DES-CBC-SHA:!DES:!DES-CBC3-SHA:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW";
2166
2167
2169 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";
2170
2172
2173
2174
2175
2179 return 0;
2180 }
2181
2184 }
2185
2186
2187
2191 return 0;
2192 }
2193
2196 }
2197
2200
2201 return 1;
2202}
2203
2210 }
2213 }
2214}
2215#endif
2216
2222
2224
2227#ifndef NO_SSL
2230
2231#endif
2236 } else {
2240 sin.sin_addr = * (
struct in_addr *)
he->h_addr_list[0];
2241 if (connect(sock, (
struct sockaddr *) &sin,
sizeof(sin)) != 0) {
2246 }
2247 }
2248 return sock;
2249}
2250
2256
2262#ifndef NO_SSL
2267 free(conn);
2269#endif
2270 } else {
2273 conn->
buf = (
char *) (conn + 1);
2278#ifndef NO_SSL
2280
2281
2284 }
2285#endif
2286 }
2287
2288 return conn;
2289}
2290
2293 const char *fmt, ...) {
2296
2302 } else {
2304 }
2305 if (
ebuf[0] !=
'\0' && conn !=
NULL) {
2308 }
2309
2310 return conn;
2311}
2312
2313
2316}
2317
2325 }
2328}
2329
2331#ifdef _WIN32
2336#else
2338#endif
2339}
2340
2344#if defined(USE_IPV6)
2346 (
void *) &
usa->
sin.sin_addr :
2348#elif defined(_WIN32)
2349
2351#else
2353#endif
2354}
2355
2356
2362
2366
2367
2368
2369
2373
2376 timestamp = time(
NULL);
2377
2379 fprintf(
fp,
"[%010lu] [error] [client %s] ", (
unsigned long) timestamp,
2381
2385 }
2386
2391 }
2392 }
2393}
2394
2397}
2398
2399
2400
2401
2409 (header ==
NULL && http_version &&
strcmp(http_version,
"1.1"))) {
2410 return 0;
2411 }
2412 return 1;
2413}
2414
2417}
2418
2420 const char *
reason,
const char *fmt, ...) {
2423 int len = 0;
2424
2427
2428
2432
2436 }
2438
2441 "Content-Length: %d\r\n"
2445 }
2446}
2447
2448
2449
2454
2456 sent = 0;
2457 while (sent < len) {
2458
2459
2461
2462#if !defined(NO_SSL)
2465 } else
2466#endif
2471 } else {
2473 }
2474
2476 break;
2477
2479 }
2480
2481 return sent;
2482}
2483
2484
2485
2488
2489 if (len <= 0) return 0;
2491
2492
2493
2495#ifndef NO_SSL
2496 }
else if (conn->
ssl !=
NULL) {
2498#endif
2499 } else {
2501 }
2504 }
2505
2507}
2508
2511
2516 break;
2517 }
else if (
n == 0) {
2518 break;
2519 } else {
2522 }
2523 }
2524
2526}
2527
2531
2533 return 0;
2534 }
2535
2536
2537
2538
2539
2540
2541
2546
2553 }
2554
2555
2559 }
2562 }
2563
2565}
2566
2570
2575 }
2579 }
2589 break;
2590 }
2596 }
2597 }
2598 } else {
2601 }
2603}
2604
2608#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
2609
2612 isxdigit(* (
const unsigned char *) (src +
i + 1)) &&
2613 isxdigit(* (
const unsigned char *) (src +
i + 2))) {
2614 a =
tolower(* (
const unsigned char *) (src +
i + 1));
2615 b =
tolower(* (
const unsigned char *) (src +
i + 2));
2620 } else {
2622 }
2623 }
2624
2626
2628}
2629
2632 const char *p, *
e, *s;
2633 size_t name_len;
2634 int len;
2635
2637 len = -2;
2639 len = -1;
2640 dst[0] = '\0';
2641 } else {
2644 len = -1;
2645 dst[0] = '\0';
2646
2647
2648 for (p =
data; p + name_len <
e; p++) {
2649 if ((p ==
data || p[-1] ==
'&') && p[name_len] ==
'=' &&
2651
2652
2653 p += name_len + 1;
2654
2655
2656 s = (
const char *)
memchr(p,
'&', (
size_t)(
e - p));
2659 }
2660 assert(s >= p);
2661
2662
2664
2665
2666 if (len == -1) {
2667 len = -2;
2668 }
2669 break;
2670 }
2671 }
2672 }
2673
2674 return len;
2675}
2676
2679 const char *s, *p, *
end;
2680 int name_len, len = -1;
2681
2683 len = -2;
2685 len = -1;
2686 dst[0] = '\0';
2687 } else {
2690 dst[0] = '\0';
2691
2693 if (s[name_len] == '=') {
2694 s += name_len + 1;
2697 if (p[-1] == ';')
2698 p--;
2699 if (*s == '"' && p[-1] == '"' && p > s + 1) {
2700 s++;
2701 p--;
2702 }
2704 len = p - s;
2706 } else {
2707 len = -3;
2708 }
2709 break;
2710 }
2711 }
2712 }
2713 return len;
2714}
2715
2716
2722 char *p;
2726
2727
2729 return 0;
2730 }
2731
2732
2733
2734
2736
2742 break;
2743 }
2744 }
2745
2747 return 1;
2748 }
2749
2750
2751
2752
2753
2754
2755
2761 return 1;
2762 }
2763 }
2764 }
2765
2766
2768 if (*p == '/') {
2769 *p = '\0';
2773
2774
2775
2776
2777
2780 p[1] = '/';
2781 return 1;
2782 } else {
2783 *p = '/';
2784 }
2785 }
2786 }
2787
2788 return 0;
2789}
2790
2791
2792
2793
2794
2797
2799
2800
2801
2802 if (!
isprint(* (
const unsigned char *) &buf[
i]) && buf[
i] !=
'\r' &&
2803 buf[
i] !=
'\n' && * (
const unsigned char *) &buf[
i] < 128) {
2804 return -1;
2805 }
else if (buf[
i] ==
'\n' &&
i + 1 <
buf_len && buf[
i + 1] ==
'\n') {
2807 }
else if (buf[
i] ==
'\n' &&
i + 2 <
buf_len && buf[
i + 1] ==
'\r' &&
2808 buf[
i + 2] ==
'\n') {
2810 }
2811 }
2812
2813 return 0;
2814}
2815
2816
2817
2819 char *p = s;
2820
2821 while (*s != '\0') {
2822 *p++ = *s++;
2823 if (s[-1] == '/' || s[-1] == '\\') {
2824
2825 while (s[0] != '\0') {
2826 if (s[0] == '/' || s[0] == '\\') {
2827 s++;
2828 } else if (s[0] == '.' && s[1] == '.') {
2829 s += 2;
2830 } else {
2831 break;
2832 }
2833 }
2834 }
2835 }
2836 *p = '\0';
2837}
2838
2839static const struct {
2844 {".html", 5, "text/html"},
2845 {".htm", 4, "text/html"},
2846 {".shtm", 5, "text/html"},
2847 {".shtml", 6, "text/html"},
2848 {".css", 4, "text/css"},
2849 {".js", 3, "application/x-javascript"},
2850 {".ico", 4, "image/x-icon"},
2851 {".gif", 4, "image/gif"},
2852 {".jpg", 4, "image/jpeg"},
2853 {".jpeg", 5, "image/jpeg"},
2854 {".png", 4, "image/png"},
2855 {".svg", 4, "image/svg+xml"},
2856 {".txt", 4, "text/plain"},
2857 {".torrent", 8, "application/x-bittorrent"},
2858 {".wav", 4, "audio/x-wav"},
2859 {".mp3", 4, "audio/x-mp3"},
2860 {".mid", 4, "audio/mid"},
2861 {".m3u", 4, "audio/x-mpegurl"},
2862 {".ogg", 4, "application/ogg"},
2863 {".ram", 4, "audio/x-pn-realaudio"},
2864 {".xml", 4, "text/xml"},
2865 {".json", 5, "text/json"},
2866 {".xslt", 5, "application/xml"},
2867 {".xsl", 4, "application/xml"},
2868 {".ra", 3, "audio/x-pn-realaudio"},
2869 {".doc", 4, "application/msword"},
2870 {".exe", 4, "application/octet-stream"},
2871 {".zip", 4, "application/x-zip-compressed"},
2872 {".xls", 4, "application/excel"},
2873 {".tgz", 4, "application/x-tar-gz"},
2874 {".tar", 4, "application/x-tar"},
2875 {".gz", 3, "application/x-gunzip"},
2876 {".arj", 4, "application/x-arj-compressed"},
2877 {".rar", 4, "application/x-arj-compressed"},
2878 {".rtf", 4, "application/rtf"},
2879 {".pdf", 4, "application/pdf"},
2880 {".swf", 4, "application/x-shockwave-flash"},
2881 {".mpg", 4, "video/mpeg"},
2882 {".webm", 5, "video/webm"},
2883 {".mpeg", 5, "video/mpeg"},
2884 {".mov", 4, "video/quicktime"},
2885 {".mp4", 4, "video/mp4"},
2886 {".m4v", 4, "video/x-m4v"},
2887 {".asf", 4, "video/x-ms-asf"},
2888 {".avi", 4, "video/x-msvideo"},
2889 {".bmp", 4, "image/bmp"},
2890 {".ttf", 4, "application/x-font-ttf"},
2892};
2893
2895 const char *ext;
2897
2899
2905 }
2906 }
2907
2908 return "text/plain";
2909}
2910
2911
2912
2916 const char *
list, *ext;
2918
2920
2921
2922
2925
2929 return;
2930 }
2931 }
2932
2935}
2936
2939 static const char *
hex =
"0123456789abcdef";
2941
2942 for (; *src !=
'\0' && dst <
end; src++, dst++) {
2943 if (
isalnum(*(
const unsigned char *) src) ||
2945 *dst = *src;
2946 }
else if (dst + 2 <
end) {
2947 dst[0] = '%';
2948 dst[1] =
hex[(* (
const unsigned char *) src) >> 4];
2949 dst[2] =
hex[(* (
const unsigned char *) src) & 0xf];
2950 dst += 2;
2951 }
2952 }
2953
2954 *dst = '\0';
2955}
2956
2960
2962 mg_snprintf(size,
sizeof(size),
"%s",
"[DIRECTORY]");
2963 } else {
2964
2965
2974 } else {
2976 "%.1fG", (
double)
de->
file.
size / 1073741824);
2977 }
2978 }
2983 "<tr><td><a href=\"%s%s%s\">%s%s</a></td>"
2984 "<td> %s</td><td> %s</td></tr>\n",
2986}
2987
2988
2989
2990
2991
2993 const struct de *a = (
const struct de *)
p1, *b = (
const struct de *)
p2;
2996
2997 if (query_string ==
NULL) {
2998 query_string = "na";
2999 }
3000
3002 return -1;
3004 return 1;
3005 } else if (*query_string == 'n') {
3007 } else if (*query_string == 's') {
3009 a->
file.
size > b->file.size ? 1 : -1;
3010 } else if (*query_string == 'd') {
3013 }
3014
3016}
3017
3023}
3024
3026 void *
data,
void (*cb)(
struct de *,
void *)) {
3031
3033 return 0;
3034 } else {
3036
3038
3042 continue;
3043 }
3044
3045 mg_snprintf(path,
sizeof(path),
"%s%c%s", dir,
'/',
dp->d_name);
3046
3047
3048
3049
3050
3051
3054
3057 }
3059 }
3060 return 1;
3061}
3062
3068
3070 return 0;
3071 } else {
3073
3075
3078 continue;
3079 }
3080
3081 mg_snprintf(path,
sizeof(path),
"%s%c%s", dir,
'/',
dp->d_name);
3082
3083
3084
3085
3086
3087
3093 } else {
3095 }
3096 }
3097
3098 }
3100
3102 }
3103
3104 return 1;
3105}
3106
3111};
3112
3113
3114static void *
realloc2(
void *ptr,
size_t size) {
3117 free(ptr);
3118 }
3120}
3121
3124
3125 if (
dsd->entries ==
NULL ||
dsd->num_entries >=
dsd->arr_size) {
3128 sizeof(
dsd->entries[0]));
3129 }
3131
3132 dsd->num_entries = 0;
3133 } else {
3138 }
3139}
3140
3142 const char *dir) {
3145
3149 return;
3150 }
3151
3154
3157 "HTTP/1.1 200 OK\r\n"
3158 "Transfer-Encoding: Chunked\r\n"
3159 "Content-Type: text/html; charset=utf-8\r\n\r\n");
3160
3162 "<html><head><title>Index of %s</title>"
3163 "<style>th {text-align: left;}</style></head>"
3164 "<body><h1>Index of %s</h1><pre><table cellpadding=\"0\">"
3165 "<tr><th><a href=\"?n%c\">Name</a></th>"
3166 "<th><a href=\"?d%c\">Modified</a></th>"
3167 "<th><a href=\"?s%c\">Size</a></th></tr>"
3168 "<tr><td colspan=\"3\"><hr></td></tr>",
3171
3172
3174 "<tr><td><a href=\"%s%s\">%s</a></td>"
3175 "<td> %s</td><td> %s</td></tr>\n",
3177
3178
3181 for (
i = 0;
i <
data.num_entries;
i++) {
3183 free(
data.entries[
i].file_name);
3184 }
3186
3188 "</table></body></html>");
3191}
3192
3193
3198
3199
3201 return;
3202 }
3203
3204 while (len > 0) {
3205
3209 }
3210
3211
3213 break;
3214 }
3215
3216
3218 break;
3219 }
3220
3221
3224 }
3225}
3226
3229}
3230
3233}
3234
3238 (
unsigned long)
filep->modification_time,
filep->size);
3239}
3240
3243#ifndef _WIN32
3245#endif
3246 }
3247}
3248
3252 const char *msg =
"OK", *
hdr;
3260
3264 range[0] = '\0';
3265
3266
3267
3268
3269 if (
filep->gzipped) {
3272 encoding =
"Content-Encoding: gzip\r\n";
3273 }
3274
3278 return;
3279 }
3280
3282
3283
3287 r1 >= 0 &&
r2 >= 0) {
3288
3289
3290 if (
filep->gzipped) {
3292 "range requests in gzipped files are not supported");
3293 return;
3294 }
3296 cl =
n == 2 ? (
r2 > cl ? cl :
r2) -
r1 + 1: cl -
r1;
3298 "Content-Range: bytes "
3302 msg = "Partial Content";
3303 }
3304
3305
3306
3310
3312 "HTTP/1.1 %d %s\r\n"
3313 "Date: %s\r\n"
3314 "Last-Modified: %s\r\n"
3315 "Etag: %s\r\n"
3316 "Content-Type: %.*s\r\n"
3318 "Connection: %s\r\n"
3319 "Accept-Ranges: bytes\r\n"
3320 "%s%s%s\r\n",
3324
3327 }
3329}
3330
3335 } else {
3337 }
3338}
3339
3340
3341
3342
3345
3348 ri->http_headers[
i].value =
skip(buf,
"\r\n");
3349 if (
ri->http_headers[
i].name[0] ==
'\0')
3350 break;
3351 ri->num_headers =
i + 1;
3352 }
3353}
3354
3356 return !
strcmp(method,
"GET") || !
strcmp(method,
"POST") ||
3357 !
strcmp(method,
"HEAD") || !
strcmp(method,
"CONNECT") ||
3359 !
strcmp(method,
"OPTIONS") || !
strcmp(method,
"PROPFIND")
3360 || !
strcmp(method,
"MKCOL")
3361 ;
3362}
3363
3364
3365
3366
3370
3371 ri->remote_user =
ri->request_method =
ri->uri =
ri->http_version =
NULL;
3372 ri->num_headers = 0;
3373
3375
3376
3377 while (*buf !=
'\0' &&
isspace(* (
unsigned char *) buf)) {
3378 buf++;
3379 }
3380 ri->request_method =
skip(&buf,
" ");
3381 ri->uri =
skip(&buf,
" ");
3382 ri->http_version =
skip(&buf,
"\r\n");
3383
3384
3385
3390 } else {
3392 ri->http_version += 5;
3393 }
3395 }
3396 }
3398}
3399
3400
3401
3402
3403
3404
3407 int request_len,
n = 0;
3408
3412 request_len == 0 &&
3417 }
3418
3419 return request_len <= 0 &&
n <= 0 ? -1 : request_len;
3420}
3421
3422
3423
3424
3432
3433
3434
3435
3436 while (
n > 0 && path[
n - 1] ==
'/') {
3438 }
3440
3441
3442
3444
3445
3447 continue;
3448
3449
3451
3452
3454
3457 break;
3458 }
3459 }
3460
3461
3464 }
3465
3467}
3468
3469
3478}
3479
3482 const char *
expect, *body;
3486
3489
3494 } else {
3496 (
void)
mg_printf(conn,
"%s",
"HTTP/1.1 100 Continue\r\n\r\n");
3497 }
3498
3502
3506 }
3510 }
3511
3517 }
3520 break;
3521 }
3522 }
3523
3526 }
3527
3528
3531 }
3532 }
3533
3535}
3536
3537#if !defined(NO_CGI)
3538
3539
3540
3541
3542
3543
3544
3545
3552};
3553
3557
3558
3559
3564
3565
3568
3569
3571
3572
3576
3577
3580
3582
3584 } else {
3586 }
3587
3589}
3590
3595 const char *s, *
slash;
3599
3603
3608
3609
3610 addenv(
blk,
"%s",
"GATEWAY_INTERFACE=CGI/1.1");
3611 addenv(
blk,
"%s",
"SERVER_PROTOCOL=HTTP/1.1");
3612 addenv(
blk,
"%s",
"REDIRECT_STATUS=200");
3613
3614
3616
3617 addenv(
blk,
"REQUEST_METHOD=%s",
ri->request_method);
3621 ri->query_string ==
NULL ?
"" :
"?",
3622 ri->query_string ==
NULL ?
"" :
ri->query_string);
3623
3624
3629 } else {
3635 }
3636
3640
3643
3644 if (
ri->query_string !=
NULL) {
3646 }
3647
3650
3653
3654#if defined(_WIN32)
3657 }
3660 }
3663 }
3666 }
3667 if ((s =
getenv(
"ProgramFiles(x86)")) !=
NULL) {
3669 }
3670 if ((s =
getenv(
"CommonProgramFiles(x86)")) !=
NULL) {
3671 addenv(
blk,
"CommonProgramFiles(x86)=%s", s);
3672 }
3673#else
3676#endif
3677
3680
3681 if (
ri->remote_user !=
NULL) {
3684 }
3685
3686
3687 for (
i = 0;
i <
ri->num_headers;
i++) {
3689 ri->http_headers[
i].name,
ri->http_headers[
i].value);
3690
3691
3692 for (; *p != '=' && *p != '\0'; p++) {
3693 if (*p == '-')
3694 *p = '_';
3696 }
3697 }
3698
3699
3703 }
3704
3706 blk->buf[
blk->len++] =
'\0';
3707
3709 assert(
blk->len > 0);
3710 assert(
blk->len < (
int)
sizeof(
blk->buf));
3711}
3712
3721
3723
3724
3725
3726
3729 *p++ = '\0';
3730 } else {
3731 dir[0] = '.', dir[1] = '\0';
3733 }
3734
3739 }
3740
3742 if (pid == (
pid_t) -1) {
3746 }
3747
3748
3753
3754
3755
3756
3757
3761
3762
3768 }
3769
3772
3773
3777 }
3778
3779
3783
3784
3785
3786
3787
3788 data_len = 0;
3792 "CGI program sent malformed or too big (>%u bytes) "
3793 "HTTP headers: [%.*s]",
3794 (
unsigned)
sizeof(
buf), data_len,
buf);
3796 }
3800
3801
3808 }
3811 } else {
3813 }
3817 }
3820
3821
3822 for (
i = 0;
i <
ri.num_headers;
i++) {
3824 ri.http_headers[
i].name,
ri.http_headers[
i].value);
3825 }
3827
3828
3831
3832
3834
3836 if (pid != (
pid_t) -1) {
3838 }
3839 if (
fdin[0] != -1) {
3841 }
3842 if (
fdout[1] != -1) {
3844 }
3845
3848 }
else if (
fdin[1] != -1) {
3850 }
3851
3854 }
else if (
fdout[0] != -1) {
3856 }
3857}
3858#endif
3859
3860
3861
3862
3863static int put_dir(
const char *path) {
3865 const char *s, *p;
3868
3869 for (s = p = path + 2; (p =
strchr(s,
'/')) !=
NULL; s = ++p) {
3870 len = p - path;
3871 if (len >= (int) sizeof(buf)) {
3873 break;
3874 }
3876 buf[len] = '\0';
3877
3878
3882 break;
3883 }
3884
3885
3886 if (p[1] == '\0') {
3888 }
3889 }
3890
3892}
3893
3897
3900
3904 return;
3905 }
3906
3908 if(body_len > 0) {
3911 return;
3912 }
3913
3915
3919 }
else if (
rc == -1) {
3929 else
3932 }
3933}
3934
3938 const char *range;
3941
3943
3946 }
else if (
rc == -1) {
3953 } else {
3960 }
3963 }
3964 mg_printf(conn,
"HTTP/1.1 %d OK\r\nContent-Length: 0\r\n\r\n",
3967 }
3968}
3969
3975
3976
3977
3979
3983
3984
3988
3991 p[1] = '\0';
3992 }
3995 } else {
3996 cry(conn,
"Bad SSI #include: [%s]", tag);
3997 return;
3998 }
3999
4001 cry(conn,
"Cannot open SSI #include: [%s]: fopen(%s): %s",
4003 } else {
4008 } else {
4010 }
4012 }
4013}
4014
4015#if !defined(NO_POPEN)
4019
4020 if (
sscanf(tag,
" \"%[^\"]\"", cmd) != 1) {
4021 cry(conn,
"Bad SSI #exec: [%s]", tag);
4024 } else {
4027 }
4028}
4029#endif
4030
4035
4037 cry(conn,
"SSI #include level is too deep (%s)", path);
4038 return;
4039 }
4040
4046 buf[len] = '\0';
4047 assert(len <= (int) sizeof(buf));
4048 if (len < 6 ||
memcmp(buf,
"<!--#", 5) != 0) {
4049
4051 } else {
4052 if (!
memcmp(buf + 5,
"include", 7)) {
4054#if !defined(NO_POPEN)
4055 }
else if (!
memcmp(buf + 5,
"exec", 4)) {
4057#endif
4058 } else {
4059 cry(conn,
"%s: unknown SSI " "command: \"%s\"", path, buf);
4060 }
4061 }
4062 len = 0;
4064 if (len == 5 &&
memcmp(buf,
"<!--#", 5) != 0) {
4065
4067 } else if (len == (int) sizeof(buf) - 2) {
4068 cry(conn,
"%s: SSI tag is too large", path);
4069 len = 0;
4070 }
4071 buf[len++] =
ch & 0xff;
4072 }
else if (
ch ==
'<') {
4074 if (len > 0) {
4076 }
4077 len = 0;
4078 buf[len++] =
ch & 0xff;
4079 } else {
4080 buf[len++] =
ch & 0xff;
4081 if (len == (int) sizeof(buf)) {
4083 len = 0;
4084 }
4085 }
4086 }
4087
4088
4089 if (len > 0) {
4091 }
4092}
4093
4095 const char *path) {
4098
4102 } else {
4107 "Content-Type: %.*s\r\n"
4108 "Connection: close\r\n\r\n",
4112 }
4113}
4114
4116 static const char reply[] =
"HTTP/1.1 200 OK\r\n"
4117 "Allow: GET, POST, HEAD, CONNECT, PUT, DELETE, OPTIONS, PROPFIND, MKCOL\r\n"
4118 "DAV: 1\r\n\r\n";
4119
4122}
4123
4124
4130 "<d:response>"
4131 "<d:href>%s</d:href>"
4132 "<d:propstat>"
4133 "<d:prop>"
4134 "<d:resourcetype>%s</d:resourcetype>"
4135 "<d:getcontentlength>%" INT64_FMT "</d:getcontentlength>"
4136 "<d:getlastmodified>%s</d:getlastmodified>"
4137 "</d:prop>"
4138 "<d:status>HTTP/1.1 200 OK</d:status>"
4139 "</d:propstat>"
4140 "</d:response>\n",
4141 uri,
4142 filep->is_directory ?
"<d:collection/>" :
"",
4145}
4146
4155}
4156
4160
4163 mg_printf(conn,
"HTTP/1.1 207 Multi-Status\r\n"
4164 "Connection: close\r\n"
4165 "Content-Type: text/xml; charset=utf-8\r\n\r\n");
4166
4168 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
4169 "<d:multistatus xmlns:d='DAV:'>\n");
4170
4171
4173
4174
4175 if (
filep->is_directory &&
4179 }
4180
4182}
4183
4184#if defined(USE_WEBSOCKET)
4185
4186
4187
4188#define SHA1HANDSOFF
4189#if defined(__sun)
4190#include "solarisfixes.h"
4191#endif
4192
4194
4195#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
4196
4198
4202 }
4204}
4205
4206#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
4207 ^block->l[(i+2)&15]^block->l[i&15],1))
4208#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(block, i)+0x5A827999+rol(v,5);w=rol(w,30);
4209#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
4210#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
4211#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
4212#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
4213
4214typedef struct {
4217 unsigned char buffer[64];
4219
4223
4230 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);
4231 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);
4232 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);
4233 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);
4234 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);
4235 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);
4236 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);
4237 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);
4238 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);
4239 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);
4240 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);
4241 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);
4242 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);
4243 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);
4244 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);
4245 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);
4246 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);
4247 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);
4248 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);
4249 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);
4255 a = b =
c =
d =
e = 0;
4257}
4258
4260 context->state[0] = 0x67452301;
4261 context->state[1] = 0xEFCDAB89;
4262 context->state[2] = 0x98BADCFE;
4263 context->state[3] = 0x10325476;
4264 context->state[4] = 0xC3D2E1F0;
4265 context->count[0] = context->count[1] = 0;
4266}
4267
4271
4272 j = context->count[0];
4273 if ((context->count[0] += len << 3) <
j)
4274 context->count[1]++;
4275 context->count[1] += (len>>29);
4277 if ((
j + len) > 63) {
4280 for ( ;
i + 63 < len;
i += 64) {
4282 }
4284 }
4287}
4288
4292
4293 for (
i = 0;
i < 8;
i++) {
4295 >> ((3-(
i & 3)) * 8) ) & 255);
4296 }
4299 while ((context->count[0] & 504) != 448) {
4302 }
4304 for (
i = 0;
i < 20;
i++) {
4306 ((context->state[
i>>2] >> ((3-(
i & 3)) * 8) ) & 255);
4307 }
4308 memset(context,
'\0',
sizeof(*context));
4310}
4311
4312
4314 static const char *
b64 =
4315 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4317
4322
4323 dst[
j++] =
b64[a >> 2];
4324 dst[
j++] =
b64[((a & 3) << 4) | (b >> 4)];
4326 dst[
j++] =
b64[(b & 15) << 2 | (
c >> 6)];
4327 }
4329 dst[
j++] =
b64[
c & 63];
4330 }
4331 }
4332 while (
j % 4 != 0) {
4334 }
4336}
4337
4339 static const char *
magic =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
4342
4350 "HTTP/1.1 101 Switching Protocols\r\n"
4351 "Upgrade: websocket\r\n"
4352 "Connection: Upgrade\r\n"
4353 "Sec-WebSocket-Accept: ",
b64_sha,
"\r\n\r\n");
4354}
4355
4357
4358
4359
4360 unsigned char *buf = (
unsigned char *) conn->
buf + conn->
request_len;
4364
4366
4367
4368
4371
4372
4373
4374
4376 len = buf[1] & 127;
4379 data_len = len;
4381 }
else if (len == 126 && body_len >= 4 +
mask_len) {
4383 data_len = ((((
int) buf[2]) << 8) + buf[3]);
4384 }
else if (body_len >= 10 +
mask_len) {
4388 }
4389 }
4390
4391
4392
4393
4394
4395
4396
4397
4398
4400
4402
4403
4404 data_len = 0;
4405 break;
4406 }
4407
4408
4409 *bits = buf[0];
4411
4412
4417
4420 } else {
4423 memmove(buf, buf + len, body_len - len);
4425 }
4426
4427
4429 for (
i = 0;
i < data_len;
i++) {
4430 (*data)[
i] ^=
mask[
i % 4];
4431 }
4432 }
4433
4434 return data_len;
4435 } else {
4436
4439 break;
4440 }
4442 }
4443 }
4444
4445 return 0;
4446}
4447
4449 const char *
data,
size_t data_len) {
4450 unsigned char *copy;
4453
4454 if ((copy = (
unsigned char *)
malloc(data_len + 10)) ==
NULL) {
4455 return -1;
4456 }
4457
4458 copy[0] = 0x80 + (
opcode & 0x0f);
4459
4460
4461 if (data_len < 126) {
4462
4463 copy[1] = data_len;
4466 }
else if (data_len <= 0
xFFFF) {
4467
4468 copy[1] = 126;
4472 } else {
4473
4474 copy[1] = 127;
4479 }
4480
4481
4484 }
4485 free(copy);
4486
4488}
4489#endif
4490
4492 return n >= 0 &&
n <= 255;
4493}
4494
4496 int n, a, b,
c,
d,
slash = 32, len = 0;
4497
4505 }
4506
4507 return len;
4508}
4509
4511 int throttle = 0;
4514 char mult;
4515 double v;
4516
4518 mult = ',';
4519 if (
sscanf(
val.ptr,
"%lf%c", &v, &mult) < 1 || v < 0 ||
4521 continue;
4522 }
4527 if ((remote_ip &
mask) ==
net) {
4529 }
4532 }
4533 }
4534
4535 return throttle;
4536}
4537
4540}
4541
4545 char *buf,
fname[1024], boundary[100], *s;
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4567 "boundary=")) ==
NULL ||
4570 boundary[0] == '\0') {
4572 }
4573
4574 boundary_len =
strlen(boundary);
4575 bl = boundary_len + 4;
4576
4577
4578
4579
4580
4581
4582
4586
4587 for (;;) {
4588
4593 }
4597 }
4599 break;
4600 }
4601
4602
4605 if (buf[
i] ==
'\r' && buf[
i + 1] ==
'\n') {
4606 buf[
i] = buf[
i + 1] =
'\0';
4607
4608
4609 sscanf(&buf[
j],
"Content-Disposition: %*s %*s filename=\"%1023[^\"]",
4612 }
4613 }
4614
4615
4616 if (
fname[0] ==
'\0') {
4617 break;
4618 }
4619
4620
4625
4626
4627
4629
4630
4634 }
4635
4636
4639 break;
4640 }
4641
4642
4644 do {
4647 if (!
memcmp(&buf[
i],
"\r\n--", 4) &&
4648 !
memcmp(&buf[
i + 4], boundary, boundary_len)) {
4649
4654 break;
4655 }
4656 }
4661 }
4665 }
4668
4672 } else {
4674 }
4675 }
4676
4678}
4679
4685}
4686
4691 }
4693}
4694
4696 char host[1025];
4698
4701
4703 }
4704
4705 mg_printf(conn,
"HTTP/1.1 302 Found\r\nLocation: https://%s:%d%s\r\n\r\n",
4708}
4709
4711 const char *path) {
4713
4724 } else {
4727 }
4728}
4729
4730
4731
4732
4733
4739
4742 }
4748 path[0] = '\0';
4750
4751
4752
4757
4762
4763 }
else if (!
strcmp(
ri->request_method,
"OPTIONS")) {
4770 }
else if (!
strcmp(
ri->request_method,
"PUT")) {
4772 }
else if (!
strcmp(
ri->request_method,
"MKCOL")) {
4774 }
else if (!
strcmp(
ri->request_method,
"DELETE")) {
4780 mg_printf(conn,
"HTTP/1.1 301 Moved Permanently\r\n"
4781 "Location: %s/\r\n\r\n",
ri->uri);
4782 }
else if (!
strcmp(
ri->request_method,
"PROPFIND")) {
4788 } else {
4790 "Directory listing denied");
4791 }
4792#ifdef USE_LUA
4795#endif
4796#if !defined(NO_CGI)
4799 path) > 0) {
4800 if (
strcmp(
ri->request_method,
"POST") &&
4801 strcmp(
ri->request_method,
"HEAD") &&
4802 strcmp(
ri->request_method,
"GET")) {
4804 "Method %s is not implemented",
ri->request_method);
4805 } else {
4807 }
4808#endif
4811 path) > 0) {
4815 } else {
4817 }
4818}
4819
4824 }
4826}
4827
4829 return port > 0 && port < 0xffff;
4830}
4831
4832
4833
4834
4836 unsigned int a, b,
c,
d,
ch, port;
4837 int len;
4838#if defined(USE_IPV6)
4839 char buf[100];
4840#endif
4841
4842
4843
4844
4847
4848 if (
sscanf(
vec->
ptr,
"%u.%u.%u.%u:%u%n", &a, &b, &
c, &
d, &port, &len) == 5) {
4849
4850 so->lsa.sin.sin_addr.s_addr =
htonl((a << 24) | (b << 16) | (
c << 8) |
d);
4852#if defined(USE_IPV6)
4853
4854 }
else if (
sscanf(
vec->
ptr,
"[%49[^]]]:%d%n", buf, &port, &len) == 2 &&
4856
4859#endif
4860 }
else if (
sscanf(
vec->
ptr,
"%u%n", &port, &len) == 1) {
4861
4863 } else {
4864 port = len = 0;
4865 }
4866
4868 so->is_ssl =
ch ==
's';
4869 so->ssl_redir =
ch ==
'r';
4870
4871
4873 (
ch ==
'\0' ||
ch ==
's' ||
ch ==
'r' ||
ch ==
',');
4874}
4875
4879#if defined(USE_IPV6)
4881#endif
4884
4887 cry(
fc(ctx),
"%s: %.*s: invalid port spec. Expecting list of: %s",
4891 cry(
fc(ctx),
"Cannot add SSL socket, is -ssl_certificate option set?");
4895
4896
4898 (
void *) &
on,
sizeof(
on)) != 0 ||
4902 sizeof(
off)) != 0) ||
4916 } else {
4921 }
4922 }
4923
4926 }
4927
4929}
4930
4934
4937 } else {
4939 }
4940}
4941
4946
4949
4951 return;
4952
4955
4958
4964 conn->status_code, conn->num_bytes_sent);
4969
4972}
4973
4974
4975
4981
4982
4984
4987 if ((
flag !=
'+' &&
flag !=
'-') ||
4989 cry(
fc(ctx),
"%s: subnet must be [+|-]x.x.x.x[/x]",
__func__);
4990 return -1;
4991 }
4992
4993 if (
net == (remote_ip &
mask)) {
4995 }
4996 }
4997
4999}
5000
5001#if !defined(_WIN32)
5006
5009 } else {
5012 }
else if (
setgid(
pw->pw_gid) == -1) {
5014 }
else if (
setuid(
pw->pw_uid) == -1) {
5016 } else {
5018 }
5019 }
5020
5022}
5023#endif
5024
5030 return 0;
5031 }
5032 return 1;
5033}
5034
5037}
5038
5044}
5045
5047#if defined(_WIN32)
5050#endif
5052
5053
5054
5059
5060
5063
5064#if defined(_WIN32)
5065
5066
5067
5068
5069
5070 do {
5073#endif
5074
5075
5077}
5078
5081
5082#ifndef NO_SSL
5084
5088 }
5089#endif
5093 }
5094}
5095
5097#ifndef NO_SSL
5100 }
5101#endif
5103 free(conn);
5104}
5105
5107
5108
5109 return uri[0] == '/' || (uri[0] == '*' && uri[1] == '\0');
5110}
5111
5113 const char *cl;
5114
5120
5128 } else {
5129
5130
5131
5132
5133
5134
5135
5136
5140 }
5143 }
5145 }
5146 return ebuf[0] ==
'\0';
5147}
5148
5153
5155 keep_alive = 0;
5156
5157
5158
5160 do {
5167 }
else if (
strcmp(
ri->http_version,
"1.0") &&
5171 }
5172
5173 if (
ebuf[0] ==
'\0') {
5177 }
5178 if (
ri->remote_user !=
NULL) {
5179 free((
void *)
ri->remote_user);
5180
5181
5183 }
5184
5185
5186
5187
5188
5191
5192
5201 } while (keep_alive);
5202}
5203
5204
5208
5209
5212 }
5213
5214
5216
5220
5221
5225 }
5226 }
5227
5230
5232}
5233
5237
5240 cry(
fc(
ctx),
"%s",
"Cannot create new connection struct, OOM");
5241 } else {
5243 conn->
buf = (
char *) (conn + 1);
5246
5248
5249
5250
5253
5254
5255
5256
5257
5263
5268 ) {
5270 }
5271
5273 }
5275 free(conn);
5276 }
5277
5278
5284
5287}
5288
5289
5292
5293
5297 }
5298
5300
5304 }
5305
5308}
5309
5311#ifdef _WIN32
5313#else
5317#endif
5320}
5321
5329
5335 } else {
5336
5342
5343
5344
5345
5346
5347
5351 }
5352}
5353
5358
5359
5360#if defined(_WIN32)
5362#endif
5363
5364#if defined(ISSUE_317)
5368#endif
5369
5371
5377 }
5378
5381
5382
5383
5384
5387 }
5388 }
5389 }
5390 }
5393
5394
5396
5397
5399
5400
5404 }
5406
5407
5412
5413#if !defined(NO_SSL)
5415#endif
5417
5419
5420
5421
5422
5425}
5426
5429
5430
5434 }
5435
5436#ifndef NO_SSL
5437
5440 }
5444 }
5445#endif
5446
5447
5448 free(ctx);
5449}
5450
5453
5454
5457 }
5459
5460#if defined(_WIN32) && !defined(__SYMBIAN32__)
5462#endif
5463}
5464
5471
5472#if defined(_WIN32) && !defined(__SYMBIAN32__)
5475#endif
5476
5477
5478
5481 }
5484
5487 cry(
fc(ctx),
"Invalid option: %s",
name);
5491 cry(
fc(ctx),
"%s: option value cannot be NULL",
name);
5494 }
5496 cry(
fc(ctx),
"warning: %s: duplicate option",
name);
5498 }
5501 }
5502
5503
5508 }
5509 }
5510
5511
5512
5524 }
5525
5526#if !defined(_WIN32) && !defined(__SYMBIAN32__)
5527
5528
5530#endif
5531
5536
5537
5539
5540
5543 cry(
fc(ctx),
"Cannot start worker thread: %ld", (
long)
ERRNO);
5544 } else {
5546 }
5547 }
5548
5549 return ctx;
5550}
5551
5552#ifdef USE_LUA
5553#ifdef _WIN32
5560 return p;
5561}
5562#define munmap(x, y) UnmapViewOfFile(x)
5563#define MAP_FAILED NULL
5564#define MAP_PRIVATE 0
5565#define PROT_READ 0
5566#else
5567#include <sys/mman.h>
5568#endif
5569
5570static const char *
LUASOCKET =
"luasocket";
5571
5572
5575
5580}
5581
5586}
5587
5594}
5595
5600 } else {
5602 }
5603 return 1;
5604}
5605
5607 char buf[2000];
5609
5615 } else {
5617 }
5618 } else {
5620 }
5621 return 1;
5622}
5623
5625 const char *buf;
5626 size_t len, sent = 0;
5628
5633 while (sent < len) {
5634 if ((
n =
send(sock, buf + sent, len - sent, 0)) <= 0) {
5635 break;
5636 }
5638 }
5640 } else {
5642 }
5643 return 1;
5644}
5645
5651};
5652
5656
5662 } else {
5668 }
5669 } else {
5670 return luaL_error(
L,
"connect(host,port,is_ssl): invalid parameter given.");
5671 }
5672 return 1;
5673}
5674
5680 return 0;
5681}
5682
5683
5692}
5693
5698
5699 for (
i = 0;
i < len;
i++) {
5700 if (p[
i] ==
'\n')
lines++;
5701 if (p[
i] ==
'<' && p[
i + 1] ==
'?') {
5702 for (
j =
i + 1;
j < len ;
j++) {
5704 if (p[
j] ==
'?' && p[
j + 1] ==
'>') {
5706
5711
5713 } else {
5714
5716 }
5717
5720 break;
5721 }
5722 }
5726 }
5727 }
5728 }
5729
5732 }
5733
5734 return 0;
5735}
5736
5740 size_t size;
5742
5748 }
5749 }
5750
5751 return 0;
5752}
5753
5758
5759 if (len <= 0) return 0;
5761
5762 return 1;
5763}
5764
5765
5770
5771
5773 }
5774 return 0;
5775}
5776
5777
5781 return 0;
5782}
5783
5784
5790 return 0;
5791}
5792
5797
5799#ifdef USE_LUA_SQLITE3
5801#endif
5802
5809
5810 if (conn ==
NULL)
return;
5811
5812
5814
5821
5822
5834 for (
i = 0;
i <
ri->num_headers;
i++) {
5836 }
5839
5841
5842
5843 luaL_dostring(
L,
"mg.onerror = function(e) mg.write('\\nLua error:\\n', "
5844 "debug.traceback(e, 1)) end");
5845}
5846
5849
5857 } else {
5860 }
5861
5862
5863 return 0;
5864}
5865
5870
5874
5881 }
5882 }
5883
5886 }
5889 }
5890}
5891
5893 const char *fmt, ...) {
5896
5900
5903 } else {
5906 }
5907}
5908
5914 int error = 1;
5915
5916
5925 } else {
5926
5929 }
5930 error =
lsp(conn, path, p,
filep->size,
L);
5931 }
5932
5936
5937 return error;
5938}
5939#endif
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_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)
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 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 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 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)
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 const char * http_500_error
static int set_acl_option(struct mg_context *ctx)
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)