Lines Matching refs:connection
22 * @file connection.c
30 #include "connection.h"
119 * @param connection connection to get values from
128 MHD_get_connection_values (struct MHD_Connection *connection,
135 if (NULL == connection)
138 for (pos = connection->headers_received; NULL != pos; pos = pos->next)
153 * connection (so that the #MHD_get_connection_values function will
163 * until the connection is closed. (The easiest way to do this is by
166 * @param connection the connection for which a
177 MHD_set_connection_value (struct MHD_Connection *connection,
183 pos = MHD_pool_allocate (connection->pool,
192 if (NULL == connection->headers_received_tail)
194 connection->headers_received = pos;
195 connection->headers_received_tail = pos;
199 connection->headers_received_tail->next = pos;
200 connection->headers_received_tail = pos;
210 * @param connection connection to get values from
217 MHD_lookup_connection_value (struct MHD_Connection *connection,
222 if (NULL == connection)
224 for (pos = connection->headers_received; NULL != pos; pos = pos->next)
237 * message for this connection?
239 * @param connection connection to test
243 need_100_continue (struct MHD_Connection *connection)
247 return ( (NULL == connection->response) &&
248 (NULL != connection->version) &&
249 (MHD_str_equal_caseless_(connection->version,
251 (NULL != (expect = MHD_lookup_connection_value (connection,
255 (connection->continue_message_write_offset <
261 * Close the given connection and give the
264 * @param connection connection to close
268 MHD_connection_close (struct MHD_Connection *connection,
273 daemon = connection->daemon;
274 if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
275 shutdown (connection->socket_fd,
276 (MHD_YES == connection->read_closed) ? SHUT_WR : SHUT_RDWR);
277 connection->state = MHD_CONNECTION_CLOSED;
278 connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
280 (MHD_YES == connection->client_aware) )
282 connection,
283 &connection->client_context,
285 connection->client_aware = MHD_NO;
291 * connection (and notify the application).
293 * @param connection connection to close with error
297 connection_close_error (struct MHD_Connection *connection,
302 MHD_DLOG (connection->daemon, emsg);
304 MHD_connection_close (connection, MHD_REQUEST_TERMINATED_WITH_ERROR);
320 * Prepare the response buffer of this connection for
326 * @param connection the connection
332 try_ready_normal_body (struct MHD_Connection *connection)
337 response = connection->response;
343 connection->response_write_position) &&
345 connection->response_write_position) )
349 (0 == (connection->daemon->options & MHD_USE_SSL)) )
357 connection->response_write_position,
361 connection->response_write_position));
366 response->total_size = connection->response_write_position;
370 MHD_connection_close (connection, MHD_REQUEST_TERMINATED_COMPLETED_OK);
372 CONNECTION_CLOSE_ERROR (connection,
373 "Closing connection (stream error)\n");
376 response->data_start = connection->response_write_position;
380 connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
390 * Prepare the response buffer of this connection for sending.
395 * @param connection the connection
399 try_ready_chunked_body (struct MHD_Connection *connection)
408 response = connection->response;
409 if (0 == connection->write_buffer_size)
411 size = connection->daemon->pool_size;
418 CONNECTION_CLOSE_ERROR (connection,
419 "Closing connection (out of memory)\n");
422 buf = MHD_pool_allocate (connection->pool, size, MHD_NO);
425 connection->write_buffer_size = size;
426 connection->write_buffer = buf;
430 connection->response_write_position) &&
432 connection->response_write_position) )
435 ret = response->data_size + response->data_start - connection->response_write_position;
437 (((size_t) ret) > connection->write_buffer_size - sizeof (cbuf) - 2) )
438 ret = connection->write_buffer_size - sizeof (cbuf) - 2;
439 memcpy (&connection->write_buffer[sizeof (cbuf)],
440 &response->data[connection->response_write_position - response->data_start],
450 connection->response_write_position,
451 &connection->write_buffer[sizeof (cbuf)],
452 connection->write_buffer_size - sizeof (cbuf) - 2);
457 response->total_size = connection->response_write_position;
458 CONNECTION_CLOSE_ERROR (connection,
459 "Closing connection (error generating response)\n");
466 strcpy (connection->write_buffer, "0\r\n");
467 connection->write_buffer_append_offset = 3;
468 connection->write_buffer_send_offset = 0;
469 response->total_size = connection->response_write_position;
474 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
484 memcpy (&connection->write_buffer[sizeof (cbuf) - cblen], cbuf, cblen);
485 memcpy (&connection->write_buffer[sizeof (cbuf) + ret], "\r\n", 2);
486 connection->response_write_position += ret;
487 connection->write_buffer_send_offset = sizeof (cbuf) - cblen;
488 connection->write_buffer_append_offset = sizeof (cbuf) + ret + 2;
494 * Are we allowed to keep the given connection alive? We can use the
495 * TCP stream for a second request if the connection is HTTP 1.1 and
496 * the "Connection" header either does not exist or is not set to
497 * "close", or if the connection is HTTP 1.0 and the "Connection"
500 * connection. If the "Connection" header is not exactly "close" or
505 * @param connection the connection to check for keepalive
510 keepalive_possible (struct MHD_Connection *connection)
514 if (NULL == connection->version)
516 if ( (NULL != connection->response) &&
517 (0 != (connection
519 end = MHD_lookup_connection_value (connection,
522 if (MHD_str_equal_caseless_(connection->version,
532 if (MHD_str_equal_caseless_(connection->version,
604 * @param connection the connection
608 try_grow_read_buffer (struct MHD_Connection *connection)
613 if (0 == connection->read_buffer_size)
614 new_size = connection->daemon->pool_size / 2;
616 new_size = connection->read_buffer_size + MHD_BUF_INC_SIZE;
617 buf = MHD_pool_reallocate (connection->pool,
618 connection->read_buffer,
619 connection->read_buffer_size,
624 connection->read_buffer = buf;
625 connection->read_buffer_size = new_size;
631 * Allocate the connection's write buffer and fill it with all of the
636 * @param connection the connection
640 build_header_response (struct MHD_Connection *connection)
663 EXTRA_CHECK (NULL != connection->version);
664 if (0 == strlen (connection->version))
666 data = MHD_pool_allocate (connection->pool, 0, MHD_YES);
667 connection->write_buffer = data;
668 connection->write_buffer_append_offset = 0;
669 connection->write_buffer_send_offset = 0;
670 connection->write_buffer_size = 0;
673 if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
675 rc = connection->responseCode & (~MHD_ICY_FLAG);
679 (0 != (connection->responseCode & MHD_ICY_FLAG))
682 connection->version))
691 if ( (0 == (connection->daemon->options & MHD_SUPPRESS_DATE_NO_CLOCK)) &&
692 (NULL == MHD_get_response_header (connection->response,
707 /* calculate extra headers we need to add, such as 'Connection: close',
713 switch (connection->state)
716 response_has_close = MHD_get_response_header (connection->response,
725 client_requested_close = MHD_lookup_connection_value (connection,
733 connection->have_chunked_upload = MHD_NO;
735 if ( (MHD_SIZE_UNKNOWN == connection->response->total_size) &&
741 close the connection */
744 if ( (MHD_YES == keepalive_possible (connection)) &&
746 connection->version) ) )
748 have_encoding = MHD_get_response_header (connection->response,
753 connection->have_chunked_upload = MHD_YES;
762 connection->have_chunked_upload = MHD_YES;
776 (MHD_YES == connection->read_closed) ) &&
778 (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
782 have_content_length = MHD_get_response_header (connection->response,
785 if ( (MHD_SIZE_UNKNOWN != connection->response->total_size) &&
787 ( (NULL == connection->method) ||
788 (! MHD_str_equal_caseless_ (connection->method,
809 (MHD_UNSIGNED_LONG_LONG) connection->response->total_size);
817 (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) &&
818 (MHD_YES == keepalive_possible (connection)) )
828 size += strlen ("Connection: close\r\n");
830 size += strlen ("Connection: Keep-Alive\r\n");
838 for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
846 data = MHD_pool_allocate (connection->pool, size + 1, MHD_NO);
850 MHD_DLOG (connection->daemon,
855 if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
861 /* we must add the 'Connection: close' header */
863 "Connection: close\r\n",
864 strlen ("Connection: close\r\n"));
865 off += strlen ("Connection: close\r\n");
869 /* we must add the 'Connection: Keep-Alive' header */
871 "Connection: Keep-Alive\r\n",
872 strlen ("Connection: Keep-Alive\r\n"));
873 off += strlen ("Connection: Keep-Alive\r\n");
891 for (pos = connection->response->first_header; NULL != pos; pos = pos->next)
901 if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
911 connection->write_buffer = data;
912 connection->write_buffer_append_offset = size;
913 connection->write_buffer_send_offset = 0;
914 connection->write_buffer_size = size + 1;
924 * @param connection the connection
929 transmit_error_response (struct MHD_Connection *connection,
935 if (NULL == connection->version)
939 connection->version = MHD_HTTP_VERSION_1_0;
941 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
942 connection->read_closed = MHD_YES;
944 MHD_DLOG (connection->daemon,
945 "Error %u (`%s') processing request, closing connection.\n",
948 EXTRA_CHECK (NULL == connection->response);
952 MHD_queue_response (connection, status_code, response);
953 EXTRA_CHECK (NULL != connection->response);
955 if (MHD_NO == build_header_response (connection))
958 CONNECTION_CLOSE_ERROR (connection,
959 "Closing connection (failed to create response header)\n");
963 connection->state = MHD_CONNECTION_HEADERS_SENDING;
969 * Update the 'event_loop_info' field of this connection based on the state
970 * that the connection is now in. May also close the connection or
971 * perform other updates to the connection if needed to prepare for
974 * @param connection connetion to get poll set for
977 MHD_connection_update_event_loop_info (struct MHD_Connection *connection)
982 MHD_DLOG (connection->daemon,
985 MHD_state_to_string (connection->state));
987 switch (connection->state)
991 if (SSL_want_read (connection->tls_session))
992 connection
994 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1002 if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
1003 (MHD_NO == try_grow_read_buffer (connection)) )
1005 transmit_error_response (connection,
1006 (connection->url != NULL)
1012 if (MHD_NO == connection->read_closed)
1013 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
1015 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1024 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1027 if (connection->read_buffer_offset == connection->read_buffer_size)
1029 if ((MHD_YES != try_grow_read_buffer (connection)) &&
1030 (0 != (connection->daemon->options &
1042 on the connection (if a timeout is even
1044 Solution: we kill the connection with an error */
1045 transmit_error_response (connection,
1051 if ( (connection->read_buffer_offset < connection->read_buffer_size) &&
1052 (MHD_NO == connection->read_closed) )
1053 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
1055 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1061 if (MHD_YES == connection->read_closed)
1063 CONNECTION_CLOSE_ERROR (connection,
1067 connection->event_loop_info = MHD_EVENT_LOOP_INFO_READ;
1072 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1076 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1082 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1085 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1088 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1091 connection->event_loop_info = MHD_EVENT_LOOP_INFO_BLOCK;
1097 connection->event_loop_info = MHD_EVENT_LOOP_INFO_WRITE;
1103 connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
1117 * far too long, close the connection. If no line is
1121 * @param connection connection we're processing
1125 get_next_header_line (struct MHD_Connection *connection)
1130 if (0 == connection->read_buffer_offset)
1133 rbuf = connection->read_buffer;
1134 while ((pos < connection->read_buffer_offset - 1) &&
1137 if ( (pos == connection->read_buffer_offset - 1) &&
1141 if ( (connection->read_buffer_offset == connection->read_buffer_size) &&
1143 try_grow_read_buffer (connection)) )
1145 transmit_error_response (connection,
1146 (NULL != connection->url)
1157 connection->read_buffer += pos;
1158 connection->read_buffer_size -= pos;
1159 connection->read_buffer_offset -= pos;
1165 * Add an entry to the HTTP headers of a connection. If this fails,
1168 * @param connection the connection for which a
1176 connection_add_header (struct MHD_Connection *connection,
1179 if (MHD_NO == MHD_set_connection_value (connection,
1184 MHD_DLOG (connection->daemon,
1187 transmit_error_response (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
1199 * @param kind header kind to use for adding to the connection
1200 * @param connection connection to add headers to
1206 struct MHD_Connection *connection,
1223 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1224 connection,
1226 return connection_add_header (connection,
1235 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1236 connection,
1239 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1240 connection,
1242 return connection_add_header (connection, args, equals, kind);
1252 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1253 connection,
1256 connection_add_header (connection,
1271 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1272 connection,
1275 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1276 connection,
1278 if (MHD_NO == connection_add_header (connection, args, equals, kind))
1292 parse_cookie_header (struct MHD_Connection *connection)
1304 hdr = MHD_lookup_connection_value (connection,
1309 cpy = MHD_pool_allocate (connection->pool, strlen (hdr) + 1, MHD_YES);
1313 MHD_DLOG (connection->daemon,
1316 transmit_error_response (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
1341 connection_add_header (connection, pos, "", MHD_COOKIE_KIND))
1374 if (MHD_NO == connection_add_header (connection,
1386 * @param connection the connection (updated)
1391 parse_initial_message_line (struct MHD_Connection *connection,
1401 connection->method = line;
1411 if (NULL != connection->daemon->uri_log_callback)
1412 connection->client_context
1413 = connection->daemon->uri_log_callback (connection->daemon->uri_log_callback_cls,
1415 connection);
1421 parse_arguments (MHD_GET_ARGUMENT_KIND, connection, args);
1423 connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
1424 connection,
1426 connection->url = uri;
1428 connection->version = "";
1430 connection->version = http_version;
1437 * connection. Handles chunking of the upload
1440 * @param connection connection we're processing
1443 call_connection_handler (struct MHD_Connection *connection)
1447 if (NULL != connection->response)
1450 connection->client_aware = MHD_YES;
1452 connection->daemon->default_handler (connection->daemon-> default_handler_cls,
1453 connection,
1454 connection->url,
1455 connection->method,
1456 connection->version,
1458 &connection->client_context))
1460 /* serious internal error, close connection */
1461 CONNECTION_CLOSE_ERROR (connection,
1462 "Internal application error, closing connection.\n");
1471 * connection. Handles chunking of the upload
1474 * @param connection connection we're processing
1477 process_request_body (struct MHD_Connection *connection)
1488 if (NULL != connection->response)
1491 buffer_head = connection->read_buffer;
1492 available = connection->read_buffer_offset;
1496 if ( (MHD_YES == connection->have_chunked_upload) &&
1497 (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) )
1499 if ( (connection->current_chunk_offset == connection->current_chunk_size) &&
1500 (0 != connection->current_chunk_offset) &&
1512 CONNECTION_CLOSE_ERROR (connection,
1513 "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1518 connection->current_chunk_offset = 0;
1519 connection->current_chunk_size = 0;
1521 if (connection->current_chunk_offset <
1522 connection->current_chunk_size)
1528 connection->current_chunk_size -
1529 connection->current_chunk_offset;
1558 connection->current_chunk_size = strtoul (buffer_head, &end, 16);
1564 CONNECTION_CLOSE_ERROR (connection,
1565 "Received malformed HTTP request (bad chunked encoding), closing connection.\n");
1575 connection->current_chunk_offset = 0;
1579 if (0 == connection->current_chunk_size)
1581 connection->remaining_upload_size = 0;
1590 if ( (0 != connection->remaining_upload_size) &&
1591 (MHD_SIZE_UNKNOWN != connection->remaining_upload_size) &&
1592 (connection->remaining_upload_size < available) )
1594 processed = connection->remaining_upload_size;
1606 connection->client_aware = MHD_YES;
1608 connection->daemon->default_handler (connection->daemon->default_handler_cls,
1609 connection,
1610 connection->url,
1611 connection->method,
1612 connection->version,
1615 &connection->client_context))
1617 /* serious internal error, close connection */
1618 CONNECTION_CLOSE_ERROR (connection,
1619 "Internal application error, closing connection.\n");
1633 if (connection->have_chunked_upload == MHD_YES)
1634 connection->current_chunk_offset += used;
1638 if (connection->remaining_upload_size != MHD_SIZE_UNKNOWN)
1639 connection->remaining_upload_size -= used;
1643 memmove (connection->read_buffer, buffer_head, available);
1644 connection->read_buffer_offset = available;
1650 * read buffer of the connection.
1652 * @param connection connection we're processing
1658 do_read (struct MHD_Connection *connection)
1662 if (connection->read_buffer_size == connection->read_buffer_offset)
1664 bytes_read = connection->recv_cls (connection,
1665 &connection->read_buffer
1666 [connection->read_buffer_offset],
1667 connection->read_buffer_size -
1668 connection->read_buffer_offset);
1676 CONNECTION_CLOSE_ERROR (connection, NULL);
1679 CONNECTION_CLOSE_ERROR (connection, NULL);
1684 /* other side closed connection; RFC 2616, section 8.1.4 suggests
1686 connection->read_closed = MHD_YES;
1687 MHD_connection_close (connection,
1691 connection->read_buffer_offset += bytes_read;
1698 * write buffer of the connection.
1700 * @param connection connection we're processing
1705 do_write (struct MHD_Connection *connection)
1710 max = connection->write_buffer_append_offset - connection->write_buffer_send_offset;
1711 ret = connection->send_cls (connection,
1712 &connection->write_buffer
1713 [connection->write_buffer_send_offset],
1721 CONNECTION_CLOSE_ERROR (connection, NULL);
1728 &connection->write_buffer[connection->write_buffer_send_offset]);
1733 connection->write_buffer_send_offset += ret;
1742 * @param connection connection to check write status for
1747 check_write_done (struct MHD_Connection *connection,
1750 if (connection->write_buffer_append_offset !=
1751 connection->write_buffer_send_offset)
1753 connection->write_buffer_append_offset = 0;
1754 connection->write_buffer_send_offset = 0;
1755 connection->state = next_state;
1756 MHD_pool_reallocate (connection->pool,
1757 connection->write_buffer,
1758 connection->write_buffer_size, 0);
1759 connection->write_buffer = NULL;
1760 connection->write_buffer_size = 0;
1770 * @param connection connection we're processing
1775 process_header_line (struct MHD_Connection *connection, char *line)
1784 CONNECTION_CLOSE_ERROR (connection,
1785 "Received malformed line (no colon), closing connection.\n");
1793 /* we do the actual adding of the connection
1798 connection->last = line;
1799 connection->colon = colon;
1806 * The previous line(s) are in connection->last.
1808 * @param connection connection we're processing
1815 process_broken_line (struct MHD_Connection *connection,
1823 last = connection->last;
1843 last = MHD_pool_reallocate (connection->pool,
1849 transmit_error_response (connection,
1855 connection->last = last;
1858 EXTRA_CHECK ((NULL != last) && (NULL != connection->colon));
1859 if ((MHD_NO == connection_add_header (connection,
1860 last, connection->colon, kind)))
1862 transmit_error_response (connection, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
1869 if (MHD_NO == process_header_line (connection, line))
1871 transmit_error_response (connection,
1885 * @param connection connection we're processing
1888 parse_connection_headers (struct MHD_Connection *connection)
1896 parse_cookie_header (connection);
1897 if ( (0 != (MHD_USE_PEDANTIC_CHECKS & connection->daemon->options)) &&
1898 (NULL != connection->version) &&
1899 (MHD_str_equal_caseless_(MHD_HTTP_VERSION_1_1, connection->version)) &&
1901 MHD_lookup_connection_value (connection,
1906 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
1907 connection->read_closed = MHD_YES;
1909 MHD_DLOG (connection->daemon,
1913 EXTRA_CHECK (NULL == connection->response);
1918 MHD_queue_response (connection, MHD_HTTP_BAD_REQUEST, response);
1923 connection->remaining_upload_size = 0;
1924 enc = MHD_lookup_connection_value (connection,
1929 connection->remaining_upload_size = MHD_SIZE_UNKNOWN;
1931 connection->have_chunked_upload = MHD_YES;
1935 clen = MHD_lookup_connection_value (connection,
1945 MHD_DLOG (connection->daemon,
1946 "Failed to parse `%s' header `%s', closing connection.\n",
1950 CONNECTION_CLOSE_ERROR (connection, NULL);
1953 connection->remaining_upload_size = cval;
1960 * Update the 'last_activity' field of the connection to the current time
1961 * and move the connection to the head of the 'normal_timeout' list if
1962 * the timeout for the connection uses the default value.
1964 * @param connection the connection that saw some activity
1967 update_last_activity (struct MHD_Connection *connection)
1969 struct MHD_Daemon *daemon = connection->daemon;
1971 connection->last_activity = MHD_monotonic_time();
1972 if (connection->connection_timeout != daemon->connection_timeout)
1975 /* move connection to head of timeout list (by remove + add operation) */
1981 connection);
1984 connection);
1992 * This function handles a particular connection when it has been
1995 * @param connection connection to handle
1997 * connection)
2000 MHD_connection_handle_read (struct MHD_Connection *connection)
2002 connection);
2003 if (MHD_CONNECTION_CLOSED == connection->state)
2007 if (connection->read_buffer_offset + connection->daemon->pool_increment >
2008 connection->read_buffer_size)
2009 try_grow_read_buffer (connection);
2010 if (MHD_NO == do_read (connection))
2015 MHD_DLOG (connection->daemon, "%s: state: %s\n",
2017 MHD_state_to_string (connection->state));
2019 switch (connection->state)
2031 if (MHD_YES == connection->read_closed)
2033 MHD_connection_close (connection,
2042 MHD_pool_reallocate (connection->pool,
2043 connection->read_buffer,
2044 connection->read_buffer_size + 1,
2045 connection->read_buffer_offset);
2058 * @param connection connection to handle
2060 * connection)
2063 MHD_connection_handle_write (struct MHD_Connection *connection)
2068 update_last_activity (connection);
2072 MHD_DLOG (connection->daemon, "%s: state: %s\n",
2074 MHD_state_to_string (connection->state));
2076 switch (connection->state)
2087 ret = connection->send_cls (connection,
2089 [connection->continue_message_write_offset],
2091 connection->continue_message_write_offset);
2098 MHD_DLOG (connection->daemon,
2102 CONNECTION_CLOSE_ERROR (connection, NULL);
2109 &HTTP_100_CONTINUE[connection->continue_message_write_offset]);
2111 connection->continue_message_write_offset += ret;
2120 do_write (connection);
2121 if (connection->state != MHD_CONNECTION_HEADERS_SENDING)
2123 check_write_done (connection, MHD_CONNECTION_HEADERS_SENT);
2129 response = connection->response;
2132 if (MHD_YES != try_ready_normal_body (connection))
2134 ret = connection->send_cls (connection,
2136 [connection->response_write_position
2139 (connection->response_write_position
2147 &response->data[connection->response_write_position -
2157 MHD_DLOG (connection->daemon,
2161 CONNECTION_CLOSE_ERROR (connection, NULL);
2164 connection->response_write_position += ret;
2165 if (connection->response_write_position ==
2166 connection->response->total_size)
2167 connection->state = MHD_CONNECTION_FOOTERS_SENT; /* have no footers */
2173 do_write (connection);
2174 if (MHD_CONNECTION_CHUNKED_BODY_READY != connection->state)
2176 check_write_done (connection,
2177 (connection->response->total_size ==
2178 connection->response_write_position) ?
2187 do_write (connection);
2188 if (connection->state != MHD_CONNECTION_FOOTERS_SENDING)
2190 check_write_done (connection, MHD_CONNECTION_FOOTERS_SENT);
2202 CONNECTION_CLOSE_ERROR (connection,
2213 * Clean up the state of the given connection and move it into the
2216 * @param connection handle for the connection to clean up
2219 cleanup_connection (struct MHD_Connection *connection)
2221 struct MHD_Daemon *daemon = connection->daemon;
2223 if (NULL != connection->response)
2225 MHD_destroy_response (connection->response);
2226 connection->response = NULL;
2231 if (connection->connection_timeout == daemon->connection_timeout)
2234 connection);
2238 connection);
2239 if (MHD_YES == connection->suspended)
2242 connection);
2246 connection);
2249 connection);
2250 connection->suspended = MHD_NO;
2251 connection->resuming = MHD_NO;
2252 connection->in_idle = MHD_NO;
2260 * This function was created to handle per-connection processing that
2263 * @param connection connection to handle
2265 * connection (not dead yet), #MHD_NO if it died
2268 MHD_connection_handle_idle (struct MHD_Connection *connection)
2270 struct MHD_Daemon *daemon = connection->daemon;
2276 connection->in_idle = MHD_YES;
2283 MHD_state_to_string (connection->state));
2285 switch (connection->state)
2288 line = get_next_header_line (connection);
2291 if (MHD_CONNECTION_INIT != connection->state)
2293 if (MHD_YES == connection->read_closed)
2295 CONNECTION_CLOSE_ERROR (connection,
2301 if (MHD_NO == parse_initial_message_line (connection, line))
2302 CONNECTION_CLOSE_ERROR (connection, NULL);
2304 connection->state = MHD_CONNECTION_URL_RECEIVED;
2307 line = get_next_header_line (connection);
2310 if (MHD_CONNECTION_URL_RECEIVED != connection->state)
2312 if (MHD_YES == connection->read_closed)
2314 CONNECTION_CLOSE_ERROR (connection,
2322 connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
2325 if (MHD_NO == process_header_line (connection, line))
2327 transmit_error_response (connection,
2332 connection->state = MHD_CONNECTION_HEADER_PART_RECEIVED;
2335 line = get_next_header_line (connection);
2338 if (connection->state != MHD_CONNECTION_HEADER_PART_RECEIVED)
2340 if (MHD_YES == connection->read_closed)
2342 CONNECTION_CLOSE_ERROR (connection,
2349 process_broken_line (connection, line, MHD_HEADER_KIND))
2353 connection->state = MHD_CONNECTION_HEADERS_RECEIVED;
2358 parse_connection_headers (connection);
2359 if (MHD_CONNECTION_CLOSED == connection->state)
2361 connection->state = MHD_CONNECTION_HEADERS_PROCESSED;
2364 call_connection_handler (connection); /* first call */
2365 if (MHD_CONNECTION_CLOSED == connection->state)
2367 if (need_100_continue (connection))
2369 connection->state = MHD_CONNECTION_CONTINUE_SENDING;
2372 if ( (NULL != connection->response) &&
2373 ( (MHD_str_equal_caseless_ (connection->method,
2375 (MHD_str_equal_caseless_ (connection->method,
2379 connection->remaining_upload_size = 0;
2381 connection->read_closed = MHD_YES;
2383 connection->state = (0 == connection->remaining_upload_size)
2387 if (connection->continue_message_write_offset ==
2390 connection->state = MHD_CONNECTION_CONTINUE_SENT;
2395 if (0 != connection->read_buffer_offset)
2397 process_request_body (connection); /* loop call */
2398 if (MHD_CONNECTION_CLOSED == connection->state)
2401 if ((0 == connection->remaining_upload_size) ||
2402 ((connection->remaining_upload_size == MHD_SIZE_UNKNOWN) &&
2403 (0 == connection->read_buffer_offset) &&
2404 (MHD_YES == connection->read_closed)))
2406 if ((MHD_YES == connection->have_chunked_upload) &&
2407 (MHD_NO == connection->read_closed))
2408 connection->state = MHD_CONNECTION_BODY_RECEIVED;
2410 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2415 line = get_next_header_line (connection);
2418 if (connection->state != MHD_CONNECTION_BODY_RECEIVED)
2420 if (MHD_YES == connection->read_closed)
2422 CONNECTION_CLOSE_ERROR (connection,
2430 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2433 if (MHD_NO == process_header_line (connection, line))
2435 transmit_error_response (connection,
2440 connection->state = MHD_CONNECTION_FOOTER_PART_RECEIVED;
2443 line = get_next_header_line (connection);
2446 if (connection->state != MHD_CONNECTION_FOOTER_PART_RECEIVED)
2448 if (MHD_YES == connection->read_closed)
2450 CONNECTION_CLOSE_ERROR (connection,
2457 process_broken_line (connection, line, MHD_FOOTER_KIND))
2461 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2466 call_connection_handler (connection); /* "final" call */
2467 if (connection->state == MHD_CONNECTION_CLOSED)
2469 if (NULL == connection
2471 if (MHD_NO == build_header_response (connection))
2474 CONNECTION_CLOSE_ERROR (connection,
2475 "Closing connection (failed to create response header)\n");
2478 connection->state = MHD_CONNECTION_HEADERS_SENDING;
2484 setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2493 if (connection->have_chunked_upload)
2494 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
2496 connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
2502 if (NULL != connection->response->crc)
2503 (void) MHD_mutex_lock_ (&connection->response->mutex);
2504 if (0 == connection->response->total_size)
2506 if (NULL != connection->response->crc)
2507 (void) MHD_mutex_unlock_ (&connection->response->mutex);
2508 connection->state = MHD_CONNECTION_BODY_SENT;
2511 if (MHD_YES == try_ready_normal_body (connection))
2513 if (NULL != connection->response->crc)
2514 (void) MHD_mutex_unlock_ (&connection->response->mutex);
2515 connection->state = MHD_CONNECTION_NORMAL_BODY_READY;
2524 if (NULL != connection->response->crc)
2525 (void) MHD_mutex_lock_ (&connection->response->mutex);
2526 if (0 == connection->response->total_size)
2528 if (NULL != connection->response->crc)
2529 (void) MHD_mutex_unlock_ (&connection->response->mutex);
2530 connection->state = MHD_CONNECTION_BODY_SENT;
2533 if (MHD_YES == try_ready_chunked_body (connection))
2535 if (NULL != connection->response->crc)
2536 (void) MHD_mutex_unlock_ (&connection->response->mutex);
2537 connection->state = MHD_CONNECTION_CHUNKED_BODY_READY;
2540 if (NULL != connection->response->crc)
2541 (void) MHD_mutex_unlock_ (&connection->response->mutex);
2544 if (MHD_NO == build_header_response (connection))
2547 CONNECTION_CLOSE_ERROR (connection,
2548 "Closing connection (failed to create response header)\n");
2551 if ( (MHD_NO == connection->have_chunked_upload) ||
2552 (connection->write_buffer_send_offset ==
2553 connection->write_buffer_append_offset) )
2554 connection->state = MHD_CONNECTION_FOOTERS_SENT;
2556 connection->state = MHD_CONNECTION_FOOTERS_SENDING;
2566 setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val,
2571 MHD_get_response_header (connection->response,
2574 MHD_destroy_response (connection->response);
2575 connection->response = NULL;
2577 (MHD_YES == connection->client_aware) )
2580 connection,
2581 &connection->client_context,
2583 connection->client_aware = MHD_NO;
2586 MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
2588 if ( (MHD_YES == connection->read_closed) ||
2592 connection->read_closed = MHD_YES;
2593 connection->read_buffer_offset = 0;
2595 if (((MHD_YES == connection->read_closed) &&
2596 (0 == connection->read_buffer_offset)) ||
2597 (MHD_NO == keepalive_possible (connection)))
2600 MHD_connection_close (connection,
2602 MHD_pool_destroy (connection->pool);
2603 connection->pool = NULL;
2604 connection->read_buffer = NULL;
2605 connection->read_buffer_size = 0;
2606 connection->read_buffer_offset = 0;
2611 connection->version = NULL;
2612 connection->state = MHD_CONNECTION_INIT;
2613 connection->read_buffer
2614 = MHD_pool_reset (connection->pool,
2615 connection->read_buffer,
2616 connection->read_buffer_size);
2618 connection->client_aware = MHD_NO;
2619 connection->client_context = NULL;
2620 connection->continue_message_write_offset = 0;
2621 connection->responseCode = 0;
2622 connection->headers_received = NULL;
2623 connection->headers_received_tail = NULL;
2624 connection->response_write_position = 0;
2625 connection->have_chunked_upload = MHD_NO;
2626 connection->method = NULL;
2627 connection->url = NULL;
2628 connection->write_buffer = NULL;
2629 connection->write_buffer_size = 0;
2630 connection->write_buffer_send_offset = 0;
2631 connection->write_buffer_append_offset = 0;
2634 cleanup_connection (connection);
2642 timeout = connection->connection_timeout;
2644 (timeout <= (MHD_monotonic_time() - connection->last_activity)) )
2646 MHD_connection_close (connection, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
2647 connection->in_idle = MHD_NO;
2650 MHD_connection_update_event_loop_info (connection);
2652 switch (connection->event_loop_info)
2655 if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
2656 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2657 (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
2661 connection);
2662 connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2666 if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
2667 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2668 (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
2672 connection);
2673 connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2677 /* we should look at this connection again in the next iteration
2679 if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) &&
2680 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) )
2684 connection);
2685 connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2689 /* This connection is finished, nothing left to do */
2692 return MHD_connection_epoll_update_ (connection);
2701 * Perform epoll() processing, possibly moving the connection back into
2704 * @param connection connection to process
2706 * connection (not dead yet), #MHD_NO if it died
2709 MHD_connection_epoll_update_ (struct MHD_Connection *connection)
2711 struct MHD_Daemon *daemon = connection->daemon;
2714 (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) &&
2715 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
2716 ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ||
2717 ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
2718 ( (MHD_EVENT_LOOP_INFO_READ == connection->event_loop_info) ||
2719 (connection->read_buffer_size > connection->read_buffer_offset) ) &&
2720 (MHD_NO == connection->read_closed) ) ) )
2726 event.data.ptr = connection;
2729 connection->socket_fd,
2738 connection->state = MHD_CONNECTION_CLOSED;
2739 cleanup_connection (connection);
2742 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2744 connection->in_idle = MHD_NO;
2751 * Set callbacks for this connection to those for HTTP.
2753 * @param connection connection to initialize
2756 MHD_set_http_callbacks_ (struct MHD_Connection *connection)
2758 connection->read_handler = &MHD_connection_handle_read;
2759 connection->write_handler = &MHD_connection_handle_write;
2760 connection->idle_handler = &MHD_connection_handle_idle;
2765 * Obtain information about the given connection.
2767 * @param connection what connection to get information about
2775 MHD_get_connection_info (struct MHD_Connection *connection,
2782 if (connection->tls_session == NULL)
2784 connection->cipher = SSL_CIPHER_get_name (SSL_get_current_cipher (connection->tls_session));
2785 return (const union MHD_ConnectionInfo *) &connection->cipher;
2787 if (connection->tls_session == NULL)
2789 connection->protocol = SSL_CIPHER_get_version (SSL_get_current_cipher (connection->tls_session));
2790 return (const union MHD_ConnectionInfo *) &connection->protocol;
2792 if (connection->tls_session == NULL)
2794 return (const union MHD_ConnectionInfo *) &connection->tls_session;
2797 return (const union MHD_ConnectionInfo *) &connection->addr;
2799 return (const union MHD_ConnectionInfo *) &connection->daemon;
2801 return (const union MHD_ConnectionInfo *) &connection->socket_fd;
2803 return (const union MHD_ConnectionInfo *) &connection->socket_context;
2811 * Set a custom option for the given connection, overriding defaults.
2813 * @param connection connection to modify
2820 MHD_set_connection_option (struct MHD_Connection *connection,
2827 daemon = connection->daemon;
2834 if (MHD_YES != connection->suspended)
2836 if (connection->connection_timeout == daemon->connection_timeout)
2839 connection);
2843 connection);
2846 connection->connection_timeout = va_arg (ap, unsigned int);
2848 if (MHD_YES != connection->suspended)
2850 if (connection->connection_timeout == daemon->connection_timeout)
2853 connection);
2857 connection);
2873 * @param connection the connection identifying the client
2881 MHD_queue_response (struct MHD_Connection *connection,
2885 if ( (NULL == connection) ||
2887 (NULL != connection->response) ||
2888 ( (MHD_CONNECTION_HEADERS_PROCESSED != connection->state) &&
2889 (MHD_CONNECTION_FOOTERS_RECEIVED != connection->state) ) )
2892 connection->response = response;
2893 connection->responseCode = status_code;
2894 if ( (NULL != connection->method) &&
2895 (MHD_str_equal_caseless_ (connection->method, MHD_HTTP_METHOD_HEAD)) )
2899 connection->response_write_position = response->total_size;
2901 if ( (MHD_CONNECTION_HEADERS_PROCESSED == connection->state) &&
2902 (NULL != connection->method) &&
2903 ( (MHD_str_equal_caseless_ (connection->method,
2905 (MHD_str_equal_caseless_ (connection->method,
2910 connection->read_closed = MHD_YES;
2911 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
2913 if (MHD_NO == connection->in_idle)
2914 connection);
2919 /* end of connection.c */