diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-05-26 20:49:55 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-05-26 21:21:15 +0300 |
commit | 0c28412a3a863f4c416838032426e622f657e9c1 (patch) | |
tree | e998b7eb0ff683db619cfaa16678a4a6fa30bd68 | |
parent | 547db4308735f8a4895e43182b42daf46182688c (diff) | |
download | libmicrohttpd-0c28412a3a863f4c416838032426e622f657e9c1.tar.gz libmicrohttpd-0c28412a3a863f4c416838032426e622f657e9c1.zip |
Refactored handling of incompatible HTTP versions
Removed some workarounds
-rw-r--r-- | src/microhttpd/connection.c | 77 |
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 | */ | ||
856 | static void | ||
857 | connection_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, |