35 #if HAVE_NETINET_TCP_H
37 #include <netinet/tcp.h>
43 #define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
53 #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>"
55 #define REQUEST_TOO_BIG ""
66 #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>"
68 #define REQUEST_LACKS_HOST ""
79 #define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
81 #define REQUEST_MALFORMED ""
91 #define INTERNAL_ERROR "<html><head><title>Internal server error</title></head><body>Some programmer needs to study the manual more carefully.</body></html>"
93 #define INTERNAL_ERROR ""
100 #define DEBUG_CLOSE MHD_NO
105 #define DEBUG_SEND_DATA MHD_NO
126 if (
NULL == connection)
130 if (0 != (pos->
kind & kind))
133 if ((
NULL != iterator) &&
134 (
MHD_YES != iterator (iterator_cls,
174 const char *key,
const char *
value)
182 pos->
header = (
char *) key;
183 pos->
value = (
char *) value;
216 if (
NULL == connection)
219 if ((0 != (pos->
kind & kind)) &&
223 (0 == strcasecmp (key, pos->
header))) ))
241 unsigned int status_code,
struct MHD_Response *response)
243 if ( (
NULL == connection) ||
244 (
NULL == response) ||
286 (0 == strcasecmp (connection->
version,
291 (0 == strcasecmp (expect,
"100-continue")) &&
310 daemon = connection->
daemon;
337 MHD_DLOG (connection->
daemon, emsg);
348 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, emsg)
350 #define CONNECTION_CLOSE_ERROR(c, emsg) connection_close_error (c, NULL)
379 if ( (-1 != response->
fd) &&
409 ?
"Closing connection (end of response)\n"
410 :
"Closing connection (stream error)\n");
454 "Closing connection (out of memory)\n");
490 "Closing connection (error generating response)\n");
512 cblen = strlen (cbuf);
514 memcpy (&connection->
write_buffer[sizeof (cbuf) - cblen], cbuf, cblen);
515 memcpy (&connection->
write_buffer[sizeof (cbuf) + ret],
"\r\n", 2);
540 if ((
NULL == have) || (0 != strcasecmp (have,
"close")))
581 static const char *days[] =
582 {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" };
583 static const char *mons[] =
584 {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
593 "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
594 days[now.tm_wday % 7],
596 mons[now.tm_mon % 12],
597 1900 + now.tm_year, now.tm_hour, now.tm_min, now.tm_sec);
644 const char *reason_phrase;
649 if (0 == strlen(connection->
version))
683 size += strlen (date);
693 (0 == strcasecmp (connection->
version,
698 size += strlen (
"Connection: close\r\n");
700 if (pos->
kind == kind)
701 size += strlen (pos->
header) + strlen (pos->
value) + 4;
707 MHD_DLOG (connection->
daemon,
"Not enough memory for write!\n");
713 memcpy (data, code, off);
721 memcpy (&data[off],
"Connection: close\r\n",
722 strlen (
"Connection: close\r\n"));
723 off += strlen (
"Connection: close\r\n");
726 if (pos->
kind == kind)
733 strcpy (&data[off], date);
734 off += strlen (date);
736 memcpy (&data[off],
"\r\n", 2);
760 unsigned int status_code,
774 MHD_DLOG (connection->
daemon,
775 "Error %u (`%s') processing request, closing connection.\n",
776 status_code, message);
789 "Closing connection (failed to create response header)\n");
812 if ( (
NULL != max_fd) &&
833 fd_set *write_fd_set,
834 fd_set *except_fd_set,
873 "Failed to create memory pool!\n");
883 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
884 __FUNCTION__, MHD_state_to_string (connection->
state));
886 switch (connection->
state)
890 if (0 == gnutls_record_get_direction (connection->tls_session))
905 "Connection buffer to small for request\n");
1035 while ((pos < connection->read_buffer_offset - 1) &&
1036 (
'\r' != rbuf[pos]) && (
'\n' != rbuf[pos]))
1066 if ((
'\r' == rbuf[pos]) && (
'\n' == rbuf[pos + 1]))
1096 MHD_DLOG (connection->
daemon,
1097 "Not enough memory to allocate header record!\n");
1124 while (
NULL != args)
1126 equals = strchr (args,
'=');
1127 amper = strchr (args,
'&');
1156 if ( (
NULL == equals) ||
1219 MHD_DLOG (connection->
daemon,
"Not enough memory to parse cookies!\n");
1225 memcpy (cpy, hdr, strlen (hdr) + 1);
1233 while (((*sce) !=
'\0') &&
1234 ((*sce) !=
',') && ((*sce) !=
';') && ((*sce) !=
'='))
1238 while ((*ekill ==
' ') && (ekill >= pos))
1256 while ((semicolon[0] !=
'\0') &&
1258 ((semicolon[0] !=
';') && (semicolon[0] !=
','))))
1260 if (semicolon[0] ==
'"')
1261 quotes = (quotes + 1) & 1;
1264 if (semicolon[0] ==
'\0')
1266 if (semicolon !=
NULL)
1268 semicolon[0] =
'\0';
1272 if ((equals[0] ==
'"') && (equals[strlen (equals) - 1] ==
'"'))
1274 equals[strlen (equals) - 1] =
'\0';
1300 if (
NULL == (uri = strchr (line,
' ')))
1303 connection->
method = line;
1305 while (uri[0] ==
' ')
1307 httpVersion = strchr (uri,
' ');
1308 if (httpVersion !=
NULL)
1310 httpVersion[0] =
'\0';
1317 uri_log_callback_cls, uri);
1318 args = strchr (uri,
'?');
1328 connection->
url = uri;
1329 if (
NULL == httpVersion)
1332 connection->
version = httpVersion;
1353 default_handler_cls,
1354 connection, connection->
url,
1362 "Internal application error, closing connection.\n");
1403 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1405 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1411 "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1428 if (processed > available)
1429 processed = available;
1430 if (available > processed)
1437 while (i < available)
1439 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1449 if ((i + 1 >= available) &&
1450 !((i == 1) && (available == 2) && (buffer_head[0] ==
'0')))
1452 malformed = (i >= 6);
1455 buffer_head[i] =
'\0';
1457 malformed = (
'\0' != *end);
1463 "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1467 if ((i < available) &&
1468 ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n')))
1500 processed = available;
1507 default_handler_cls,
1508 connection, connection->
url,
1511 buffer_head, &processed,
1516 "Internal application error, closing connection.\n");
1519 if (processed > used)
1533 buffer_head += used;
1538 while (
MHD_YES == instant_retry);
1540 memmove (connection->
read_buffer, buffer_head, available);
1560 bytes_read = connection->
recv_cls (connection,
1567 if ((EINTR == errno) || (EAGAIN == errno))
1572 MHD_DLOG (connection->
daemon,
1573 "Failed to receive data: %s\n",
1574 gnutls_strerror (bytes_read));
1577 MHD_DLOG (connection->
daemon,
1578 "Failed to receive data: %s\n",
STRERROR (errno));
1583 if (0 == bytes_read)
1606 ret = connection->
send_cls (connection,
1614 if ((EINTR == errno) || (EAGAIN == errno))
1619 MHD_DLOG (connection->
daemon,
1620 "Failed to send data: %s\n",
1621 gnutls_strerror (ret));
1624 MHD_DLOG (connection->
daemon,
1625 "Failed to send data: %s\n",
STRERROR (errno));
1632 "Sent response: `%.*s'\n",
1654 connection->
state = next_state;
1673 colon = strchr (line,
':');
1678 "Received malformed line (no colon), closing connection.\n");
1684 while ((colon[0] !=
'\0') && ((colon[0] ==
' ') || (colon[0] ==
'\t')))
1691 connection->
last = line;
1692 connection->
colon = colon;
1715 last = connection->
last;
1716 if ((line[0] ==
' ') || (line[0] ==
'\t'))
1720 last_len = strlen (last);
1723 while ((tmp[0] ==
' ') || (tmp[0] ==
'\t'))
1725 tmp_len = strlen (tmp);
1729 last_len + tmp_len + 1);
1737 memcpy (&last[last_len], tmp, tmp_len + 1);
1738 connection->
last = last;
1743 last, connection->
colon, kind)))
1750 if (strlen (line) != 0)
1789 MHD_DLOG (connection->
daemon,
1790 "Received `%s' request without `%s' header.\n",
1808 cval = strtoul (clen, &end, 10);
1809 if ( (
'\0' != *end) ||
1810 ( (LONG_MAX == cval) && (errno == ERANGE) ) )
1813 MHD_DLOG (connection->
daemon,
1814 "Failed to parse `%s' header `%s', closing connection.\n",
1835 if (0 == strcasecmp (enc,
"chunked"))
1868 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
1869 __FUNCTION__, MHD_state_to_string (connection->
state));
1871 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);
1986 pthread_mutex_unlock (&response->
mutex);
1989 ret = connection->
send_cls (connection,
1999 "Sent DATA response: `%.*s'\n",
2005 pthread_mutex_unlock (&response->
mutex);
2008 if ((errno == EINTR) || (errno == EAGAIN))
2011 MHD_DLOG (connection->
daemon,
2012 "Failed to send data: %s\n",
STRERROR (errno));
2035 case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
2078 unsigned int timeout;
2086 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
2087 __FUNCTION__, MHD_state_to_string (connection->
state));
2089 switch (connection->
state)
2124 if (strlen (line) == 0)
2155 if (strlen (line) == 0)
2228 if (strlen (line) == 0)
2259 if (strlen (line) == 0)
2275 "Closing connection (failed to create response header)\n");
2280 #if HAVE_DECL_TCP_CORK
2284 setsockopt (connection->
socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2343 #if HAVE_DECL_TCP_CORK
2347 setsockopt (connection->
socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2354 rend = ( (end !=
NULL) && (0 == strcasecmp (end,
"close")) );
2380 if ( (rend) || ((end !=
NULL) && (0 == strcasecmp (end,
"close"))) )
2414 daemon = connection->
daemon;
2417 MHD_PANIC (
"Failed to acquire cleanup mutex\n");
2427 MHD_PANIC (
"Failed to release cleanup mutex\n");
2437 if ( (timeout != 0) &&
2478 if (connection->tls_session ==
NULL)
2480 connection->cipher = gnutls_cipher_get (connection->tls_session);
2483 if (connection->tls_session ==
NULL)
2485 connection->protocol = gnutls_protocol_get_version (connection->tls_session);
2488 if (connection->tls_session ==
NULL)
2520 va_start (ap, option);