Go to the documentation of this file.
35 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
36 #include "mhd_locks.h"
41 #ifdef MHD_LINUX_SOLARIS_SENDFILE
42 #include <sys/sendfile.h>
44 #if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_DARWIN_SENDFILE)
45 #include <sys/types.h>
46 #include <sys/socket.h>
52 #ifdef HAVE_SYS_PARAM_H
54 #include <sys/param.h>
61 #define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
71 #define REQUEST_TOO_BIG \
72 "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>"
74 #define REQUEST_TOO_BIG ""
85 #define REQUEST_LACKS_HOST \
86 "<html><head><title>"Host:" header required</title></head><body>In HTTP 1.1, requests must include a "Host:" header, and your HTTP 1.1 request lacked such a header.</body></html>"
88 #define REQUEST_LACKS_HOST ""
99 #define REQUEST_MALFORMED \
100 "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
102 #define REQUEST_MALFORMED ""
112 #define INTERNAL_ERROR \
113 "<html><head><title>Internal server error</title></head><body>Please ask the developer of this Web server to carefully read the GNU libmicrohttpd documentation about connection management and blocking.</body></html>"
115 #define INTERNAL_ERROR ""
122 #define DEBUG_CLOSE MHD_NO
127 #define DEBUG_SEND_DATA MHD_NO
133 #define MHD_SENFILE_CHUNK_ (0x20000)
138 #define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000)
140 #ifdef HAVE_FREEBSD_SENDFILE
145 static int freebsd_sendfile_flags_;
150 static int freebsd_sendfile_flags_thd_p_c_;
156 MHD_conn_init_static_ (
void)
162 long sys_page_size = sysconf (_SC_PAGESIZE);
163 if (0 > sys_page_size)
165 freebsd_sendfile_flags_ = SF_NODISKIO;
166 freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO;
170 freebsd_sendfile_flags_ =
172 freebsd_sendfile_flags_thd_p_c_ =
227 else if (i > (
size_t) ret)
281 else if (i > (
size_t) ret)
309 if (
NULL == connection)
316 if ( (
NULL != iterator) &&
317 (
MHD_YES != iterator (iterator_cls,
348 if (
NULL == connection)
352 if (
NULL == iterator)
363 if (
MHD_NO == iterator (iterator_cls,
407 pos->
header = (
char *) key;
462 ( ((key ? strlen (key) : 0) != key_size) ||
540 (
NULL == key) ? 0 : strlen (key),
571 const char **value_ptr,
572 size_t *value_size_ptr)
576 if (
NULL == connection)
605 if (
NULL != value_ptr)
606 *value_ptr = pos->
value;
608 if (
NULL != value_size_ptr)
673 #define MHD_lookup_header_s_token_ci(c,h,tkn) \
674 MHD_lookup_header_token_ci ((c),(h),MHD_STATICSTR_LEN_ (h), \
675 (tkn),MHD_STATICSTR_LEN_ (tkn))
774 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
789 struct MHD_UpgradeResponseHandle *urh = connection->urh;
800 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
805 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
807 if (urh->in_eready_list)
810 daemon->eready_urh_tail,
812 urh->in_eready_list =
false;
819 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
824 MHD_PANIC (
_ (
"Failed to remove FD from epoll set\n"));
829 shutdown (urh->mhd.socket, SHUT_RDWR);
854 MHD_DLOG (connection->
daemon,
869 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, emsg)
871 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, NULL)
904 #if defined(_MHD_HAVE_SENDFILE)
905 if (MHD_resp_sender_sendfile == connection->resp_sender)
923 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
932 "Closing connection (application reported error generating data)\n"));
940 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
976 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
981 _ (
"Closing connection (out of memory)\n"));
984 if ( (2 * (0xFFFFFF +
sizeof(cbuf) + 2)) < size)
985 size = 2 * (0xFFFFFF +
sizeof(cbuf) + 2);
1002 const size_t data_write_offset
1005 ret = response->
data_size - data_write_offset;
1009 &response->
data[data_write_offset],
1024 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1029 "Closing connection (application error generating response)\n"));
1047 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1054 cblen = MHD_snprintf_ (cbuf,
1057 (
unsigned int) ret);
1060 memcpy (&connection->
write_buffer[sizeof (cbuf) - cblen],
1063 memcpy (&connection->
write_buffer[sizeof (cbuf) + ret],
1143 static const char *
const days[] = {
1144 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
1146 static const char *
const mons[] = {
1147 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
1148 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
1152 #if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \
1153 ! defined(HAVE_GMTIME_R)
1159 #if defined(HAVE_C11_GMTIME_S)
1160 if (
NULL == gmtime_s (&t,
1163 #elif defined(HAVE_W32_GMTIME_S)
1164 if (0 != gmtime_s (&now,
1167 #elif defined(HAVE_GMTIME_R)
1168 if (
NULL == gmtime_r (&t,
1177 MHD_snprintf_ (date,
1179 "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
1180 days[now.tm_wday % 7],
1181 (
unsigned int) now.tm_mday,
1182 mons[now.tm_mon % 12],
1183 (
unsigned int) (1900 + now.tm_year),
1184 (
unsigned int) now.tm_hour,
1185 (
unsigned int) now.tm_min,
1186 (
unsigned int) now.tm_sec);
1210 if (0 == avail_size)
1213 new_size = avail_size / 2;
1218 grow_size = avail_size / 8;
1227 if (small_inc < avail_size)
1228 grow_size = small_inc;
1230 grow_size = avail_size;
1265 char content_length_buf[128];
1266 size_t content_length_len;
1269 const char *reason_phrase;
1271 bool client_requested_close;
1272 bool response_has_close;
1273 bool response_has_keepalive;
1274 const char *have_encoding;
1275 bool must_add_close;
1276 bool must_add_chunked_encoding;
1277 bool must_add_keep_alive;
1278 bool must_add_content_length;
1279 bool may_add_content_length;
1282 if (0 == connection->
version[0])
1297 off = MHD_snprintf_ (code,
1321 datelen = strlen (date);
1335 must_add_close =
false;
1336 must_add_chunked_encoding =
false;
1337 must_add_keep_alive =
false;
1338 must_add_content_length =
false;
1339 response_has_close =
false;
1340 switch (connection->
state)
1355 #ifdef UPGRADE_SUPPORT
1356 else if (
NULL != response->upgrade_handler)
1365 if (
NULL == have_encoding)
1366 may_add_content_length =
true;
1368 may_add_content_length =
false;
1370 #ifdef UPGRADE_SUPPORT
1371 (
NULL == response->upgrade_handler) &&
1373 (! response_has_close) &&
1374 (! client_requested_close) )
1385 if (
NULL == have_encoding)
1387 must_add_chunked_encoding =
true;
1396 must_add_close =
true;
1408 if (! response_has_close)
1409 must_add_close =
true;
1414 if ( ( (client_requested_close) ||
1417 (! response_has_close) &&
1418 #ifdef UPGRADE_SUPPORT
1419 (
NULL == response->upgrade_handler) &&
1422 must_add_close =
true;
1426 if ( (! may_add_content_length) &&
1428 (! response_has_close) )
1429 must_add_close =
true;
1442 (may_add_content_length) &&
1462 = MHD_snprintf_ (content_length_buf,
1463 sizeof (content_length_buf),
1467 must_add_content_length =
true;
1471 if ( (! response_has_keepalive) &&
1472 (! response_has_close) &&
1473 (! must_add_close) &&
1475 #ifdef UPGRADE_SUPPORT
1476 (
NULL == response->upgrade_handler) &&
1479 must_add_keep_alive =
true;
1482 response_has_keepalive =
false;
1491 if ( (must_add_close) || (response_has_close) )
1493 else if ( (must_add_keep_alive) || (response_has_keepalive) )
1499 if (must_add_keep_alive)
1501 if (must_add_chunked_encoding)
1503 if (must_add_content_length)
1504 size += content_length_len;
1505 mhd_assert (! (must_add_close && must_add_keep_alive) );
1506 mhd_assert (! (must_add_chunked_encoding && must_add_content_length) );
1512 (! ( (must_add_close) &&
1513 (response_has_keepalive) &&
1521 "Keep-Alive")) ) ) )
1530 #ifdef HAVE_MESSAGES
1531 MHD_DLOG (connection->
daemon,
1532 "Not enough memory for write!\n");
1546 "Connection: close\r\n",
1550 if (must_add_keep_alive)
1554 "Connection: Keep-Alive\r\n",
1558 if (must_add_chunked_encoding)
1562 "Transfer-Encoding: chunked\r\n",
1566 if (must_add_content_length)
1571 content_length_len);
1572 off += content_length_len;
1578 (! ( (must_add_close) &&
1579 (response_has_keepalive) &&
1587 "Keep-Alive")) ) ) )
1588 off += MHD_snprintf_ (&
data[off],
1630 unsigned int status_code,
1631 const char *message)
1654 #ifdef HAVE_MESSAGES
1655 MHD_DLOG (connection->
daemon,
1657 "Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"),
1669 if (
NULL == response)
1684 "Closing connection (failed to queue response)\n"));
1695 "Closing connection (failed to create response header)\n"));
1718 #ifdef HTTPS_SUPPORT
1721 switch (connection->tls_state)
1727 if (0 == gnutls_record_get_direction (connection->tls_session))
1740 MHD_DLOG (connection->
daemon,
1741 _ (
"In function %s handling connection at state: %s\n"),
1743 MHD_state_to_string (connection->
state));
1745 switch (connection->
state)
1779 const bool internal_poll = (0 != (connection->
daemon->
options
1854 #ifdef UPGRADE_SUPPORT
1855 case MHD_CONNECTION_UPGRADE:
1891 while ( (pos < connection->read_buffer_offset - 1) &&
1892 (
'\r' != rbuf[pos]) &&
1893 (
'\n' != rbuf[pos]) )
1896 (
'\n' != rbuf[pos]) )
1916 if ( (
'\r' == rbuf[pos]) &&
1917 (
'\n' == rbuf[pos + 1]) )
1956 #ifdef HAVE_MESSAGES
1957 MHD_DLOG (connection->
daemon,
1958 _ (
"Not enough memory in pool to allocate header record!\n"));
2003 #ifdef HAVE_MESSAGES
2004 MHD_DLOG (connection->
daemon,
2005 _ (
"Not enough memory in pool to parse cookies!\n"));
2015 cpy[hdr_len] =
'\0';
2023 while ( ((*sce) !=
'\0') &&
2030 while ( (*ekill ==
' ') &&
2054 while ( (
'\0' != semicolon[0]) &&
2056 ( (
';' != semicolon[0]) &&
2057 (
',' != semicolon[0]) ) ) )
2059 if (
'"' == semicolon[0])
2060 quotes = (quotes + 1) & 1;
2064 if (
'\0' == semicolon[0])
2066 if (
NULL != semicolon)
2068 semicolon[0] =
'\0';
2072 if ( (
'"' == equals[0]) &&
2111 unsigned int unused_num_headers;
2113 if (
NULL == (uri = memchr (line,
2118 connection->
method = line;
2122 while ( (
' ' == uri[0]) &&
2123 ( (
size_t) (uri - line) < line_len) )
2125 if ((
size_t) (uri - line) == line_len)
2138 http_version = line + line_len - 1;
2140 while ( (
' ' == http_version[0]) &&
2141 (http_version > uri) )
2144 while ( (
' ' != http_version[0]) &&
2145 (http_version > uri) )
2147 if (http_version > uri)
2150 http_version[0] =
'\0';
2151 connection->
version = http_version + 1;
2152 uri_len = http_version - uri;
2157 uri_len = line_len - (uri - line);
2161 (
NULL != memchr (uri,
2193 &unused_num_headers);
2201 connection->
url = curi;
2236 "Application reported internal error, closing connection.\n"));
2276 size_t to_be_processed;
2277 size_t left_unprocessed;
2278 size_t processed_size;
2292 if ( (
'\r' == buffer_head[i]) ||
2293 (
'\n' == buffer_head[i]) )
2295 if ( (
'\r' == buffer_head[i]) ||
2296 (
'\n' == buffer_head[i]) )
2303 "Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2314 uint64_t cur_chunk_left;
2320 if (cur_chunk_left > available)
2321 to_be_processed = available;
2324 to_be_processed = (size_t) cur_chunk_left;
2325 if (available > to_be_processed)
2337 while (i < available)
2339 if ( (
'\r' == buffer_head[i]) ||
2340 (
'\n' == buffer_head[i]) ||
2341 (
';' == buffer_head[i]) )
2349 if (
';' == buffer_head[i])
2351 while (i < available)
2353 if ( (
'\r' == buffer_head[i]) ||
2354 (
'\n' == buffer_head[i]) )
2362 if ( (i + 1 >= available) &&
2365 (
'0' == buffer_head[0]) ) )
2368 malformed = (end_size >= 16);
2374 current_chunk_size);
2375 malformed = (end_size != num_dig);
2382 "Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2386 if ( (i < available) &&
2387 ( (
'\r' == buffer_head[i]) ||
2388 (
'\n' == buffer_head[i]) ) )
2420 to_be_processed = available;
2423 left_unprocessed = to_be_processed;
2438 "Application reported internal error, closing connection.\n"));
2441 if (left_unprocessed > to_be_processed)
2445 #ifdef HAVE_MESSAGES
2446 ,
_ (
"libmicrohttpd API violation")
2451 if (0 != left_unprocessed)
2454 #ifdef HAVE_MESSAGES
2462 "WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n"));
2465 processed_size = to_be_processed - left_unprocessed;
2469 buffer_head += processed_size;
2470 available -= processed_size;
2474 while (
MHD_YES == instant_retry);
2475 if ( (available > 0) &&
2501 connection->
state = next_state;
2528 colon = strchr (line,
':');
2534 "Received malformed line (no colon). Closing connection.\n"));
2544 white = strchr (line,
' ');
2545 if ( (
NULL != white) &&
2548 white = strchr (line,
'\t');
2549 if ( (
NULL != white) &&
2556 while ( (
'\0' != colon[0]) &&
2557 ( (
' ' == colon[0]) ||
2558 (
'\t' == colon[0]) ) )
2564 connection->
last = line;
2565 connection->
colon = colon;
2590 last = connection->
last;
2591 if ( (
' ' == line[0]) ||
2596 last_len = strlen (last);
2599 while ( (
' ' == tmp[0]) ||
2602 tmp_len = strlen (tmp);
2614 last_len + tmp_len + 1);
2622 memcpy (&last[last_len],
2625 connection->
last = last;
2635 strlen (connection->
colon),
2693 #ifdef HAVE_MESSAGES
2694 MHD_DLOG (connection->
daemon,
2695 _ (
"Received HTTP 1.1 request without `Host' header.\n"));
2702 if (
NULL == response)
2707 "Closing connection (failed to create response)\n"));
2719 "Closing connection (failed to queue response)\n"));
2750 if ( (clen == end) ||
2754 #ifdef HAVE_MESSAGES
2755 MHD_DLOG (connection->
daemon,
2756 "Failed to parse `Content-Length' header. Closing connection.\n");
2791 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2801 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2821 #ifdef HTTPS_SUPPORT
2842 bytes_read = connection->
recv_cls (connection,
2857 "Socket disconnected while reading request.\n"));
2864 "Connection socket is closed due to error when reading request.\n"));
2868 if (0 == bytes_read)
2878 MHD_DLOG (connection->
daemon,
2879 _ (
"In function %s handling connection at state: %s\n"),
2881 MHD_state_to_string (connection->
state));
2883 switch (connection->
state)
2903 #ifdef UPGRADE_SUPPORT
2904 case MHD_CONNECTION_UPGRADE:
2934 #ifdef HTTPS_SUPPORT
2946 MHD_DLOG (connection->
daemon,
2947 _ (
"In function %s handling connection at state: %s\n"),
2949 MHD_state_to_string (connection->
state));
2951 switch (connection->
state)
2972 #ifdef HAVE_MESSAGES
2973 MHD_DLOG (connection->
daemon,
2974 _ (
"Failed to send data in request for %s.\n"),
2983 _ (
"Sent 100 continue response: `%.*s'\n"),
3026 "Connection was closed while sending response headers.\n"));
3054 uint64_t data_write_offset;
3056 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3065 #if defined(_MHD_HAVE_SENDFILE)
3066 if (MHD_resp_sender_sendfile == connection->resp_sender)
3068 ret = MHD_send_sendfile_ (connection);
3077 if (data_write_offset > (uint64_t)
SIZE_MAX)
3081 [(
size_t) data_write_offset],
3083 - (
size_t) data_write_offset,
3088 _ (
"Sent %d-byte DATA response: `%.*s'\n"),
3095 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3103 #ifdef HAVE_MESSAGES
3104 MHD_DLOG (connection->
daemon,
3105 _ (
"Failed to send data in request for `%s'.\n"),
3135 "Connection was closed while sending response body.\n"));
3165 "Connection was closed while sending response body.\n"));
3180 #ifdef UPGRADE_SUPPORT
3181 case MHD_CONNECTION_UPGRADE:
3188 _ (
"Internal error\n"));
3216 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3248 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3256 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3257 (! MHD_itc_activate_ (daemon->
itc,
"c")) )
3259 #ifdef HAVE_MESSAGES
3262 "Failed to signal end of connection via inter-thread communication channel"));
3290 #ifdef HTTPS_SUPPORT
3293 if ((MHD_TLS_CONN_INIT <= connection->tls_state) &&
3300 _ (
"In function %s handling connection at state: %s\n"),
3302 MHD_state_to_string (connection->
state));
3304 switch (connection->
state)
3313 if ( (
NULL == line) ||
3529 "Closing connection (failed to create response header)\n"));
3539 #ifdef UPGRADE_SUPPORT
3542 connection->
state = MHD_CONNECTION_UPGRADE;
3573 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3579 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3588 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3604 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3612 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3621 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3638 "Closing connection (failed to create response header)\n"));
3724 #ifdef UPGRADE_SUPPORT
3725 case MHD_CONNECTION_UPGRADE:
3739 if ( (0 != timeout) &&
3751 #ifdef EPOLL_SUPPORT
3755 ret = MHD_connection_epoll_update_ (connection);
3763 #ifdef EPOLL_SUPPORT
3786 struct epoll_event event;
3788 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
3789 event.data.ptr = connection;
3790 if (0 != epoll_ctl (daemon->epoll_fd,
3795 #ifdef HAVE_MESSAGES
3798 _ (
"Call to epoll_ctl failed: %s\n"),
3844 #ifdef HTTPS_SUPPORT
3846 if (
NULL == connection->tls_session)
3848 connection->cipher = gnutls_cipher_get (connection->tls_session);
3851 if (
NULL == connection->tls_session)
3853 connection->protocol = gnutls_protocol_get_version (
3854 connection->tls_session);
3857 if (
NULL == connection->tls_session)
3876 connection_timeout_dummy;
3905 daemon = connection->
daemon;
3911 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3926 va_start (ap, option);
3942 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3965 unsigned int status_code,
3970 if ( (
NULL == connection) ||
3971 (
NULL == response) ||
3976 daemon = connection->
daemon;
3982 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3985 (! MHD_thread_ID_match_current_ (connection->
pid.ID)) )
3987 #ifdef HAVE_MESSAGES
3989 _ (
"Attempted to queue response on wrong thread!\n"));
3994 #ifdef UPGRADE_SUPPORT
3995 if ( (
NULL != response->upgrade_handler) &&
3998 #ifdef HAVE_MESSAGES
4001 "Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
4006 (
NULL != response->upgrade_handler) )
4008 #ifdef HAVE_MESSAGES
4011 "Application used invalid status code for 'upgrade' response!\n"));
4019 #if defined(_MHD_HAVE_SENDFILE)
4020 if ( (response->
fd == -1) ||
4022 connection->resp_sender = MHD_resp_sender_std;
4024 connection->resp_sender = MHD_resp_sender_sendfile;
struct MHD_HTTP_Header * first_header
bool MHD_str_equal_caseless_bin_n_(const char *const str1, const char *const str2, size_t len)
Header for platform missing functions.
static char * get_next_header_line(struct MHD_Connection *connection, size_t *line_len)
#define MHD_HTTP_METHOD_PUT
LogCallback uri_log_callback
UnescapeCallback unescape_callback
limits values definitions
static int connection_add_header(struct MHD_Connection *connection, const char *key, size_t key_size, const char *value, size_t value_size, enum MHD_ValueKind kind)
#define MHD_CONTENT_READER_END_WITH_ERROR
#define MHD_mutex_unlock_chk_(pmutex)
static void call_connection_handler(struct MHD_Connection *connection)
static void transmit_error_response(struct MHD_Connection *connection, unsigned int status_code, const char *message)
struct MHD_Connection * cleanup_tail
ssize_t MHD_send_on_connection2_(struct MHD_Connection *connection, const char *header, size_t header_size, const char *buffer, size_t buffer_size)
struct MHD_Connection * manual_timeout_tail
void MHD_update_last_activity_(struct MHD_Connection *connection)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
#define MHD_UNSIGNED_LONG_LONG
#define MHD_HTTP_NOT_MODIFIED
bool MHD_parse_arguments_(struct MHD_Request *request, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
static int parse_initial_message_line(struct MHD_Connection *connection, char *line, size_t line_len)
time_t MHD_monotonic_sec_counter(void)
_MHD_EXTERN int MHD_set_connection_option(struct MHD_Connection *connection, enum MHD_CONNECTION_OPTION option,...)
unsigned int connection_timeout_dummy
struct MHD_Connection * normal_timeout_tail
ssize_t MHD_send_on_connection_(struct MHD_Connection *connection, const char *buffer, size_t buffer_size, enum MHD_SendSocketOptions options)
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
static void MHD_connection_update_event_loop_info(struct MHD_Connection *connection)
size_t write_buffer_append_offset
static void cleanup_connection(struct MHD_Connection *connection)
struct MHD_Connection * normal_timeout_head
void * notify_completed_cls
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
#define MHD_HTTP_METHOD_POST
bool MHD_run_tls_handshake_(struct MHD_Connection *connection)
#define MHD_recv_(s, b, l)
enum MHD_HTTP_StatusCode status_code
static int build_header_response(struct MHD_Connection *connection)
_MHD_EXTERN int MHD_get_connection_values(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls)
Methods for managing connections.
MHD_ContentReaderCallback crc
Methods for managing response objects.
struct MHD_Connection * suspended_connections_tail
#define MHD_INVALID_SOCKET
void * MHD_pool_reset(struct MemoryPool *pool, void *keep, size_t copy_bytes, size_t new_size)
internal shared structures
struct MHD_Connection * suspended_connections_head
#define MHD_HTTP_URI_TOO_LONG
_MHD_EXTERN int 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)
TransmitCallback send_cls
static int try_ready_normal_body(struct MHD_Connection *connection)
int MHD_str_equal_caseless_(const char *str1, const char *str2)
MHD_RequestCompletedCallback notify_completed
uint64_t current_chunk_size
#define MHD_socket_get_error_()
bool MHD_str_has_token_caseless_(const char *str, const char *const token, size_t token_len)
#define REQUEST_MALFORMED
static bool try_grow_read_buffer(struct MHD_Connection *connection, bool required)
static bool MHD_lookup_header_token_ci(const struct MHD_Connection *connection, const char *header, size_t header_len, const char *token, size_t token_len)
#define MHD_SCKT_ERR_IS_(err, code)
internal monotonic clock functions implementations
_MHD_EXTERN const union MHD_ConnectionInfo * MHD_get_connection_info(struct MHD_Connection *connection, enum MHD_ConnectionInfoType info_type,...)
static int need_100_continue(struct MHD_Connection *connection)
struct MHD_HTTP_Header * headers_received_tail
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
#define MHD_HTTP_NO_CONTENT
void MHD_connection_handle_write(struct MHD_Connection *connection)
#define EDLL_remove(head, tail, element)
_MHD_EXTERN int MHD_get_connection_values_n(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIteratorN iterator, void *iterator_cls)
#define MHD_ERR_CONNRESET_
int(* MHD_KeyValueIteratorN)(void *cls, enum MHD_ValueKind kind, const char *key, size_t key_size, const char *value, size_t value_size)
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
size_t read_buffer_offset
void * default_handler_cls
int(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
#define DLL_insert(head, tail, element)
static int process_broken_line(struct MHD_Connection *connection, char *line, enum MHD_ValueKind kind)
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
struct MHD_HTTP_Header * headers_received
uint64_t current_chunk_offset
size_t MHD_strx_to_uint64_n_(const char *str, size_t maxlen, uint64_t *out_val)
int MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
_MHD_EXTERN int MHD_set_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, const char *value)
struct sockaddr_storage addr
time_t connection_timeout
void * MHD_pool_reallocate(struct MemoryPool *pool, void *old, size_t old_size, size_t new_size)
#define DLL_remove(head, tail, element)
const _MHD_EXTERN char * MHD_lookup_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
enum MHD_CONNECTION_STATE state
#define REQUEST_LACKS_HOST
void MHD_pool_destroy(struct MemoryPool *pool)
#define MHD_socket_last_strerr_()
MHD_mutex_ cleanup_connection_mutex
enum MHD_ConnKeepAlive keepalive
#define MHD_check_response_header_s_token_ci(r, k, tkn)
#define MHD_HTTP_VERSION_1_1
#define MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
_MHD_EXTERN int MHD_queue_response(struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
void MHD_increment_response_rc(struct MHD_Response *response)
static void process_request_body(struct MHD_Connection *connection)
#define CONNECTION_CLOSE_ERROR(c, emsg)
struct MHD_Connection * manual_timeout_head
static int parse_cookie_header(struct MHD_Connection *connection)
#define MHD_SENFILE_CHUNK_THR_P_C_
int MHD_set_connection_value_n(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, size_t key_size, const char *value, size_t value_size)
#define MHD_CONTENT_READER_END_OF_STREAM
void * unescape_callback_cls
uint64_t response_write_position
struct MHD_Connection * cleanup_head
enum MHD_ConnectionEventLoopInfo event_loop_info
static void parse_connection_headers(struct MHD_Connection *connection)
static int keepalive_possible(struct MHD_Connection *connection)
#define MHD_HTTP_BAD_REQUEST
Methods for managing connections.
MHD_AccessHandlerCallback default_handler
#define HTTP_100_CONTINUE
static void connection_close_error(struct MHD_Connection *connection, const char *emsg)
const _MHD_EXTERN char * MHD_get_reason_phrase_for(unsigned int code)
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
#define MHD_HTTP_METHOD_CONNECT
uint64_t remaining_upload_size
struct MHD_Response * response
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
#define MHD_STATICSTR_LEN_(macro)
int MHD_connection_handle_idle(struct MHD_Connection *connection)
#define MHD_SENFILE_CHUNK_
#define MHD_HTTP_VERSION_1_0
#define MHD_mutex_lock_chk_(pmutex)
Header for string manipulating helpers.
void MHD_connection_handle_read(struct MHD_Connection *connection)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
#define XDLL_remove(head, tail, element)
struct MHD_Daemon * daemon
MHD_thread_handle_ID_ pid
struct MHD_Connection * connections_tail
static int process_header_line(struct MHD_Connection *connection, char *line)
MHD_RequestTerminationCode
#define XDLL_insert(head, tail, element)
size_t MHD_pool_get_free(struct MemoryPool *pool)
#define MHD_lookup_header_s_token_ci(c, h, tkn)
#define MHD_HTTP_PROCESSING
unsigned int responseCode
static int check_write_done(struct MHD_Connection *connection, enum MHD_CONNECTION_STATE next_state)
Header for platform-independent inter-thread communication.
size_t write_buffer_send_offset
static void get_date_string(char *date, size_t date_len)
struct MHD_Connection * connections_head
void * uri_log_callback_cls
const _MHD_EXTERN char * MHD_get_response_header(struct MHD_Response *response, const char *key)
#define MHD_SCKT_ECONNRESET_
#define MHD_send_(s, b, l)
#define MHD_HTTP_INTERNAL_SERVER_ERROR
#define MHD_UNSIGNED_LONG_LONG_PRINTF
Implementation of send() wrappers.
bool MHD_tls_connection_shutdown(struct MHD_Connection *connection)
#define MHD_HTTP_SWITCHING_PROTOCOLS
enum MHD_ResponseFlags flags
static int try_ready_chunked_body(struct MHD_Connection *connection)
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, int from_end)
size_t MHD_str_to_uint64_(const char *str, uint64_t *out_val)
#define MHD_SCKT_ERR_IS_EINTR_(err)
time_t connection_timeout
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
static int MHD_set_connection_value_n_nocheck_(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, size_t key_size, const char *value, size_t value_size)
MHD_PanicCallback mhd_panic
#define MHD_SCKT_SEND_MAX_SIZE_
size_t continue_message_write_offset
#define MHD_HTTP_METHOD_HEAD