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 "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>" 73 #define REQUEST_TOO_BIG "" 84 #define REQUEST_LACKS_HOST "<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>" 86 #define REQUEST_LACKS_HOST "" 97 #define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>" 99 #define REQUEST_MALFORMED "" 109 #define INTERNAL_ERROR "<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>" 111 #define INTERNAL_ERROR "" 118 #define DEBUG_CLOSE MHD_NO 123 #define DEBUG_SEND_DATA MHD_NO 129 #define MHD_SENFILE_CHUNK_ (0x20000) 134 #define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000) 136 #ifdef HAVE_FREEBSD_SENDFILE 141 static int freebsd_sendfile_flags_;
146 static int freebsd_sendfile_flags_thd_p_c_;
152 MHD_conn_init_static_ (
void)
158 long sys_page_size = sysconf (_SC_PAGESIZE);
159 if (0 > sys_page_size)
161 freebsd_sendfile_flags_ = SF_NODISKIO;
162 freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO;
166 freebsd_sendfile_flags_ =
168 freebsd_sendfile_flags_thd_p_c_ =
220 else if (i > (
size_t)ret)
274 else if (i > (
size_t)ret)
281 #if defined(_MHD_HAVE_SENDFILE) 295 #ifndef HAVE_SENDFILE64 296 const uint64_t max_off_t = (uint64_t)
OFF_T_MAX;
298 const uint64_t max_off_t = (uint64_t)OFF64_T_MAX;
300 #ifdef MHD_LINUX_SOLARIS_SENDFILE 301 #ifndef HAVE_SENDFILE64 307 #ifdef HAVE_FREEBSD_SENDFILE 311 #ifdef HAVE_DARWIN_SENDFILE 316 size_t send_size = 0;
317 mhd_assert (MHD_resp_sender_sendfile == connection->resp_sender);
323 send_size = (left > chunk_size) ? chunk_size : (
size_t) left;
324 if (max_off_t < offsetu64)
326 connection->resp_sender = MHD_resp_sender_std;
329 #ifdef MHD_LINUX_SOLARIS_SENDFILE 330 #ifndef HAVE_SENDFILE64 331 offset = (off_t) offsetu64;
337 offset = (off64_t) offsetu64;
356 #ifdef HAVE_LINUX_SENDFILE 365 connection->resp_sender = MHD_resp_sender_std;
368 if ( (EAFNOSUPPORT == err) ||
370 (EOPNOTSUPP == err) )
372 connection->resp_sender = MHD_resp_sender_std;
375 if ( (ENOTCONN == err) ||
384 else if (send_size > (
size_t)ret)
387 #elif defined(HAVE_FREEBSD_SENDFILE) 389 flags = used_thr_p_c ?
390 freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_;
392 if (0 != sendfile (file_fd,
407 return (ssize_t)sent_bytes;
413 connection->resp_sender = MHD_resp_sender_std;
418 ret = (ssize_t)sent_bytes;
419 #elif defined(HAVE_DARWIN_SENDFILE) 420 len = (off_t)send_size;
421 if (0 != sendfile (file_fd,
440 if (ENOTCONN == err ||
443 if (ENOTSUP == err ||
447 connection->resp_sender = MHD_resp_sender_std;
481 _MHD_static_inline
bool 485 #if defined(TCP_CORK) || defined(TCP_PUSH) 500 _MHD_static_inline
bool 504 #if defined(TCP_NODELAY) 510 if (0 == setsockopt (connection->
socket_fd,
513 (
const void *) &off_val,
521 #if defined(MHD_TCP_CORK_NOPUSH) 527 if (0 == setsockopt (connection->
socket_fd,
530 (
const void *) &on_val,
538 #if defined(TCP_NODELAY) 552 _MHD_static_inline
bool 555 #if defined(MHD_TCP_CORK_NOPUSH) 560 if (0 == setsockopt (connection->
socket_fd,
563 (
const void *) &off_val,
571 #if defined(TCP_NODELAY) 576 if (0 == setsockopt (connection->
socket_fd,
579 (
const void *) &on_val,
597 _MHD_static_inline
bool 601 #if defined(TCP_NOPUSH) && !defined(TCP_CORK) 604 #if defined(TCP_CORK) || (defined(__FreeBSD__) && __FreeBSD__+0 >= 9) 608 if (0 == setsockopt (connection->
socket_fd,
611 (
const void *) &off_val,
619 #if defined(__FreeBSD__) && __FreeBSD__+0 >= 9 621 #elif defined(TCP_NOPUSH) && !defined(TCP_CORK) 639 _MHD_static_inline
bool 643 #if defined(MHD_TCP_CORK_NOPUSH) 648 if (0 == setsockopt (connection->
socket_fd,
651 (
const void *) &off_val,
659 #if defined(TCP_NODELAY) 664 if (0 == setsockopt (connection->
socket_fd,
667 (
const void *) &off_val,
699 if (
NULL == connection)
706 if ( (
NULL != iterator) &&
707 (
MHD_YES != iterator (iterator_cls,
738 if (
NULL == connection)
742 if (
NULL == iterator)
753 if (
MHD_NO == iterator (iterator_cls,
797 pos->
header = (
char *) key;
852 ( ((key ? strlen(key) : 0) != key_size) ||
930 (
NULL == key) ? 0 : strlen(key),
961 const char **value_ptr,
962 size_t *value_size_ptr)
966 if (
NULL == connection)
995 if (
NULL != value_ptr)
996 *value_ptr = pos->
value;
998 if (
NULL != value_size_ptr)
1058 #define MHD_lookup_header_s_token_ci(c,h,tkn) \ 1059 MHD_lookup_header_token_ci((c),(h),MHD_STATICSTR_LEN_(h),\ 1060 (tkn),MHD_STATICSTR_LEN_(tkn)) 1107 #ifdef HTTPS_SUPPORT 1159 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 1174 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1185 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1190 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
1192 if (urh->in_eready_list)
1195 daemon->eready_urh_tail,
1197 urh->in_eready_list =
false;
1204 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1209 MHD_PANIC (
_(
"Failed to remove FD from epoll set\n"));
1214 shutdown (urh->mhd.socket, SHUT_RDWR);
1236 #ifdef HAVE_MESSAGES 1238 MHD_DLOG (connection->
daemon,
1252 #ifdef HAVE_MESSAGES 1253 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, emsg) 1255 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, NULL) 1288 #if defined(_MHD_HAVE_SENDFILE) 1289 if (MHD_resp_sender_sendfile == connection->resp_sender)
1307 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1315 _(
"Closing connection (application reported error generating data)\n"));
1323 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1359 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1364 _(
"Closing connection (out of memory)\n"));
1367 if ( (2 * (0xFFFFFF +
sizeof(cbuf) + 2)) < size)
1368 size = 2 * (0xFFFFFF +
sizeof(cbuf) + 2);
1385 const size_t data_write_offset
1388 ret = response->
data_size - data_write_offset;
1392 &response->
data[data_write_offset],
1407 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1411 _(
"Closing connection (application error generating response)\n"));
1429 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 1436 cblen = MHD_snprintf_(cbuf,
1439 (
unsigned int) ret);
1442 memcpy (&connection->
write_buffer[sizeof (cbuf) - cblen],
1445 memcpy (&connection->
write_buffer[sizeof (cbuf) + ret],
1524 static const char *
const days[] = {
1525 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" 1527 static const char *
const mons[] = {
1528 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
1529 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" 1533 #if !defined(HAVE_C11_GMTIME_S) && !defined(HAVE_W32_GMTIME_S) && !defined(HAVE_GMTIME_R) 1539 #if defined(HAVE_C11_GMTIME_S) 1540 if (
NULL == gmtime_s (&t,
1543 #elif defined(HAVE_W32_GMTIME_S) 1544 if (0 != gmtime_s (&now,
1547 #elif defined(HAVE_GMTIME_R) 1548 if (
NULL == gmtime_r(&t,
1557 MHD_snprintf_ (date,
1559 "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
1560 days[now.tm_wday % 7],
1561 (
unsigned int) now.tm_mday,
1562 mons[now.tm_mon % 12],
1563 (
unsigned int) (1900 + now.tm_year),
1564 (
unsigned int) now.tm_hour,
1565 (
unsigned int) now.tm_min,
1566 (
unsigned int) now.tm_sec);
1590 if (0 == avail_size)
1593 new_size = avail_size / 2;
1598 grow_size = avail_size / 8;
1607 if (small_inc < avail_size)
1608 grow_size = small_inc;
1610 grow_size = avail_size;
1645 char content_length_buf[128];
1646 size_t content_length_len;
1649 const char *reason_phrase;
1651 bool client_requested_close;
1652 bool response_has_close;
1653 bool response_has_keepalive;
1654 const char *have_encoding;
1656 int must_add_chunked_encoding;
1657 int must_add_keep_alive;
1658 int must_add_content_length;
1659 int may_add_content_length;
1662 if (0 == connection->
version[0])
1677 off = MHD_snprintf_ (code,
1699 datelen = strlen (date);
1714 must_add_chunked_encoding =
MHD_NO;
1715 must_add_keep_alive =
MHD_NO;
1716 must_add_content_length =
MHD_NO;
1717 response_has_close =
false;
1718 switch (connection->
state)
1733 #ifdef UPGRADE_SUPPORT 1734 else if (
NULL != response->upgrade_handler)
1743 if (
NULL == have_encoding)
1744 may_add_content_length =
MHD_YES;
1746 may_add_content_length =
MHD_NO;
1748 #ifdef UPGRADE_SUPPORT
1749 (
NULL == response->upgrade_handler) &&
1751 (! response_has_close) &&
1752 (! client_requested_close) )
1763 if (
NULL == have_encoding)
1765 must_add_chunked_encoding =
MHD_YES;
1786 if (! response_has_close)
1792 if ( ( (client_requested_close) ||
1795 (! response_has_close) &&
1796 #ifdef UPGRADE_SUPPORT
1797 (
NULL == response->upgrade_handler) &&
1804 if ( (! may_add_content_length) &&
1806 (! response_has_close) )
1819 (may_add_content_length) &&
1840 = MHD_snprintf_ (content_length_buf,
1841 sizeof (content_length_buf),
1844 must_add_content_length =
MHD_YES;
1848 if ( (! response_has_keepalive) &&
1849 (! response_has_close) &&
1850 (
MHD_NO == must_add_close) &&
1852 #ifdef UPGRADE_SUPPORT
1853 (
NULL == response->upgrade_handler) &&
1856 must_add_keep_alive =
MHD_YES;
1859 response_has_keepalive =
false;
1868 if ( (must_add_close) || (response_has_close) )
1870 else if ( (must_add_keep_alive) || (response_has_keepalive) )
1876 if (must_add_keep_alive)
1878 if (must_add_chunked_encoding)
1880 if (must_add_content_length)
1881 size += content_length_len;
1882 mhd_assert (! (must_add_close && must_add_keep_alive) );
1883 mhd_assert (! (must_add_chunked_encoding && must_add_content_length) );
1889 (! ( (
MHD_YES == must_add_close) &&
1890 (response_has_keepalive) &&
1896 "Keep-Alive")) ) ) )
1905 #ifdef HAVE_MESSAGES 1906 MHD_DLOG (connection->
daemon,
1907 "Not enough memory for write!\n");
1921 "Connection: close\r\n",
1925 if (must_add_keep_alive)
1929 "Connection: Keep-Alive\r\n",
1933 if (must_add_chunked_encoding)
1937 "Transfer-Encoding: chunked\r\n",
1941 if (must_add_content_length)
1946 content_length_len);
1947 off += content_length_len;
1953 (! ( (
MHD_YES == must_add_close) &&
1954 (response_has_keepalive) &&
1960 "Keep-Alive")) ) ) )
1961 off += MHD_snprintf_ (&
data[off],
2003 unsigned int status_code,
2004 const char *message)
2027 #ifdef HAVE_MESSAGES 2028 MHD_DLOG (connection->
daemon,
2029 _(
"Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"),
2041 if (
NULL == response)
2055 _(
"Closing connection (failed to queue response)\n"));
2065 _(
"Closing connection (failed to create response header)\n"));
2088 #ifdef HTTPS_SUPPORT 2091 switch (connection->tls_state)
2097 if (0 == gnutls_record_get_direction (connection->tls_session))
2110 MHD_DLOG (connection->
daemon,
2111 _(
"In function %s handling connection at state: %s\n"),
2113 MHD_state_to_string (connection->
state));
2115 switch (connection->
state)
2149 const bool internal_poll = (0 != (connection->
daemon->
options &
2225 #ifdef UPGRADE_SUPPORT 2226 case MHD_CONNECTION_UPGRADE:
2262 while ( (pos < connection->read_buffer_offset - 1) &&
2263 (
'\r' != rbuf[pos]) &&
2264 (
'\n' != rbuf[pos]) )
2267 (
'\n' != rbuf[pos]) )
2287 if ( (
'\r' == rbuf[pos]) &&
2288 (
'\n' == rbuf[pos + 1]) )
2327 #ifdef HAVE_MESSAGES 2328 MHD_DLOG (connection->
daemon,
2329 _(
"Not enough memory in pool to allocate header record!\n"));
2373 #ifdef HAVE_MESSAGES 2374 MHD_DLOG (connection->
daemon,
2375 _(
"Not enough memory in pool to parse cookies!\n"));
2385 cpy[hdr_len] =
'\0';
2393 while ( ((*sce) !=
'\0') &&
2400 while ( (*ekill ==
' ') &&
2424 while ( (
'\0' != semicolon[0]) &&
2426 ( (
';' != semicolon[0]) &&
2427 (
',' != semicolon[0]) ) ) )
2429 if (
'"' == semicolon[0])
2430 quotes = (quotes + 1) & 1;
2434 if (
'\0' == semicolon[0])
2436 if (
NULL != semicolon)
2438 semicolon[0] =
'\0';
2442 if ( (
'"' == equals[0]) &&
2481 unsigned int unused_num_headers;
2483 if (
NULL == (uri = memchr (line,
2488 connection->
method = line;
2492 while ( (
' ' == uri[0]) &&
2493 ( (
size_t)(uri - line) < line_len) )
2495 if ((
size_t)(uri - line) == line_len)
2508 http_version = line + line_len - 1;
2510 while ( (
' ' == http_version[0]) &&
2511 (http_version > uri) )
2514 while ( (
' ' != http_version[0]) &&
2515 (http_version > uri) )
2517 if (http_version > uri)
2520 http_version[0] =
'\0';
2521 connection->
version = http_version + 1;
2522 uri_len = http_version - uri;
2527 uri_len = line_len - (uri - line);
2531 (
NULL != memchr (uri,
2563 &unused_num_headers);
2571 connection->
url = curi;
2605 _(
"Application reported internal error, closing connection.\n"));
2645 size_t to_be_processed;
2646 size_t left_unprocessed;
2647 size_t processed_size;
2660 if ( (
'\r' == buffer_head[i]) ||
2661 (
'\n' == buffer_head[i]) )
2663 if ( (
'\r' == buffer_head[i]) ||
2664 (
'\n' == buffer_head[i]) )
2670 _(
"Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2681 uint64_t cur_chunk_left;
2687 if (cur_chunk_left > available)
2688 to_be_processed = available;
2691 to_be_processed = (size_t)cur_chunk_left;
2692 if (available > to_be_processed)
2704 while (i < available)
2706 if ( (
'\r' == buffer_head[i]) ||
2707 (
'\n' == buffer_head[i]) ||
2708 (
';' == buffer_head[i]) )
2716 if (
';' == buffer_head[i])
2718 while (i < available)
2720 if ( (
'\r' == buffer_head[i]) ||
2721 (
'\n' == buffer_head[i]) )
2729 if ( (i + 1 >= available) &&
2732 (
'0' == buffer_head[0]) ) )
2735 malformed = (end_size >= 16);
2741 malformed = (end_size != num_dig);
2747 _(
"Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2751 if ( (i < available) &&
2752 ( (
'\r' == buffer_head[i]) ||
2753 (
'\n' == buffer_head[i]) ) )
2785 to_be_processed = available;
2788 left_unprocessed = to_be_processed;
2802 _(
"Application reported internal error, closing connection.\n"));
2805 if (left_unprocessed > to_be_processed)
2809 #ifdef HAVE_MESSAGES
2810 ,
_(
"libmicrohttpd API violation")
2815 if (0 != left_unprocessed)
2818 #ifdef HAVE_MESSAGES 2825 _(
"WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n"));
2828 processed_size = to_be_processed - left_unprocessed;
2832 buffer_head += processed_size;
2833 available -= processed_size;
2837 while (
MHD_YES == instant_retry);
2838 if ( (available > 0) &&
2864 connection->
state = next_state;
2891 colon = strchr (line,
':');
2896 _(
"Received malformed line (no colon). Closing connection.\n"));
2906 white = strchr (line,
' ');
2907 if ( (
NULL != white) &&
2910 white = strchr (line,
'\t');
2911 if ( (
NULL != white) &&
2918 while ( (
'\0' != colon[0]) &&
2919 ( (
' ' == colon[0]) ||
2920 (
'\t' == colon[0]) ) )
2927 connection->
last = line;
2928 connection->
colon = colon;
2953 last = connection->
last;
2954 if ( (
' ' == line[0]) ||
2959 last_len = strlen (last);
2962 while ( (
' ' == tmp[0]) ||
2965 tmp_len = strlen (tmp);
2978 last_len + tmp_len + 1);
2986 memcpy (&last[last_len],
2989 connection->
last = last;
2999 strlen (connection->
colon),
3056 #ifdef HAVE_MESSAGES 3057 MHD_DLOG (connection->
daemon,
3058 _(
"Received HTTP 1.1 request without `Host' header.\n"));
3065 if (
NULL == response)
3069 _(
"Closing connection (failed to create response)\n"));
3080 _(
"Closing connection (failed to queue response)\n"));
3109 if ( (clen == end) ||
3113 #ifdef HAVE_MESSAGES 3114 MHD_DLOG (connection->
daemon,
3115 "Failed to parse `Content-Length' header. Closing connection.\n");
3150 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3160 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3180 #ifdef HTTPS_SUPPORT 3200 bytes_read = connection->
recv_cls (connection,
3214 _(
"Socket disconnected while reading request.\n"));
3220 _(
"Connection socket is closed due to error when reading request.\n"));
3224 if (0 == bytes_read)
3234 MHD_DLOG (connection->
daemon,
3235 _(
"In function %s handling connection at state: %s\n"),
3237 MHD_state_to_string (connection->
state));
3239 switch (connection->
state)
3259 #ifdef UPGRADE_SUPPORT 3260 case MHD_CONNECTION_UPGRADE:
3290 #ifdef HTTPS_SUPPORT 3302 MHD_DLOG (connection->
daemon,
3303 _(
"In function %s handling connection at state: %s\n"),
3305 MHD_state_to_string (connection->
state));
3307 switch (connection->
state)
3318 ret = connection->
send_cls (connection,
3327 #ifdef HAVE_MESSAGES 3328 MHD_DLOG (connection->
daemon,
3329 _(
"Failed to send data in request for %s.\n"),
3338 _(
"Sent 100 continue response: `%.*s'\n"),
3352 ret = connection->
send_cls (connection,
3362 _(
"Connection was closed while sending response headers.\n"));
3379 uint64_t data_write_offset;
3381 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3390 #if defined(_MHD_HAVE_SENDFILE) 3391 if (MHD_resp_sender_sendfile == connection->resp_sender)
3393 ret = sendfile_adapter (connection);
3402 if (data_write_offset > (uint64_t)
SIZE_MAX)
3404 ret = connection->
send_cls (connection,
3406 [(
size_t)data_write_offset],
3408 (
size_t)data_write_offset);
3412 _(
"Sent %d-byte DATA response: `%.*s'\n"),
3419 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3427 #ifdef HAVE_MESSAGES 3428 MHD_DLOG (connection->
daemon,
3429 _(
"Failed to send data in request for `%s'.\n"),
3447 ret = connection->
send_cls (connection,
3457 _(
"Connection was closed while sending response body.\n"));
3475 ret = connection->
send_cls (connection,
3485 _(
"Connection was closed while sending response body.\n"));
3500 #ifdef UPGRADE_SUPPORT 3501 case MHD_CONNECTION_UPGRADE:
3508 _(
"Internal error\n"));
3536 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3568 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3576 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
3577 (! MHD_itc_activate_ (daemon->
itc,
"c")) )
3579 #ifdef HAVE_MESSAGES 3581 _(
"Failed to signal end of connection via inter-thread communication channel"));
3609 #ifdef HTTPS_SUPPORT 3612 if ((MHD_TLS_CONN_INIT <= connection->tls_state) &&
3619 _(
"In function %s handling connection at state: %s\n"),
3621 MHD_state_to_string (connection->
state));
3623 switch (connection->
state)
3632 if ( (
NULL == line) ||
3854 _(
"Closing connection (failed to create response header)\n"));
3872 #ifdef UPGRADE_SUPPORT 3876 connection->
state = MHD_CONNECTION_UPGRADE;
3911 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3917 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3926 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3943 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3951 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3960 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 3977 _(
"Closing connection (failed to create response header)\n"));
4069 #ifdef UPGRADE_SUPPORT 4070 case MHD_CONNECTION_UPGRADE:
4084 if ( (0 != timeout) &&
4095 #ifdef EPOLL_SUPPORT 4099 ret = MHD_connection_epoll_update_ (connection);
4107 #ifdef EPOLL_SUPPORT 4130 struct epoll_event event;
4132 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
4133 event.data.ptr = connection;
4134 if (0 != epoll_ctl (daemon->epoll_fd,
4139 #ifdef HAVE_MESSAGES 4142 _(
"Call to epoll_ctl failed: %s\n"),
4186 #ifdef HTTPS_SUPPORT 4188 if (
NULL == connection->tls_session)
4190 connection->cipher = gnutls_cipher_get (connection->tls_session);
4193 if (
NULL == connection->tls_session)
4195 connection->protocol = gnutls_protocol_get_version (connection->tls_session);
4198 if (
NULL == connection->tls_session)
4244 daemon = connection->
daemon;
4250 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4265 va_start (ap, option);
4281 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4304 unsigned int status_code,
4309 if ( (
NULL == connection) ||
4310 (
NULL == response) ||
4315 daemon = connection->
daemon;
4321 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) 4324 (!MHD_thread_ID_match_current_(connection->
pid.ID)) )
4326 #ifdef HAVE_MESSAGES 4328 _(
"Attempted to queue response on wrong thread!\n"));
4333 #ifdef UPGRADE_SUPPORT 4334 if ( (
NULL != response->upgrade_handler) &&
4337 #ifdef HAVE_MESSAGES 4339 _(
"Attempted 'upgrade' connection on daemon without MHD_ALLOW_UPGRADE option!\n"));
4344 (
NULL != response->upgrade_handler) )
4346 #ifdef HAVE_MESSAGES 4348 _(
"Application used invalid status code for 'upgrade' response!\n"));
4356 #if defined(_MHD_HAVE_SENDFILE) 4357 if ( (response->
fd == -1) ||
4359 connection->resp_sender = MHD_resp_sender_std;
4361 connection->resp_sender = MHD_resp_sender_sendfile;
static int process_header_line(struct MHD_Connection *connection, char *line)
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
#define MHD_send_(s, b, l)
int(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
_MHD_EXTERN int MHD_get_connection_values_n(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIteratorN iterator, void *iterator_cls)
static int parse_cookie_header(struct MHD_Connection *connection)
void * unescape_callback_cls
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)
void MHD_connection_handle_write(struct MHD_Connection *connection)
Header for platform missing functions.
static int try_ready_normal_body(struct MHD_Connection *connection)
uint64_t current_chunk_offset
_MHD_EXTERN const char * MHD_lookup_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
#define MHD_HTTP_METHOD_CONNECT
static void MHD_connection_update_event_loop_info(struct MHD_Connection *connection)
struct sockaddr_storage addr
struct MHD_Connection * cleanup_head
enum MHD_CONNECTION_STATE state
static int try_ready_chunked_body(struct MHD_Connection *connection)
#define MHD_lookup_header_s_token_ci(c, h, tkn)
uint64_t response_write_position
enum MHD_ConnKeepAlive keepalive
size_t MHD_str_to_uint64_(const char *str, uint64_t *out_val)
#define HTTP_100_CONTINUE
enum MHD_ConnectionEventLoopInfo event_loop_info
#define MHD_mutex_unlock_chk_(pmutex)
size_t MHD_pool_get_free(struct MemoryPool *pool)
time_t connection_timeout
Methods for managing connections.
MHD_PanicCallback mhd_panic
#define MHD_socket_get_error_()
internal monotonic clock functions implementations
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
struct MHD_Response * response
#define REQUEST_LACKS_HOST
#define MHD_SENFILE_CHUNK_
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_HTTP_NOT_MODIFIED
bool MHD_str_has_token_caseless_(const char *str, const char *const token, size_t token_len)
bool MHD_parse_arguments_(struct MHD_Request *request, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
struct MHD_Connection * manual_timeout_head
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
MHD_RequestTerminationCode
MHD_thread_handle_ID_ pid
int MHD_str_equal_caseless_(const char *str1, const char *str2)
_MHD_static_inline bool socket_start_no_buffering_flush(struct MHD_Connection *connection)
time_t MHD_monotonic_sec_counter(void)
static void transmit_error_response(struct MHD_Connection *connection, unsigned int status_code, const char *message)
MHD_AccessHandlerCallback default_handler
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
static void call_connection_handler(struct MHD_Connection *connection)
uint64_t remaining_upload_size
unsigned int responseCode
#define MHD_ERR_CONNRESET_
Methods for managing response objects.
static void cleanup_connection(struct MHD_Connection *connection)
void MHD_update_last_activity_(struct MHD_Connection *connection)
#define MHD_UNSIGNED_LONG_LONG
void * uri_log_callback_cls
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
struct MHD_Daemon * daemon
int MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
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_check_response_header_s_token_ci(r, k, tkn)
#define MHD_SENFILE_CHUNK_THR_P_C_
Header for platform-independent inter-thread communication.
static void connection_close_error(struct MHD_Connection *connection, const char *emsg)
void * MHD_pool_reset(struct MemoryPool *pool, void *keep, size_t copy_bytes, size_t new_size)
_MHD_EXTERN const union MHD_ConnectionInfo * MHD_get_connection_info(struct MHD_Connection *connection, enum MHD_ConnectionInfoType info_type,...)
static int keepalive_possible(struct MHD_Connection *connection)
#define DLL_insert(head, tail, element)
void MHD_increment_response_rc(struct MHD_Response *response)
#define MHD_HTTP_URI_TOO_LONG
struct MHD_HTTP_Header * first_header
#define MHD_socket_last_strerr_()
size_t write_buffer_send_offset
struct MHD_Connection * connections_tail
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, int from_end)
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)
bool sk_tcp_cork_nopush_on
size_t continue_message_write_offset
#define REQUEST_MALFORMED
#define MHD_INVALID_SOCKET
size_t MHD_strx_to_uint64_n_(const char *str, size_t maxlen, uint64_t *out_val)
internal shared structures
enum MHD_HTTP_StatusCode status_code
#define MHD_SCKT_SEND_MAX_SIZE_
void * MHD_pool_reallocate(struct MemoryPool *pool, void *old, size_t old_size, size_t new_size)
struct MHD_Connection * connections_head
_MHD_static_inline bool socket_start_normal_buffering(struct MHD_Connection *connection)
#define MHD_HTTP_NO_CONTENT
LogCallback uri_log_callback
void MHD_connection_handle_read(struct MHD_Connection *connection)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
time_t connection_timeout
_MHD_EXTERN int MHD_set_connection_option(struct MHD_Connection *connection, enum MHD_CONNECTION_OPTION option,...)
#define MHD_SCKT_ERR_IS_(err, code)
Methods for managing connections.
#define MHD_CONTENT_READER_END_OF_STREAM
#define EDLL_remove(head, tail, element)
struct MHD_Connection * manual_timeout_tail
static void get_date_string(char *date, size_t date_len)
Header for string manipulating helpers.
#define DLL_remove(head, tail, element)
static int need_100_continue(struct MHD_Connection *connection)
#define MHD_STATICSTR_LEN_(macro)
#define MHD_HTTP_VERSION_1_1
struct MHD_Connection * normal_timeout_head
void MHD_pool_destroy(struct MemoryPool *pool)
#define MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
UnescapeCallback unescape_callback
_MHD_EXTERN int MHD_queue_response(struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
#define XDLL_remove(head, tail, element)
unsigned int connection_timeout_dummy
#define MHD_HTTP_BAD_REQUEST
_MHD_EXTERN struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
struct MHD_Connection * suspended_connections_tail
static int check_write_done(struct MHD_Connection *connection, enum MHD_CONNECTION_STATE next_state)
bool MHD_run_tls_handshake_(struct MHD_Connection *connection)
struct MHD_Connection * cleanup_tail
int MHD_connection_handle_idle(struct MHD_Connection *connection)
static int process_broken_line(struct MHD_Connection *connection, char *line, enum MHD_ValueKind kind)
enum MHD_ResponseFlags flags
#define MHD_recv_(s, b, l)
#define MHD_HTTP_METHOD_HEAD
static void parse_connection_headers(struct MHD_Connection *connection)
size_t write_buffer_append_offset
struct MHD_Connection * normal_timeout_tail
MHD_RequestCompletedCallback notify_completed
#define MHD_mutex_lock_chk_(pmutex)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
#define MHD_HTTP_METHOD_PUT
void * notify_completed_cls
static void process_request_body(struct MHD_Connection *connection)
#define MHD_HTTP_VERSION_1_0
TransmitCallback send_cls
_MHD_EXTERN int MHD_get_connection_values(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls)
#define MHD_HTTP_INTERNAL_SERVER_ERROR
#define MHD_CONTENT_READER_END_WITH_ERROR
MHD_ContentReaderCallback crc
static int parse_initial_message_line(struct MHD_Connection *connection, char *line, size_t line_len)
#define XDLL_insert(head, tail, element)
_MHD_static_inline bool socket_flush_possible(struct MHD_Connection *connection)
#define MHD_UNSIGNED_LONG_LONG_PRINTF
#define MHD_HTTP_PROCESSING
#define MHD_SCKT_ECONNRESET_
_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)
struct MHD_Connection * suspended_connections_head
_MHD_static_inline bool socket_start_no_buffering(struct MHD_Connection *connection)
size_t read_buffer_offset
static char * get_next_header_line(struct MHD_Connection *connection, size_t *line_len)
void * default_handler_cls
_MHD_EXTERN const char * MHD_get_response_header(struct MHD_Response *response, const char *key)
#define MHD_SCKT_ERR_IS_EINTR_(err)
MHD_mutex_ cleanup_connection_mutex
#define CONNECTION_CLOSE_ERROR(c, emsg)
uint64_t current_chunk_size
struct MHD_HTTP_Header * headers_received
#define MHD_HTTP_SWITCHING_PROTOCOLS
limits values definitions
_MHD_EXTERN const char * MHD_get_reason_phrase_for(unsigned int code)
_MHD_static_inline bool socket_start_extra_buffering(struct MHD_Connection *connection)
bool MHD_tls_connection_shutdown(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 MHD_HTTP_Header * headers_received_tail
static int build_header_response(struct MHD_Connection *connection)
#define MHD_HTTP_METHOD_POST
bool MHD_str_equal_caseless_bin_n_(const char *const str1, const char *const str2, size_t len)
int(* MHD_KeyValueIteratorN)(void *cls, enum MHD_ValueKind kind, const char *key, size_t key_size, const char *value, size_t value_size)