35 #if HAVE_NETINET_TCP_H
37 #include <netinet/tcp.h>
44 #define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
54 #define REQUEST_TOO_BIG "<html><head><title>Request too big</title></head><body>Your HTTP header was too big for the memory constraints of this webserver.</body></html>"
56 #define REQUEST_TOO_BIG ""
67 #define REQUEST_LACKS_HOST "<html><head><title>"Host:" header required</title></head><body>In HTTP 1.1, requests must include a "Host:" header, and your HTTP 1.1 request lacked such a header.</body></html>"
69 #define REQUEST_LACKS_HOST ""
80 #define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
82 #define REQUEST_MALFORMED ""
92 #define INTERNAL_ERROR "<html><head><title>Internal server error</title></head><body>Some programmer needs to study the manual more carefully.</body></html>"
94 #define INTERNAL_ERROR ""
101 #define DEBUG_CLOSE MHD_NO
106 #define DEBUG_SEND_DATA MHD_NO
128 if (
NULL == connection)
132 if (0 != (pos->
kind & kind))
135 if ((
NULL != iterator) &&
136 (
MHD_YES != iterator (iterator_cls,
172 const char *key,
const char *
value)
180 pos->
header = (
char *) key;
181 pos->
value = (
char *) value;
215 if (
NULL == connection)
218 if ((0 != (pos->
kind & kind)) &&
222 (0 == strcasecmp (key, pos->
header))) ))
242 (0 == strcasecmp (connection->
version,
247 (0 == strcasecmp (expect,
"100-continue")) &&
266 daemon = connection->
daemon;
295 MHD_DLOG (connection->
daemon, emsg);
306 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, emsg)
308 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, NULL)
341 if ( (-1 != response->
fd) &&
361 pthread_mutex_unlock (&response->
mutex);
362 if ( ((ssize_t)MHD_CONTENT_READER_END_OF_STREAM) == ret)
366 "Closing connection (stream error)\n");
375 pthread_mutex_unlock (&response->
mutex);
412 "Closing connection (out of memory)\n");
452 "Closing connection (error generating response)\n");
474 "%X\r\n", (
unsigned int) ret);
475 cblen = strlen (cbuf);
477 memcpy (&connection->
write_buffer[sizeof (cbuf) - cblen], cbuf, cblen);
478 memcpy (&connection->
write_buffer[sizeof (cbuf) + ret],
"\r\n", 2);
495 const char *have_close;
496 const char *client_close;
497 const char *have_encoding;
505 if ( (
NULL != client_close) && (0 != strcasecmp (client_close,
"close")) )
509 if ( (
NULL != have_close) && (0 != strcasecmp (have_close,
"close")) )
517 if (
NULL == have_close)
521 if ((
NULL == client_close) &&
528 if (
NULL == have_encoding)
532 else if (0 != strcasecmp (have_encoding,
"chunked"))
545 if ( (
NULL != client_close) &&
546 (
NULL == have_close) )
553 (0 != strcasecmp (connection->
method,
594 static const char *
const days[] =
595 {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" };
596 static const char *
const mons[] =
597 {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
606 "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
607 days[now.tm_wday % 7],
608 (
unsigned int) now.tm_mday,
609 mons[now.tm_mon % 12],
610 (
unsigned int) (1900 + now.tm_year),
611 (
unsigned int) now.tm_hour,
612 (
unsigned int) now.tm_min,
613 (
unsigned int) now.tm_sec);
669 const char *reason_phrase;
674 if (0 == strlen (connection->
version))
708 size += strlen (date);
718 (0 == strcasecmp (connection->
version,
723 size += strlen (
"Connection: close\r\n");
725 if (pos->
kind == kind)
726 size += strlen (pos->
header) + strlen (pos->
value) + 4;
732 MHD_DLOG (connection->
daemon,
"Not enough memory for write!\n");
738 memcpy (data, code, off);
746 memcpy (&data[off],
"Connection: close\r\n",
747 strlen (
"Connection: close\r\n"));
748 off += strlen (
"Connection: close\r\n");
751 if (pos->
kind == kind)
752 off += SPRINTF (&data[off],
758 strcpy (&data[off], date);
759 off += strlen (date);
761 memcpy (&data[off],
"\r\n", 2);
785 unsigned int status_code,
799 MHD_DLOG (connection->
daemon,
800 "Error %u (`%s') processing request, closing connection.\n",
801 status_code, message);
814 "Closing connection (failed to create response header)\n");
837 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
838 __FUNCTION__, MHD_state_to_string (connection->
state));
840 switch (connection->
state)
844 if (0 == gnutls_record_get_direction (connection->tls_session))
987 while ((pos < connection->read_buffer_offset - 1) &&
988 (
'\r' != rbuf[pos]) && (
'\n' != rbuf[pos]))
991 (
'\n' != rbuf[pos]) )
1007 if ((
'\r' == rbuf[pos]) && (
'\n' == rbuf[pos + 1]))
1037 MHD_DLOG (connection->
daemon,
1038 "Not enough memory to allocate header record!\n");
1065 while (
NULL != args)
1067 equals = strchr (args,
'=');
1068 amper = strchr (args,
'&');
1097 if ( (
NULL == equals) ||
1160 MHD_DLOG (connection->
daemon,
"Not enough memory to parse cookies!\n");
1166 memcpy (cpy, hdr, strlen (hdr) + 1);
1174 while (((*sce) !=
'\0') &&
1175 ((*sce) !=
',') && ((*sce) !=
';') && ((*sce) !=
'='))
1179 while ((*ekill ==
' ') && (ekill >= pos))
1197 while ((semicolon[0] !=
'\0') &&
1199 ((semicolon[0] !=
';') && (semicolon[0] !=
','))))
1201 if (semicolon[0] ==
'"')
1202 quotes = (quotes + 1) & 1;
1205 if (semicolon[0] ==
'\0')
1207 if (
NULL != semicolon)
1209 semicolon[0] =
'\0';
1213 if ((equals[0] ==
'"') && (equals[strlen (equals) - 1] ==
'"'))
1215 equals[strlen (equals) - 1] =
'\0';
1241 if (
NULL == (uri = strchr (line,
' ')))
1244 connection->
method = line;
1246 while (uri[0] ==
' ')
1248 http_version = strchr (uri,
' ');
1249 if (
NULL != http_version)
1251 http_version[0] =
'\0';
1259 args = strchr (uri,
'?');
1269 connection->
url = uri;
1270 if (
NULL == http_version)
1273 connection->
version = http_version;
1296 default_handler_cls,
1297 connection, connection->
url,
1305 "Internal application error, closing connection.\n");
1348 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1350 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1356 "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1373 if (processed > available)
1374 processed = available;
1375 if (available > processed)
1382 while (i < available)
1384 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1394 if ((i + 1 >= available) &&
1395 !((i == 1) && (available == 2) && (buffer_head[0] ==
'0')))
1397 malformed = (i >= 6);
1400 buffer_head[i] =
'\0';
1402 malformed = (
'\0' != *end);
1408 "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1412 if ((i < available) &&
1413 ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n')))
1445 processed = available;
1452 default_handler_cls,
1453 connection, connection->
url,
1456 buffer_head, &processed,
1461 "Internal application error, closing connection.\n");
1464 if (processed > used)
1478 buffer_head += used;
1483 while (
MHD_YES == instant_retry);
1485 memmove (connection->
read_buffer, buffer_head, available);
1506 bytes_read = connection->
recv_cls (connection,
1513 if ((EINTR == errno) || (EAGAIN == errno))
1518 MHD_DLOG (connection->
daemon,
1519 "Failed to receive data: %s\n",
1520 gnutls_strerror (bytes_read));
1523 MHD_DLOG (connection->
daemon,
1524 "Failed to receive data: %s\n", STRERROR (errno));
1529 if (0 == bytes_read)
1557 ret = connection->
send_cls (connection,
1564 if ((EINTR == errno) || (EAGAIN == errno))
1569 MHD_DLOG (connection->
daemon,
1570 "Failed to send data: %s\n",
1571 gnutls_strerror (ret));
1574 MHD_DLOG (connection->
daemon,
1575 "Failed to send data: %s\n", STRERROR (errno));
1582 "Sent response: `%.*s'\n",
1611 connection->
state = next_state;
1636 colon = strchr (line,
':');
1641 "Received malformed line (no colon), closing connection.\n");
1647 while ((colon[0] !=
'\0') && ((colon[0] ==
' ') || (colon[0] ==
'\t')))
1654 connection->
last = line;
1655 connection->
colon = colon;
1679 last = connection->
last;
1680 if ((line[0] ==
' ') || (line[0] ==
'\t'))
1684 last_len = strlen (last);
1687 while ((tmp[0] ==
' ') || (tmp[0] ==
'\t'))
1689 tmp_len = strlen (tmp);
1702 last_len + tmp_len + 1);
1710 memcpy (&last[last_len], tmp, tmp_len + 1);
1711 connection->
last = last;
1716 last, connection->
colon, kind)))
1723 if (0 != strlen (line))
1764 MHD_DLOG (connection->
daemon,
1765 "Received `%s' request without `%s' header.\n",
1785 if (0 == strcasecmp (enc,
"chunked"))
1795 cval = strtoul (clen, &end, 10);
1796 if ( (
'\0' != *end) ||
1797 ( (LONG_MAX == cval) && (errno == ERANGE) ) )
1800 MHD_DLOG (connection->
daemon,
1801 "Failed to parse `%s' header `%s', closing connection.\n",
1832 MHD_PANIC (
"Failed to acquire cleanup mutex\n");
1841 MHD_PANIC (
"Failed to release cleanup mutex\n");
1869 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
1870 __FUNCTION__, MHD_state_to_string (connection->
state));
1872 switch (connection->
state)
1925 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
1926 __FUNCTION__, MHD_state_to_string (connection->
state));
1928 switch (connection->
state)
1939 ret = connection->
send_cls (connection,
1946 if ((errno == EINTR) || (errno == EAGAIN))
1949 MHD_DLOG (connection->
daemon,
1950 "Failed to send data: %s\n", STRERROR (errno));
1957 "Sent 100 continue response: `%.*s'\n",
1982 pthread_mutex_lock (&response->
mutex);
1985 ret = connection->
send_cls (connection,
1995 "Sent DATA response: `%.*s'\n",
2001 pthread_mutex_unlock (&response->
mutex);
2004 if ((errno == EINTR) || (errno == EAGAIN))
2007 MHD_DLOG (connection->
daemon,
2008 "Failed to send data: %s\n", STRERROR (errno));
2031 case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
2078 MHD_PANIC (
"Failed to acquire cleanup mutex\n");
2103 MHD_PANIC (
"Failed to release cleanup mutex\n");
2119 unsigned int timeout;
2128 MHD_DLOG (daemon,
"%s: state: %s\n",
2129 __FUNCTION__, MHD_state_to_string (connection->
state));
2131 switch (connection->
state)
2166 if (strlen (line) == 0)
2197 if (0 == strlen (line))
2219 ( (0 == strcasecmp (connection->
method,
2221 (0 == strcasecmp (connection->
method,
2274 if (strlen (line) == 0)
2305 if (strlen (line) == 0)
2321 "Closing connection (failed to create response header)\n");
2326 #if HAVE_DECL_TCP_CORK
2330 setsockopt (connection->
socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2401 #if HAVE_DECL_TCP_CORK
2405 setsockopt (connection->
socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2413 ( (end !=
NULL) && (0 == strcasecmp (end,
"close")) ) );
2438 if ( (rend) || ((end !=
NULL) && (0 == strcasecmp (end,
"close"))) )
2476 if ( (timeout != 0) &&
2493 daemon->eready_tail,
2505 daemon->eready_tail,
2514 daemon->eready_tail,
2526 daemon->eready_tail,
2535 return MHD_connection_epoll_update_ (connection);
2566 struct epoll_event event;
2568 event.events = EPOLLIN | EPOLLOUT | EPOLLET;
2569 event.data.ptr = connection;
2570 if (0 != epoll_ctl (daemon->epoll_fd,
2578 "Call to epoll_ctl failed: %s\n",
2625 if (connection->tls_session ==
NULL)
2627 connection->cipher = gnutls_cipher_get (connection->tls_session);
2630 if (connection->tls_session ==
NULL)
2632 connection->protocol = gnutls_protocol_get_version (connection->tls_session);
2635 if (connection->tls_session ==
NULL)
2668 daemon = connection->
daemon;
2674 MHD_PANIC (
"Failed to acquire cleanup mutex\n");
2683 va_start (ap, option);
2696 MHD_PANIC (
"Failed to release cleanup mutex\n");
2717 unsigned int status_code,
struct MHD_Response *response)
2719 if ( (
NULL == connection) ||
2720 (
NULL == response) ||
2737 ( (0 == strcasecmp (connection->
method,
2739 (0 == strcasecmp (connection->
method,