aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-05-26 20:49:55 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-05-26 21:21:15 +0300
commit0c28412a3a863f4c416838032426e622f657e9c1 (patch)
treee998b7eb0ff683db619cfaa16678a4a6fa30bd68
parent547db4308735f8a4895e43182b42daf46182688c (diff)
downloadlibmicrohttpd-0c28412a3a863f4c416838032426e622f657e9c1.tar.gz
libmicrohttpd-0c28412a3a863f4c416838032426e622f657e9c1.zip
Refactored handling of incompatible HTTP versions
Removed some workarounds
-rw-r--r--src/microhttpd/connection.c77
1 files changed, 53 insertions, 24 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 5e15b708..b304ca25 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -847,6 +847,40 @@ connection_close_error (struct MHD_Connection *connection,
847 847
848 848
849/** 849/**
850 * A serious error occurred, check whether error response is already
851 * queued and close the connection if response wasn't queued.
852 *
853 * @param connection connection to close with error
854 * @param emsg error message (can be NULL)
855 */
856static void
857connection_close_error_check (struct MHD_Connection *connection,
858 const char *emsg)
859{
860 if ( (NULL != connection->response) &&
861 (400 <= connection->responseCode) &&
862 (connection->read_closed) &&
863 (MHD_CONNECTION_HEADERS_SENDING == connection->state) )
864 return; /* An error response was already queued */
865
866 connection_close_error (connection, emsg);
867}
868
869
870/**
871 * Macro to only include error message in call to
872 * #connection_close_error_check() if we have HAVE_MESSAGES.
873 */
874#ifdef HAVE_MESSAGES
875#define CONNECTION_CLOSE_ERROR_CHECK(c, emsg) \
876 connection_close_error_check (c, emsg)
877#else
878#define CONNECTION_CLOSE_ERROR_CHECK(c, emsg) \
879 connection_close_error_check (c, NULL)
880#endif
881
882
883/**
850 * Prepare the response buffer of this connection for 884 * Prepare the response buffer of this connection for
851 * sending. Assumes that the response mutex is 885 * sending. Assumes that the response mutex is
852 * already held. If the transmission is complete, 886 * already held. If the transmission is complete,
@@ -1286,19 +1320,20 @@ build_header_response (struct MHD_Connection *connection)
1286 bool must_add_content_length; 1320 bool must_add_content_length;
1287 bool may_add_content_length; 1321 bool may_add_content_length;
1288 1322
1289 mhd_assert (MHD_HTTP_VER_UNKNOWN != connection->http_ver); 1323 /* HTTP version must be supported.
1290 if (MHD_HTTP_VER_INVALID == connection->http_ver) 1324 * Allow limited set of error replies for unsupported HTTP versions. */
1291 { 1325 mhd_assert (MHD_IS_HTTP_VER_SUPPORTED (connection->http_ver) || \
1292 /* TODO: allow error replies */ 1326 (MHD_HTTP_BAD_REQUEST == connection->responseCode) || \
1293 data = MHD_pool_allocate (connection->pool, 1327 (MHD_HTTP_REQUEST_TIMEOUT == connection->responseCode) || \
1294 0, 1328 (MHD_HTTP_URI_TOO_LONG == connection->responseCode) || \
1295 true); 1329 (MHD_HTTP_TOO_MANY_REQUESTS == connection->responseCode) || \
1296 connection->write_buffer = data; 1330 (MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE == \
1297 connection->write_buffer_append_offset = 0; 1331 connection->responseCode) || \
1298 connection->write_buffer_send_offset = 0; 1332 (MHD_HTTP_NOT_IMPLEMENTED == connection->responseCode) || \
1299 connection->write_buffer_size = 0; 1333 (MHD_HTTP_SERVICE_UNAVAILABLE == connection->responseCode) || \
1300 return MHD_YES; 1334 (MHD_HTTP_HTTP_VERSION_NOT_SUPPORTED == \
1301 } 1335 connection->responseCode) );
1336
1302 rc = connection->responseCode & (~MHD_ICY_FLAG); 1337 rc = connection->responseCode & (~MHD_ICY_FLAG);
1303 if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state) 1338 if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state)
1304 { 1339 {
@@ -1643,15 +1678,6 @@ transmit_error_response (struct MHD_Connection *connection,
1643 struct MHD_Response *response; 1678 struct MHD_Response *response;
1644 enum MHD_Result iret; 1679 enum MHD_Result iret;
1645 1680
1646 if (! MHD_IS_HTTP_VER_SUPPORTED (connection->http_ver))
1647 {
1648 /* The header has not been processed yet or request HTTP version is
1649 * not supported.
1650 * Reply in mode compatible with HTTP/1.0 clients. */
1651 /* TODO: remove substitution here and process incompatible versions
1652 * directly in other functions.*/
1653 connection->http_ver = MHD_HTTP_VER_1_0;
1654 }
1655 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; 1681 connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
1656 connection->read_closed = true; 1682 connection->read_closed = true;
1657 if (0 != connection->read_buffer_size) 1683 if (0 != connection->read_buffer_size)
@@ -3484,10 +3510,13 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3484 if (MHD_NO == parse_initial_message_line (connection, 3510 if (MHD_NO == parse_initial_message_line (connection,
3485 line, 3511 line,
3486 line_len)) 3512 line_len))
3487 CONNECTION_CLOSE_ERROR (connection, 3513 CONNECTION_CLOSE_ERROR_CHECK (connection,
3488 NULL); 3514 NULL);
3489 else 3515 else
3516 {
3517 mhd_assert (MHD_IS_HTTP_VER_SUPPORTED (connection->http_ver));
3490 connection->state = MHD_CONNECTION_URL_RECEIVED; 3518 connection->state = MHD_CONNECTION_URL_RECEIVED;
3519 }
3491 continue; 3520 continue;
3492 case MHD_CONNECTION_URL_RECEIVED: 3521 case MHD_CONNECTION_URL_RECEIVED:
3493 line = get_next_header_line (connection, 3522 line = get_next_header_line (connection,