86#define FUZZ_HARNESS_NAME "fuzz_request"
90#include <sys/socket.h>
91#include <netinet/in.h>
92#include <sys/select.h>
98#if defined(__GNUC__) || defined(__clang__)
99#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
107#if defined(__linux__)
109#if defined(MFD_CLOEXEC)
110#define FUZZ_HAVE_MEMFD 1
114#define MAX_SEGMENTS 96
115#define MAX_CONNECTIONS 8
116#define RESP_BUF_SIZE 16384
117#define GEN_BUF_SIZE 8192
118#define MAX_EXPECT_BODY 4096
121#define RESP_KIND_COUNT 16
123#define DAUTH_VARIANT_COUNT 10
125#define MAX_DIGEST_BIN 64
127#define DIGEST_REALM "TestRealm"
128#define DIGEST_USER "user"
129#define DIGEST_PASS "pass"
139 unsigned int insanity;
140 unsigned int nonce_nc_size;
151 unsigned int resp_kind;
152 unsigned int resp_nhdr;
155 unsigned int dauth_variant;
156 unsigned int fail_variant;
159 unsigned int loop_mode;
166 unsigned int suspend_mode;
168 unsigned int upgrade_action;
173static struct fuzz_cfg
cfg;
200 "%s: daemons=%lu handler calls=%lu (final=%lu) body bytes=%lu "
201 "401 challenges=%lu authenticated=%lu\n",
213 0 , 128, 192, 256, 320, 384, 512, 768, 1024, 1400, 1500,
256static const unsigned int nnc_tbl[] = { 4, 1, 8, 64 };
260 "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
261 "\xfe\xdc\xba\x98\x76\x54\x32\x10\xfe\xdc\xba\x98\x76\x54\x32\x10";
366static const char resp_body[] =
"hello world, this is the response body";
367#define RESP_BODY_LEN (sizeof (resp_body) - 1)
390 "X-Fuzz",
"Content-Type",
"Cache-Control",
"Accept-Ranges",
393 "Connection",
"Set-Cookie",
"X-\x01" "Bad",
"",
"Trailer",
"Date",
394 "X-Fuzz",
"Server",
"Location",
"ETag",
"Vary",
"Age"
398 "1",
"text/plain",
"no-cache",
"bytes",
"keep-alive",
"a=b",
399 "x\r\nInjected: yes",
"",
"X-Fuzz",
"Thu, 01 Jan 1970 00:00:00 GMT",
400 "\x7f",
"mhd",
"/",
"\"tag\"",
"*",
"0"
403#define HDR_COUNT (sizeof (hdr_names) / sizeof (hdr_names[0]))
416 unsigned int pattern;
426 struct crc_state *st = (
struct crc_state *) cls;
435 if ( (0 <= st->err_at) &&
436 (st->calls > st->err_at) )
438 if (pos >= st->total)
440 n = (size_t) (st->total - pos);
445 for (i = 0; i < n; i++)
446 buf[i] = (
char) (
'a' + (int) ((pos + i + st->pattern) % 26));
473 const char *extra_in,
474 size_t extra_in_size,
476 struct MHD_UpgradeResponseHandle *urh)
478 volatile size_t sink = 0;
484 if ( (
NULL != extra_in) &&
485 (0 != extra_in_size) )
486 sink += (size_t) (
unsigned char) extra_in[extra_in_size - 1];
488 if (0 != (
cfg.upgrade_action & 0x01u))
490 if (0 != (
cfg.upgrade_action & 0x02u))
506#ifdef FUZZ_HAVE_MEMFD
509 fd = memfd_create (
"mhd-fuzz", MFD_CLOEXEC);
537 (void) close (pf[0]);
538 (void) close (pf[1]);
541 (void) close (pf[1]);
559 for (i = 0; i <
cfg.resp_nhdr; i++)
567 unsigned int k = (
unsigned int) (
cfg.hdr_seed + 1u) %
HDR_COUNT;
571 if (
cfg.resp_hdr_api)
574 volatile size_t sink = 0;
585 (((
cfg.hdr_seed & 0x01) ?
587 | ((
cfg.hdr_seed & 0x02) ?
589 | ((
cfg.hdr_seed & 0x04) ?
592 | ((
cfg.hdr_seed & 0x08) ?
613 struct crc_state *st;
617 switch (
cfg.resp_kind)
624 if (
cfg.chunked_reply)
687 st = (
struct crc_state *) calloc (1,
sizeof (
struct crc_state));
690 st->total = (uint64_t) (1u + (
cfg.crc_seed & 0x7Fu));
691 st->pattern =
cfg.crc_seed;
694 st->err_at = (0 != (
cfg.crc_seed & 0x80u))
695 ? (
int) (1u + (
cfg.crc_seed & 0x03u))
699 (
size_t) (16u + (
cfg.crc_seed & 0x3Fu)),
715 if (11 ==
cfg.resp_kind)
717 else if (12 ==
cfg.resp_kind)
755 (0 != iov[2].
iov_len) ? 3u : 2u,
785 volatile size_t sink = 0;
790 sink += strlen (key);
792 sink += strlen (value);
812 volatile size_t sink = 0;
816 if ( (
NULL != key) && (0 != key_size) )
817 sink += (size_t) (
unsigned char) key[key_size - 1];
818 if ( (
NULL != value) && (0 != value_size) )
819 sink += (size_t) (
unsigned char) value[value_size - 1];
829 const char *filename,
831 const char *transfer_encoding,
836 volatile size_t sink = 0;
842 sink += strlen (key);
843 if (
NULL != filename)
844 sink += strlen (filename);
847 if (
NULL != transfer_encoding)
848 sink += strlen (transfer_encoding);
849 if ( (
NULL !=
data) && (0 != size) )
850 sink += (size_t) (
unsigned char)
data[size - 1];
875 "request body desync: the bytes MHD delivered to the application "
876 "differ from the body encoded in the generated request "
877 "(chunked/Content-Length framing bug, cf. HTTP request smuggling)");
878 hs->body_off += size;
905#define DAUTH_CHALLENGE 0
906#define DAUTH_PASSED 1
938 claim = hs - (size_t) (
cfg.crc_seed % (
unsigned int) (hs + 1u));
940 bin = malloc (claim);
957 claim = (2u * hs + 1u)
958 - (
size_t) (
cfg.hdr_seed % (
unsigned int) (2u * hs + 2u));
959 hex = (
char *) malloc (claim);
987 unsigned int variant =
cfg.dauth_variant;
992 volatile size_t sink = 0;
1056 a3 = (0 != (
cfg.hdr_seed & 0x01))
1060 a3 = digest_algos[
cfg.hdr_seed
1061 % (
sizeof (digest_algos)
1062 /
sizeof (digest_algos[0]))];
1065 (hs >
sizeof (ud)) ||
1147 sink += (size_t) ai->
nc;
1187 switch (
cfg.fail_variant)
1205 if (0 != (
cfg.hdr_seed & 0x01))
1221 "0123456789abcdef" ,
1249 volatile size_t sink = 0;
1251 if (
cfg.conn_lookup)
1253 static const char *
const keys[] = {
1254 "Host",
"Content-Length",
"Transfer-Encoding",
"Authorization",
1255 "Cookie",
"",
"X-Fuzz",
"connection"
1257 const char *k = keys[
cfg.hdr_seed % (
sizeof (keys) /
sizeof (keys[0]))];
1259 const char *vp =
NULL;
1261 const char *uri =
NULL;
1277 if (
cfg.conn_setvalue)
1302 for (i = 0; i <
sizeof (cinfo) /
sizeof (cinfo[0]); i++)
1305 for (i = 0; i <
sizeof (dinfo) /
sizeof (dinfo[0]); i++)
1310 if (
cfg.conn_option)
1313 (
unsigned int) (
cfg.crc_seed & 0x0F));
1346 if ( (0 ==
cfg.suspend_mode) ||
1350 if (1 ==
cfg.suspend_mode)
1364 const char *version,
1365 const char *upload_data,
1366 size_t *upload_data_size,
1369 struct hstate *hs = (
struct hstate *) *req_cls;
1372 volatile size_t sink = 0;
1373 const char *conn_hdr =
NULL;
1380 hs = (
struct hstate *) calloc (1,
sizeof (
struct hstate));
1390 sink += strlen (url);
1392 sink += strlen (method);
1393 if (
NULL != version)
1394 sink += strlen (version);
1397 if (0 != *upload_data_size)
1401 if (
cfg.do_postproc)
1403 if ( (
NULL == hs->pp) &&
1415 *upload_data_size = 0;
1429 if (0 != (
cfg.hdr_seed & 0x10))
1438 "request body truncated: MHD completed the request but delivered "
1439 "fewer body bytes than the generated request contained");
1448 if (
cfg.allow_upgrade)
1453 if (
NULL != conn_hdr)
1457 for (i = 0; (i + 1 <
sizeof (conn_lc)) && (
'\0' != conn_hdr[i]); i++)
1458 conn_lc[i] = (
char) (( (
'A' <= conn_hdr[i]) && (
'Z' >= conn_hdr[i]))
1459 ? (conn_hdr[i] -
'A' +
'a') : conn_hdr[i]);
1475 sink += strlen (user);
1477 sink += strlen (pass);
1499 if (
cfg.calc_helpers)
1533 if (
cfg.allow_upgrade &&
1534 (
NULL != version) &&
1539 (
NULL != conn_hdr) &&
1540 (
NULL != strstr (conn_lc,
"upgrade")) &&
1541 (
NULL == strstr (conn_lc,
"close")))
1592 struct hstate *hs = (
struct hstate *) *req_cls;
1617 (void) snprintf (msg,
sizeof (msg),
1618 "MHD_PANIC() reached from network input at %s:%u: %s",
1619 (
NULL != file) ? file :
"?",
1621 (
NULL != reason) ? reason :
"?");
1642 n = recv (sock, tmp,
sizeof (tmp), MSG_DONTWAIT);
1656 while (
NULL != (p = strstr (p,
"nonce=\"")))
1658 const char *s = p + 7;
1659 const char *e = strchr (s,
'"');
1664 if ((
size_t) (e - s) <
sizeof (
nonce_val))
1666 memcpy (
nonce_val, s, (
size_t) (e - s));
1700 if (0 ==
cfg.loop_mode)
1708 if (1 ==
cfg.loop_mode)
1724 (
unsigned int) FD_SETSIZE))
1730 if (
cfg.use_timeouts)
1734 volatile int64_t sink;
1745 (void) select ((
int) max_fd + 1, &rs, &ws, &es, &tv);
1746 if (1 ==
cfg.loop_mode)
1756 unsigned int rounds)
1760 for (i = 0; i < rounds; i++)
1785 static const char tok[] =
"%%NONCE%%";
1786 const size_t tok_len =
sizeof (tok) - 1;
1792 if ( (i + tok_len <= in_len) &&
1793 (0 == memcmp (in + i, tok, tok_len)) )
1813 const uint8_t *
data,
1817 unsigned int stall = 0;
1819 while ( (off < len) &&
1822 ssize_t s = send (sock,
data + off, len - off, MSG_DONTWAIT);
1833 (EAGAIN != errno) &&
1834 (EWOULDBLOCK != errno) &&
1846 struct sockaddr_in sa;
1848 if (0 != socketpair (AF_UNIX, SOCK_STREAM, 0, sv))
1850 memset (&sa, 0,
sizeof (sa));
1851 sa.sin_family = AF_INET;
1852 sa.sin_port = htons (44444);
1853 sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1856 (
const struct sockaddr *) &sa,
1857 (socklen_t)
sizeof (sa)))
1860 (void) close (sv[0]);
1874 (void) shutdown (*sock, SHUT_WR);
1876 (void) close (*sock);
1891 unsigned int nopt = 0;
1895 unsigned int nseg = 0;
1896 unsigned int nconn = 1;
1917 memset (&
cfg, 0,
sizeof (
cfg));
1921 cfg.do_digest = (0 != (
data[1] & 0x01));
1922 cfg.do_basic = (0 != (
data[1] & 0x02));
1923 cfg.do_postproc = (0 != (
data[1] & 0x04));
1924 cfg.do_iterate = (0 != (
data[1] & 0x08));
1929 cfg.chunked_reply = (0 != (
data[1] & 0x20));
1930 cfg.error_reply = (0 != (
data[1] & 0x40));
1933 const char *e = getenv (
"MHD_FUZZ_MIN_MEM_LIMIT");
1939 if ( (0 !=
cfg.mem_limit) &&
1944 const char *e = getenv (
"MHD_FUZZ_MIN_DISCIPLINE");
1957 cfg.qop = (0 != (
data[3] & 0x04))
1962 cfg.resp_kind = (
unsigned int) (
data[4] & 0x0F);
1963 cfg.resp_nhdr = (
unsigned int) ((
data[4] >> 4) & 0x03);
1964 cfg.resp_footer = (0 != (
data[4] & 0x40));
1965 cfg.resp_hdr_api = (0 != (
data[4] & 0x80));
1968 cfg.fail_variant = (
unsigned int) ((
data[5] >> 4) & 0x03);
1969 cfg.basic_v1 = (0 != (
data[5] & 0x40));
1970 cfg.calc_helpers = (0 != (
data[5] & 0x80));
1972 cfg.loop_mode = (
unsigned int) (
data[6] & 0x03);
1973 cfg.use_timeouts = (0 != (
data[6] & 0x04));
1974 cfg.conn_lookup = (0 != (
data[6] & 0x08));
1975 cfg.conn_setvalue = (0 != (
data[6] & 0x10));
1976 cfg.conn_info = (0 != (
data[6] & 0x20));
1977 cfg.conn_option = (0 != (
data[6] & 0x40));
1978 cfg.quiesce = (0 != (
data[6] & 0x80));
1982 cfg.suspend_mode = (
unsigned int) (
data[7] & 0x03);
1983 if (3 ==
cfg.suspend_mode)
1984 cfg.suspend_mode = 1;
1986 (0 != (
data[7] & 0x04)) &&
1988 cfg.upgrade_action = (
unsigned int) ((
data[7] >> 3) & 0x03);
2000 if (0 !=
cfg.mem_limit)
2003 opts[nopt].
value = (intptr_t)
cfg.mem_limit;
2008 opts[nopt].
value = (intptr_t)
cfg.discipline;
2012 opts[nopt].
value = (intptr_t)
cfg.insanity;
2016 opts[nopt].
value = (intptr_t)
cfg.nonce_nc_size;
2024 opts[nopt].
value = 0;
2030 if (0 !=
cfg.suspend_mode)
2032 if (
cfg.allow_upgrade)
2065 while ( (pos + 2 <= size) &&
2068 unsigned int hdr = (
unsigned int)
data[pos]
2069 | ((
unsigned int)
data[pos + 1] << 8);
2070 unsigned int op = hdr >> 14;
2071 size_t slen = (size_t) (hdr & 0x3FFF);
2076 if (slen > size - pos)
2104 pump (d, sock, (2 ==
op) ? 12u : 3u);
2154 if (b->len + n > b->cap)
2155 n = b->cap - b->len;
2156 memcpy (b->p + b->len, v, n);
2165 sb_raw (b, s, strlen (s));
2173 unsigned int min_digits)
2180 unsigned int dig = (
unsigned int) (v % (hex ? 16u : 10u));
2181 tmp[n++] = (char) ((dig < 10) ? (
'0' + dig) : (
'a' + dig - 10));
2182 v /= (hex ? 16u : 10u);
2184 while ( (0 != v) && (n <
sizeof (tmp)) );
2185 while ( (n < min_digits) && (n <
sizeof (tmp)) )
2196 "GET",
"POST",
"PUT",
"HEAD",
"DELETE",
"OPTIONS",
"TRACE",
"PATCH",
2197 "CONNECT",
"BREW",
"get",
"M-SEARCH",
"\tGET",
"GET "
2201 "HTTP/1.1",
"HTTP/1.0",
"HTTP/1.1",
"HTTP/1.1",
"HTTP/0.9",
"HTTP/1.2",
2202 "HTTP/2.0",
"http/1.1",
"HTTP/1.",
"HTTP/11"
2206 "/",
"/a",
"/a/b/c",
"/a?x=1",
"/a?x=1&y=2",
"/?novalue",
"/?a=1&b",
2207 "/?a&b&c",
"/%41%42",
"/a%00b",
"/%zz",
"/a?%41=%42",
"*",
2208 "http://example.org/a",
"/a?x=1&novalue",
"/..%2f..%2fetc",
2209 "/a?=",
"/a?&",
"/very/long/path/that/keeps/going/and/going/and/going"
2213 "Host",
"Accept",
"User-Agent",
"Connection",
"Cookie",
"Content-Type",
2214 "Expect",
"TE",
"Trailer",
"X-Custom",
"Referer",
"Accept-Encoding",
2215 "content-length",
"transfer-encoding",
"X-A-Very-Long-Header-Name-Indeed"
2219 "example.org",
"*/*",
"fuzz/1.0",
"keep-alive",
"close",
2220 "a=1; b=2; c",
"100-continue",
"trailers",
"X-Trail",
"value",
2221 "",
" ",
"\ttabbed",
"a, b, c",
"chunked",
"identity, chunked"
2226 "MD5",
"SHA-256",
"SHA-512-256",
"MD5-sess",
"SHA-256-sess",
2227 "SHA-512-256-sess",
"sha-256",
"SHA256",
"BOGUS",
"",
"\"SHA-256\"",
2228 "MD5 ",
"SHA-1",
"xyzzy",
"SHA-512",
"\"BOGUS\"",
"0"
2232 "application/x-www-form-urlencoded",
2233 "multipart/form-data; boundary=--abc",
2234 "multipart/form-data; boundary=\"XY\"",
2235 "multipart/form-data",
2248 int force_trailing_novalue)
2253 if ( (0 == n) && (! force_trailing_novalue) )
2256 for (i = 0; i < n; i++)
2268 if (force_trailing_novalue)
2284 for (i = 0; i < n; i++)
2288 /
sizeof (
char *)))]);
2294 /
sizeof (
char *)))]);
2296 sb_str (b,
"\r\n\tfolded-continuation");
2318 unsigned int nchunks = 1 +
fuzz_below (rng, 4);
2323 for (i = 0; i < nchunks; i++)
2325 unsigned int clen = 1 +
fuzz_below (rng, 24);
2342 sb_str (b,
";ext=\"quoted value\"");
2345 sb_str (b,
";a=1;b=2;c");
2348 sb_str (b,
";x=\"a;b\"");
2353 for (j = 0; j < clen; j++)
2355 char c = (char) (
'A' + ((i * 7 + j) % 26));
2365 sb_str (b,
";final=\"x\"");
2368 sb_str (b,
"X-Trailer: value\r\n");
2377 int use_nonce_token,
2378 int overlong_response,
2384 sb_str (b,
"Authorization: Digest ");
2385 sb_str (b,
"username=\"");
2389 unsigned int n = 2 * (16 +
fuzz_below (rng, 48));
2390 for (i = 0; i < n; i++)
2397 sb_str (b,
"userhash=true, ");
2401 sb_str (b,
"\", nonce=\"");
2402 if (use_nonce_token)
2407 for (i = 0; i < n; i++)
2410 sb_str (b,
"\", uri=\"");
2416 sb_str (b,
", cnonce=\"deadbeef\", algorithm=");
2422 /
sizeof (
char *)))]);
2423 sb_str (b,
", opaque=\"0123456789abcdef\", response=\"");
2424 if (overlong_response)
2428 for (i = 0; i < nresp; i++)
2430 char c =
"0123456789abcdef"[
fuzz_below (rng, 16)];
2483 sb_str (b,
"POST /a HTTP/1.1\r\nHost: x\r\nContent-Length: ");
2487 for (i = 0; i < blen; i++)
2489 char c = (char) (
'a' + (i % 26));
2499 sb_str (b,
"POST /a HTTP/1.1\r\nHost: x\r\n"
2500 "Transfer-Encoding: chunked\r\n\r\n");
2505 sb_str (b,
"GET /a HTTP/1.1\r\nHost: x\r\n");
2511 if (! second_of_pair)
2512 sb_str (b,
"GET /a HTTP/1.1\r\nHost: x\r\n\r\n");
2515 sb_str (b,
"GET /a HTTP/1.1\r\nHost: x\r\n");
2522 sb_str (b,
"GET /a HTTP/1.1\r\nHost: x\r\nAuthorization: Basic ");
2527 for (i = 0; i < n; i++)
2530 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
2543 /
sizeof (
char *)))];
2545 sb_str (b,
"POST /a HTTP/1.1\r\nHost: x\r\nContent-Type: ");
2547 sb_str (b,
"\r\nTransfer-Encoding: chunked\r\n\r\n");
2555 /
sizeof (
char *)))]);
2559 /
sizeof (
char *)))]);
2563 /
sizeof (
char *)))]);
2575 sb_str (b,
" HTTP/1.1\r\n");
2590 const uint8_t *body,
2597 while (off < body_len)
2616 chunk = body_len - off;
2619 if (chunk > body_len - off)
2620 chunk = body_len - off;
2623 op = (first && new_conn_first) ? 3u : (
fuzz_chance (rng, 4) ? 2u : 0u);
2624 hv = (
op << 14) | (
unsigned int) chunk;
2625 hdr[0] = (uint8_t) (hv & 0xFF);
2626 hdr[1] = (uint8_t) (hv >> 8);
2627 if (out->len + 2 + chunk > out->cap)
2630 sb_raw (out, body + off, chunk);
2646 uint8_t cfg_bytes[4];
2659 const char *e = getenv (
"MHD_FUZZ_SHAPE");
2679 cfg_bytes[0] = (uint8_t) (1 +
fuzz_below (rng, 9));
2683 cfg_bytes[0] = (uint8_t) (
fuzz_chance (rng, 2) ? 0 : 12);
2684 cfg_bytes[1] = (uint8_t) ((cfg_bytes[1] | 0x01u) & ~0x04u);
2687 cfg_bytes[3] = (uint8_t) ((cfg_bytes[3] & 0xF0u) | 0x00u);
2690 cfg_bytes[1] |= 0x04u;
2694 cfg_bytes[1] &= (uint8_t) ~0x04u;
2699 cfg_bytes[1] |= 0x08u;
2700 sb_raw (&out, cfg_bytes, 4);
2705 for (i = 0; i < nreq; i++)
2709 rb.cap =
sizeof (req);
2717 hdr[0] = (uint8_t) (hv & 0xFF);
2718 hdr[1] = (uint8_t) (hv >> 8);
2748 unsigned char cfg[4];
2749 struct seed_part parts[4];
2753 unsigned char ext[6];
2756#define P_END { 0, NULL }
2762 {
"content-length-body", { 0x00, 0x08, 0x03, 0x00 },
2764 { 0,
"POST /a HTTP/1.1\r\nHost: x\r\nContent-Length: 5\r\n\r\nhello" },
2769 {
"chunked-with-extensions", { 0x00, 0x08, 0x03, 0x00 },
2771 { 0,
"POST /a HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n"
2772 "\r\n2;ext=val\r\nAB\r\n3;a=\"b;c\"\r\nCDE\r\n0\r\n\r\n" },
2775 {
"chunked-split", { 0x00, 0x08, 0x03, 0x00 },
2777 { 0,
"POST /a HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n"
2778 "\r\n3\r\nABC\r\n3;x=\"y\"" },
2779 { 2,
"\r\nDEF\r\n0\r\n\r\n" },
2784 {
"small-pool-trailing-query-arg", { 0x06, 0x08, 0x03, 0x00 },
2787 {
"small-pool-trailing-query-arg-2", { 0x03, 0x08, 0x03, 0x00 },
2792 {
"digest-unknown-algorithm", { 0x00, 0x09, 0x03, 0x00 },
2793 { { 0,
"GET /a HTTP/1.1\r\nHost: x\r\nAuthorization: Digest "
2794 "username=\"user\", realm=\"TestRealm\", nonce=\"0000\", "
2795 "uri=\"/a\", algorithm=BOGUS, response=\"00\"\r\n\r\n" },
2800 {
"digest-overlong-response", { 0x00, 0x09, 0x03, 0x00 },
2801 { { 0,
"GET /a HTTP/1.1\r\nHost: x\r\n\r\n" },
2802 { 3,
"GET /a HTTP/1.1\r\nHost: x\r\nAuthorization: Digest "
2803 "username=\"user\", realm=\"TestRealm\", nonce=\"%%NONCE%%\", "
2804 "uri=\"/a\", qop=auth, nc=00000001, cnonce=\"deadbeef\", "
2805 "algorithm=SHA-256, response=\""
2806 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
2807 "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
2811 {
"digest-userhash", { 0x00, 0x09, 0x03, 0x00 },
2812 { { 0,
"GET /a HTTP/1.1\r\nHost: x\r\n\r\n" },
2813 { 3,
"GET /a HTTP/1.1\r\nHost: x\r\nAuthorization: Digest "
2815 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
2816 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
2817 "\", userhash=true, realm=\"TestRealm\", nonce=\"%%NONCE%%\", "
2818 "uri=\"/a\", qop=auth, nc=00000001, cnonce=\"deadbeef\", "
2819 "algorithm=SHA-256, response=\"0123456789abcdef\"\r\n\r\n" },
2822 {
"basic-auth", { 0x00, 0x0a, 0x03, 0x00 },
2823 { { 0,
"GET /a HTTP/1.1\r\nHost: x\r\n"
2824 "Authorization: Basic dXNlcjpwYXNz\r\n\r\n" },
2827 {
"multipart-post", { 0x00, 0x0c, 0x03, 0x00 },
2828 { { 0,
"POST /a HTTP/1.1\r\nHost: x\r\n"
2829 "Content-Type: multipart/form-data; boundary=--abc\r\n"
2830 "Transfer-Encoding: chunked\r\n\r\n"
2831 "52\r\n----abc\r\nContent-Disposition: form-data; name=\"k\"\r\n\r\n"
2832 "value\r\n----abc--\r\n\r\n0\r\n\r\n" },
2835 {
"urlencoded-post", { 0x00, 0x0c, 0x03, 0x00 },
2836 { { 1,
"a=1&b=%41&c" },
2837 { 0,
"POST /a HTTP/1.1\r\nHost: x\r\n"
2838 "Content-Type: application/x-www-form-urlencoded\r\n"
2839 "Content-Length: 11\r\n\r\na=1&b=%41&c" },
2842 {
"folded-header", { 0x00, 0x08, 0x00, 0x00 },
2843 { { 0,
"GET /a HTTP/1.1\r\nHost: x\r\nX-Fold: a\r\n\tb\r\n\r\n" },
2846 {
"pipelined", { 0x00, 0x08, 0x03, 0x00 },
2847 { { 0,
"GET /a HTTP/1.1\r\nHost: x\r\n\r\n"
2848 "GET /b?q HTTP/1.1\r\nHost: x\r\n\r\n" },
2863 {
"ext-callback-chunked", { 0x00, 0x08, 0x03, 0x00 },
2865 { 0x0A | 0x20 | 0x40, 0x00, 0x00, 0x00, 0x01, 0x20 } },
2869 {
"ext-callback-error", { 0x00, 0x08, 0x03, 0x00 },
2871 { 0x09, 0x00, 0x00, 0x00, 0x02, 0x82 } },
2873 {
"ext-fd-response", { 0x00, 0x08, 0x03, 0x00 },
2875 { 0x0B, 0x00, 0x00, 0x00, 0x00, 0x10 } },
2877 {
"ext-fd-at-offset-response", { 0x00, 0x08, 0x03, 0x00 },
2879 { 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10 } },
2881 {
"ext-pipe-response", { 0x00, 0x08, 0x03, 0x00 },
2883 { 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10 } },
2885 {
"ext-iovec-response", { 0x00, 0x08, 0x03, 0x00 },
2887 { 0x0F, 0x00, 0x00, 0x00, 0x00, 0x07 } },
2890 {
"ext-empty-response-hdrapi", { 0x00, 0x08, 0x03, 0x00 },
2892 { 0x02 | 0x30 | 0x40 | 0x80, 0x00, 0x00, 0x00, 0x05, 0x00 } },
2895 {
"ext-digest-check-digest3", { 0x00, 0x09, 0x03, 0x00 },
2896 { { 0,
"GET / HTTP/1.1\r\nHost: x\r\n\r\n" },
2897 { 0,
"GET / HTTP/1.1\r\nHost: x\r\nAuthorization: Digest "
2898 "username=\"user\", realm=\"TestRealm\", nonce=\"%%NONCE%%\", "
2899 "uri=\"/\", response=\"00000000000000000000000000000000\"\r\n\r\n" },
2901 { 0x00, 0x05 | 0x80, 0x00, 0x00, 0x01, 0x00 } },
2904 {
"ext-digest-v1-wrappers", { 0x00, 0x09, 0x03, 0x00 },
2906 { 0x00, 0x01 | 0x10, 0x00, 0x00, 0x00, 0x00 } },
2908 {
"ext-digest-request-info", { 0x00, 0x09, 0x03, 0x00 },
2910 { 0x00, 0x08 | 0x20, 0x00, 0x00, 0x03, 0x00 } },
2914 {
"ext-external-event-loop", { 0x00, 0x08, 0x03, 0x00 },
2916 { 0x01, 0x00, 0x02 | 0x04, 0x00, 0x00, 0x00 } },
2919 {
"ext-external-event-loop-v1", { 0x00, 0x08, 0x03, 0x00 },
2921 { 0x01, 0x00, 0x01 | 0x04, 0x00, 0x00, 0x00 } },
2924 {
"ext-connection-api", { 0x00, 0x08, 0x03, 0x00 },
2925 { { 0,
"GET /path?a=1 HTTP/1.1\r\nHost: x\r\nCookie: a=b\r\n\r\n" },
2927 { 0x01, 0x00, 0x08 | 0x10 | 0x20 | 0x40 | 0x80, 0x00, 0x10, 0x00 } },
2930 {
"ext-suspend-resume", { 0x00, 0x08, 0x03, 0x00 },
2931 { { 0,
"GET / HTTP/1.1\r\nHost: x\r\n\r\n" },
2933 { 0x01, 0x00, 0x00, 0x02, 0x00, 0x00 } },
2941 {
"ext-suspend-two-connections", { 0x00, 0x08, 0x03, 0x00 },
2942 { { 0,
"GET /a HTTP/1.1\r\nHost: x\r\n\r\n" },
2943 { 3,
"GET /b HTTP/1.1\r\nHost: x\r\n\r\n" },
2945 { 0x01, 0x00, 0x00, 0x02, 0x00, 0x00 } },
2949 {
"ext-upgrade", { 0x00, 0x08, 0x03, 0x00 },
2950 { { 0,
"GET / HTTP/1.1\r\nHost: x\r\nConnection: Upgrade\r\n"
2951 "Upgrade: fuzz-protocol\r\n\r\n" },
2953 { 0x01, 0x00, 0x00, 0x04 | 0x08, 0x00, 0x00 } },
2959 {
"ext-buffer-persistent", { 0x00, 0x08, 0x03, 0x00 },
2961 { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 } },
2963 {
"ext-buffer-free-callback", { 0x00, 0x08, 0x03, 0x00 },
2965 { 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 } },
2967 {
"ext-from-data", { 0x00, 0x08, 0x03, 0x00 },
2969 { 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 } },
2971 {
"ext-fd64-response", { 0x00, 0x08, 0x03, 0x00 },
2973 { 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00 } },
2977 {
"ext-basic-auth-v1", { 0x00, 0x0a, 0x03, 0x00 },
2978 { { 0,
"GET / HTTP/1.1\r\nHost: x\r\n"
2979 "Authorization: Basic dXNlcjpwYXNz\r\n\r\n" },
2981 { 0x01, 0x40, 0x00, 0x00, 0x00, 0x00 } },
2985 {
"ext-basic-auth-challenge", { 0x00, 0x09, 0x03, 0x00 },
2987 { 0x01, 0x30, 0x00, 0x00, 0x00, 0x00 } },
2989 {
"ext-basic-auth-challenge-utf8", { 0x00, 0x09, 0x03, 0x00 },
2991 { 0x01, 0x30, 0x00, 0x00, 0x03, 0x00 } },
2995 {
"ext-digest-check-digest-v1", { 0x00, 0x09, 0x03, 0x00 },
2997 { 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } },
2999 {
"ext-digest-check-digest2", { 0x00, 0x09, 0x03, 0x00 },
3001 { 0x01, 0x04, 0x00, 0x00, 0x01, 0x00 } },
3004 {
"ext-digest-get-username-v1", { 0x00, 0x09, 0x03, 0x00 },
3005 { { 0,
"GET / HTTP/1.1\r\nHost: x\r\n"
3006 "Authorization: Digest username=\"user\", realm=\"TestRealm\"\r\n\r\n" }
3009 { 0x01, 0x06, 0x00, 0x00, 0x00, 0x00 } },
3011 {
"ext-digest-get-username3", { 0x00, 0x09, 0x03, 0x00 },
3012 { { 0,
"GET / HTTP/1.1\r\nHost: x\r\n"
3013 "Authorization: Digest userhash=true, username=\"aabb\", "
3014 "realm=\"TestRealm\"\r\n\r\n" },
3016 { 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 } }
3029static const uint8_t *
3033 const struct seed_def *sd = &
seeds[idx];
3041 sb_raw (&b, sd->ext, sizeof (sd->ext));
3042 for (i = 0; i <
sizeof (sd->parts) /
sizeof (sd->parts[0]); i++)
3048 if (
NULL == sd->parts[i].txt)
3050 n = strlen (sd->parts[i].txt);
3053 hv = (sd->parts[i].op << 14) | (
unsigned int) n;
3054 hdr[0] = (uint8_t) (hv & 0xFF);
3055 hdr[1] = (uint8_t) (hv >> 8);
3057 sb_raw (&b, sd->parts[i].txt, n);
Shared, header-only fuzzing driver for the MHD in-process fuzzers.
static FUZZ_UNUSED int fuzz_pristine
static FUZZ_UNUSED void fuzz_ignore_sigpipe(void)
static FUZZ_UNUSED int fuzz_verbose
static FUZZ_UNUSED uint32_t fuzz_below(struct fuzz_rng *r, uint32_t n)
static FUZZ_UNUSED uint8_t fuzz_byte(struct fuzz_rng *r)
static FUZZ_UNUSED void fuzz_report_finding(const char *what)
static FUZZ_UNUSED int fuzz_chance(struct fuzz_rng *r, uint32_t n)
static void pending_resume_add(struct MHD_Connection *c)
static void emit_segments(struct fuzz_rng *rng, struct sbuf *out, const uint8_t *body, size_t body_len, int new_conn_first)
static void suspend_maybe(struct MHD_Connection *connection)
static size_t fuzz_seed_count(void)
static const char *const gen_hdr_values[]
static void pump(struct MHD_Daemon *d, int sock, unsigned int rounds)
static void run_once(struct MHD_Daemon *d)
static void send_all(struct MHD_Daemon *d, int sock, const uint8_t *data, size_t len)
static int gen_one_request(struct fuzz_rng *rng, struct sbuf *b, enum gen_shape shape, int second_of_pair)
static const struct seed_def seeds[]
static int stats_registered
static void sb_u64(struct sbuf *b, uint64_t v, int hex, unsigned int min_digits)
static const char *const gen_targets[]
static unsigned long stat_daemons
static void gen_query(struct fuzz_rng *rng, struct sbuf *b, int force_trailing_novalue)
static enum MHD_DigestAuthAlgorithm algo1_tbl[]
static enum MHD_Result queue_auth_challenge(struct MHD_Connection *connection, int stale)
static int new_connection(struct MHD_Daemon *d, int *sock)
static enum MHD_Result kv_iter(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
static char resp_buf[RESP_BUF_SIZE]
static int make_memfd(void)
static void sb_str(struct sbuf *b, const char *s)
static const char *const gen_ctypes[]
static void decorate_response(struct MHD_Response *r)
static uint8_t expect_body[MAX_EXPECT_BODY]
static void pending_resume_drop(const struct MHD_Connection *c)
static int min_discipline_read
#define FUZZ_HARNESS_NAME
static int run_digest_check(struct MHD_Connection *connection)
static void drain_and_harvest(int sock)
static void upgrade_cb(void *cls, struct MHD_Connection *connection, void *req_cls, const char *extra_in, size_t extra_in_size, MHD_socket sock, struct MHD_UpgradeResponseHandle *urh)
static const uint8_t * fuzz_seed_get(size_t idx, size_t *len)
static enum MHD_DigestAuthAlgo3 algo3_tbl[]
static int min_mem_limit_read
static const char *const hdr_names[]
static size_t expect_body_len
static struct MHD_Response * make_response(void)
static const char *const gen_methods[]
static int min_discipline
static const char *const gen_hdr_names[]
static const unsigned int nnc_tbl[]
static void oracle_check_body(struct hstate *hs, const char *data, size_t size)
static void exercise_connection_api(struct MHD_Connection *connection)
static unsigned long stat_body_bytes
static unsigned long stat_auth_ok
static enum MHD_Result post_iter(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size)
static const char *const gen_algos[]
static void sb_raw(struct sbuf *b, const void *v, size_t n)
static struct MHD_Connection * pending_resume[MAX_CONNECTIONS]
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
#define DAUTH_VARIANT_COUNT
static struct MHD_Daemon * cur_daemon
static size_t fuzz_generate(struct fuzz_rng *rng, uint8_t *buf, size_t cap)
static void print_stats(void)
static void gen_headers(struct fuzz_rng *rng, struct sbuf *b, unsigned int n)
static void gen_chunked_body(struct fuzz_rng *rng, struct sbuf *b, int oracle)
static void panic_cb(void *cls, const char *file, unsigned int line, const char *reason)
static size_t min_mem_limit
static struct fuzz_cfg cfg
static uint8_t seed_render_buf[4096]
static enum MHD_DigestAuthMultiAlgo3 algo_tbl[]
static enum MHD_Result ahc(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **req_cls)
static unsigned long stat_handler_calls
static int make_pipe_fd(void)
static unsigned long stat_challenges
static char nonce_val[192]
static void close_connection(struct MHD_Daemon *d, int *sock)
static void call_calc_helpers(void)
static const char *const hdr_values[]
static int forced_shape_read
static void crc_free(void *cls)
static const char digest_rnd[32]
static int pending_resume_flush(void)
static void completed_cb(void *cls, struct MHD_Connection *connection, void **req_cls, enum MHD_RequestTerminationCode toe)
static const char resp_body[]
static const int discipline_tbl[]
static const size_t mem_limit_tbl[]
static const char *const gen_versions[]
static void gen_digest_header(struct fuzz_rng *rng, struct sbuf *b, const char *uri, int use_nonce_token, int overlong_response, int prefer_valid)
static enum MHD_Result kv_iter_n(void *cls, enum MHD_ValueKind kind, const char *key, size_t key_size, const char *value, size_t value_size)
static size_t expand_nonce(const uint8_t *in, size_t in_len, uint8_t *out, size_t out_cap)
static unsigned long stat_final_calls
static ssize_t crc_cb(void *cls, uint64_t pos, char *buf, size_t max)
_MHD_EXTERN enum MHD_Result MHD_digest_auth_calc_userdigest(enum MHD_DigestAuthAlgo3 algo3, const char *username, const char *realm, const char *password, void *userdigest_bin, size_t bin_buf_size)
_MHD_EXTERN enum MHD_Result MHD_queue_auth_fail_response(struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale)
_MHD_EXTERN int MHD_digest_auth_check2(struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)
_MHD_EXTERN enum MHD_Result MHD_queue_basic_auth_fail_response(struct MHD_Connection *connection, const char *realm, struct MHD_Response *response)
_MHD_EXTERN enum MHD_Result MHD_queue_auth_required_response3(struct MHD_Connection *connection, const char *realm, const char *opaque, const char *domain, struct MHD_Response *response, int signal_stale, enum MHD_DigestAuthMultiQOP mqop, enum MHD_DigestAuthMultiAlgo3 algo, int userhash_support, int prefer_utf8)
_MHD_EXTERN int MHD_digest_auth_check_digest2(struct MHD_Connection *connection, const char *realm, const char *username, const uint8_t *digest, size_t digest_size, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)
_MHD_EXTERN enum MHD_Result MHD_digest_auth_calc_userhash_hex(enum MHD_DigestAuthAlgo3 algo3, const char *username, const char *realm, char *userhash_hex, size_t hex_buf_size)
_MHD_EXTERN enum MHD_Result MHD_queue_basic_auth_required_response3(struct MHD_Connection *connection, const char *realm, int prefer_utf8, struct MHD_Response *response)
_MHD_EXTERN enum MHD_DigestAuthResult MHD_digest_auth_check_digest3(struct MHD_Connection *connection, const char *realm, const char *username, const void *userdigest, size_t userdigest_size, unsigned int nonce_timeout, uint32_t max_nc, enum MHD_DigestAuthMultiQOP mqop, enum MHD_DigestAuthMultiAlgo3 malgo3)
_MHD_EXTERN char * MHD_basic_auth_get_username_password(struct MHD_Connection *connection, char **password)
_MHD_EXTERN enum MHD_Result MHD_queue_auth_fail_response2(struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale, enum MHD_DigestAuthAlgorithm algo)
_MHD_EXTERN struct MHD_DigestAuthInfo * MHD_digest_auth_get_request_info3(struct MHD_Connection *connection)
_MHD_EXTERN size_t MHD_digest_get_hash_size(enum MHD_DigestAuthAlgo3 algo3)
_MHD_EXTERN int MHD_digest_auth_check_digest(struct MHD_Connection *connection, const char *realm, const char *username, const uint8_t digest[MHD_MD5_DIGEST_SIZE], unsigned int nonce_timeout)
_MHD_EXTERN char * MHD_digest_auth_get_username(struct MHD_Connection *connection)
_MHD_EXTERN int MHD_digest_auth_check(struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)
#define MHD_INVALID_NONCE
_MHD_EXTERN enum MHD_DigestAuthResult MHD_digest_auth_check3(struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout, uint32_t max_nc, enum MHD_DigestAuthMultiQOP mqop, enum MHD_DigestAuthMultiAlgo3 malgo3)
_MHD_EXTERN struct MHD_BasicAuthInfo * MHD_basic_auth_get_username_password3(struct MHD_Connection *connection)
_MHD_EXTERN enum MHD_Result MHD_digest_auth_calc_userhash(enum MHD_DigestAuthAlgo3 algo3, const char *username, const char *realm, void *userhash_bin, size_t bin_buf_size)
_MHD_EXTERN struct MHD_DigestAuthUsernameInfo * MHD_digest_auth_get_username3(struct MHD_Connection *connection)
#define MHD_MD5_DIGEST_SIZE
_MHD_EXTERN int MHD_get_timeout_i(struct MHD_Daemon *daemon)
_MHD_EXTERN int64_t MHD_get_timeout64s(struct MHD_Daemon *daemon)
#define MHD_run_from_select(d, r, w, e)
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
_MHD_EXTERN enum MHD_Result MHD_run(struct MHD_Daemon *daemon)
_MHD_EXTERN enum MHD_Result MHD_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
#define MHD_get_fdset(daemon, read_fd_set, write_fd_set, except_fd_set, max_fd)
_MHD_EXTERN enum MHD_Result MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
_MHD_EXTERN enum MHD_Result MHD_get_timeout64(struct MHD_Daemon *daemon, uint64_t *timeout)
_MHD_EXTERN enum MHD_Result MHD_run_from_select2(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set, unsigned int fd_setsize)
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...)
#define MHD_HTTP_SWITCHING_PROTOCOLS
#define MHD_HTTP_FORBIDDEN
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
_MHD_EXTERN enum MHD_Result MHD_destroy_post_processor(struct MHD_PostProcessor *pp)
_MHD_EXTERN enum MHD_Result MHD_set_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, const char *value)
_MHD_EXTERN const char * MHD_lookup_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
_MHD_EXTERN enum MHD_Result MHD_post_process(struct MHD_PostProcessor *pp, const char *post_data, size_t post_data_len)
_MHD_EXTERN int MHD_get_connection_values_n(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIteratorN iterator, void *iterator_cls)
_MHD_EXTERN int MHD_get_connection_values(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls)
_MHD_EXTERN struct MHD_PostProcessor * MHD_create_post_processor(struct MHD_Connection *connection, size_t buffer_size, MHD_PostDataIterator iter, void *iter_cls)
_MHD_EXTERN enum MHD_Result MHD_get_connection_URI_path_n(struct MHD_Connection *connection, const char **uri, size_t *uri_size)
_MHD_EXTERN enum MHD_Result MHD_lookup_connection_value_n(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, size_t key_size, const char **value_ptr, size_t *value_size_ptr)
MHD_RequestTerminationCode
@ MHD_CONNECTION_INFO_CONNECTION_TIMEOUT
@ MHD_CONNECTION_INFO_SOCKET_CONTEXT
@ MHD_CONNECTION_INFO_REQUEST_HEADER_SIZE
@ MHD_CONNECTION_INFO_CONNECTION_SUSPENDED
@ MHD_CONNECTION_INFO_CLIENT_ADDRESS
@ MHD_CONNECTION_INFO_DAEMON
@ MHD_CONNECTION_INFO_HTTP_STATUS
@ MHD_CONNECTION_INFO_CONNECTION_FD
_MHD_EXTERN int MHD_get_response_headers(struct MHD_Response *response, MHD_KeyValueIterator iterator, void *iterator_cls)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer_with_free_callback(size_t size, void *buffer, MHD_ContentReaderFreeCallback crfc)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_iovec(const struct MHD_IoVec *iov, unsigned int iovcnt, MHD_ContentReaderFreeCallback free_cb, void *cls)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_data(size_t size, void *data, int must_free, int must_copy)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer_copy(size_t size, const void *buffer)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
_MHD_EXTERN enum MHD_Result MHD_del_response_header(struct MHD_Response *response, const char *header, const char *content)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_pipe(int fd)
_MHD_EXTERN enum MHD_Result MHD_queue_response(struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd(size_t size, int fd)
_MHD_EXTERN struct MHD_Response * MHD_create_response_empty(enum MHD_ResponseFlags flags)
_MHD_EXTERN const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer_static(size_t size, const void *buffer)
_MHD_EXTERN enum MHD_Result MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_callback(uint64_t size, size_t block_size, MHD_ContentReaderCallback crc, void *crc_cls, MHD_ContentReaderFreeCallback crfc)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_fd64(uint64_t size, int fd)
_MHD_EXTERN enum MHD_Result MHD_add_response_footer(struct MHD_Response *response, const char *footer, const char *content)
_MHD_EXTERN enum MHD_Result MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
_MHD_EXTERN enum MHD_Result MHD_is_feature_supported(enum MHD_FEATURE feature)
_MHD_EXTERN enum MHD_Result MHD_set_connection_option(struct MHD_Connection *connection, enum MHD_CONNECTION_OPTION option,...)
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
_MHD_EXTERN const union MHD_ConnectionInfo * MHD_get_connection_info(struct MHD_Connection *connection, enum MHD_ConnectionInfoType info_type,...)
_MHD_EXTERN uint32_t MHD_get_version_bin(void)
_MHD_EXTERN const char * MHD_get_version(void)
_MHD_EXTERN void MHD_free(void *ptr)
#define MHD_HTTP_VERSION_1_1
public interface to libmicrohttpd
@ MHD_OPTION_CLIENT_DISCIPLINE_LVL
@ MHD_OPTION_SERVER_INSANITY
@ MHD_OPTION_DIGEST_AUTH_RANDOM
@ MHD_OPTION_NONCE_NC_SIZE
@ MHD_OPTION_CONNECTION_MEMORY_LIMIT
@ MHD_OPTION_NOTIFY_COMPLETED
#define MHD_CONTENT_READER_END_OF_STREAM
@ MHD_DIGEST_AUTH_MULT_QOP_AUTH
@ MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT
#define MHD_create_response_from_fd_at_offset(size, fd, offset)
#define MHD_UNSIGNED_LONG_LONG
_MHD_EXTERN struct MHD_Response * MHD_create_response_for_upgrade(MHD_UpgradeHandler upgrade_handler, void *upgrade_handler_cls)
@ MHD_DIGEST_AUTH_ALGO3_MD5_SESSION
@ MHD_DIGEST_AUTH_ALGO3_MD5
@ MHD_DIGEST_AUTH_ALGO3_SHA256
@ MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION
@ MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION
@ MHD_DIGEST_AUTH_ALGO3_SHA512_256
_MHD_EXTERN void MHD_resume_connection(struct MHD_Connection *connection)
#define MHD_INVALID_SOCKET
#define MHD_CONTENT_READER_END_WITH_ERROR
@ MHD_UPGRADE_ACTION_CORK_ON
@ MHD_UPGRADE_ACTION_CLOSE
@ MHD_UPGRADE_ACTION_CORK_OFF
@ MHD_DIGEST_AUTH_MULT_ALGO3_SHA256
@ MHD_DIGEST_AUTH_MULT_ALGO3_SHA512_256
@ MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION
@ MHD_DIGEST_AUTH_MULT_ALGO3_MD5
@ MHD_DAEMON_INFO_BIND_PORT
@ MHD_DAEMON_INFO_CURRENT_CONNECTIONS
@ MHD_DAEMON_INFO_LISTEN_FD
@ MHD_ALLOW_SUSPEND_RESUME
@ MHD_USE_NO_LISTEN_SOCKET
@ MHD_RF_SEND_KEEP_ALIVE_HEADER
@ MHD_RF_HTTP_VERSION_1_0_RESPONSE
@ MHD_RF_HEAD_ONLY_RESPONSE
@ MHD_RF_INSANITY_HEADER_CONTENT_LENGTH
_MHD_EXTERN enum MHD_Result MHD_set_response_options(struct MHD_Response *response, enum MHD_ResponseFlags flags,...)
_MHD_EXTERN enum MHD_Result MHD_upgrade_action(struct MHD_UpgradeResponseHandle *urh, enum MHD_UpgradeAction action,...)
_MHD_EXTERN void MHD_suspend_connection(struct MHD_Connection *connection)
@ MHD_CONNECTION_OPTION_TIMEOUT
struct MHD_Connection * connection