aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-05-22 18:31:17 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2021-05-26 21:21:15 +0300
commit547db4308735f8a4895e43182b42daf46182688c (patch)
treef76cee914b70f02b9e7f68edfed2d779a073c323
parent5e029304d46635979d21ed6dc6ccfbeeee5a3e6f (diff)
downloadlibmicrohttpd-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.c57
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,