30 #ifdef MHD_LINUX_SOLARIS_SENDFILE 31 #include <sys/sendfile.h> 33 #if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_DARWIN_SENDFILE) 34 #include <sys/types.h> 35 #include <sys/socket.h> 43 #define MHD_SENFILE_CHUNK_ (0x20000) 48 #define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000) 59 #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>" 61 #define REQUEST_TOO_BIG "" 72 #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>" 74 #define REQUEST_LACKS_HOST "" 85 #define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>" 87 #define REQUEST_MALFORMED "" 97 #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>" 99 #define INTERNAL_ERROR "" 103 #ifdef HAVE_FREEBSD_SENDFILE 108 static int freebsd_sendfile_flags_;
113 static int freebsd_sendfile_flags_thd_p_c_;
123 MHD_conn_init_static_ (
void)
129 long sys_page_size = sysconf (_SC_PAGESIZE);
130 if (0 > sys_page_size)
132 freebsd_sendfile_flags_ = SF_NODISKIO;
133 freebsd_sendfile_flags_thd_p_c_ = SF_NODISKIO;
137 freebsd_sendfile_flags_ =
139 freebsd_sendfile_flags_thd_p_c_ =
151 #define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n" 164 enum MHD_StatusCode sc,
169 MHD_DLOG (connection->
daemon,
186 #define CONNECTION_CLOSE_ERROR(c, sc, emsg) connection_close_error (c, sc, emsg) 188 #define CONNECTION_CLOSE_ERROR(c, sc, emsg) connection_close_error (c, sc, NULL) 247 if ( (
NULL != (tls = daemon->tls_api)) &&
249 connection->tls_cs)) )
263 bytes_read = connection->
recv_cls (connection,
276 ? MHD_SC_CONNECTION_CLOSED
277 : MHD_SC_CONNECTION_RESET_CLOSED,
280 :
_(
"Socket disconnected while reading request.\n"));
285 ? MHD_SC_CONNECTION_CLOSED
286 : MHD_SC_CONNECTION_READ_FAIL_CLOSED,
289 :
_(
"Connection socket is closed due to error when reading request.\n"));
304 MHD_SC_STATE_MACHINE_STATUS_REPORT,
305 _(
"In function %s handling connection at state: %s\n"),
307 MHD_state_to_string (request->
state));
309 switch (request->
state)
329 #ifdef UPGRADE_SUPPORT 330 case MHD_REQUEST_UPGRADE:
346 #if defined(_MHD_HAVE_SENDFILE) 360 const int file_fd = response->
fd;
363 #ifndef HAVE_SENDFILE64 364 const uint64_t max_off_t = (uint64_t)
OFF_T_MAX;
366 const uint64_t max_off_t = (uint64_t)OFF64_T_MAX;
368 #ifdef MHD_LINUX_SOLARIS_SENDFILE 369 #ifndef HAVE_SENDFILE64 375 #ifdef HAVE_FREEBSD_SENDFILE 379 #ifdef HAVE_DARWIN_SENDFILE 382 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->
threading_mode);
384 size_t send_size = 0;
386 mhd_assert (MHD_resp_sender_sendfile == request->resp_sender);
391 send_size = (left > chunk_size) ? chunk_size : (
size_t) left;
392 if (max_off_t < offsetu64)
394 request->resp_sender = MHD_resp_sender_std;
397 #ifdef MHD_LINUX_SOLARIS_SENDFILE 398 #ifndef HAVE_SENDFILE64 399 offset = (off_t) offsetu64;
405 offset = (off64_t) offsetu64;
425 #ifdef HAVE_LINUX_SENDFILE 434 request->resp_sender = MHD_resp_sender_std;
437 if ( (EAFNOSUPPORT == err) ||
439 (EOPNOTSUPP == err) )
441 request->resp_sender = MHD_resp_sender_std;
444 if ( (ENOTCONN == err) ||
453 else if (send_size > (
size_t)ret)
456 #elif defined(HAVE_FREEBSD_SENDFILE) 458 flags = used_thr_p_c ?
459 freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_;
461 if (0 != sendfile (file_fd,
476 return (ssize_t)sent_bytes;
482 request->resp_sender = MHD_resp_sender_std;
487 ret = (ssize_t)sent_bytes;
488 #elif defined(HAVE_DARWIN_SENDFILE) 489 len = (off_t) send_size;
490 if (0 != sendfile (file_fd,
509 if (ENOTCONN == err ||
512 if (ENOTSUP == err ||
516 request->resp_sender = MHD_resp_sender_std;
548 request->
state = next_state;
586 #if defined(_MHD_HAVE_SENDFILE) 587 if (MHD_resp_sender_sendfile ==
request->resp_sender)
611 MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED,
612 _(
"Closing connection (application reported error generating data)\n"));
652 2 * (0xFFFFFF +
sizeof(cbuf) + 2));
661 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
662 _(
"Closing connection (out of memory)\n"));
683 const size_t data_write_offset
686 ret = response->
data_size - data_write_offset;
690 &response->
data[data_write_offset],
707 MHD_SC_APPLICATION_DATA_GENERATION_FAILURE_CLOSED,
708 _(
"Closing connection (application error generating response)\n"));
731 cblen = MHD_snprintf_(cbuf,
770 if ( (
NULL != (tls = daemon->tls_api)) &&
772 connection->tls_cs)) )
779 MHD_SC_STATE_MACHINE_STATUS_REPORT,
780 _(
"In function %s handling connection at state: %s\n"),
782 MHD_state_to_string (request->
state));
784 switch (request->
state)
795 ret = connection->
send_cls (connection,
806 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
807 _(
"Failed to send data in request for %s.\n"),
811 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
825 ret = connection->
send_cls (connection,
835 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
836 _(
"Connection was closed while sending response headers.\n"));
853 uint64_t data_write_offset;
862 #if defined(_MHD_HAVE_SENDFILE) 863 if (MHD_resp_sender_sendfile == request->resp_sender)
865 ret = sendfile_adapter (connection);
874 if (data_write_offset > (uint64_t)
SIZE_MAX)
876 ret = connection->
send_cls (connection,
878 [(
size_t)data_write_offset],
880 (
size_t)data_write_offset);
884 _(
"Sent %d-byte DATA response: `%.*s'\n"),
899 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
900 _(
"Failed to send data in request for `%s'.\n"),
904 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
919 ret = connection->
send_cls (connection,
929 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
930 _(
"Connection was closed while sending response body.\n"));
948 ret = connection->
send_cls (connection,
958 MHD_SC_CONNECTION_WRITE_FAIL_CLOSED,
959 _(
"Connection was closed while sending response body.\n"));
974 #ifdef UPGRADE_SUPPORT 975 case MHD_REQUEST_UPGRADE:
982 MHD_SC_STATEMACHINE_FAILURE_CONNECTION_CLOSED,
983 _(
"Internal error\n"));
1010 if ( (
NULL == request) ||
1042 #define MHD_lookup_header_s_token_ci(r,h,tkn) \ 1043 MHD_lookup_header_token_ci((r),(h),(tkn),MHD_STATICSTR_LEN_(tkn)) 1110 static const char *
const days[] = {
1111 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" 1113 static const char *
const mons[] = {
1114 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
1115 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" 1119 #if !defined(HAVE_C11_GMTIME_S) && !defined(HAVE_W32_GMTIME_S) && !defined(HAVE_GMTIME_R) 1125 #if defined(HAVE_C11_GMTIME_S) 1126 if (
NULL == gmtime_s (&t,
1129 #elif defined(HAVE_W32_GMTIME_S) 1130 if (0 != gmtime_s (&now,
1133 #elif defined(HAVE_GMTIME_R) 1134 if (
NULL == gmtime_r(&t,
1143 MHD_snprintf_ (date,
1145 "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
1146 days[now.tm_wday % 7],
1147 (
unsigned int) now.tm_mday,
1148 mons[now.tm_mon % 12],
1149 (
unsigned int) (1900 + now.tm_year),
1150 (
unsigned int) now.tm_hour,
1151 (
unsigned int) now.tm_min,
1152 (
unsigned int) now.tm_sec);
1177 if ( (
NULL == key) ||
1180 (
'\0' == token[0]) )
1210 #define check_response_header_s_token_ci(r,k,tkn) \ 1211 check_response_header_token_ci((r),(k),(tkn),MHD_STATICSTR_LEN_(tkn)) 1235 char content_length_buf[128];
1236 size_t content_length_len;
1239 bool client_requested_close;
1240 bool response_has_close;
1241 bool response_has_keepalive;
1242 const char *have_encoding;
1243 const char *have_content_length;
1244 bool must_add_close;
1245 bool must_add_chunked_encoding;
1246 bool must_add_keep_alive;
1247 bool must_add_content_length;
1263 const char *reason_phrase;
1264 const char *version;
1275 MHD_snprintf_ (code,
1281 off = strlen (code);
1292 datelen = strlen (date);
1306 must_add_close =
false;
1307 must_add_chunked_encoding =
false;
1308 must_add_keep_alive =
false;
1309 must_add_content_length =
false;
1310 response_has_close =
false;
1311 switch (request->
state)
1318 response_has_keepalive
1322 client_requested_close
1329 #ifdef UPGRADE_SUPPORT 1330 else if (
NULL != response->upgrade_handler)
1339 #ifdef UPGRADE_SUPPORT
1340 (
NULL == response->upgrade_handler) &&
1342 (! response_has_close) &&
1343 (! client_requested_close) )
1357 if (
NULL == have_encoding)
1359 must_add_chunked_encoding =
true;
1366 must_add_close =
true;
1377 if (! response_has_close)
1378 must_add_close =
true;
1383 if ( ( (client_requested_close) ||
1386 (! response_has_close) &&
1387 #ifdef UPGRADE_SUPPORT
1388 (
NULL == response->upgrade_handler) &&
1391 must_add_close =
true;
1404 (MHD_HTTP_OK <= response->status_code) &&
1405 (
NULL == have_content_length) &&
1406 (request->
method != MHD_METHOD_CONNECT) )
1424 = MHD_snprintf_ (content_length_buf,
1425 sizeof (content_length_buf),
1428 must_add_content_length =
true;
1432 if ( (! response_has_keepalive) &&
1433 (! response_has_close) &&
1434 (! must_add_close) &&
1436 #ifdef UPGRADE_SUPPORT
1437 (
NULL == response->upgrade_handler) &&
1440 must_add_keep_alive =
true;
1443 response_has_keepalive =
false;
1452 if ( (must_add_close) ||
1453 (response_has_close) )
1455 else if ( (must_add_keep_alive) ||
1456 (response_has_keepalive) )
1462 if (must_add_keep_alive)
1464 if (must_add_chunked_encoding)
1466 if (must_add_content_length)
1467 size += content_length_len;
1468 mhd_assert (! (must_add_close && must_add_keep_alive) );
1469 mhd_assert (! (must_add_chunked_encoding && must_add_content_length) );
1475 (! ( (must_add_close) &&
1476 (response_has_keepalive) &&
1480 "Keep-Alive")) ) ) )
1481 size += strlen (pos->
header) + strlen (pos->
value) + 4;
1489 #ifdef HAVE_MESSAGES 1491 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
1492 "Not enough memory for write!\n");
1506 "Connection: close\r\n",
1510 if (must_add_keep_alive)
1514 "Connection: Keep-Alive\r\n",
1518 if (must_add_chunked_encoding)
1522 "Transfer-Encoding: chunked\r\n",
1526 if (must_add_content_length)
1531 content_length_len);
1532 off += content_length_len;
1538 (! ( (must_add_close) &&
1539 (response_has_keepalive) &&
1543 "Keep-Alive")) ) ) )
1544 off += MHD_snprintf_ (&
data[off],
1587 enum MHD_StatusCode ec,
1588 enum MHD_HTTP_StatusCode status_code,
1589 const char *message)
1601 #ifdef HAVE_MESSAGES 1602 MHD_DLOG (request->
daemon,
1604 _(
"Error processing request (HTTP response code is %u (`%s')). Closing connection.\n"),
1625 _(
"Closing connection (failed to create response header)\n"));
1640 static enum MHD_Method
1643 static const struct {
1645 enum MHD_Method value;
1647 {
"OPTIONS", MHD_METHOD_OPTIONS },
1648 {
"GET", MHD_METHOD_GET },
1649 {
"HEAD", MHD_METHOD_HEAD },
1650 {
"POST", MHD_METHOD_POST },
1651 {
"PUT", MHD_METHOD_PUT },
1652 {
"DELETE", MHD_METHOD_DELETE },
1653 {
"TRACE", MHD_METHOD_TRACE },
1654 {
"CONNECT", MHD_METHOD_CONNECT },
1655 {
"ACL", MHD_METHOD_ACL },
1656 {
"BASELINE_CONTROL", MHD_METHOD_BASELINE_CONTROL },
1657 {
"BIND", MHD_METHOD_BIND },
1658 {
"CHECKIN", MHD_METHOD_CHECKIN },
1659 {
"CHECKOUT", MHD_METHOD_CHECKOUT },
1660 {
"COPY", MHD_METHOD_COPY },
1661 {
"LABEL", MHD_METHOD_LABEL },
1662 {
"LINK", MHD_METHOD_LINK },
1663 {
"LOCK", MHD_METHOD_LOCK },
1664 {
"MERGE", MHD_METHOD_MERGE },
1665 {
"MKACTIVITY", MHD_METHOD_MKACTIVITY },
1666 {
"MKCOL", MHD_METHOD_MKCOL },
1667 {
"MKREDIRECTREF", MHD_METHOD_MKREDIRECTREF },
1668 {
"MKWORKSPACE", MHD_METHOD_MKWORKSPACE },
1669 {
"MOVE", MHD_METHOD_MOVE },
1670 {
"ORDERPATCH", MHD_METHOD_ORDERPATCH },
1671 {
"PRI", MHD_METHOD_PRI },
1672 {
"PROPFIND", MHD_METHOD_PROPFIND },
1673 {
"PROPPATCH", MHD_METHOD_PROPPATCH },
1674 {
"REBIND", MHD_METHOD_REBIND },
1675 {
"REPORT", MHD_METHOD_REPORT },
1676 {
"SEARCH", MHD_METHOD_SEARCH },
1677 {
"UNBIND", MHD_METHOD_UNBIND },
1678 {
"UNCHECKOUT", MHD_METHOD_UNCHECKOUT },
1679 {
"UNLINK", MHD_METHOD_UNLINK },
1680 {
"UNLOCK", MHD_METHOD_UNLOCK },
1681 {
"UPDATE", MHD_METHOD_UPDATE },
1682 {
"UPDATEDIRECTREF", MHD_METHOD_UPDATEDIRECTREF },
1683 {
"VERSION-CONTROL", MHD_METHOD_VERSION_CONTROL },
1684 {
NULL, MHD_METHOD_UNKNOWN }
1688 for (i=0;
NULL != methods[i].key;i++)
1692 return methods[i].value;
1693 return MHD_METHOD_UNKNOWN;
1719 #ifdef HAVE_MESSAGES 1720 MHD_DLOG (request->
daemon,
1721 MHD_SC_CONNECTION_POOL_MALLOC_FAILURE,
1722 _(
"Not enough memory in pool to allocate header record!\n"));
1725 MHD_SC_CLIENT_HEADER_TOO_BIG,
1752 unsigned int unused_num_headers;
1755 if (
NULL == (uri = memchr (line,
1765 while ( (
' ' == uri[0]) &&
1766 ( (
size_t)(uri - line) < line_len) )
1768 if ((
size_t)(uri - line) == line_len)
1774 url_end = line_len - (line - uri);
1780 http_version = line + line_len - 1;
1782 while ( (
' ' == http_version[0]) &&
1783 (http_version > uri) )
1786 while ( (
' ' != http_version[0]) &&
1787 (http_version > uri) )
1789 if (http_version > uri)
1791 http_version[0] =
'\0';
1795 http_version - uri);
1802 line_len - (uri - line));
1804 url_end = http_version - uri;
1807 (
NULL != memchr (curi,
1830 &unused_num_headers);
1836 request->
url = curi;
1858 colon = strchr (line,
1864 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1865 _(
"Received malformed line (no colon). Closing connection.\n"));
1875 white = strchr (line,
1876 (
unsigned char)
' ');
1877 if ( (
NULL != white) &&
1881 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1882 _(
"Whitespace before colon forbidden by RFC 7230. Closing connection.\n"));
1885 white = strchr (line,
1886 (
unsigned char)
'\t');
1887 if ( (
NULL != white) &&
1891 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
1892 _(
"Tab before colon forbidden by RFC 7230. Closing connection.\n"));
1899 while ( (
'\0' !=
colon[0]) &&
1900 ( (
' ' ==
colon[0]) ||
1901 (
'\t' ==
colon[0]) ) )
1936 if ( (
' ' == line[0]) ||
1941 last_len = strlen (
last);
1944 while ( (
' ' == tmp[0]) ||
1947 tmp_len = strlen (tmp);
1960 last_len + tmp_len + 1);
1964 MHD_SC_CLIENT_HEADER_TOO_BIG,
1969 memcpy (&
last[last_len],
1983 MHD_SC_CLIENT_HEADER_TOO_BIG,
1989 if (
'\0' != line[0])
1995 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
2030 (
'\r' != rbuf[pos]) &&
2031 (
'\n' != rbuf[pos]) )
2034 (
'\n' != rbuf[pos]) )
2041 MHD_SC_CLIENT_HEADER_TOO_BIG,
2055 if ( (
'\r' == rbuf[pos]) &&
2056 (
'\n' == rbuf[pos + 1]) )
2089 #if defined(TCP_CORK) || defined(TCP_PUSH) 2109 #if defined(TCP_CORK) || defined(TCP_NOPUSH) 2111 #if defined(TCP_NODELAY) 2115 #if defined(TCP_NOPUSH) && !defined(TCP_CORK) 2117 res = (0 == setsockopt (connection->
socket_fd,
2120 (
const void *) &on_val,
2123 #if defined(TCP_NODELAY) 2126 res &= (0 == setsockopt (connection->
socket_fd,
2129 (
const void *) &off_val,
2134 #if defined(TCP_NODELAY) 2138 (void) setsockopt (connection->
socket_fd,
2141 (
const void *) &off_val,
2145 res = (0 == setsockopt (connection->
socket_fd,
2148 (
const void *) &on_val,
2166 #if defined(TCP_NODELAY) 2169 #if defined(TCP_CORK) || defined(TCP_NOPUSH) 2175 #if defined(TCP_CORK) 2177 res &= (0 == setsockopt (connection->
socket_fd,
2180 (
const void *) &off_val,
2184 #if defined(TCP_NODELAY) 2186 res &= (0 == setsockopt (connection->
socket_fd,
2189 (
const void *) &on_val,
2193 #if defined(TCP_NOPUSH) && !defined(TCP_CORK) 2195 res &= (0 == setsockopt (connection->
socket_fd,
2198 (
const void *) &off_val,
2220 #if defined(TCP_NOPUSH) && !defined(TCP_CORK) 2221 const int dummy = 0;
2224 if (
NULL == connection)
2227 #if defined(TCP_NOPUSH) && !defined(TCP_CORK) 2249 #if defined(TCP_NODELAY) 2252 #if defined(TCP_CORK) 2254 socklen_t param_size =
sizeof (cork_val);
2258 #if defined(TCP_CORK) 2262 if ( (0 != getsockopt (connection->
socket_fd,
2268 res &= (0 == setsockopt (connection->
socket_fd,
2271 (
const void *) &off_val,
2274 #elif defined(TCP_NOPUSH) 2278 res &= (0 == setsockopt (connection->
socket_fd,
2281 (
const void *) &off_val,
2286 res &= (0 == setsockopt (connection->
socket_fd,
2289 (
const void *) &off_val,
2354 #ifdef HAVE_MESSAGES 2356 MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE,
2357 _(
"Not enough memory in pool to parse cookies!\n"));
2360 MHD_SC_COOKIE_POOL_ALLOCATION_FAILURE,
2375 while ( ((*sce) !=
'\0') &&
2382 while ( (*ekill ==
' ') &&
2403 while ( (
'\0' != semicolon[0]) &&
2405 ( (
';' != semicolon[0]) &&
2406 (
',' != semicolon[0]) ) ) )
2408 if (
'"' == semicolon[0])
2409 quotes = (quotes + 1) & 1;
2412 if (
'\0' == semicolon[0])
2414 if (
NULL != semicolon)
2416 semicolon[0] =
'\0';
2420 if ( (
'"' == equals[0]) &&
2421 (
'"' == equals[strlen (equals) - 1]) )
2423 equals[strlen (equals) - 1] =
'\0';
2467 #ifdef HAVE_MESSAGES 2469 MHD_SC_HOST_HEADER_MISSING,
2470 _(
"Received HTTP 1.1 request without `Host' header.\n"));
2502 if ( (clen == end) ||
2506 #ifdef HAVE_MESSAGES 2507 MHD_DLOG (request->
daemon,
2508 MHD_SC_CONTENT_LENGTH_MALFORMED,
2509 "Failed to parse `Content-Length' header. Closing connection.\n");
2512 MHD_SC_CONTENT_LENGTH_MALFORMED,
2541 MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED,
2542 _(
"Application reported internal error, closing connection.\n"));
2572 size_t to_be_processed;
2573 size_t left_unprocessed;
2574 size_t processed_size;
2576 instant_retry =
false;
2588 if ( (
'\r' == buffer_head[i]) ||
2589 (
'\n' == buffer_head[i]) )
2591 if ( (
'\r' == buffer_head[i]) ||
2592 (
'\n' == buffer_head[i]) )
2598 MHD_SC_CHUNKED_ENCODING_MALFORMED,
2599 _(
"Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2610 uint64_t cur_chunk_left;
2617 if (cur_chunk_left > available)
2619 to_be_processed = available;
2623 to_be_processed = (size_t)cur_chunk_left;
2624 if (available > to_be_processed)
2625 instant_retry =
true;
2636 while (i < available)
2638 if ( (
'\r' == buffer_head[i]) ||
2639 (
'\n' == buffer_head[i]) ||
2640 (
';' == buffer_head[i]) )
2648 if (
';' == buffer_head[i])
2650 while (i < available)
2652 if ( (
'\r' == buffer_head[i]) ||
2653 (
'\n' == buffer_head[i]) )
2661 if ( (i + 1 >= available) &&
2664 (
'0' == buffer_head[0]) ) )
2667 malformed = (end_size >= 16);
2673 malformed = (end_size != num_dig);
2679 MHD_SC_CHUNKED_ENCODING_MALFORMED,
2680 _(
"Received malformed HTTP request (bad chunked encoding). Closing connection.\n"));
2684 if ( (i < available) &&
2685 ( (
'\r' == buffer_head[i]) ||
2686 (
'\n' == buffer_head[i]) ) )
2694 instant_retry =
true;
2718 to_be_processed = available;
2721 left_unprocessed = to_be_processed;
2735 MHD_SC_APPLICATION_CALLBACK_FAILURE_CLOSED,
2736 _(
"Application reported internal error, closing connection.\n"));
2740 if (left_unprocessed > to_be_processed)
2744 #ifdef HAVE_MESSAGES
2745 ,
_(
"libmicrohttpd API violation")
2750 if (0 != left_unprocessed)
2752 instant_retry =
false;
2753 #ifdef HAVE_MESSAGES 2760 MHD_SC_APPLICATION_HUNG_CONNECTION,
2761 _(
"WARNING: incomplete upload processing and connection not suspended may result in hung connection.\n"));
2764 processed_size = to_be_processed - left_unprocessed;
2768 buffer_head += processed_size;
2769 available -= processed_size;
2773 while (instant_retry);
2840 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
2841 (! MHD_itc_activate_ (daemon->
itc,
2844 #ifdef HAVE_MESSAGES 2846 MHD_SC_ITC_USE_FAILED,
2847 _(
"Failed to signal end of connection via inter-thread communication channel"));
2854 #ifdef EPOLL_SUPPORT 2877 struct epoll_event event;
2879 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2880 event.data.ptr = connection;
2881 if (0 != epoll_ctl (daemon->epoll_fd,
2886 #ifdef HAVE_MESSAGES 2888 MHD_SC_EPOLL_CTL_ADD_FAILED,
2889 _(
"Call to epoll_ctl failed: %s\n"),
2920 #ifdef HTTPS_SUPPORT 2924 if ( (
NULL != (tls = daemon->tls_api)) &&
2935 MHD_SC_STATE_MACHINE_STATUS_REPORT,
2936 _(
"In function %s handling connection at state: %s\n"),
2938 MHD_state_to_string (request->
state));
2940 switch (request->
state)
2951 MHD_SC_CLIENT_HEADER_TOO_BIG,
2990 MHD_SC_APPLICATION_HUNG_CONNECTION_CLOSED,
3009 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3051 #ifdef UPGRADE_SUPPORT 3052 case MHD_REQUEST_UPGRADE:
3086 #ifdef HTTPS_SUPPORT 3089 if ( (
NULL != (tls = daemon->tls_api)) &&
3091 connection->tls_cs)) )
3096 MHD_SC_STATE_MACHINE_STATUS_REPORT,
3097 _(
"In function %s handling connection at state: %s\n"),
3099 MHD_state_to_string (request->
state));
3101 switch (request->
state)
3110 if ( (
NULL == line) ||
3118 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3129 MHD_SC_CONNECTION_CLOSED,
3144 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3160 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
3177 MHD_SC_CONNECTION_READ_FAIL_CLOSED,
3217 ( (MHD_METHOD_POST == request->
method) ||
3218 (MHD_METHOD_PUT == request->
method) ) )
3275 MHD_SC_CONNECTION_CLOSED,
3292 MHD_SC_CONNECTION_PARSE_FAIL_CLOSED,
3309 MHD_SC_CONNECTION_CLOSED,
3338 MHD_SC_FAILED_RESPONSE_HEADER_GENERATION,
3339 _(
"Closing connection (failed to create response header)\n"));
3357 #ifdef UPGRADE_SUPPORT 3361 request->
state = MHD_REQUEST_UPGRADE;
3362 #if FIXME_LEGACY_STYLE 3369 MHD_SC_CONNECTION_CLOSED,
3452 MHD_SC_FAILED_RESPONSE_HEADER_GENERATION,
3453 _(
"Closing connection (failed to create response header)\n"));
3531 request->
daemon = daemon;
3538 #ifdef UPGRADE_SUPPORT 3539 case MHD_REQUEST_UPGRADE:
3553 if ( (0 != timeout) &&
3564 #ifdef EPOLL_SUPPORT 3568 ret = connection_epoll_update_ (connection);
3598 bool states_info_processed =
false;
3602 #ifdef HTTPS_SUPPORT 3614 states_info_processed =
true;
3624 states_info_processed =
true;
3634 if (! states_info_processed)
3649 else if (on_fasttrack &&
3683 #ifdef HTTPS_SUPPORT #define check_response_header_s_token_ci(r, k, tkn)
static void parse_request_headers(struct MHD_Request *request)
#define MHD_send_(s, b, l)
size_t continue_message_write_offset
struct MHD_Request request
enum MHD_EventLoopSyscall event_loop_syscall
#define REQUEST_LACKS_HOST
#define HTTP_100_CONTINUE
bool data_already_pending
size_t connection_memory_limit_b
static void get_date_string(char *date, size_t date_len)
MHD_EarlyUriLogCallback early_uri_logger_cb
struct MHD_Connection * cleanup_head
size_t MHD_str_to_uint64_(const char *str, uint64_t *out_val)
size_t read_buffer_offset
#define MHD_mutex_unlock_chk_(pmutex)
MHD_PanicCallback mhd_panic
void * termination_cb_cls
#define MHD_socket_get_error_()
uint64_t current_chunk_size
enum MHD_ProtocolStrictLevel protocol_strict_level
static bool check_response_header_token_ci(const struct MHD_Response *response, const char *key, const char *token, size_t token_len)
enum MHD_Bool MHD_request_set_value(struct MHD_Request *request, enum MHD_ValueKind kind, const char *key, const char *value)
struct MHD_Response * response
MHD_RequestTerminationCallback termination_cb
#define REQUEST_MALFORMED
#define MHD_HTTP_NOT_MODIFIED
const char * MHD_request_lookup_value(struct MHD_Request *request, enum MHD_ValueKind kind, const char *key)
static bool build_header_response(struct MHD_Request *request)
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
int MHD_str_equal_caseless_(const char *str1, const char *str2)
time_t MHD_monotonic_sec_counter(void)
static bool check_write_done(struct MHD_Request *request, enum MHD_REQUEST_STATE next_state)
static void cleanup_connection(struct MHD_Connection *connection)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
static bool try_ready_chunked_body(struct MHD_Request *request)
#define MHD_lookup_header_s_token_ci(r, h, tkn)
uint64_t current_chunk_offset
internal shared structures
static void transmit_error_response(struct MHD_Request *request, enum MHD_StatusCode ec, enum MHD_HTTP_StatusCode status_code, const char *message)
static enum MHD_Method method_string_to_enum(const char *method)
#define MHD_ERR_CONNRESET_
static bool socket_start_extra_buffering(struct MHD_Connection *connection)
#define MHD_UNSIGNED_LONG_LONG
struct MHD_Daemon * daemon
int MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
static bool socket_start_normal_buffering(struct MHD_Connection *connection)
function to update last activity of a connection
time_t connection_default_timeout
enum MHD_REQUEST_STATE state
enum MHD_ConnKeepAlive keepalive
static bool MHD_lookup_header_token_ci(const struct MHD_Request *request, const char *header, const char *token, size_t token_len)
struct MHD_Daemon * daemon
void * MHD_pool_reset(struct MemoryPool *pool, void *keep, size_t copy_bytes, size_t new_size)
#define DLL_insert(head, tail, element)
#define MHD_HTTP_URI_TOO_LONG
static bool process_header_line(struct MHD_Request *request, char *line)
static void MHD_request_handle_read_(struct MHD_Request *request)
struct MHD_HTTP_Header * first_header
#define MHD_socket_last_strerr_()
struct MHD_Connection * connections_tail
#define MHD_SENFILE_CHUNK_THR_P_C_
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, int from_end)
functions to close connection
struct MHD_Response * MHD_response_from_buffer(enum MHD_HTTP_StatusCode sc, size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
static bool socket_start_no_buffering(struct MHD_Connection *connection)
MHD_UnescapeCallback unescape_cb
static bool process_broken_line(struct MHD_Request *request, char *line, enum MHD_ValueKind kind)
size_t MHD_strx_to_uint64_n_(const char *str, size_t maxlen, uint64_t *out_val)
enum MHD_HTTP_StatusCode status_code
size_t connection_memory_increment_b
void * MHD_pool_reallocate(struct MemoryPool *pool, void *old, size_t old_size, size_t new_size)
struct MHD_Connection * connections_head
static bool socket_start_no_buffering_flush(struct MHD_Connection *connection)
#define MHD_HTTP_NO_CONTENT
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
uint64_t remaining_upload_size
time_t connection_timeout
#define MHD_SCKT_ERR_IS_(err, code)
enum MHD_RequestEventLoopInfo event_loop_info
#define MHD_CONTENT_READER_END_OF_STREAM
struct MHD_Connection * manual_timeout_tail
function to call event handlers based on event mask
static bool need_100_continue(struct MHD_Request *request)
static bool socket_flush_possible(struct MHD_Connection *connection)
static int parse_cookie_header(struct MHD_Request *request)
#define DLL_remove(head, tail, element)
static bool try_grow_read_buffer(struct MHD_Request *request)
#define MHD_STATICSTR_LEN_(macro)
#define MHD_HTTP_VERSION_1_1
struct MHD_Connection * normal_timeout_head
int MHD_connection_call_handlers_(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
void MHD_pool_destroy(struct MemoryPool *pool)
#define MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
static void call_request_handler(struct MHD_Request *request)
#define XDLL_remove(head, tail, element)
#define MHD_HTTP_BAD_REQUEST
static void connection_close_error(struct MHD_Connection *connection, enum MHD_StatusCode sc, const char *emsg)
struct MHD_Connection * suspended_connections_tail
struct MHD_Connection * cleanup_tail
struct MHD_HTTP_Header * headers_received
static void process_request_body(struct MHD_Request *request)
static bool try_ready_normal_body(struct MHD_Request *request)
#define CONNECTION_CLOSE_ERROR(c, sc, emsg)
enum MHD_ResponseFlags flags
size_t write_buffer_send_offset
struct MHD_Connection * normal_timeout_tail
struct MHD_Response * response
#define MHD_mutex_lock_chk_(pmutex)
void * early_uri_logger_cb_cls
static bool request_add_header(struct MHD_Request *request, const char *key, const char *value, enum MHD_ValueKind kind)
#define MHD_HTTP_VERSION_1_0
TransmitCallback send_cls
static bool keepalive_possible(struct MHD_Request *request)
#define MHD_HTTP_INTERNAL_SERVER_ERROR
uint64_t response_write_position
#define MHD_CONTENT_READER_END_WITH_ERROR
MHD_ContentReaderCallback crc
enum MHD_Bool(* handshake)(void *cls, struct MHD_TLS_ConnectionState *cs)
static char * get_next_header_line(struct MHD_Request *request, size_t *line_len)
size_t write_buffer_append_offset
static void MHD_request_handle_write_(struct MHD_Request *request)
#define MHD_UNSIGNED_LONG_LONG_PRINTF
struct MHD_Connection * connection
#define MHD_HTTP_PROCESSING
struct MHD_Connection * suspended_connections_head
size_t read_buffer_offset
static void connection_update_event_loop_info(struct MHD_Connection *connection)
enum MHD_ThreadingMode threading_mode
#define MHD_SCKT_ERR_IS_EINTR_(err)
#define MHD_SENFILE_CHUNK_
void MHD_connection_update_last_activity_(struct MHD_Connection *connection)
bool MHD_request_handle_idle_(struct MHD_Request *request)
enum MHD_Bool(* idle_ready)(void *cls, struct MHD_TLS_ConnectionState *cs)
MHD_mutex_ cleanup_connection_mutex
static bool parse_initial_message_line(struct MHD_Request *request, char *line, size_t line_len)
_MHD_EXTERN const char * MHD_get_reason_phrase_for(unsigned int code)
const char * MHD_response_get_header(struct MHD_Response *response, const char *key)
enum MHD_Bool(* update_event_loop_info)(void *cls, struct MHD_TLS_ConnectionState *cs, enum MHD_RequestEventLoopInfo *eli)
void MHD_response_queue_for_destroy(struct MHD_Response *response)