34 #if HAVE_NETINET_TCP_H
36 #include <netinet/tcp.h>
42 #define HTTP_100_CONTINUE "HTTP/1.1 100 Continue\r\n\r\n"
52 #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>"
54 #define REQUEST_TOO_BIG ""
65 #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>"
67 #define REQUEST_LACKS_HOST ""
78 #define REQUEST_MALFORMED "<html><head><title>Request malformed</title></head><body>Your HTTP request was syntactically incorrect.</body></html>"
80 #define REQUEST_MALFORMED ""
90 #define INTERNAL_ERROR "<html><head><title>Internal server error</title></head><body>Some programmer needs to study the manual more carefully.</body></html>"
92 #define INTERNAL_ERROR ""
99 #define DEBUG_CLOSE MHD_NO
104 #define DEBUG_SEND_DATA MHD_NO
122 if (connection ==
NULL)
128 if (0 != (pos->
kind & kind))
131 if ((iterator !=
NULL) &&
132 (
MHD_YES != iterator (iterator_cls,
173 const char *key,
const char *
value)
181 pos->
header = (
char *) key;
182 pos->
value = (
char *) value;
202 if (connection ==
NULL)
207 if ((0 != (pos->
kind & kind)) && (0 == strcasecmp (key, pos->
header)))
226 unsigned int status_code,
struct MHD_Response *response)
228 if ((connection ==
NULL) ||
229 (response ==
NULL) ||
272 (0 == strcasecmp (connection->
version,
277 && (0 == strcasecmp (expect,
"100-continue"))
297 notify_completed_cls, connection,
338 if ( (response->
fd != -1) &&
368 MHD_DLOG (connection->
daemon,
369 "Closing connection (end of response or error)\n");
414 MHD_DLOG (connection->
daemon,
415 "Closing connection (out of memory)\n");
454 MHD_DLOG (connection->
daemon,
455 "Closing connection (error generating response)\n");
481 cblen = strlen (cbuf);
483 memcpy (&connection->
write_buffer[sizeof (cbuf) - cblen], cbuf, cblen);
484 memcpy (&connection->
write_buffer[sizeof (cbuf) + ret],
"\r\n", 2);
506 if ((have ==
NULL) || (0 != strcasecmp (have,
"close")))
546 static const char *days[] =
547 {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" };
548 static const char *mons[] =
549 {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
558 "Date: %3s, %02u %3s %04u %02u:%02u:%02u GMT\r\n",
559 days[now.tm_wday % 7],
561 mons[now.tm_mon % 12],
562 1900 + now.tm_year, now.tm_hour, now.tm_min, now.tm_sec);
605 const char *reason_phrase;
609 if (0 == strlen(connection->
version))
642 size += strlen (date);
653 if (pos->
kind == kind)
654 size += strlen (pos->
header) + strlen (pos->
value) + 4;
662 MHD_DLOG (connection->
daemon,
"Not enough memory for write!\n");
668 memcpy (data, code, off);
673 if (pos->
kind == kind)
679 strcpy (&data[off], date);
680 off += strlen (date);
682 memcpy (&data[off],
"\r\n", 2);
702 unsigned int status_code,
const char *message)
715 MHD_DLOG (connection->
daemon,
716 "Error %u (`%s') processing request, closing connection.\n",
717 status_code, message);
730 MHD_DLOG (connection->
daemon,
731 "Closing connection (failed to create response header)\n");
749 if ( (
NULL != max_fd) &&
761 fd_set * read_fd_set,
762 fd_set * write_fd_set,
763 fd_set * except_fd_set,
int *max_fd)
795 MHD_DLOG (connection->
daemon,
"Failed to create memory pool!\n");
807 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
808 __FUNCTION__, MHD_state_to_string (connection->
state));
810 switch (connection->
state)
814 if (0 == gnutls_record_get_direction (connection->tls_session))
959 while ((pos < connection->read_buffer_offset - 1) &&
960 (rbuf[pos] !=
'\r') && (rbuf[pos] !=
'\n'))
990 if ((rbuf[pos] ==
'\r') && (rbuf[pos + 1] ==
'\n'))
1013 MHD_DLOG (connection->
daemon,
1014 "Not enough memory to allocate header record!\n");
1038 while (args !=
NULL)
1040 equals = strstr (args,
"=");
1045 amper = strstr (equals,
"&");
1091 MHD_DLOG (connection->
daemon,
"Not enough memory to parse cookies!\n");
1097 memcpy (cpy, hdr, strlen (hdr) + 1);
1105 while (((*sce) !=
'\0') &&
1106 ((*sce) !=
',') && ((*sce) !=
';') && ((*sce) !=
'='))
1110 while ((*ekill ==
' ') && (ekill >= pos))
1128 while ((semicolon[0] !=
'\0') &&
1130 ((semicolon[0] !=
';') && (semicolon[0] !=
','))))
1132 if (semicolon[0] ==
'"')
1133 quotes = (quotes + 1) & 1;
1136 if (semicolon[0] ==
'\0')
1138 if (semicolon !=
NULL)
1140 semicolon[0] =
'\0';
1144 if ((equals[0] ==
'"') && (equals[strlen (equals) - 1] ==
'"'))
1146 equals[strlen (equals) - 1] =
'\0';
1171 uri = strstr (line,
" ");
1175 connection->
method = line;
1177 while (uri[0] ==
' ')
1179 httpVersion = strstr (uri,
" ");
1180 if (httpVersion !=
NULL)
1182 httpVersion[0] =
'\0';
1189 uri_log_callback_cls, uri);
1190 args = strstr (uri,
"?");
1200 connection->
url = uri;
1201 if (httpVersion ==
NULL)
1204 connection->
version = httpVersion;
1225 default_handler_cls,
1226 connection, connection->
url,
1234 MHD_DLOG (connection->
daemon,
1235 "Internal application error, closing connection.\n");
1277 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1279 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1285 MHD_DLOG (connection->
daemon,
1286 "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1305 if (processed > available)
1306 processed = available;
1307 if (available > processed)
1314 while (i < available)
1316 if ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n'))
1326 if ((i + 1 >= available) &&
1327 !((i == 1) && (available == 2) && (buffer_head[0] ==
'0')))
1329 malformed = (i >= 6);
1332 buffer_head[i] =
'\0';
1334 (1 !=
SSCANF (buffer_head,
"%X",
1336 (1 !=
SSCANF (buffer_head,
"%x",
1343 MHD_DLOG (connection->
daemon,
1344 "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1350 if ((i < available) &&
1351 ((buffer_head[i] ==
'\r') || (buffer_head[i] ==
'\n')))
1371 processed = available;
1377 default_handler_cls,
1378 connection, connection->
url,
1381 buffer_head, &processed,
1386 MHD_DLOG (connection->
daemon,
1387 "Internal application error, closing connection.\n");
1392 if (processed > used)
1406 buffer_head += used;
1411 while (instant_retry ==
MHD_YES);
1413 memmove (connection->
read_buffer, buffer_head, available);
1433 bytes_read = connection->
recv_cls (connection,
1445 MHD_DLOG (connection->
daemon,
1446 "Failed to receive data: %s\n",
1447 gnutls_strerror (bytes_read));
1450 MHD_DLOG (connection->
daemon,
1451 "Failed to receive data: %s\n",
STRERROR (errno));
1456 if (bytes_read == 0)
1479 ret = connection->
send_cls (connection,
1492 MHD_DLOG (connection->
daemon,
1493 "Failed to send data: %s\n",
1494 gnutls_strerror (ret));
1497 MHD_DLOG (connection->
daemon,
1498 "Failed to send data: %s\n",
STRERROR (errno));
1505 "Sent response: `%.*s'\n",
1527 connection->
state = next_state;
1546 colon = strstr (line,
":");
1551 MHD_DLOG (connection->
daemon,
1552 "Received malformed line (no colon), closing connection.\n");
1560 while ((colon[0] !=
'\0') && ((colon[0] ==
' ') || (colon[0] ==
'\t')))
1567 connection->
last = line;
1568 connection->
colon = colon;
1590 last = connection->
last;
1591 if ((line[0] ==
' ') || (line[0] ==
'\t'))
1595 last_len = strlen (last);
1598 while ((tmp[0] ==
' ') || (tmp[0] ==
'\t'))
1600 tmp_len = strlen (tmp);
1604 last_len + tmp_len + 1);
1612 memcpy (&last[last_len], tmp, tmp_len + 1);
1613 connection->
last = last;
1618 last, connection->
colon, kind)))
1625 if (strlen (line) != 0)
1662 MHD_DLOG (connection->
daemon,
1663 "Received `%s' request without `%s' header.\n",
1684 MHD_DLOG (connection->
daemon,
1685 "Failed to parse `%s' header `%s', closing connection.\n",
1706 if (0 == strcasecmp (enc,
"chunked"))
1737 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
1738 __FUNCTION__, MHD_state_to_string (connection->
state));
1740 switch (connection->
state)
1793 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
1794 __FUNCTION__, MHD_state_to_string (connection->
state));
1796 switch (connection->
state)
1807 ret = connection->
send_cls (connection,
1817 MHD_DLOG (connection->
daemon,
1818 "Failed to send data: %s\n",
STRERROR (errno));
1825 "Sent 100 continue response: `%.*s'\n",
1848 pthread_mutex_lock (&response->
mutex);
1852 pthread_mutex_unlock (&response->
mutex);
1856 ret = connection->
send_cls (connection,
1866 "Sent DATA response: `%.*s'\n",
1872 pthread_mutex_unlock (&response->
mutex);
1878 MHD_DLOG (connection->
daemon,
1879 "Failed to send data: %s\n",
STRERROR (errno));
1900 case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
1940 unsigned int timeout;
1947 MHD_DLOG (connection->
daemon,
"%s: state: %s\n",
1948 __FUNCTION__, MHD_state_to_string (connection->
state));
1950 switch (connection->
state)
1983 if (strlen (line) == 0)
2013 if (strlen (line) == 0)
2085 if (strlen (line) == 0)
2115 if (strlen (line) == 0)
2131 MHD_DLOG (connection->
daemon,
2132 "Closing connection (failed to create response header)\n");
2139 #if HAVE_DECL_TCP_CORK
2143 setsockopt (connection->
socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2202 #if HAVE_DECL_TCP_CORK
2206 setsockopt (connection->
socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2214 notify_completed_cls,
2234 if ((end !=
NULL) && (0 == strcasecmp (end,
"close")))
2310 if (connection->tls_session ==
NULL)
2312 connection->cipher = gnutls_cipher_get (connection->tls_session);
2315 if (connection->tls_session ==
NULL)
2317 connection->protocol = gnutls_protocol_get_version (connection->tls_session);
2320 if (connection->tls_session ==
NULL)