diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-05-22 18:31:17 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2021-05-26 21:21:15 +0300 |
commit | 547db4308735f8a4895e43182b42daf46182688c (patch) | |
tree | f76cee914b70f02b9e7f68edfed2d779a073c323 | |
parent | 5e029304d46635979d21ed6dc6ccfbeeee5a3e6f (diff) | |
download | libmicrohttpd-547db4308735f8a4895e43182b42daf46182688c.tar.gz libmicrohttpd-547db4308735f8a4895e43182b42daf46182688c.zip |
HTTP version string processing fixes
Fixed wrongly used case-insensitive match for HTTP version string,
HTTP version should be checked as case-sensitive.
Hypothetical HTTP/1.2 - HTTP/1.9 must be used as HTTP/1.1 (required
by HTTP/1.1 specification)
-rw-r--r-- | src/microhttpd/connection.c | 57 |
1 files changed, 26 insertions, 31 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index 8876f692..5e15b708 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -652,18 +652,16 @@ need_100_continue (struct MHD_Connection *connection) | |||
652 | { | 652 | { |
653 | const char *expect; | 653 | const char *expect; |
654 | 654 | ||
655 | return ( (NULL != connection->version) && | 655 | return (MHD_IS_HTTP_VER_1_1_COMPAT (connection->http_ver) && |
656 | (MHD_str_equal_caseless_ (connection->version, | 656 | (MHD_NO != MHD_lookup_connection_value_n (connection, |
657 | MHD_HTTP_VERSION_1_1)) && | 657 | MHD_HEADER_KIND, |
658 | (MHD_NO != MHD_lookup_connection_value_n (connection, | 658 | MHD_HTTP_HEADER_EXPECT, |
659 | MHD_HEADER_KIND, | 659 | MHD_STATICSTR_LEN_ ( |
660 | MHD_HTTP_HEADER_EXPECT, | 660 | MHD_HTTP_HEADER_EXPECT), |
661 | MHD_STATICSTR_LEN_ ( | 661 | &expect, |
662 | MHD_HTTP_HEADER_EXPECT), | 662 | NULL)) && |
663 | &expect, | 663 | (MHD_str_equal_caseless_ (expect, |
664 | NULL)) && | 664 | "100-continue")) ); |
665 | (MHD_str_equal_caseless_ (expect, | ||
666 | "100-continue")) ); | ||
667 | } | 665 | } |
668 | 666 | ||
669 | 667 | ||
@@ -1092,14 +1090,11 @@ keepalive_possible (struct MHD_Connection *connection) | |||
1092 | { | 1090 | { |
1093 | if (MHD_CONN_MUST_CLOSE == connection->keepalive) | 1091 | if (MHD_CONN_MUST_CLOSE == connection->keepalive) |
1094 | return MHD_NO; | 1092 | return MHD_NO; |
1095 | if (NULL == connection->version) | ||
1096 | return MHD_NO; | ||
1097 | if ( (NULL != connection->response) && | 1093 | if ( (NULL != connection->response) && |
1098 | (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) ) | 1094 | (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) ) |
1099 | return MHD_NO; | 1095 | return MHD_NO; |
1100 | 1096 | ||
1101 | if (MHD_str_equal_caseless_ (connection->version, | 1097 | if (MHD_IS_HTTP_VER_1_1_COMPAT (connection->http_ver) && |
1102 | MHD_HTTP_VERSION_1_1) && | ||
1103 | ( (NULL == connection->response) || | 1098 | ( (NULL == connection->response) || |
1104 | (0 == (connection->response->flags | 1099 | (0 == (connection->response->flags |
1105 | & MHD_RF_HTTP_VERSION_1_0_RESPONSE) ) ) ) | 1100 | & MHD_RF_HTTP_VERSION_1_0_RESPONSE) ) ) ) |
@@ -1116,8 +1111,7 @@ keepalive_possible (struct MHD_Connection *connection) | |||
1116 | 1111 | ||
1117 | return MHD_YES; | 1112 | return MHD_YES; |
1118 | } | 1113 | } |
1119 | if (MHD_str_equal_caseless_ (connection->version, | 1114 | if (MHD_HTTP_VER_1_0 == connection->http_ver) |
1120 | MHD_HTTP_VERSION_1_0)) | ||
1121 | { | 1115 | { |
1122 | if (MHD_lookup_header_s_token_ci (connection, | 1116 | if (MHD_lookup_header_s_token_ci (connection, |
1123 | MHD_HTTP_HEADER_CONNECTION, | 1117 | MHD_HTTP_HEADER_CONNECTION, |
@@ -1292,9 +1286,10 @@ build_header_response (struct MHD_Connection *connection) | |||
1292 | bool must_add_content_length; | 1286 | bool must_add_content_length; |
1293 | bool may_add_content_length; | 1287 | bool may_add_content_length; |
1294 | 1288 | ||
1295 | mhd_assert (NULL != connection->version); | 1289 | mhd_assert (MHD_HTTP_VER_UNKNOWN != connection->http_ver); |
1296 | if (0 == connection->version[0]) | 1290 | if (MHD_HTTP_VER_INVALID == connection->http_ver) |
1297 | { | 1291 | { |
1292 | /* TODO: allow error replies */ | ||
1298 | data = MHD_pool_allocate (connection->pool, | 1293 | data = MHD_pool_allocate (connection->pool, |
1299 | 0, | 1294 | 0, |
1300 | true); | 1295 | true); |
@@ -1308,13 +1303,13 @@ build_header_response (struct MHD_Connection *connection) | |||
1308 | if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state) | 1303 | if (MHD_CONNECTION_FOOTERS_RECEIVED == connection->state) |
1309 | { | 1304 | { |
1310 | reason_phrase = MHD_get_reason_phrase_for (rc); | 1305 | reason_phrase = MHD_get_reason_phrase_for (rc); |
1306 | /* TODO: reply as HTTP/1.1 for HTTP/1.0 requests */ | ||
1311 | off = MHD_snprintf_ (code, | 1307 | off = MHD_snprintf_ (code, |
1312 | sizeof (code), | 1308 | sizeof (code), |
1313 | "%s %u %s\r\n", | 1309 | "%s %u %s\r\n", |
1314 | (0 != (connection->responseCode & MHD_ICY_FLAG)) | 1310 | (0 != (connection->responseCode & MHD_ICY_FLAG)) |
1315 | ? "ICY" | 1311 | ? "ICY" |
1316 | : ( (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_0, | 1312 | : ( (MHD_HTTP_VER_1_0 == connection->http_ver || |
1317 | connection->version) || | ||
1318 | (0 != (connection->response->flags | 1313 | (0 != (connection->response->flags |
1319 | & MHD_RF_HTTP_VERSION_1_0_RESPONSE)) ) | 1314 | & MHD_RF_HTTP_VERSION_1_0_RESPONSE)) ) |
1320 | ? MHD_HTTP_VERSION_1_0 | 1315 | ? MHD_HTTP_VERSION_1_0 |
@@ -1394,8 +1389,7 @@ build_header_response (struct MHD_Connection *connection) | |||
1394 | /* 'close' header doesn't exist yet, see if we need to add one; | 1389 | /* 'close' header doesn't exist yet, see if we need to add one; |
1395 | if the client asked for a close, no need to start chunk'ing */ | 1390 | if the client asked for a close, no need to start chunk'ing */ |
1396 | if ( (MHD_NO != keepalive_possible (connection)) && | 1391 | if ( (MHD_NO != keepalive_possible (connection)) && |
1397 | (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1, | 1392 | (MHD_IS_HTTP_VER_1_1_COMPAT (connection->http_ver)) ) |
1398 | connection->version) ) ) | ||
1399 | { | 1393 | { |
1400 | if (NULL == have_encoding) | 1394 | if (NULL == have_encoding) |
1401 | { | 1395 | { |
@@ -1649,11 +1643,14 @@ transmit_error_response (struct MHD_Connection *connection, | |||
1649 | struct MHD_Response *response; | 1643 | struct MHD_Response *response; |
1650 | enum MHD_Result iret; | 1644 | enum MHD_Result iret; |
1651 | 1645 | ||
1652 | if (NULL == connection->version) | 1646 | if (! MHD_IS_HTTP_VER_SUPPORTED (connection->http_ver)) |
1653 | { | 1647 | { |
1654 | /* we were unable to process the full header line, so we don't | 1648 | /* The header has not been processed yet or request HTTP version is |
1655 | really know what version the client speaks; assume 1.0 */ | 1649 | * not supported. |
1656 | connection->version = MHD_HTTP_VERSION_1_0; | 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; | ||
1657 | } | 1654 | } |
1658 | connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; | 1655 | connection->state = MHD_CONNECTION_FOOTERS_RECEIVED; |
1659 | connection->read_closed = true; | 1656 | connection->read_closed = true; |
@@ -2767,9 +2764,7 @@ parse_connection_headers (struct MHD_Connection *connection) | |||
2767 | 2764 | ||
2768 | parse_cookie_header (connection); | 2765 | parse_cookie_header (connection); |
2769 | if ( (1 <= connection->daemon->strict_for_client) && | 2766 | if ( (1 <= connection->daemon->strict_for_client) && |
2770 | (NULL != connection->version) && | 2767 | (MHD_IS_HTTP_VER_1_1_COMPAT (connection->http_ver)) && |
2771 | (MHD_str_equal_caseless_ (MHD_HTTP_VERSION_1_1, | ||
2772 | connection->version)) && | ||
2773 | (MHD_NO == | 2768 | (MHD_NO == |
2774 | MHD_lookup_connection_value_n (connection, | 2769 | MHD_lookup_connection_value_n (connection, |
2775 | MHD_HEADER_KIND, | 2770 | MHD_HEADER_KIND, |