35#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
41#ifdef MHD_LINUX_SOLARIS_SENDFILE
42#include <sys/sendfile.h>
44#if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_DARWIN_SENDFILE)
46#include <sys/socket.h>
52#ifdef HAVE_SYS_PARAM_H
65#define MHD_ALLOW_BARE_LF_AS_CRLF_(discp_lvl) (0 >= discp_lvl)
75#define MHD_CHUNK_HEADER_REASONABLE_LEN 24
80#define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
87#define ERR_MSG_REQUEST_TOO_BIG \
89 "<head><title>Request too big</title></head>" \
90 "<body>Request HTTP header is too big for the memory constraints " \
91 "of this webserver.</body>" \
94#define ERR_MSG_REQUEST_TOO_BIG ""
101#define ERR_MSG_REQUEST_HEADER_TOO_BIG \
103 "<head><title>Request too big</title></head>" \
104 "<body><p>The total size of the request headers, which includes the " \
105 "request target and the request field lines, exceeds the memory " \
106 "constraints of this web server.</p>" \
107 "<p>The request could be re-tried with shorter field lines, a shorter " \
108 "request target or a shorter request method token.</p></body>" \
111#define ERR_MSG_REQUEST_HEADER_TOO_BIG ""
118#define ERR_MSG_REQUEST_HEADER_WITH_COOKIES_TOO_BIG \
120 "<head><title>Request too big</title></head>" \
121 "<body><p>The total size of the request headers, which includes the " \
122 "request target and the request field lines, exceeds the memory " \
123 "constraints of this web server.</p> " \
124 "<p>The request could be re-tried with smaller " \
125 "<b>"Cookie:"</b> field value, shorter other field lines, " \
126 "a shorter request target or a shorter request method token.</p></body> " \
129#define ERR_MSG_REQUEST_HEADER_WITH_COOKIES_TOO_BIG ""
137#define ERR_MSG_REQUEST_CHUNK_LINE_EXT_TOO_BIG \
139 "<head><title>Request too big</title></head>" \
140 "<body><p>The total size of the request target, the request field lines " \
141 "and the chunk size line exceeds the memory constraints of this web " \
143 "<p>The request could be re-tried without chunk extensions, with a smaller " \
144 "chunk size, shorter field lines, a shorter request target or a shorter " \
145 "request method token.</p></body>" \
148#define ERR_MSG_REQUEST_CHUNK_LINE_EXT_TOO_BIG ""
156#define ERR_MSG_REQUEST_CHUNK_LINE_TOO_BIG \
158 "<head><title>Request too big</title></head>" \
159 "<body><p>The total size of the request target, the request field lines " \
160 "and the chunk size line exceeds the memory constraints of this web " \
162 "<p>The request could be re-tried with a smaller " \
163 "chunk size, shorter field lines, a shorter request target or a shorter " \
164 "request method token.</p></body>" \
167#define ERR_MSG_REQUEST_CHUNK_LINE_TOO_BIG ""
174#define ERR_MSG_REQUEST_FOOTER_TOO_BIG \
176 "<head><title>Request too big</title></head>" \
177 "<body><p>The total size of the request headers, which includes the " \
178 "request target, the request field lines and the chunked trailer " \
179 "section exceeds the memory constraints of this web server.</p>" \
180 "<p>The request could be re-tried with a shorter chunked trailer " \
181 "section, shorter field lines, a shorter request target or " \
182 "a shorter request method token.</p></body>" \
185#define ERR_MSG_REQUEST_FOOTER_TOO_BIG ""
192#define RQ_LINE_TOO_MANY_WSP \
194 "<head><title>Request broken</title></head>" \
195 "<body>The request line has more then two whitespaces.</body>" \
198#define RQ_LINE_TOO_MANY_WSP ""
206#define BARE_CR_IN_HEADER \
208 "<head><title>Request broken</title></head>" \
209 "<body>Request HTTP header has bare CR character without " \
210 "following LF character.</body>" \
213#define BARE_CR_IN_HEADER ""
221#define BARE_CR_IN_FOOTER \
223 "<head><title>Request broken</title></head>" \
224 "<body>Request HTTP footer has bare CR character without " \
225 "following LF character.</body>" \
228#define BARE_CR_IN_FOOTER ""
236#define BARE_LF_IN_HEADER \
238 "<head><title>Request broken</title></head>" \
239 "<body>Request HTTP header has bare LF character without " \
240 "preceding CR character.</body>" \
243#define BARE_LF_IN_HEADER ""
251#define BARE_LF_IN_FOOTER \
253 "<head><title>Request broken</title></head>" \
254 "<body>Request HTTP footer has bare LF character without " \
255 "preceding CR character.</body>" \
258#define BARE_LF_IN_FOOTER ""
265#define RQ_TARGET_INVALID_CHAR \
267 "<head><title>Request broken</title></head>" \
268 "<body>HTTP request has invalid characters in " \
269 "the request-target.</body>" \
272#define RQ_TARGET_INVALID_CHAR ""
279#define ERR_RSP_OBS_FOLD \
281 "<head><title>Request broken</title></head>" \
282 "<body>Obsolete line folding is used in HTTP request header.</body>" \
285#define ERR_RSP_OBS_FOLD ""
292#define ERR_RSP_OBS_FOLD_FOOTER \
294 "<head><title>Request broken</title></head>" \
295 "<body>Obsolete line folding is used in HTTP request footer.</body>" \
298#define ERR_RSP_OBS_FOLD_FOOTER ""
306#define ERR_RSP_WSP_BEFORE_HEADER \
308 "<head><title>Request broken</title></head>" \
309 "<body>HTTP request has whitespace between the request line and " \
310 "the first header.</body>" \
313#define ERR_RSP_WSP_BEFORE_HEADER ""
321#define ERR_RSP_WSP_BEFORE_FOOTER \
323 "<head><title>Request broken</title></head>" \
324 "<body>First HTTP footer line has whitespace at the first " \
328#define ERR_RSP_WSP_BEFORE_FOOTER ""
336#define ERR_RSP_WSP_IN_HEADER_NAME \
338 "<head><title>Request broken</title></head>" \
339 "<body>HTTP request has whitespace before the first colon " \
340 "in header line.</body>" \
343#define ERR_RSP_WSP_IN_HEADER_NAME ""
351#define ERR_RSP_WSP_IN_FOOTER_NAME \
353 "<head><title>Request broken</title></head>" \
354 "<body>HTTP request has whitespace before the first colon " \
355 "in footer line.</body>" \
358#define ERR_RSP_WSP_IN_FOOTER_NAME ""
367#define ERR_RSP_INVALID_CHAR_IN_FIELD_NAME \
369 "<head><title>Request broken</title></head>" \
370 "<body>HTTP request has invalid character in field name.</body>" \
373#define ERR_RSP_INVALID_CHAR_IN_FIELD_NAME ""
380#define ERR_RSP_INVALID_CHR_IN_HEADER \
382 "<head><title>Request broken</title></head>" \
383 "<body>HTTP request has invalid character in header.</body>" \
386#define ERR_RSP_INVALID_CHR_IN_HEADER ""
393#define ERR_RSP_INVALID_CHR_IN_FOOTER \
395 "<head><title>Request broken</title></head>" \
396 "<body>HTTP request has invalid character in footer.</body>" \
399#define ERR_RSP_INVALID_CHR_IN_FOOTER ""
406#define ERR_RSP_HEADER_WITHOUT_COLON \
408 "<head><title>Request broken</title></head>" \
409 "<body>HTTP request header line has no colon character.</body>" \
412#define ERR_RSP_HEADER_WITHOUT_COLON ""
419#define ERR_RSP_FOOTER_WITHOUT_COLON \
421 "<head><title>Request broken</title></head>" \
422 "<body>HTTP request footer line has no colon character.</body>" \
425#define ERR_RSP_FOOTER_WITHOUT_COLON ""
432#define ERR_RSP_EMPTY_HEADER_NAME \
434 "<head><title>Request broken</title></head>" \
435 "<body>HTTP request header has empty header name.</body>" \
438#define ERR_RSP_EMPTY_HEADER_NAME ""
445#define ERR_RSP_EMPTY_FOOTER_NAME \
447 "<head><title>Request broken</title></head>" \
448 "<body>HTTP request footer has empty footer name.</body>" \
451#define ERR_RSP_EMPTY_FOOTER_NAME ""
462#define REQUEST_LACKS_HOST \
464 "<head><title>"Host:" header required</title></head>" \
465 "<body>HTTP/1.1 request without <b>"Host:"</b>.</body>" \
469#define REQUEST_LACKS_HOST ""
475#define REQUEST_MULTIPLE_HOST_HDR \
477 "<head><title>Multiple "Host:" headers</title></head>" \
478 "<body>Request contains several <b>"Host:"</b> headers." \
486#define REQUEST_AMBIGUOUS_CONTENT_LENGTH \
488 "<head><title>"Content-Length:" header must be unique</title></head>" \
489 "<body>HTTP/1.1 request with multiple <b>"Content-Length:"</b> headers.</body>" \
493#define REQUEST_AMBIGUOUS_CONTENT_LENGTH ""
500#define REQUEST_UNSUPPORTED_TR_ENCODING \
502 "<head><title>Unsupported Transfer-Encoding</title></head>" \
503 "<body>The Transfer-Encoding used in request is not supported.</body>" \
506#define REQUEST_UNSUPPORTED_TR_ENCODING ""
514#define REQUEST_LENGTH_WITH_TR_ENCODING \
516 "<head><title>Malformed request</title></head>" \
517 "<body>Wrong combination of the request headers: both Transfer-Encoding " \
518 "and Content-Length headers are used at the same time.</body>" \
521#define REQUEST_LENGTH_WITH_TR_ENCODING ""
527#define REQUEST_HTTP1_0_TR_ENCODING \
528 "<html><head><title>Malformed request</title></head>" \
529 "<body><b>"Transfer-Encoding:"</b> must not be used " \
530 "with HTTP/1.0.</body></html>"
540#define REQUEST_MALFORMED \
541 "<html><head><title>Request malformed</title></head>" \
542 "<body>HTTP request is syntactically incorrect.</body></html>"
544#define REQUEST_MALFORMED ""
550#define REQUEST_HAS_NUL_CHAR_IN_PATH \
551 "<html><head><title>Bad Request Path</title></head>" \
552 "<body>The request path contains invalid characters.</body></html>"
559#define REQUEST_CHUNKED_MALFORMED \
560 "<html><head><title>Request malformed</title></head>" \
561 "<body>HTTP chunked encoding is syntactically incorrect.</body></html>"
563#define REQUEST_CHUNKED_MALFORMED ""
570#define REQUEST_CHUNK_TOO_LARGE \
571 "<html><head><title>Request content too large</title></head>" \
572 "<body>The chunk size used in HTTP chunked encoded " \
573 "request is too large.</body></html>"
575#define REQUEST_CHUNK_TOO_LARGE ""
582#define REQUEST_CONTENTLENGTH_TOOLARGE \
583 "<html><head><title>Request content too large</title></head>" \
584 "<body>HTTP request has too large value for " \
585 "<b>Content-Length</b> header.</body></html>"
587#define REQUEST_CONTENTLENGTH_TOOLARGE ""
595#define REQUEST_CONTENTLENGTH_MALFORMED \
596 "<html><head><title>Request malformed</title></head>" \
597 "<body>HTTP request has wrong value for " \
598 "<b>Content-Length</b> header.</body></html>"
600#define REQUEST_CONTENTLENGTH_MALFORMED ""
610#define ERROR_MSG_DATA_NOT_HANDLED_BY_APP \
611 "<html><head><title>Internal server error</title></head>" \
612 "<body>Please ask the developer of this Web server to carefully " \
613 "read the GNU libmicrohttpd documentation about connection " \
614 "management and blocking.</body></html>"
616#define ERROR_MSG_DATA_NOT_HANDLED_BY_APP ""
623#define REQ_HTTP_VER_IS_TOO_OLD \
624 "<html><head><title>Requested HTTP version is not supported</title></head>" \
625 "<body>Requested HTTP version is too old and not " \
626 "supported.</body></html>"
628#define REQ_HTTP_VER_IS_TOO_OLD ""
635#define REQ_HTTP_VER_IS_NOT_SUPPORTED \
636 "<html><head><title>Requested HTTP version is not supported</title></head>" \
637 "<body>Requested HTTP version is not supported.</body></html>"
639#define REQ_HTTP_VER_IS_NOT_SUPPORTED ""
646#define MHD_SENFILE_CHUNK_ (0x20000)
651#define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000)
660str_conn_error_ (ssize_t mhd_err_code)
662 switch (mhd_err_code)
665 return _ (
"The operation would block, retry later");
667 return _ (
"The connection was forcibly closed by remote peer");
669 return _ (
"The socket is not connected");
671 return _ (
"Not enough system resources to serve the request");
673 return _ (
"Bad FD value");
675 return _ (
"Argument value is invalid");
677 return _ (
"Argument value is not supported");
679 return _ (
"The socket is no longer available for sending");
681 return _ (
"TLS encryption or decryption error");
685 if (0 <= mhd_err_code)
686 return _ (
"Not an error code");
689 return _ (
"Wrong error code value");
709 struct MemoryPool *
const pool = c->
pool;
710 size_t need_to_be_freed = 0;
803 connection->epoll_state &=
826 else if (i > (
size_t) ret)
827 connection->epoll_state &=
841 if (
NULL != uri_size)
852 *uri = connection->
rq.
url;
853 if (
NULL != uri_size)
881 if (
NULL == connection)
888 if ( (
NULL != iterator) &&
889 (
MHD_NO == iterator (iterator_cls,
920 if (
NULL == connection)
924 if (
NULL == iterator)
935 if (
MHD_NO == iterator (iterator_cls,
1038 ( ((key ? strlen (key) : 0) != key_size) ||
1116 (
NULL == key) ? 0 : strlen (key),
1147 const char **value_ptr,
1148 size_t *value_size_ptr)
1152 if (
NULL == connection)
1170 ( (key == pos->
header) ||
1181 if (
NULL != value_ptr)
1182 *value_ptr = pos->
value;
1184 if (
NULL != value_size_ptr)
1216 (
NULL == token) || (0 == token[0]))
1245#define MHD_lookup_header_s_token_ci(c,h,tkn) \
1246 MHD_lookup_header_token_ci ((c),(h),MHD_STATICSTR_LEN_ (h), \
1247 (tkn),MHD_STATICSTR_LEN_ (tkn))
1338#ifdef MHD_USE_THREADS
1364#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1379 struct MHD_UpgradeResponseHandle *urh = connection->urh;
1381#ifdef MHD_USE_THREADS
1396 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1401 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
1403 if (urh->in_eready_list)
1406 daemon->eready_urh_tail,
1408 urh->in_eready_list =
false;
1415 (0 != epoll_ctl (daemon->epoll_upgrade_fd,
1420 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
1425 shutdown (urh->mhd.socket, SHUT_RDWR);
1453 MHD_DLOG (connection->
daemon,
1469#define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, emsg)
1471#define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, NULL)
1514 _ (
"Closing connection (out of memory)."));
1531#if defined(_MHD_HAVE_SENDFILE)
1532 if (MHD_resp_sender_sendfile == connection->
rp.resp_sender)
1541 (
char *) response->
data,
1551#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1559 _ (
"Closing connection (application reported " \
1560 "error generating data)."));
1568#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1595 static const size_t max_chunk = 0xFFFFFF;
1598 static const size_t max_chunk_hdr_len =
sizeof(chunk_hdr) + 2;
1600 static const size_t max_chunk_overhead =
sizeof(chunk_hdr) + 2 + 2;
1601 size_t chunk_hdr_len;
1602 uint64_t left_to_send;
1603 size_t size_to_fill;
1618#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1623 _ (
"Closing connection (out of memory)."));
1627 if ( (max_chunk + max_chunk_overhead) < size)
1628 size = max_chunk + max_chunk_overhead;
1641 mhd_assert (max_chunk_overhead < connection->write_buffer_size);
1651 if (max_chunk < size_to_fill)
1652 size_to_fill = max_chunk;
1653 if (left_to_send < size_to_fill)
1654 size_to_fill = (size_t) left_to_send;
1656 if (0 == left_to_send)
1666 const size_t data_write_offset
1672 ret = (ssize_t) (response->
data_size - data_write_offset);
1673 if ( ((
size_t) ret) > size_to_fill)
1674 ret = (ssize_t) size_to_fill;
1676 &response->
data[data_write_offset],
1683#if defined(MHD_USE_THREADS)
1687 _ (
"No callback for the chunked data."));
1700#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1704 _ (
"Closing connection (application error " \
1705 "generating response)."));
1718#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1723 if (size_to_fill < (
size_t) ret)
1725#if defined(MHD_USE_THREADS)
1729 _ (
"Closing connection (application returned " \
1730 "more data than requested)."));
1736 mhd_assert (chunk_hdr_len <
sizeof(chunk_hdr));
1737 *p_finished =
false;
1739 (max_chunk_hdr_len - (chunk_hdr_len + 2));
1743 connection->
write_buffer[max_chunk_hdr_len - 2] =
'\r';
1744 connection->
write_buffer[max_chunk_hdr_len - 1] =
'\n';
1745 connection->
write_buffer[max_chunk_hdr_len + (size_t) ret] =
'\r';
1746 connection->
write_buffer[max_chunk_hdr_len + (size_t) ret + 1] =
'\n';
1785#ifdef UPGRADE_SUPPORT
1788 if (
NULL != r->upgrade_handler)
1846 static const char *
const days[] = {
1847 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
1849 static const char *
const mons[] = {
1850 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
1851 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
1853 static const size_t buf_len = 29;
1857#if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \
1858 ! defined(HAVE_GMTIME_R)
1862 if ((time_t) -1 == time (&t))
1864#if defined(HAVE_C11_GMTIME_S)
1865 if (
NULL == gmtime_s (&t,
1868#elif defined(HAVE_W32_GMTIME_S)
1869 if (0 != gmtime_s (&now,
1872#elif defined(HAVE_GMTIME_R)
1873 if (
NULL == gmtime_r (&t,
1884 src = days[now.tm_wday % 7];
1892 date + 5, buf_len - 5))
1896 src = mons[now.tm_mon % 12];
1971 if (0 == avail_size)
1974 new_size = avail_size / 2;
1979 grow_size = avail_size / 8;
1980 if (def_grow_size > grow_size)
1982 const size_t left_free =
1986 if ((def_grow_size <= grow_size + left_free)
1987 && (left_free < def_grow_size))
1988 grow_size = def_grow_size - left_free;
1989 else if (! required)
1994 const size_t small_inc =
1997 if (small_inc < avail_size)
1998 grow_size = small_inc;
2000 grow_size = avail_size;
2085 struct MemoryPool *
const pool = connection->
pool;
2134connection_shrink_write_buffer (
struct MHD_Connection *connection)
2137 struct MemoryPool *
const pool = connection->
pool;
2241#ifdef UPGRADE_SUPPORT
2252 (2 == rcode / 100) )
2297#ifdef UPGRADE_SUPPORT
2310 use_chunked =
false;
2314 use_chunked =
false;
2324 use_chunked =
false;
2334 use_chunked =
false;
2359 _ (
"This reply with response code %u cannot use reply body. "
2360 "Non-empty response body is ignored and not used.\n"),
2367 _ (
"This reply with response code %u cannot use reply body. "
2368 "Application defined \"Content-Length\" header violates"
2369 "HTTP specification.\n"),
2398 if (buf_size < *ppos + append_size)
2400 memcpy (buf + *ppos, append, append_size);
2401 *ppos += append_size;
2416#define buffer_append_s(buf,ppos,buf_size,str) \
2417 buffer_append (buf,ppos,buf_size,str, MHD_STATICSTR_LEN_ (str))
2444 bool filter_transf_enc,
2445 bool filter_content_len,
2447 bool add_keep_alive)
2453 mhd_assert (! add_close || ! add_keep_alive);
2456 filter_transf_enc =
false;
2458 filter_content_len =
false;
2462 add_keep_alive =
false;
2469 size_t initial_pos = *ppos;
2472 if (filter_transf_enc)
2479 filter_transf_enc =
false;
2483 if (filter_content_len)
2499 if (buf_size < *ppos + el_size)
2503 buf[(*ppos)++] =
':';
2504 buf[(*ppos)++] =
' ';
2505 if (add_close || add_keep_alive)
2515 if (buf_size < initial_pos + el_size)
2517 memcpy (buf + *ppos,
"close, ",
2524 if (buf_size < initial_pos + el_size)
2526 memcpy (buf + *ppos,
"Keep-Alive, ",
2531 add_keep_alive =
false;
2536 buf[(*ppos)++] =
'\r';
2537 buf[(*ppos)++] =
'\n';
2538 mhd_assert (initial_pos + el_size == (*ppos));
2562 bool use_conn_close;
2563 bool use_conn_k_alive;
2574#ifdef UPGRADE_SUPPORT
2583#ifdef UPGRADE_SUPPORT
2595 use_conn_close =
true;
2596 use_conn_k_alive =
false;
2600 use_conn_close =
false;
2608 use_conn_k_alive =
true;
2610 use_conn_k_alive =
false;
2614 use_conn_close =
false;
2615 use_conn_k_alive =
false;
2654 if (buf_size < pos + 5)
2674 if (buf_size < pos + 2)
2688 if (buf_size < pos + 38)
2694 mhd_assert (! use_conn_close || ! use_conn_k_alive);
2695 mhd_assert (! use_conn_k_alive || ! use_conn_close);
2704 else if (use_conn_k_alive)
2755 if (buf_size < pos + 2)
2765 if (buf_size < pos + 2)
2807 buf[used_size++] =
'0';
2808 buf[used_size++] =
'\r';
2809 buf[used_size++] =
'\n';
2815 size_t new_used_size;
2818 if (new_used_size > buf_size)
2822 buf[used_size++] =
':';
2823 buf[used_size++] =
' ';
2826 buf[used_size++] =
'\r';
2827 buf[used_size++] =
'\n';
2831 if (used_size + 2 > buf_size)
2833 buf[used_size++] =
'\r';
2834 buf[used_size++] =
'\n';
2861 unsigned int status_code,
2862 const char *message,
2865 size_t header_name_len,
2867 size_t header_value_len)
2878 free (header_value);
2884 MHD_DLOG (connection->
daemon,
2885 _ (
"Error processing request (HTTP response code is %u ('%s')). " \
2886 "Closing connection.\n"),
2893 MHD_DLOG (connection->
daemon,
2894 _ (
"Too late to send an error response, " \
2895 "response is being sent already.\n"),
2900 _ (
"Too late for error response."));
2902 free (header_value);
2925 if (
NULL == response)
2928 MHD_DLOG (connection->
daemon,
2929 _ (
"Failed to create error response.\n"),
2936 free (header_value);
2945 if (
NULL != header_name)
2949 header_name, header_name_len,
2950 header_value, header_value_len);
2954 free (header_value);
2976 _ (
"Closing connection " \
2977 "(failed to queue error response)."));
3008 _ (
"Closing connection " \
3009 "(failed to create error response header)."));
3021# define transmit_error_response_static(c, code, msg) \
3022 transmit_error_response_len (c, code, \
3023 msg, MHD_STATICSTR_LEN_ (msg), \
3026# define transmit_error_response_static(c, code, msg) \
3027 transmit_error_response_len (c, code, \
3036# define transmit_error_response_header(c, code, m, hd_n, hd_n_l, hd_v, hd_v_l) \
3037 transmit_error_response_len (c, code, \
3038 m, MHD_STATICSTR_LEN_ (m), \
3042# define transmit_error_response_header(c, code, m, hd_n, hd_n_l, hd_v, hd_v_l) \
3043 transmit_error_response_len (c, code, \
3097#ifndef MHD_MAX_REASONABLE_HEADERS_SIZE_
3107# define MHD_MAX_REASONABLE_HEADERS_SIZE_ (6 * 1024)
3110#ifndef MHD_MAX_REASONABLE_REQ_TARGET_SIZE_
3121# define MHD_MAX_REASONABLE_REQ_TARGET_SIZE_ 8000
3124#ifndef MHD_MIN_REASONABLE_HEADERS_SIZE_
3132# define MHD_MIN_REASONABLE_HEADERS_SIZE_ 26
3135#ifndef MHD_MIN_REASONABLE_REQ_TARGET_SIZE_
3143# define MHD_MIN_REASONABLE_REQ_TARGET_SIZE_ 40
3146#ifndef MHD_MIN_REASONABLE_REQ_METHOD_SIZE_
3154# define MHD_MIN_REASONABLE_REQ_METHOD_SIZE_ 16
3157#ifndef MHD_MIN_REASONABLE_REQ_CHUNK_LINE_LENGTH_
3163# define MHD_MIN_REASONABLE_REQ_CHUNK_LINE_LENGTH_ 4
3181 const char *add_element,
3182 size_t add_element_size)
3186 size_t opt_headers_size;
3187 size_t host_field_line_size;
3215 host_field_line_size = 0;
3220 && (0 != add_element_size))
3222 static const size_t header_host_key_len =
3224 const bool is_host_header =
3225 (header_host_key_len + 1 <= add_element_size)
3226 && ( (0 == add_element[header_host_key_len])
3227 || (
':' == add_element[header_host_key_len]) )
3230 header_host_key_len);
3233 const bool is_parsed = ! (
3237 size_t actual_element_size;
3239 mhd_assert (! is_parsed || (0 == add_element[header_host_key_len]));
3245 actual_element_size = add_element_size + 1;
3247 actual_element_size = add_element_size;
3249 host_field_line_size = actual_element_size;
3250 mhd_assert (opt_headers_size >= actual_element_size);
3251 opt_headers_size -= actual_element_size;
3254 if (0 == host_field_line_size)
3256 static const size_t host_field_name_len =
3258 size_t host_field_name_value_len;
3262 host_field_name_len,
3264 &host_field_name_value_len))
3268 host_field_line_size =
3269 host_field_name_len + host_field_name_value_len + 2;
3272 if (opt_headers_size >= host_field_line_size)
3274 opt_headers_size -= host_field_line_size;
3276 if (opt_headers_size >= 2)
3277 opt_headers_size -= 2;
3280 host_field_line_size = 0;
3290 method_size = strlen (c->
rq.
method);
3297 if (opt_headers_size > (uri_size / 8))
3299 if ((opt_headers_size / 2) > method_size)
3306 if ((uri_size / 16) > method_size)
3316 if ((uri_size / 16) > method_size)
3327 if ((opt_headers_size * 4) > uri_size)
3329 if (opt_headers_size > method_size)
3336 if (uri_size > method_size * 4)
3345 if (uri_size > method_size * 4)
3364 if ((1 < opt_headers_size) || (1 < uri_size))
3366 if (opt_headers_size >= uri_size)
3374 if (0 != host_field_line_size)
3393 const char *add_header,
3394 size_t add_header_size)
3396 unsigned int err_code;
3408#ifdef COOKIE_SUPPORT
3417 unsigned int err_code;
3444 const char *chunk_size_line,
3445 size_t chunk_size_line_size)
3447 unsigned int err_code;
3449 if (
NULL != chunk_size_line)
3451 const char *semicol;
3453 semicol = memchr (chunk_size_line,
';', chunk_size_line_size);
3454 if (
NULL != semicol)
3465 chunk_size_line_size);
3484 const char *add_footer,
3485 size_t add_footer_size)
3487 (void) add_footer; (void) add_footer_size;
3542 _ (
"No space left in the read buffer when " \
3543 "receiving the initial part of " \
3544 "the request line."));
3562 _ (
"No space left in the read buffer when " \
3563 "receiving the URI in " \
3564 "the request line. " \
3565 "The request uses non-standard HTTP request " \
3664 bool rbuff_grow_desired;
3668 bool rbuff_grow_required;
3674 if (rbuff_grow_required)
3675 rbuff_grow_desired =
true;
3681 if ((rbuff_grow_desired) &&
3689 rbuff_grow_desired =
3696 rbuff_grow_desired =
3701 const uint64_t cur_chunk_left =
3706 rbuff_grow_desired =
3713 if (! rbuff_grow_desired)
3719 if (! rbuff_grow_required)
3785#ifdef UPGRADE_SUPPORT
3786 case MHD_CONNECTION_UPGRADE:
3816 switch (connection->tls_state)
3823 if (0 == gnutls_record_get_direction (connection->tls_session))
3839 MHD_PANIC (
_ (
"Invalid TLS state value.\n"));
3846 MHD_DLOG (connection->
daemon,
3847 _ (
"In function %s handling connection at state: %s\n"),
3849 MHD_state_to_string (connection->
state));
3851 switch (connection->
state)
3943#ifdef UPGRADE_SUPPORT
3944 case MHD_CONNECTION_UPGRADE:
3996 MHD_DLOG (connection->
daemon,
3997 _ (
"Not enough memory in pool to allocate header record!\n"));
4008#ifdef COOKIE_SUPPORT
4013enum _MHD_ParseCookie
4015 MHD_PARSE_COOKIE_OK =
MHD_YES,
4016 MHD_PARSE_COOKIE_OK_LAX = 2,
4017 MHD_PARSE_COOKIE_MALFORMED = -1,
4018 MHD_PARSE_COOKIE_NO_MEMORY =
MHD_NO
4034static enum _MHD_ParseCookie
4035parse_cookies_string (
char *str,
4036 const size_t str_len,
4062 while (
' ' == str[i] ||
'\t' == str[i] ||
';' == str[i])
4064 if (! allow_wsp_empty)
4065 return MHD_PARSE_COOKIE_MALFORMED;
4069 return non_strict? MHD_PARSE_COOKIE_OK_LAX : MHD_PARSE_COOKIE_OK;
4076 const char l = str[i];
4077 if ((
'=' == l) || (
' ' == l) || (
'\t' == l) || (
'"' == l) || (
',' == l) ||
4078 (
';' == l) || (0 == l))
4080 }
while (str_len > ++i);
4081 name_len = i - name_start;
4083 while (str_len > i && (
' ' == str[i] ||
'\t' == str[i]))
4085 if (! wsp_around_eq)
4086 return MHD_PARSE_COOKIE_MALFORMED;
4090 if ((str_len == i) || (
'=' != str[i]) || (0 == name_len))
4091 return MHD_PARSE_COOKIE_MALFORMED;
4096 while (str_len > i && (
' ' == str[i] ||
'\t' == str[i]))
4098 if (! wsp_around_eq)
4099 return MHD_PARSE_COOKIE_MALFORMED;
4115 val_quoted = (
'"' == str[i]);
4122 const char l = str[i];
4123 if ((
';' == l) || (
'"' == l) || (
',' == l) || (
';' == l) ||
4124 (
'\\' == l) || (0 == l))
4126 if ((
' ' == l) || (
'\t' == l))
4130 if (! wsp_in_quoted)
4131 return MHD_PARSE_COOKIE_MALFORMED;
4136 value_len = i - value_start;
4139 if ((str_len == i) || (
'"' != str[i]))
4140 return MHD_PARSE_COOKIE_MALFORMED;
4144 if ((str_len > i) && ((
' ' == str[i]) || (
'\t' == str[i])))
4149 }
while (str_len > i && (
' ' == str[i] ||
'\t' == str[i]));
4153 if (! allow_wsp_empty)
4154 return MHD_PARSE_COOKIE_MALFORMED;
4159 valid_cookie =
true;
4160 else if (
';' == str[i])
4161 valid_cookie =
true;
4163 valid_cookie =
false;
4166 return MHD_PARSE_COOKIE_MALFORMED;
4169 str[name_start + name_len] = 0;
4172 mhd_assert (value_start + value_len <= str_len);
4173 str[value_start + value_len] = 0;
4181 return MHD_PARSE_COOKIE_NO_MEMORY;
4192 return MHD_PARSE_COOKIE_NO_MEMORY;
4198 mhd_assert (
';' != str[i] || val_quoted || non_strict || 0 == value_len);
4202 if (! allow_wsp_empty)
4203 return MHD_PARSE_COOKIE_MALFORMED;
4206 else if (
' ' != str[i])
4208 if ((
'\t' == str[i]) && tab_as_sp)
4210 else if (! allow_no_space)
4211 return MHD_PARSE_COOKIE_MALFORMED;
4219 if (! allow_wsp_empty)
4220 return MHD_PARSE_COOKIE_MALFORMED;
4226 return non_strict? MHD_PARSE_COOKIE_OK_LAX : MHD_PARSE_COOKIE_OK;
4238static enum _MHD_ParseCookie
4245 enum _MHD_ParseCookie parse_res;
4248 const bool allow_partially_correct_cookie =
4252 return MHD_PARSE_COOKIE_OK;
4257 parse_res = MHD_PARSE_COOKIE_NO_MEMORY;
4263 cpy[hdr_len] =
'\0';
4267 while (i < hdr_len && (
' ' == cpy[i] ||
'\t' == cpy[i]))
4270 parse_res = parse_cookies_string (cpy + i, hdr_len - i, connection);
4275 case MHD_PARSE_COOKIE_OK:
4277 case MHD_PARSE_COOKIE_OK_LAX:
4280 MHD_DLOG (connection->
daemon,
4281 _ (
"The Cookie header has been parsed, but it is not fully "
4282 "compliant with the standard.\n"));
4285 case MHD_PARSE_COOKIE_MALFORMED:
4288 if (! allow_partially_correct_cookie)
4295 MHD_DLOG (connection->
daemon,
4296 _ (
"The Cookie header has been ignored as it contains "
4297 "malformed data.\n"));
4302 MHD_DLOG (connection->
daemon,
4303 _ (
"The Cookie header has been only partially parsed as it "
4304 "contains malformed data.\n"));
4309 MHD_DLOG (connection->
daemon,
4310 _ (
"The Cookie header has malformed data.\n"));
4313 case MHD_PARSE_COOKIE_NO_MEMORY:
4315 MHD_DLOG (connection->
daemon,
4316 _ (
"Not enough memory in the connection pool to "
4317 "parse client cookies!\n"));
4324#ifndef HAVE_MESSAGES
4338#define HTTP_VER_LEN (MHD_STATICSTR_LEN_ (MHD_HTTP_VERSION_1_1))
4351 const char *http_string,
4354 const char *
const h = http_string;
4360 (
'H' != h[0]) || (
'T' != h[1]) || (
'T' != h[2]) || (
'P' != h[3]) ||
4363 ((
'0' > h[5]) || (
'9' < h[5])) ||
4364 ((
'0' > h[7]) || (
'9' < h[7])))
4372 if (1 == h[5] -
'0')
4375 if (1 == h[7] -
'0')
4377 else if (0 == h[7] -
'0')
4385 if (0 == h[5] -
'0')
4415 const char *
const m = method;
4479 _ (
"Application reported internal error, " \
4480 "closing connection."));
4504 const bool bare_lf_as_crlf = (-2 > discp_lvl);
4507 const bool allow_bws = (2 > discp_lvl);
4515 size_t to_be_processed;
4516 size_t left_unprocessed;
4517 size_t processed_size;
4519 instant_retry =
false;
4532 if ( (2 <= available) &&
4533 (
'\r' == buffer_head[0]) &&
4534 (
'\n' == buffer_head[1]) )
4536 else if (bare_lf_as_crlf && (
'\n' == buffer_head[0]))
4538 else if (2 > available)
4558 uint64_t cur_chunk_left;
4564 if (cur_chunk_left > available)
4565 to_be_processed = available;
4568 to_be_processed = (size_t) cur_chunk_left;
4569 if (available > to_be_processed)
4570 instant_retry =
true;
4577 uint64_t chunk_size;
4591 if (num_dig == available)
4594 broken = (0 == num_dig);
4609 size_t chunk_size_line_len;
4611 chunk_size_line_len = 0;
4612 if ((
';' == buffer_head[num_dig]) ||
4614 ((
' ' == buffer_head[num_dig]) ||
4615 (
'\t' == buffer_head[num_dig]))))
4620 for (i = num_dig; i < available; ++i)
4622 if ((
' ' != buffer_head[i]) && (
'\t' != buffer_head[i]))
4627 if (
';' == buffer_head[i])
4630 for (++i; i < available; ++i)
4632 if ((
'\r' == buffer_head[i]) ||
4633 (
'\n' == buffer_head[i]))
4640 if (
'\r' == buffer_head[i])
4642 if (i + 1 == available)
4644 if (
'\n' == buffer_head[i + 1])
4645 chunk_size_line_len = i;
4650 if (bare_lf_as_crlf)
4651 chunk_size_line_len = i;
4666 if ((2 <= (available - num_dig)) &&
4667 (
'\r' == buffer_head[num_dig]) &&
4668 (
'\n' == buffer_head[num_dig + 1]))
4669 chunk_size_line_len = num_dig + 2;
4670 else if (bare_lf_as_crlf &&
4671 (
'\n' == buffer_head[num_dig]))
4672 chunk_size_line_len = num_dig + 1;
4673 else if (2 > (available - num_dig))
4677 if (0 != chunk_size_line_len)
4679 mhd_assert (chunk_size_line_len <= available);
4684 available -= chunk_size_line_len;
4685 buffer_head += chunk_size_line_len;
4687 if (0 == chunk_size)
4693 instant_retry =
true;
4718 to_be_processed = available;
4720 left_unprocessed = to_be_processed;
4736 _ (
"Application reported internal error, " \
4737 "closing connection."));
4742 if (left_unprocessed > to_be_processed)
4743 MHD_PANIC (
_ (
"libmicrohttpd API violation.\n"));
4746 (left_unprocessed != to_be_processed);
4748 if (0 != left_unprocessed)
4750 instant_retry =
false;
4760 _ (
"WARNING: Access Handler Callback has not processed " \
4761 "any upload data and connection is not suspended. " \
4762 "This may result in hung connection.\n"));
4766 processed_size = to_be_processed - left_unprocessed;
4768 buffer_head += processed_size;
4769 available -= processed_size;
4780 }
while (instant_retry);
4782 if ( (available > 0) &&
4813 connection->
state = next_state;
4832 have_hdr_host =
false;
4833 have_cntn_len =
false;
4861 have_hdr_host =
true;
4863#ifdef COOKIE_SUPPORT
4868 if (MHD_PARSE_COOKIE_NO_MEMORY == parse_cookie_header (c,
4872 handle_req_cookie_no_space (c);
4884 uint64_t decoded_val;
4904 if ((0 == num_digits) ||
4905 (val_len != num_digits) ||
4917 if ((val_len != num_digits)
4918 || (
'0' > clen[0]) || (
'9' < clen[0]))
4922 _ (
"Malformed 'Content-Length' header. " \
4923 "Closing connection.\n"));
4933 _ (
"Too large value of 'Content-Length' header. " \
4934 "Closing connection.\n"));
4942 if ((have_cntn_len) &&
4962 have_cntn_len =
true;
5014 _ (
"The 'Content-Length' request header is ignored "
5015 "as chunked Transfer-Encoding is set in the "
5016 "same request.\n"));
5035 _ (
"Received HTTP/1.1 request without `Host' header.\n"));
5052_MHD_static_inline
void
5063_MHD_static_inline
void
5072#ifndef MHD_MAX_EMPTY_LINES_SKIP
5077#define MHD_MAX_EMPTY_LINES_SKIP 1024
5094 const bool skip_empty_lines = (1 >= discp_lvl);
5097 const bool skip_several_empty_lines = (skip_empty_lines && (0 >= discp_lvl));
5100 const bool skip_unlimited_empty_lines =
5101 (skip_empty_lines && (-3 >= discp_lvl));
5107 const bool tab_as_wsp = (0 >= discp_lvl);
5110 const bool other_wsp_as_wsp = (-1 >= discp_lvl);
5113 const bool wsp_blocks = (-1 >= discp_lvl);
5116 const bool wsp_in_uri = (0 >= discp_lvl);
5120 const bool wsp_in_uri_keep = (-2 >= discp_lvl);
5123 const bool bare_cr_keep = (wsp_in_uri_keep && (-3 >= discp_lvl));
5126 const bool bare_cr_as_sp = ((! bare_cr_keep) && (-1 >= discp_lvl));
5148 && (skip_empty_lines))
5162 is_empty_line =
false;
5169 is_empty_line =
true;
5179 is_empty_line =
true;
5187 if ((! skip_unlimited_empty_lines) &&
5188 (((
unsigned int) ((skip_several_empty_lines) ?
5193 _ (
"Too many meaningless extra empty lines " \
5194 "received before the request"));
5200 }
while (is_empty_line);
5208 while (p < c->read_buffer_offset)
5227 end_of_line =
false;
5256 else if (! bare_cr_keep)
5268 _ (
"Bare CR characters are not allowed " \
5269 "in the request line.\n"));
5274 else if (
'\n' == chr)
5278 if (bare_lf_as_crlf)
5295 _ (
"Bare LF characters are not allowed " \
5296 "in the request line.\n"));
5420 _ (
"The request line is malformed.\n"));
5426 if ((! wsp_blocks) &&
5463 || ((
'\t' == chr) && (tab_as_wsp))
5464 || ((other_wsp_as_wsp) && ((0xb == chr) || (0xc == chr))))
5483 _ (
"The request line starts with "
5484 "a whitespace.\n"));
5521 _ (
"The request line has more than "
5522 "two whitespaces.\n"));
5597 else if ((0xb == chr) || (0xc == chr))
5610 _ (
"Invalid character is in the "
5611 "request line.\n"));
5619 _ (
"The NUL character is in the "
5620 "request line.\n"));
5633#ifndef MHD_MAX_FIXED_URI_LEN
5637#define MHD_MAX_FIXED_URI_LEN (64 * 1024)
5651 size_t fixed_uri_len;
5655 size_t hdr_name_len;
5665 (
NULL == (b = malloc (fixed_uri_len + 1))) )
5668 _ (
"The request has whitespace character is " \
5669 "in the URI and the URI is too large to " \
5670 "send automatic redirect to fixed URI.\n"));
5709 }
while (i < c->rq.req_target_len);
5714 hdr_name = malloc (hdr_name_len + 1);
5715 if (
NULL != hdr_name)
5732 _ (
"The request has whitespace character is in the " \
5834 const bool wsp_in_uri = (0 >= discp_lvl);
5837 const bool wsp_in_uri_keep = (-2 >= discp_lvl);
5873 if (! wsp_in_uri_keep)
6020 bool process_footers,
6032 const bool bare_cr_keep = (-3 >= discp_lvl);
6035 const bool bare_cr_as_sp = ((! bare_cr_keep) && (-1 >= discp_lvl));
6038 const bool nul_as_sp = (-1 >= discp_lvl);
6041 const bool allow_folded = (0 >= discp_lvl);
6047 const bool allow_wsp_at_start = allow_folded && (-1 >= discp_lvl);
6050 const bool allow_wsp_in_name = (-2 >= discp_lvl);
6053 const bool allow_empty_name = (-2 >= discp_lvl);
6056 const bool allow_extended_charset = (-2 >= discp_lvl);
6059 const bool allow_wsp_before_colon = (-3 >= discp_lvl);
6063 const bool allow_line_without_colon = (-2 >= discp_lvl);
6067#if ! defined (HAVE_MESSAGES) && ! defined(_DEBUG)
6068 (void) process_footers;
6078 while (p < c->read_buffer_offset)
6127 else if (! bare_cr_keep)
6129 if (! process_footers)
6139 end_of_line =
false;
6142 else if (
'\n' == chr)
6146 if (bare_lf_as_crlf)
6158 if (! process_footers)
6170 end_of_line =
false;
6178 const size_t line_len = p + ((
'\r' == chr) ? 2 : 1);
6179 char next_line_char;
6180 mhd_assert (line_len <= c->read_buffer_offset);
6199 mhd_assert (line_len < c->read_buffer_offset);
6203 if ((
' ' == next_line_char) ||
6204 (
'\t' == next_line_char))
6209 if (! process_footers)
6230 bool skip_line =
false;
6240 _ (
"Whitespace-prefixed first header line " \
6241 "has been skipped.\n"));
6247 if (! allow_line_without_colon)
6249 if (! process_footers)
6306 hdr_value->
len = value_len;
6316 else if ((
' ' == chr) || (
'\t' == chr))
6320 if (! allow_wsp_at_start)
6322 if (! process_footers)
6338 if (allow_wsp_in_name || allow_wsp_before_colon)
6345 if (! process_footers)
6368 if (! process_footers)
6392 if ( (! allow_extended_charset) &&
6408 mhd_assert (allow_wsp_in_name || allow_wsp_before_colon);
6409 if (! allow_wsp_before_colon)
6411 if (! process_footers)
6422#ifndef MHD_FAVOR_SMALL_CODE
6428 if (! process_footers)
6446 mhd_assert (allow_wsp_in_name || allow_wsp_before_colon);
6447 if (! allow_wsp_in_name)
6449 if (! process_footers)
6460#ifndef MHD_FAVOR_SMALL_CODE
6471#ifndef MHD_FAVOR_SMALL_CODE
6475#ifdef MHD_FAVOR_SMALL_CODE
6513 res =
get_req_header (c, process_footers, &hdr_name, &hdr_value);
6528 (hdr_name.
str[hdr_name.
len - 1] !=
' '));
6530 (hdr_name.
str[hdr_name.
len - 1] !=
'\t'));
6534 (hdr_value.
str[hdr_value.
len - 1] !=
' '));
6536 (hdr_value.
str[hdr_value.
len - 1] !=
'\t'));
6540 (! process_footers) ?
6543 hdr_name.
str, hdr_name.
len,
6544 hdr_value.
str, hdr_value.
len))
6546 size_t add_element_size;
6552 _ (
"Failed to allocate memory in the connection memory " \
6553 "pool to store %s.\n"),
6554 (! process_footers) ?
_ (
"header") :
_ (
"footer"));
6557 add_element_size = hdr_value.
len
6558 + (size_t) (hdr_value.
str - hdr_name.
str);
6560 if (! process_footers)
6600 _ (
"One bare CR character has been replaced with space " \
6602 (! process_footers) ?
6603 _ (
"the request line or in the request headers") :
6604 _ (
"the request footers"));
6609 _ (
"%" PRIu64 " bare CR characters have been replaced with " \
6610 "spaces in the request line and/or in the request %s.\n"),
6612 (! process_footers) ?
_ (
"headers") :
_ (
"footers"));
6617 _ (
"One %s line without colon has been skipped.\n"),
6618 (! process_footers) ?
_ (
"header") :
_ (
"footer"));
6623 _ (
"%" PRIu64 " %s lines without colons has been skipped.\n"),
6625 (! process_footers) ?
_ (
"header") :
_ (
"footer"));
6630 if (! process_footers)
6649 const char *last_elmnt_end;
6650 size_t shift_back_size;
6658 shift_back_size = (size_t) (c->
read_buffer - (last_elmnt_end + 1));
6685#if defined(MHD_USE_THREADS)
6701#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6711#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6750 bytes_read = connection->
recv_cls (connection,
6755 if ((bytes_read < 0) || socket_error)
6759 if ((bytes_read > 0) && connection->
sk_nonblck)
6762 bytes_read = connection->
recv_cls (connection, &dummy,
sizeof (dummy));
6770 MHD_DLOG (connection->
daemon,
6771 _ (
"Socket has been disconnected when reading request.\n"));
6782 MHD_DLOG (connection->
daemon,
6783 _ (
"Connection socket is closed when reading " \
6784 "request due to the error: %s\n"),
6785 (bytes_read < 0) ? str_conn_error_ (bytes_read) :
6786 "detected connection closure");
6793 if (0 == bytes_read)
6800 MHD_DLOG (connection->
daemon,
6801 _ (
"Connection was closed by remote side with incomplete "
6821 MHD_DLOG (connection->
daemon,
6822 _ (
"In function %s handling connection at state: %s\n"),
6824 MHD_state_to_string (connection->
state));
6827 switch (connection->
state)
6845#ifdef UPGRADE_SUPPORT
6846 case MHD_CONNECTION_UPGRADE:
6919 MHD_DLOG (connection->
daemon,
6920 _ (
"In function %s handling connection at state: %s\n"),
6922 MHD_state_to_string (connection->
state));
6924 switch (connection->
state)
6946 MHD_DLOG (connection->
daemon,
6947 _ (
"Failed to send data in request for %s.\n"),
6948 connection->
rq.
url);
6954#if _MHD_DEBUG_SEND_DATA
6956 _ (
"Sent 100 continue response: `%.*s'\n"),
7032 MHD_DLOG (connection->
daemon,
7033 _ (
"Failed to send the response headers for the " \
7034 "request for `%s'. Error: %s\n"),
7036 str_conn_error_ (ret));
7043 if (((
size_t) ret) > wb_ready)
7069 uint64_t data_write_offset;
7071#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7080#if defined(_MHD_HAVE_SENDFILE)
7081 if (MHD_resp_sender_sendfile == connection->
rp.resp_sender)
7084 ret = MHD_send_sendfile_ (connection);
7098 if (data_write_offset > (uint64_t)
SIZE_MAX)
7099 MHD_PANIC (
_ (
"Data offset exceeds limit.\n"));
7102 [(
size_t) data_write_offset],
7104 - (
size_t) data_write_offset,
7106#if _MHD_DEBUG_SEND_DATA
7109 _ (
"Sent %d-byte DATA response: `%.*s'\n"),
7113 - rp.response->data_start]);
7116#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7125 MHD_DLOG (connection->
daemon,
7126 _ (
"Failed to send the response body for the " \
7127 "request for `%s'. Error: %s\n"),
7129 str_conn_error_ (ret));
7157 MHD_DLOG (connection->
daemon,
7158 _ (
"Failed to send the chunked response body for the " \
7159 "request for `%s'. Error: %s\n"),
7161 str_conn_error_ (ret));
7193 MHD_DLOG (connection->
daemon,
7194 _ (
"Failed to send the footers for the " \
7195 "request for `%s'. Error: %s\n"),
7197 str_conn_error_ (ret));
7215#ifdef UPGRADE_SUPPORT
7216 case MHD_CONNECTION_UPGRADE:
7223 _ (
"Internal error.\n"));
7241 uint64_t since_actv;
7251 if (timeout < since_actv)
7258 if (5000 >= jump_back)
7262 _ (
"Detected system clock %u milliseconds jump back.\n"),
7263 (
unsigned int) jump_back);
7269 _ (
"Detected too large system clock %" PRIu64 " milliseconds "
7292#ifdef MHD_USE_THREADS
7306#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7338#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7346 if ( (MHD_ITC_IS_VALID_ (daemon->
itc)) &&
7347 (! MHD_itc_activate_ (daemon->
itc,
"c")) )
7351 _ (
"Failed to signal end of connection via inter-thread " \
7352 "communication channel.\n"));
7367 size_t read_buf_size;
7380 memset (&c->
rq, 0,
sizeof(c->
rq));
7381 memset (&c->
rp, 0,
sizeof(c->
rp));
7432 size_t new_read_buf_size;
7454 memset (&c->
rq, 0,
sizeof(c->
rq));
7457 memset (&c->
rp, 0,
sizeof(c->
rp));
7499#ifdef MHD_USE_THREADS
7519 _ (
"In function %s handling connection at state: %s\n"),
7521 MHD_state_to_string (connection->
state));
7523 switch (connection->
state)
7665 _ (
"Closing connection (failed to create "
7666 "response header).\n"));
7676#ifdef UPGRADE_SUPPORT
7679 connection->
state = MHD_CONNECTION_UPGRADE;
7720#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7726#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7738#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7758#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7766#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7778#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7799 _ (
"Closing connection (failed to create " \
7800 "response footer)."));
7832#ifdef UPGRADE_SUPPORT
7833 case MHD_CONNECTION_UPGRADE:
7856 ret = MHD_connection_epoll_update_ (connection);
7885 daemon->eready_tail,
7898 struct epoll_event event;
7900 event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
7901 event.data.ptr = connection;
7902 if (0 != epoll_ctl (daemon->epoll_fd,
7910 _ (
"Call to epoll_ctl failed: %s\n"),
7959 if (
NULL == connection->tls_session)
7963 gnutls_cipher_algorithm_t res;
7964 res = gnutls_cipher_get (connection->tls_session);
7969 if (
NULL == connection->tls_session)
7973 gnutls_protocol_t res;
7974 res = gnutls_protocol_get_version (connection->tls_session);
7979 if (
NULL == connection->tls_session)
7997 sizeof(connection->
addr));
8017#if SIZEOF_UNSIGNED_INT <= (SIZEOF_UINT64_T - 2)
8058 unsigned int ui_val;
8060 daemon = connection->
daemon;
8066 va_start (ap, option);
8067 ui_val = va_arg (ap,
unsigned int);
8069#if (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT
8073 MHD_DLOG (connection->
daemon,
8074 _ (
"The specified connection timeout (%u) is too " \
8075 "large. Maximum allowed value (%" PRIu64 ") will be used " \
8085#if defined(MHD_USE_THREADS)
8108#if defined(MHD_USE_THREADS)
8166 unsigned int status_code,
8172 if ((
NULL == connection) || (
NULL == response))
8175 daemon = connection->
daemon;
8183#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
8190 _ (
"Attempted to queue response on wrong thread!\n"));
8206#ifdef UPGRADE_SUPPORT
8207 if (
NULL != response->upgrade_handler)
8214 _ (
"Attempted 'upgrade' connection on daemon without" \
8215 " MHD_ALLOW_UPGRADE option!\n"));
8223 _ (
"Application used invalid status code for" \
8224 " 'upgrade' response!\n"));
8232 _ (
"Application used invalid response" \
8233 " without \"Connection\" header!\n"));
8246 _ (
"Application used invalid response" \
8247 " without \"upgrade\" token in" \
8248 " \"Connection\" header!\n"));
8256 _ (
"Connection \"Upgrade\" can be used only " \
8257 "with HTTP/1.1 connections!\n"));
8265#ifdef UPGRADE_SUPPORT
8266 if (
NULL == response->upgrade_handler)
8270 _ (
"Application used status code 101 \"Switching Protocols\" " \
8271 "with non-'upgrade' response!\n"));
8278 _ (
"Application used status code 101 \"Switching Protocols\", " \
8279 "but this MHD was built without \"Upgrade\" support!\n"));
8284 if ( (100 > status_code) ||
8285 (999 < status_code) )
8289 _ (
"Refused wrong status code (%u). " \
8290 "HTTP requires three digits status code!\n"),
8295 if (200 > status_code)
8301 _ (
"Wrong status code (%u) refused. " \
8302 "HTTP/1.0 clients do not support 1xx status codes!\n"),
8312 _ (
"Wrong status code (%u) refused. " \
8313 "HTTP/1.0 reply mode does not support 1xx status codes!\n"),
8320 (2 == status_code / 100) )
8324 _ (
"Successful (%u) response code cannot be used to answer " \
8325 "\"CONNECT\" request!\n"),
8336 _ (
"HEAD-only response cannot be used when the request requires "
8337 "reply body to be sent!\n"));
8347 _ (
"The response has application-defined \"Content-Length\" " \
8348 "header. The reply to the request will be not " \
8349 "HTTP-compliant and may result in hung connection or " \
8350 "other problems!\n"));
8358#if defined(_MHD_HAVE_SENDFILE)
8359 if ( (response->
fd == -1) ||
8363 defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE)
8368 connection->
rp.resp_sender = MHD_resp_sender_std;
8370 connection->
rp.resp_sender = MHD_resp_sender_sendfile;
#define ERR_MSG_REQUEST_CHUNK_LINE_TOO_BIG
#define REQUEST_CONTENTLENGTH_TOOLARGE
static enum MHD_Result build_connection_chunked_response_footer(struct MHD_Connection *connection)
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
#define ERR_RSP_EMPTY_FOOTER_NAME
static enum MHD_Result build_header_response(struct MHD_Connection *connection)
static void connection_close_error(struct MHD_Connection *connection, const char *emsg)
static bool char_legal_in_field_name(char chr)
static bool process_request_target(struct MHD_Connection *c)
void MHD_connection_set_initial_state_(struct MHD_Connection *c)
#define MHD_CHUNK_HEADER_REASONABLE_LEN
#define MHD_lookup_header_s_token_ci(c, h, tkn)
@ MHD_PROC_RECV_BODY_CHUNKED
@ MHD_PROC_RECV_BODY_NORMAL
#define REQUEST_CHUNK_TOO_LARGE
void MHD_connection_handle_write(struct MHD_Connection *connection)
static void MHD_connection_update_event_loop_info(struct MHD_Connection *connection)
#define buffer_append_s(buf, ppos, buf_size, str)
void * MHD_connection_alloc_memory_(struct MHD_Connection *connection, size_t size)
#define MHD_MAX_FIXED_URI_LEN
static enum MHD_Result try_ready_normal_body(struct MHD_Connection *connection)
#define REQUEST_CHUNKED_MALFORMED
#define REQ_HTTP_VER_IS_NOT_SUPPORTED
#define MHD_MAX_REASONABLE_HEADERS_SIZE_
#define RQ_LINE_TOO_MANY_WSP
static void call_connection_handler(struct MHD_Connection *connection)
static enum MHD_Result connection_add_header(void *cls, const char *key, size_t key_size, const char *value, size_t value_size, enum MHD_ValueKind kind)
static void process_request_body(struct MHD_Connection *connection)
#define ERR_RSP_INVALID_CHR_IN_FOOTER
static void setup_reply_properties(struct MHD_Connection *connection)
#define ERR_RSP_INVALID_CHAR_IN_FIELD_NAME
#define HTTP_100_CONTINUE
static void send_redirect_fixed_rq_target(struct MHD_Connection *c)
static void handle_recv_no_space(struct MHD_Connection *c, enum MHD_ProcRecvDataStage stage)
#define transmit_error_response_static(c, code, msg)
#define REQUEST_MALFORMED
static bool get_request_line(struct MHD_Connection *c)
@ MHD_HDR_LINE_READING_NEED_MORE_DATA
@ MHD_HDR_LINE_READING_GOT_END_OF_HEADER
@ MHD_HDR_LINE_READING_GOT_HEADER
@ MHD_HDR_LINE_READING_DATA_ERROR
_MHD_static_inline void reset_rq_header_processing_state(struct MHD_Connection *c)
#define ERR_RSP_HEADER_WITHOUT_COLON
static void connection_shrink_read_buffer(struct MHD_Connection *connection)
#define ERR_RSP_WSP_IN_FOOTER_NAME
#define MHD_ALLOW_BARE_LF_AS_CRLF_(discp_lvl)
static enum replyBodyUse is_reply_body_needed(struct MHD_Connection *connection, unsigned int rcode)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
static void transmit_error_response_len(struct MHD_Connection *connection, unsigned int status_code, const char *message, size_t message_len, char *header_name, size_t header_name_len, char *header_value, size_t header_value_len)
#define REQ_HTTP_VER_IS_TOO_OLD
#define ERR_MSG_REQUEST_TOO_BIG
#define MHD_MAX_REASONABLE_REQ_TARGET_SIZE_
#define ERR_MSG_REQUEST_FOOTER_TOO_BIG
#define ERR_MSG_REQUEST_CHUNK_LINE_EXT_TOO_BIG
static bool connection_check_timedout(struct MHD_Connection *c)
static enum MHD_ConnKeepAlive keepalive_possible(struct MHD_Connection *connection)
static void handle_req_chunk_size_line_no_space(struct MHD_Connection *c, const char *chunk_size_line, size_t chunk_size_line_size)
#define REQUEST_LACKS_HOST
#define BARE_CR_IN_FOOTER
static bool try_grow_read_buffer(struct MHD_Connection *connection, bool required)
static bool parse_http_version(struct MHD_Connection *connection, const char *http_string, size_t len)
#define BARE_LF_IN_HEADER
#define ERR_RSP_EMPTY_HEADER_NAME
static bool need_100_continue(struct MHD_Connection *connection)
#define ERR_RSP_WSP_IN_HEADER_NAME
#define REQUEST_HTTP1_0_TR_ENCODING
static bool get_req_headers(struct MHD_Connection *c, bool process_footers)
#define ERROR_MSG_DATA_NOT_HANDLED_BY_APP
#define MHD_MIN_REASONABLE_REQ_METHOD_SIZE_
static unsigned int get_no_space_err_status_code(struct MHD_Connection *c, enum MHD_ProcRecvDataStage stage, const char *add_element, size_t add_element_size)
#define REQUEST_UNSUPPORTED_TR_ENCODING
enum MHD_Result MHD_connection_handle_idle(struct MHD_Connection *connection)
static void cleanup_connection(struct MHD_Connection *connection)
#define ERR_RSP_OBS_FOLD_FOOTER
static void parse_http_std_method(struct MHD_Connection *connection, const char *method, size_t len)
static bool check_and_grow_read_buffer_space(struct MHD_Connection *c)
static enum MHD_Result try_ready_chunked_body(struct MHD_Connection *connection, bool *p_finished)
static bool get_date_str(char *date)
static void parse_connection_headers(struct MHD_Connection *c)
#define BARE_LF_IN_FOOTER
static void connection_reset(struct MHD_Connection *connection, bool reuse)
#define REQUEST_LENGTH_WITH_TR_ENCODING
#define MHD_MIN_REASONABLE_REQ_TARGET_SIZE_
#define RQ_TARGET_INVALID_CHAR
static bool get_request_line_inner(struct MHD_Connection *c)
static void handle_req_footers_no_space(struct MHD_Connection *c, const char *add_footer, size_t add_footer_size)
void MHD_connection_handle_read(struct MHD_Connection *connection, bool socket_error)
#define REQUEST_AMBIGUOUS_CONTENT_LENGTH
static void connection_switch_from_recv_to_send(struct MHD_Connection *connection)
#define ERR_RSP_WSP_BEFORE_FOOTER
#define ERR_RSP_INVALID_CHR_IN_HEADER
#define REQUEST_MULTIPLE_HOST_HDR
void MHD_update_last_activity_(struct MHD_Connection *connection)
#define MHD_MAX_EMPTY_LINES_SKIP
#define MHD_MIN_REASONABLE_HEADERS_SIZE_
#define REQUEST_HAS_NUL_CHAR_IN_PATH
#define BARE_CR_IN_HEADER
#define ERR_MSG_REQUEST_HEADER_TOO_BIG
static bool add_user_headers(char *buf, size_t *ppos, size_t buf_size, struct MHD_Response *response, bool filter_transf_enc, bool filter_content_len, bool add_close, bool add_keep_alive)
#define REQUEST_CONTENTLENGTH_MALFORMED
static enum MHD_HdrLineReadRes_ get_req_header(struct MHD_Connection *c, bool process_footers, struct _MHD_str_w_len *hdr_name, struct _MHD_str_w_len *hdr_value)
static void check_connection_reply(struct MHD_Connection *connection)
static void handle_req_headers_no_space(struct MHD_Connection *c, const char *add_header, size_t add_header_size)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
static size_t connection_maximize_write_buffer(struct MHD_Connection *connection)
static bool has_unprocessed_upload_body_data_in_buffer(struct MHD_Connection *c)
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
#define CONNECTION_CLOSE_ERROR(c, emsg)
#define transmit_error_response_header(c, code, m, hd_n, hd_n_l, hd_v, hd_v_l)
static bool buffer_append(char *buf, size_t *ppos, size_t buf_size, const char *append, size_t append_size)
static enum MHD_Result check_write_done(struct MHD_Connection *connection, enum MHD_CONNECTION_STATE next_state)
#define ERR_RSP_WSP_BEFORE_HEADER
#define ERR_MSG_REQUEST_HEADER_WITH_COOKIES_TOO_BIG
_MHD_static_inline void switch_to_rq_headers_processing(struct MHD_Connection *c)
static bool get_date_header(char *header)
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 ERR_RSP_FOOTER_WITHOUT_COLON
#define MHD_MIN_REASONABLE_REQ_CHUNK_LINE_LENGTH_
Methods for managing connections.
#define MHD_ERR_CONNRESET_
#define MHD_connection_finish_forward_(conn)
#define MHD_ERR_OPNOTSUPP_
bool MHD_tls_connection_shutdown(struct MHD_Connection *connection)
bool MHD_run_tls_handshake_(struct MHD_Connection *connection)
Methods for managing connections.
#define MHD_HTTP_INTERNAL_SERVER_ERROR
#define MHD_HTTP_MOVED_PERMANENTLY
#define MHD_HTTP_URI_TOO_LONG
#define MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
#define MHD_HTTP_PROCESSING
#define MHD_HTTP_NOT_IMPLEMENTED
#define MHD_HTTP_SWITCHING_PROTOCOLS
#define MHD_HTTP_HTTP_VERSION_NOT_SUPPORTED
#define MHD_HTTP_CONTENT_TOO_LARGE
#define MHD_HTTP_NOT_MODIFIED
#define MHD_HTTP_NO_CONTENT
#define MHD_HTTP_BAD_REQUEST
#define MHD_HTTP_METHOD_TRACE
#define MHD_HTTP_METHOD_OPTIONS
#define MHD_HTTP_METHOD_GET
#define MHD_HTTP_METHOD_HEAD
#define MHD_HTTP_METHOD_POST
#define MHD_HTTP_METHOD_PUT
#define MHD_HTTP_METHOD_CONNECT
#define MHD_HTTP_METHOD_DELETE
_MHD_EXTERN enum MHD_Result MHD_set_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, const char *value)
enum MHD_Result(* MHD_KeyValueIterator)(void *cls, 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)
enum MHD_Result(* MHD_KeyValueIteratorN)(void *cls, enum MHD_ValueKind kind, const char *key, size_t key_size, const char *value, size_t value_size)
_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)
static enum MHD_Result 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_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_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)
_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_GNUTLS_SESSION
@ MHD_CONNECTION_INFO_REQUEST_HEADER_SIZE
@ MHD_CONNECTION_INFO_CIPHER_ALGO
@ MHD_CONNECTION_INFO_CONNECTION_SUSPENDED
@ MHD_CONNECTION_INFO_CLIENT_ADDRESS
@ MHD_CONNECTION_INFO_DAEMON
@ MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT
@ MHD_CONNECTION_INFO_HTTP_STATUS
@ MHD_CONNECTION_INFO_CONNECTION_FD
@ MHD_CONNECTION_INFO_PROTOCOL
@ MHD_REQUEST_TERMINATED_TIMEOUT_REACHED
@ MHD_REQUEST_TERMINATED_COMPLETED_OK
@ MHD_REQUEST_TERMINATED_WITH_ERROR
@ MHD_REQUEST_TERMINATED_READ_ERROR
@ MHD_REQUEST_TERMINATED_CLIENT_ABORT
_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_buffer_static(size_t size, const void *buffer)
_MHD_EXTERN enum MHD_Result MHD_set_connection_option(struct MHD_Connection *connection, enum MHD_CONNECTION_OPTION option,...)
_MHD_EXTERN const union MHD_ConnectionInfo * MHD_get_connection_info(struct MHD_Connection *connection, enum MHD_ConnectionInfoType info_type,...)
#define MHD_HTTP_VERSION_1_0
#define MHD_HTTP_VERSION_1_1
enum MHD_Result MHD_parse_arguments_(struct MHD_Connection *connection, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, void *cls)
MHD internal shared structures.
@ MHD_CONNECTION_BODY_RECEIVED
@ MHD_CONNECTION_CHUNKED_BODY_SENT
@ MHD_CONNECTION_REQ_HEADERS_RECEIVING
@ MHD_CONNECTION_BODY_RECEIVING
@ MHD_CONNECTION_HEADERS_SENDING
@ MHD_CONNECTION_FOOTERS_SENDING
@ MHD_CONNECTION_FOOTERS_RECEIVED
@ MHD_CONNECTION_FULL_REPLY_SENT
@ MHD_CONNECTION_HEADERS_SENT
@ MHD_CONNECTION_HEADERS_PROCESSED
@ MHD_CONNECTION_REQ_LINE_RECEIVED
@ MHD_CONNECTION_NORMAL_BODY_UNREADY
@ MHD_CONNECTION_HEADERS_RECEIVED
@ MHD_CONNECTION_NORMAL_BODY_READY
@ MHD_CONNECTION_START_REPLY
@ MHD_CONNECTION_FOOTERS_RECEIVING
@ MHD_CONNECTION_CHUNKED_BODY_READY
@ MHD_CONNECTION_FULL_REQ_RECEIVED
@ MHD_CONNECTION_CHUNKED_BODY_UNREADY
@ MHD_CONNECTION_CONTINUE_SENDING
@ MHD_CONNECTION_REQ_LINE_RECEIVING
#define XDLL_insert(head, tail, element)
@ MHD_EPOLL_STATE_SUSPENDED
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
@ MHD_EPOLL_STATE_READ_READY
@ MHD_EPOLL_STATE_IN_EPOLL_SET
@ MHD_EPOLL_STATE_WRITE_READY
@ MHD_TLS_CONN_TLS_CLOSING
@ MHD_TLS_CONN_WR_CLOSING
@ MHD_TLS_CONN_INVALID_STATE
@ MHD_TLS_CONN_TLS_CLOSED
@ MHD_TLS_CONN_TLS_FAILED
@ MHD_TLS_CONN_HANDSHAKING
#define DLL_insert(head, tail, element)
@ MHD_EVENT_LOOP_INFO_PROCESS_READ
@ MHD_EVENT_LOOP_INFO_PROCESS
@ MHD_EVENT_LOOP_INFO_READ
@ MHD_EVENT_LOOP_INFO_WRITE
@ MHD_EVENT_LOOP_INFO_CLEANUP
#define EDLL_insert(head, tail, element)
struct MHD_IoVec MHD_iovec_
#define MHD_IS_HTTP_VER_SUPPORTED(ver)
_MHD_static_inline struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *const daemon)
@ MHD_RAF_HAS_CONTENT_LENGTH
@ MHD_RAF_HAS_CONNECTION_CLOSE
@ MHD_RAF_HAS_TRANS_ENC_CHUNKED
@ MHD_RAF_HAS_CONNECTION_HDR
@ MHD_CONN_KEEPALIVE_UNKOWN
#define MHD_IS_HTTP_VER_1_1_COMPAT(ver)
@ MHD_HTTP_MTHD_NO_METHOD
#define EDLL_remove(head, tail, element)
#define XDLL_remove(head, tail, element)
#define MHD_D_IS_USING_THREAD_PER_CONN_(d)
#define DLL_remove(head, tail, element)
#define MHD_D_IS_USING_THREADS_(d)
#define MHD_D_IS_USING_EPOLL_(d)
void * MHD_pool_reallocate(struct MemoryPool *pool, void *old, size_t old_size, size_t new_size)
void MHD_pool_destroy(struct MemoryPool *pool)
bool MHD_pool_is_resizable_inplace(struct MemoryPool *pool, void *block, size_t block_size)
void MHD_pool_deallocate(struct MemoryPool *pool, void *block, size_t block_size)
void * MHD_pool_try_alloc(struct MemoryPool *pool, size_t size, size_t *required_bytes)
size_t MHD_pool_get_free(struct MemoryPool *pool)
void * MHD_pool_reset(struct MemoryPool *pool, void *keep, size_t copy_bytes, size_t new_size)
void * MHD_pool_allocate(struct MemoryPool *pool, size_t size, bool from_end)
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
#define mhd_assert(ignore)
Header for platform missing functions.
Header for platform-independent inter-thread communication.
limits values definitions
Header for platform-independent locks abstraction.
#define MHD_mutex_unlock_chk_(ignore)
#define MHD_mutex_lock_chk_(ignore)
uint64_t MHD_monotonic_msec_counter(void)
internal monotonic clock functions implementations
ssize_t MHD_send_hdr_and_body_(struct MHD_Connection *connection, const char *header, size_t header_size, bool never_push_hdr, const char *body, size_t body_size, bool complete_response)
ssize_t MHD_send_iovec_(struct MHD_Connection *connection, struct MHD_iovec_track_ *const r_iov, bool push_data)
ssize_t MHD_send_data_(struct MHD_Connection *connection, const char *buffer, size_t buffer_size, bool push_data)
Declarations of send() wrappers.
#define MHD_SCKT_ERR_IS_(err, code)
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
#define MHD_socket_last_strerr_()
#define MHD_SCKT_EOPNOTSUPP_
#define MHD_socket_get_error_()
#define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err)
#define MHD_SCKT_ERR_IS_EINTR_(err)
#define MHD_SCKT_SEND_MAX_SIZE_
#define MHD_SCKT_ENOTCONN_
#define MHD_recv_(s, b, l)
#define MHD_SEND_SPIPE_SUPPRESS_NEEDED
int MHD_str_equal_caseless_(const char *str1, const char *str2)
size_t MHD_uint8_to_str_pad(uint8_t val, uint8_t min_digits, char *buf, size_t buf_size)
size_t MHD_uint16_to_str(uint16_t val, char *buf, size_t buf_size)
size_t MHD_str_to_uint64_n_(const char *str, size_t maxlen, uint64_t *out_val)
size_t MHD_uint64_to_str(uint64_t val, char *buf, size_t buf_size)
size_t MHD_strx_to_uint64_n_(const char *str, size_t maxlen, uint64_t *out_val)
int MHD_str_equal_caseless_n_(const char *const str1, const char *const str2, size_t maxlen)
bool MHD_str_has_token_caseless_(const char *str, const char *const token, size_t token_len)
bool MHD_str_equal_caseless_bin_n_(const char *const str1, const char *const str2, size_t len)
size_t MHD_uint32_to_strx(uint32_t val, char *buf, size_t buf_size)
Header for string manipulating helpers.
#define MHD_str_has_s_token_caseless_(str, tkn)
#define MHD_str_equal_caseless_s_bin_n_(a, s, l)
#define MHD_STATICSTR_LEN_(macro)
#define MHD_thread_handle_ID_is_current_thread_(hndl_id)
#define MHD_CONTENT_READER_END_OF_STREAM
_MHD_EXTERN size_t MHD_get_reason_phrase_len_for(unsigned int code)
#define MHD_INVALID_SOCKET
_MHD_EXTERN const char * MHD_get_reason_phrase_for(unsigned int code)
#define MHD_CONTENT_READER_END_WITH_ERROR
@ MHD_USE_SUPPRESS_DATE_NO_CLOCK
@ MHD_RF_SEND_KEEP_ALIVE_HEADER
@ MHD_RF_HEAD_ONLY_RESPONSE
@ MHD_RF_HTTP_1_0_COMPATIBLE_STRICT
@ MHD_RF_INSANITY_HEADER_CONTENT_LENGTH
@ MHD_CONNECTION_OPTION_TIMEOUT
bool MHD_add_response_entry_no_alloc_(struct MHD_Response *response, enum MHD_ValueKind kind, char *header, size_t header_len, char *content, size_t content_len)
void MHD_increment_response_rc(struct MHD_Response *response)
Methods for managing response objects.
enum MHD_Result MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
size_t write_buffer_send_offset
enum MHD_ConnectionEventLoopInfo event_loop_info
size_t write_buffer_append_offset
enum MHD_ConnKeepAlive keepalive
union MHD_ConnectionInfo connection_info_dummy
size_t continue_message_write_offset
size_t read_buffer_offset
enum MHD_CONNECTION_STATE state
struct MHD_Daemon * daemon
uint64_t connection_timeout_ms
struct sockaddr_storage * addr
MHD_AccessHandlerCallback default_handler
LogCallback uri_log_callback
struct MHD_Connection * normal_timeout_tail
void * unescape_callback_cls
struct MHD_Connection * connections_tail
struct MHD_Connection * suspended_connections_tail
struct MHD_Connection * manual_timeout_head
struct MHD_Connection * normal_timeout_head
MHD_RequestCompletedCallback notify_completed
struct MHD_Connection * cleanup_head
uint64_t connection_timeout_ms
struct MHD_Connection * manual_timeout_tail
struct MHD_Connection * cleanup_tail
UnescapeCallback unescape_callback
void * notify_completed_cls
struct MHD_Connection * suspended_connections_head
void * default_handler_cls
struct MHD_Connection * connections_head
void * uri_log_callback_cls
bool use_reply_body_headers
uint64_t rsp_write_position
struct MHD_iovec_track_ resp_iov
struct MHD_Response * response
unsigned int responseCode
struct MHD_Reply_Properties props
unsigned int skipped_empty_lines
struct MHD_HTTP_Req_Header * headers_received
union MHD_HeadersProcessing hdrs
uint64_t current_chunk_size
uint64_t current_chunk_offset
bool some_payload_processed
size_t skipped_broken_lines
size_t num_cr_sp_replaced
enum MHD_HTTP_Version http_ver
union MHD_StartOrSize field_lines
struct MHD_HTTP_Req_Header * headers_received_tail
enum MHD_HTTP_Method http_mthd
const char * url_for_callback
uint64_t remaining_upload_size
MHD_ContentReaderCallback crc
enum MHD_ResponseAutoFlags flags_auto
enum MHD_ResponseFlags flags
struct MHD_HTTP_Res_Header * first_header
unsigned int connection_timeout
struct MHD_Daemon * daemon
struct sockaddr * client_addr