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
62#define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
72#define REQUEST_TOO_BIG \
73 "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>"
75#define REQUEST_TOO_BIG ""
86#define REQUEST_LACKS_HOST \
87 "<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>"
89#define REQUEST_LACKS_HOST ""
100#define REQUEST_MALFORMED \
101 "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
103#define REQUEST_MALFORMED ""
111#define REQUEST_CHUNKED_MALFORMED \
112 "<html><head><title>Request malformed</title></head><body>Your HTTP chunked encoding was syntactically incorrect.</body></html>"
114#define REQUEST_CHUNKED_MALFORMED ""
121#define REQUEST_CHUNK_TOO_LARGE \
122 "<html><head><title>Request content too large</title></head><body>The chunk size used in your HTTP chunked encoded request is too large.</body></html>"
124#define REQUEST_CHUNK_TOO_LARGE ""
131#define REQUEST_CONTENTLENGTH_TOOLARGE \
132 "<html><head><title>Request content too large</title></head>" \
133 "<body>Your HTTP request has too large value for <b>Content-Length</b> header.</body></html>"
135#define REQUEST_CONTENTLENGTH_TOOLARGE ""
143#define REQUEST_CONTENTLENGTH_MALFORMED \
144 "<html><head><title>Request malformed</title></head>" \
145 "<body>Your HTTP request has wrong value for <b>Content-Length</b> header.</body></html>"
147#define REQUEST_CONTENTLENGTH_MALFORMED ""
157#define INTERNAL_ERROR \
158 "<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>"
160#define INTERNAL_ERROR ""
167#define REQ_HTTP_VER_IS_TOO_OLD \
168 "<html><head><title>Requested HTTP version is not supported</title></head><body>Requested HTTP version is too old and not supported.</body></html>"
170#define REQ_HTTP_VER_IS_TOO_OLD ""
177#define REQ_HTTP_VER_IS_NOT_SUPPORTED \
178 "<html><head><title>Requested HTTP version is not supported</title></head><body>Requested HTTP version is not supported.</body></html>"
180#define REQ_HTTP_VER_IS_NOT_SUPPORTED ""
187#define MHD_SENFILE_CHUNK_ (0x20000)
192#define MHD_SENFILE_CHUNK_THR_P_C_ (0x200000)
206 return _ (
"The operation would block, retry later");
208 return _ (
"The connection was forcibly closed by remote peer");
210 return _ (
"The socket is not connected");
212 return _ (
"Not enough system resources to serve the request");
214 return _ (
"Bad FD value");
216 return _ (
"Argument value is invalid");
218 return _ (
"Argument value is not supported");
220 return _ (
"The socket is no longer available for sending");
222 return _ (
"TLS encryption or decryption error");
227 return _ (
"Not an error code");
230 return _ (
"Wrong error code value");
250 struct MemoryPool *
const pool =
c->
pool;
257 if (
NULL !=
c->write_buffer)
261 if (
c->write_buffer_size -
c->write_buffer_append_offset >=
need_to_free)
267 c->write_buffer_size,
273 c->write_buffer =
buf;
278 else if (
NULL !=
c->read_buffer)
292 c->read_buffer =
buf;
340 connection->epoll_state &=
363 else if (
i > (
size_t)
ret)
364 connection->epoll_state &=
392 if (
NULL == connection)
431 if (
NULL == connection)
489 pos->
header = (
char *) key;
544 ( ((key ?
strlen (key) : 0) != key_size) ||
658 if (
NULL == connection)
755#define MHD_lookup_header_s_token_ci(c,h,tkn) \
756 MHD_lookup_header_token_ci ((c),(h),MHD_STATICSTR_LEN_ (h), \
757 (tkn),MHD_STATICSTR_LEN_ (tkn))
837#ifdef MHD_USE_THREADS
863#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
880#ifdef MHD_USE_THREADS
895 (0 !=
epoll_ctl (daemon->epoll_upgrade_fd,
900 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
902 if (
urh->in_eready_list)
905 daemon->eready_urh_tail,
907 urh->in_eready_list =
false;
914 (0 !=
epoll_ctl (daemon->epoll_upgrade_fd,
919 MHD_PANIC (
_ (
"Failed to remove FD from epoll set.\n"));
968#define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, emsg)
970#define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, NULL)
1001#define CONNECTION_CLOSE_ERROR_CHECK(c, emsg) \
1002 connection_close_error_check (c, emsg)
1004#define CONNECTION_CLOSE_ERROR_CHECK(c, emsg) \
1005 connection_close_error_check (c, NULL)
1048 _ (
"Closing connection (out of memory)."));
1065#if defined(_MHD_HAVE_SENDFILE)
1085#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1094 "Closing connection (application reported error generating data)."));
1102#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1129 static const size_t max_chunk = 0xFFFFFF;
1152#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1157 _ (
"Closing connection (out of memory)."));
1166 write_buffer_size, size);
1208#if defined(MHD_USE_THREADS)
1212 _ (
"No callback for the chunked data."));
1225#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1230 "Closing connection (application error generating response)."));
1243#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1250#if defined(MHD_USE_THREADS)
1254 _ (
"Closing connection (application returned " \
1255 "more data than requested)."));
1310#ifdef UPGRADE_SUPPORT
1313 if (
NULL !=
r->upgrade_handler)
1324 mhd_assert ( (!
c->stop_with_error) || (
c->discard_request));
1325 if ((
c->read_closed) || (
c->discard_request))
1371 static const char *
const days[] = {
1372 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
1374 static const char *
const mons[] = {
1375 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
1376 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
1378 static const size_t buf_len = 29;
1382#if ! defined(HAVE_C11_GMTIME_S) && ! defined(HAVE_W32_GMTIME_S) && \
1383 ! defined(HAVE_GMTIME_R)
1389#if defined(HAVE_C11_GMTIME_S)
1393#elif defined(HAVE_W32_GMTIME_S)
1397#elif defined(HAVE_GMTIME_R)
1553 if ((
NULL ==
c->read_buffer) || (0 ==
c->read_buffer_size))
1560 mhd_assert (
c->read_buffer_offset <=
c->read_buffer_size);
1562 c->read_buffer_offset);
1565 c->read_buffer_size =
c->read_buffer_offset;
1580 struct MemoryPool *
const pool = connection->
pool;
1586 mhd_assert (
c->write_buffer_append_offset >=
c->write_buffer_send_offset);
1587 mhd_assert (
c->write_buffer_size >=
c->write_buffer_append_offset);
1599 c->write_buffer_size,
1604 if (
c->write_buffer_send_offset ==
c->write_buffer_append_offset)
1607 c->write_buffer_send_offset = 0;
1608 c->write_buffer_append_offset = 0;
1612 return c->write_buffer_size -
c->write_buffer_append_offset;
1629 struct MemoryPool *
const pool = connection->
pool;
1633 mhd_assert (
c->write_buffer_append_offset >=
c->write_buffer_send_offset);
1634 mhd_assert (
c->write_buffer_size >=
c->write_buffer_append_offset);
1636 if ( (
NULL ==
c->write_buffer) || (0 ==
c->write_buffer_size))
1640 c->write_buffer =
NULL;
1643 if (
c->write_buffer_append_offset ==
c->write_buffer_size)
1647 c->write_buffer_append_offset);
1649 (0 ==
c->write_buffer_append_offset));
1650 c->write_buffer_size =
c->write_buffer_append_offset;
1651 if (0 ==
c->write_buffer_size)
1652 c->write_buffer =
NULL;
1707#ifdef UPGRADE_SUPPORT
1708 if (
NULL !=
c->response->upgrade_handler)
1713 (2 ==
rcode / 100) )
1775 if (
c->rp_props.use_reply_body_headers)
1778 c->rp_props.send_reply_body =
false;
1780 if (
c->rp_props.use_reply_body_headers)
1814 c->rp_props.set =
true;
1855#define buffer_append_s(buf,ppos,buf_size,str) \
1856 buffer_append(buf,ppos,buf_size,str, MHD_STATICSTR_LEN_(str))
1915 hdr->header_size) &&
1917 hdr->header,
hdr->header_size)) )
1929 (*ppos) +=
hdr->header_size;
1930 buf[(*ppos)++] =
':';
1931 buf[(*ppos)++] =
' ';
1960 if (0 !=
hdr->value_size)
1963 buf[(*ppos)++] =
'\r';
1964 buf[(*ppos)++] =
'\n';
2002#ifdef UPGRADE_SUPPORT
2008 mhd_assert ((!
c->rp_props.chunked) ||
c->rp_props.use_reply_body_headers);
2010 c->rp_props.use_reply_body_headers);
2011#ifdef UPGRADE_SUPPORT
2013 !
c->rp_props.use_reply_body_headers);
2048 buf =
c->write_buffer;
2049 pos =
c->write_buffer_append_offset;
2141 !
c->rp_props.chunked,
2148 if (
c->rp_props.use_reply_body_headers)
2151 if (
c->rp_props.chunked)
2188 c->write_buffer_append_offset = pos;
2222 buf =
c->write_buffer +
c->write_buffer_append_offset;
2229 for (pos =
c->response->first_header;
NULL != pos; pos = pos->
next)
2255 mhd_assert (
c->write_buffer_append_offset <=
c->write_buffer_size);
2273 unsigned int status_code,
2292 _ (
"Error processing request (HTTP response code is %u ('%s')). " \
2293 "Closing connection.\n"),
2301 _ (
"Too late to send an error response, " \
2302 "response is being sent already.\n"),
2307 _ (
"Too late for error response."));
2331 if (
NULL == response)
2335 _ (
"Failed to create error response.\n"),
2351 _ (
"Closing connection " \
2352 "(failed to queue error response)."));
2383 _ (
"Closing connection " \
2384 "(failed to create error response header)."));
2395#define transmit_error_response_static(c, code, msg) \
2396 transmit_error_response_len (c, code, msg, MHD_STATICSTR_LEN_ (msg))
2415 switch (connection->tls_state)
2435 _ (
"In function %s handling connection at state: %s\n"),
2439 switch (connection->
state)
2559#ifdef UPGRADE_SUPPORT
2600 const char c =
rbuf[pos];
2604 (
'\n' ==
rbuf[pos + 1]) )
2678 _ (
"Not enough memory in pool to allocate header record!\n"));
2724 _ (
"Not enough memory in pool to parse cookies!\n"));
2742 while ( ((*
sce) !=
'\0') &&
2749 while ( (*
ekill ==
' ') &&
2791 if ( (
'"' ==
equals[0]) &&
2832 (
h[0] !=
'H') || (
h[1] !=
'T') || (
h[2] !=
'T') || (
h[3] !=
'P') ||
2835 ((
h[5] <
'0') || (
h[5] >
'9')) ||
2836 ((
h[7] <
'0') || (
h[7] >
'9')))
2844 if (1 ==
h[5] -
'0')
2847 if (1 ==
h[7] -
'0')
2849 else if (0 ==
h[7] -
'0')
2857 if (0 ==
h[5] -
'0')
2889 const char *
const m = method;
2960 while ( (
' ' ==
uri[0]) &&
3083 "Application reported internal error, closing connection."));
3276 if (((
'0' <=
d) && (
'9' >=
d)) ||
3277 ((
'A' <=
d) && (
'F' >=
d)) ||
3278 ((
'a' <=
d) && (
'f' >=
d)))
3322 _ (
"Application reported internal error, " \
3323 "closing connection."));
3331 ,
_ (
"libmicrohttpd API violation.\n")
3346 _ (
"WARNING: incomplete upload processing and connection " \
3347 "not suspended may result in hung connection.\n"));
3442 while ( (
'\0' != colon[0]) &&
3443 ( (
' ' == colon[0]) ||
3444 (
'\t' == colon[0]) ) )
3452 connection->
colon = colon;
3477 if ( (
' ' ==
line[0]) ||
3547 _ (
"Received HTTP/1.1 request without `Host' header.\n"));
3590 (
'0' <=
clen[0]) && (
'9' >=
clen[0]))
3594 _ (
"Too large value of 'Content-Length' header. " \
3595 "Closing connection.\n"));
3605 _ (
"Failed to parse `Content-Length' header. " \
3606 "Closing connection.\n"));
3642#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3652#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3718 _ (
"Socket has been disconnected when reading request.\n"));
3730 _ (
"Connection socket is closed when reading " \
3731 "request due to the error: %s\n"),
3733 "detected connection closure");
3748 _ (
"Connection was closed by remote side with incomplete "
3769 _ (
"In function %s handling connection at state: %s\n"),
3773 switch (connection->
state)
3795#ifdef UPGRADE_SUPPORT
3846 _ (
"In function %s handling connection at state: %s\n"),
3850 switch (connection->
state)
3874 _ (
"Failed to send data in request for %s.\n"),
3881#if _MHD_DEBUG_SEND_DATA
3883 _ (
"Sent 100 continue response: `%.*s'\n"),
3907 (0 ==
resp->data_start) || \
3910 (
resp->total_size ==
3935 (
resp->total_size ==
resp->data_size));
3949 ((0 ==
resp->total_size) ||
3960 _ (
"Failed to send the response headers for the " \
3961 "request for `%s'. Error: %s\n"),
3998#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4007#if defined(_MHD_HAVE_SENDFILE)
4026 MHD_PANIC (
_ (
"Data offset exceeds limit.\n"));
4033#if _MHD_DEBUG_SEND_DATA
4036 _ (
"Sent %d-byte DATA response: `%.*s'\n"),
4043#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4053 _ (
"Failed to send the response body for the " \
4054 "request for `%s'. Error: %s\n"),
4085 _ (
"Failed to send the chunked response body for the " \
4086 "request for `%s'. Error: %s\n"),
4121 _ (
"Failed to send the footers for the " \
4122 "request for `%s'. Error: %s\n"),
4142#ifdef UPGRADE_SUPPORT
4150 _ (
"Internal error.\n"));
4189 _ (
"Detected system clock %u milliseconds jump back.\n"),
4196 _ (
"Detected too large system clock %" PRIu64 " milliseconds "
4219#ifdef MHD_USE_THREADS
4232#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4264#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4278 "Failed to signal end of connection via inter-thread communication channel.\n"));
4306 c->read_buffer =
NULL;
4307 c->read_buffer_size = 0;
4308 c->read_buffer_offset = 0;
4309 c->write_buffer =
NULL;
4310 c->write_buffer_size = 0;
4311 c->write_buffer_send_offset = 0;
4312 c->write_buffer_append_offset = 0;
4321 if ( (
NULL !=
d->notify_completed) &&
4323 d->notify_completed (
d->notify_completed_cls,
4327 c->client_aware =
false;
4329 if (
NULL !=
c->response)
4347 c->read_buffer_offset,
4350 c->continue_message_write_offset = 0;
4351 c->headers_received =
NULL;
4352 c->headers_received_tail =
NULL;
4353 c->have_chunked_upload =
false;
4354 c->current_chunk_size = 0;
4355 c->current_chunk_offset = 0;
4356 c->responseCode = 0;
4357 c->response_write_position = 0;
4361 memset (&
c->rp_props, 0,
sizeof(
c->rp_props));
4362 c->write_buffer =
NULL;
4363 c->write_buffer_size = 0;
4364 c->write_buffer_send_offset = 0;
4365 c->write_buffer_append_offset = 0;
4391#ifdef MHD_USE_THREADS
4411 _ (
"In function %s handling connection at state: %s\n"),
4415 switch (connection->
state)
4662 _ (
"Closing connection (failed to create "
4663 "response header).\n"));
4674#ifdef UPGRADE_SUPPORT
4713#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4719#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4731#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4747#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4755#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4767#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4786 "Closing connection (failed to create response footer)."));
4820#ifdef UPGRADE_SUPPORT
4878 event.data.ptr = connection;
4887 _ (
"Call to epoll_ctl failed: %s\n"),
4934 if (
NULL == connection->tls_session)
4939 if (
NULL == connection->tls_session)
4942 connection->tls_session);
4945 if (
NULL == connection->tls_session)
4964 connection_timeout_dummy;
4998 daemon = connection->
daemon;
5004#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5022#if (SIZEOF_UINT64_T - 2) <= SIZEOF_UNSIGNED_INT
5027 _ (
"The specified connection timeout (%u) is too " \
5028 "large. Maximum allowed value (%" PRIu64 ") will be used " \
5050#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5079 unsigned int status_code,
5084 if ((
NULL == connection) || (
NULL == response))
5087 daemon = connection->
daemon;
5089#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5096 _ (
"Attempted to queue response on wrong thread!\n"));
5111#ifdef UPGRADE_SUPPORT
5112 if (
NULL != response->upgrade_handler)
5119 _ (
"Attempted 'upgrade' connection on daemon without" \
5120 " MHD_ALLOW_UPGRADE option!\n"));
5128 _ (
"Application used invalid status code for" \
5129 " 'upgrade' response!\n"));
5137 _ (
"Application used invalid response" \
5138 " without \"Connection\" header!\n"));
5151 _ (
"Application used invalid response" \
5152 " without \"upgrade\" token in" \
5153 " \"Connection\" header!\n"));
5161 _ (
"Connection \"Upgrade\" can be used " \
5162 "with HTTP/1.1 connections!\n"));
5173 _ (
"Refused wrong status code (%u). " \
5174 "HTTP requires three digits status code!\n"),
5185 _ (
"Wrong status code (%u) refused. " \
5186 "HTTP/1.0 clients do not support 1xx status codes!\n"),
5196 _ (
"Wrong status code (%u) refused. " \
5197 "HTTP/1.0 reply mode does not support 1xx status codes!\n"),
5207#if defined(_MHD_HAVE_SENDFILE)
5208 if ( (response->
fd == -1) ||
#define REQUEST_CONTENTLENGTH_TOOLARGE
static void connection_close_error_check(struct MHD_Connection *connection, const char *emsg)
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)
static bool is_reply_body_headers_needed(struct MHD_Connection *connection)
static enum MHD_Result build_header_response(struct MHD_Connection *connection)
static void connection_close_error(struct MHD_Connection *connection, const char *emsg)
static enum MHD_Result process_header_line(struct MHD_Connection *connection, char *line)
static void * connection_alloc_memory(struct MHD_Connection *connection, size_t size)
#define MHD_lookup_header_s_token_ci(c, h, tkn)
#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)
static bool add_user_headers(char *buf, size_t *ppos, size_t buf_size, struct MHD_Response *response, enum MHD_ValueKind kind, bool filter_transf_enc, bool add_close, bool add_keep_alive)
static enum MHD_Result try_ready_normal_body(struct MHD_Connection *connection)
#define REQUEST_CHUNKED_MALFORMED
#define REQ_HTTP_VER_IS_NOT_SUPPORTED
static void call_connection_handler(struct MHD_Connection *connection)
static void process_request_body(struct MHD_Connection *connection)
static void setup_reply_properties(struct MHD_Connection *connection)
#define HTTP_100_CONTINUE
static enum MHD_Result parse_cookie_header(struct MHD_Connection *connection)
#define transmit_error_response_static(c, code, msg)
#define REQUEST_MALFORMED
static void connection_shrink_read_buffer(struct MHD_Connection *connection)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
#define REQ_HTTP_VER_IS_TOO_OLD
static bool connection_check_timedout(struct MHD_Connection *c)
static enum MHD_ConnKeepAlive keepalive_possible(struct MHD_Connection *connection)
#define REQUEST_LACKS_HOST
static bool try_grow_read_buffer(struct MHD_Connection *connection, bool required)
static char * get_next_header_line(struct MHD_Connection *connection, size_t *line_len)
static enum MHD_Result parse_http_std_method(struct MHD_Connection *connection, const char *method, size_t len)
static bool need_100_continue(struct MHD_Connection *connection)
enum MHD_Result MHD_connection_handle_idle(struct MHD_Connection *connection)
#define CONNECTION_CLOSE_ERROR_CHECK(c, emsg)
static void cleanup_connection(struct MHD_Connection *connection)
static bool is_reply_body_needed(struct MHD_Connection *connection)
static enum MHD_Result process_broken_line(struct MHD_Connection *connection, char *line, enum MHD_ValueKind kind)
static enum MHD_Result try_ready_chunked_body(struct MHD_Connection *connection, bool *p_finished)
static bool get_date_str(char *date)
static void connection_reset(struct MHD_Connection *connection, bool reuse)
void MHD_connection_handle_read(struct MHD_Connection *connection, bool socket_error)
static void transmit_error_response_len(struct MHD_Connection *connection, unsigned int status_code, const char *message, size_t message_len)
static void connection_switch_from_recv_to_send(struct MHD_Connection *connection)
static void parse_connection_headers(struct MHD_Connection *connection)
void MHD_update_last_activity_(struct MHD_Connection *connection)
#define REQUEST_CONTENTLENGTH_MALFORMED
static enum MHD_Result parse_initial_message_line(struct MHD_Connection *connection, char *line, size_t line_len)
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 enum MHD_Result connection_add_header(struct MHD_Connection *connection, const char *key, size_t key_size, const char *value, size_t value_size, enum MHD_ValueKind kind)
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
#define CONNECTION_CLOSE_ERROR(c, emsg)
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)
static enum MHD_Result parse_http_version(struct MHD_Connection *connection, const char *http_string, size_t len)
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)
Methods for managing connections.
#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_URI_TOO_LONG
#define MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE
#define MHD_HTTP_PROCESSING
#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
enum MHD_Result(* MHD_KeyValueIterator)(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
_MHD_EXTERN int MHD_get_connection_values_n(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIteratorN iterator, void *iterator_cls)
_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)
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)
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 const char * MHD_lookup_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key)
_MHD_EXTERN int MHD_get_connection_values(struct MHD_Connection *connection, enum MHD_ValueKind kind, MHD_KeyValueIterator iterator, void *iterator_cls)
_MHD_EXTERN enum MHD_Result MHD_set_connection_value(struct MHD_Connection *connection, enum MHD_ValueKind kind, const char *key, const char *value)
_MHD_EXTERN 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_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 struct MHD_Response * MHD_create_response_from_buffer(size_t size, void *buffer, enum MHD_ResponseMemoryMode mode)
_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 const union MHD_ConnectionInfo * MHD_get_connection_info(struct MHD_Connection *connection, enum MHD_ConnectionInfoType info_type,...)
_MHD_EXTERN enum MHD_Result MHD_set_connection_option(struct MHD_Connection *connection, enum MHD_CONNECTION_OPTION option,...)
#define MHD_HTTP_VERSION_1_0
#define MHD_HTTP_VERSION_1_1
bool MHD_parse_arguments_(struct MHD_Request *request, enum MHD_ValueKind kind, char *args, MHD_ArgumentIterator_ cb, unsigned int *num_headers)
#define MHD_ERR_CONNRESET_
#define XDLL_insert(head, tail, element)
MHD_PanicCallback mhd_panic
@ MHD_EPOLL_STATE_SUSPENDED
@ MHD_EPOLL_STATE_READ_READY
@ MHD_EPOLL_STATE_IN_EPOLL_SET
@ MHD_EPOLL_STATE_WRITE_READY
#define DLL_insert(head, tail, element)
@ MHD_CONN_KEEPALIVE_UNKOWN
#define EDLL_remove(head, tail, element)
#define XDLL_remove(head, tail, element)
#define DLL_remove(head, tail, element)
void * MHD_pool_reallocate(struct MemoryPool *pool, void *old, size_t old_size, size_t new_size)
void MHD_pool_destroy(struct MemoryPool *pool)
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, int from_end)
#define MHD_mutex_unlock_chk_(pmutex)
#define MHD_mutex_lock_chk_(pmutex)
#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)
int MHD_str_equal_caseless_(const char *str1, const char *str2)
size_t MHD_str_to_uint64_n_(const char *str, size_t maxlen, uint64_t *out_val)
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)
#define MHD_str_has_s_token_caseless_(str, tkn)
#define MHD_STATICSTR_LEN_(macro)
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.
MHD internal shared structures.
@ MHD_CONNECTION_BODY_RECEIVED
@ MHD_CONNECTION_HEADER_PART_RECEIVED
@ MHD_CONNECTION_HEADERS_SENDING
@ MHD_CONNECTION_FOOTERS_SENDING
@ MHD_CONNECTION_FOOTERS_RECEIVED
@ MHD_CONNECTION_HEADERS_SENT
@ MHD_CONNECTION_HEADERS_PROCESSED
@ MHD_CONNECTION_NORMAL_BODY_UNREADY
@ MHD_CONNECTION_HEADERS_RECEIVED
@ MHD_CONNECTION_NORMAL_BODY_READY
@ MHD_CONNECTION_START_REPLY
@ MHD_CONNECTION_CHUNKED_BODY_READY
@ MHD_CONNECTION_FOOTER_PART_RECEIVED
@ MHD_CONNECTION_CONTINUE_SENT
@ MHD_CONNECTION_FOOTERS_SENT
@ MHD_CONNECTION_FULL_REQ_RECEIVED
@ MHD_CONNECTION_CHUNKED_BODY_UNREADY
@ MHD_CONNECTION_BODY_SENT
@ MHD_CONNECTION_CONTINUE_SENDING
@ MHD_CONNECTION_URL_RECEIVED
@ MHD_CONNECTION_REQ_LINE_RECEIVING
@ MHD_TLS_CONN_HANDSHAKING
@ MHD_EVENT_LOOP_INFO_READ
@ MHD_EVENT_LOOP_INFO_WRITE
@ MHD_EVENT_LOOP_INFO_CLEANUP
@ MHD_EVENT_LOOP_INFO_BLOCK
struct MHD_IoVec MHD_iovec_
#define MHD_IS_HTTP_VER_SUPPORTED(ver)
@ MHD_RAF_HAS_CONNECTION_CLOSE
@ MHD_RAF_HAS_TRANS_ENC_CHUNKED
@ MHD_RAF_HAS_CONNECTION_HDR
#define MHD_IS_HTTP_VER_1_1_COMPAT(ver)
@ MHD_HTTP_MTHD_NO_METHOD
void * MHD_pool_try_alloc(struct MemoryPool *pool, size_t size, size_t *required_bytes)
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
Header for platform missing functions.
Header for platform-independent inter-thread communication.
limits values definitions
uint64_t MHD_monotonic_msec_counter(void)
internal monotonic clock functions implementations
#define MHD_SEND_SPIPE_SUPPRESS_NEEDED
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_uint64_to_str(uint64_t val, char *buf, size_t buf_size)
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.
void MHD_increment_response_rc(struct MHD_Response *response)
#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_THREAD_PER_CONNECTION
@ MHD_USE_SUPPRESS_DATE_NO_CLOCK
@ MHD_USE_INTERNAL_POLLING_THREAD
@ MHD_RF_SEND_KEEP_ALIVE_HEADER
@ MHD_RF_HTTP_1_0_COMPATIBLE_STRICT
@ MHD_CONNECTION_OPTION_TIMEOUT
Methods for managing response objects.
enum MHD_Result MHD_response_execute_upgrade_(struct MHD_Response *response, struct MHD_Connection *connection)
enum MHD_HTTP_Method http_mthd
size_t write_buffer_send_offset
struct MHD_Reply_Properties rp_props
enum MHD_HTTP_Version http_ver
enum MHD_ConnectionEventLoopInfo event_loop_info
size_t write_buffer_append_offset
uint64_t remaining_upload_size
struct MHD_Response * response
enum MHD_ConnKeepAlive keepalive
struct MHD_HTTP_Header * headers_received
size_t continue_message_write_offset
uint64_t response_write_position
struct sockaddr_storage addr
struct MHD_HTTP_Header * headers_received_tail
uint64_t current_chunk_offset
size_t read_buffer_offset
uint64_t current_chunk_size
struct MHD_iovec_track_ resp_iov
unsigned int responseCode
MHD_thread_handle_ID_ pid
enum MHD_CONNECTION_STATE state
struct MHD_Daemon * daemon
unsigned int connection_timeout_dummy
uint64_t connection_timeout_ms
MHD_AccessHandlerCallback default_handler
LogCallback uri_log_callback
void * unescape_callback_cls
MHD_mutex_ cleanup_connection_mutex
struct MHD_Connection * connections_head
MHD_RequestCompletedCallback notify_completed
uint64_t connection_timeout_ms
struct MHD_Connection * manual_timeout_tail
UnescapeCallback unescape_callback
void * notify_completed_cls
struct MHD_Connection * cleanup_tail
MHD_thread_handle_ID_ pid
struct MHD_Connection * manual_timeout_head
void * default_handler_cls
struct MHD_Connection * suspended_connections_tail
struct MHD_Connection * cleanup_head
struct MHD_Connection * normal_timeout_head
struct MHD_Connection * normal_timeout_tail
void * uri_log_callback_cls
struct MHD_Connection * suspended_connections_head
struct MHD_Connection * connections_tail
struct MHD_HTTP_Header * first_header
enum MHD_HTTP_StatusCode status_code
MHD_ContentReaderCallback crc
enum MHD_ResponseAutoFlags flags_auto
enum MHD_ResponseFlags flags