diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2017-05-09 21:38:11 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2017-05-09 22:20:43 +0300 |
commit | e0825eab1376a4bd8177172bab9773d2bf3b0d2c (patch) | |
tree | ce1f6d3230070d9f3edeae5be3c4cee1c334e87c | |
parent | 17d1176f26fb679602b990e8194bf21a1c92d005 (diff) | |
download | libmicrohttpd-e0825eab1376a4bd8177172bab9773d2bf3b0d2c.tar.gz libmicrohttpd-e0825eab1376a4bd8177172bab9773d2bf3b0d2c.zip |
Fixed: check all request "Connection" headers for "Close" and "Upgrade" tokens instead of
using only first "Connection" header with full string match.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/microhttpd/connection.c | 64 |
2 files changed, 34 insertions, 35 deletions
@@ -1,3 +1,8 @@ | |||
1 | Tue May 9 21:01:00 MSK 2017 | ||
2 | Fixed: check all "Connection" headers of request for "Close" and "Upgrade" | ||
3 | tokens instead of using only first "Connection" header with full string | ||
4 | match. -EG | ||
5 | |||
1 | Tue May 9 12:28:00 MSK 2017 | 6 | Tue May 9 12:28:00 MSK 2017 |
2 | Revert: continue match footers in MHD_get_response_header() for backward | 7 | Revert: continue match footers in MHD_get_response_header() for backward |
3 | compatibility. -EG | 8 | compatibility. -EG |
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index 6c7d5226..e3bf9e29 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -912,8 +912,6 @@ try_ready_chunked_body (struct MHD_Connection *connection) | |||
912 | static int | 912 | static int |
913 | keepalive_possible (struct MHD_Connection *connection) | 913 | keepalive_possible (struct MHD_Connection *connection) |
914 | { | 914 | { |
915 | const char *end; | ||
916 | |||
917 | if (MHD_CONN_MUST_CLOSE == connection->keepalive) | 915 | if (MHD_CONN_MUST_CLOSE == connection->keepalive) |
918 | return MHD_NO; | 916 | return MHD_NO; |
919 | if (NULL == connection->version) | 917 | if (NULL == connection->version) |
@@ -921,37 +919,37 @@ keepalive_possible (struct MHD_Connection *connection) | |||
921 | if ( (NULL != connection->response) && | 919 | if ( (NULL != connection->response) && |
922 | (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) ) | 920 | (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) ) |
923 | return MHD_NO; | 921 | return MHD_NO; |
924 | end = MHD_lookup_connection_value (connection, | 922 | |
925 | MHD_HEADER_KIND, | ||
926 | MHD_HTTP_HEADER_CONNECTION); | ||
927 | if (MHD_str_equal_caseless_(connection->version, | 923 | if (MHD_str_equal_caseless_(connection->version, |
928 | MHD_HTTP_VERSION_1_1)) | 924 | MHD_HTTP_VERSION_1_1)) |
929 | { | 925 | { |
930 | if (NULL == end) | 926 | if (MHD_lookup_header_s_token_ci (connection, |
931 | return MHD_YES; | 927 | MHD_HTTP_HEADER_CONNECTION, |
932 | if (MHD_str_equal_caseless_ (end, | 928 | "upgrade")) |
933 | "close")) | 929 | { |
934 | return MHD_NO; | ||
935 | #ifdef UPGRADE_SUPPORT | 930 | #ifdef UPGRADE_SUPPORT |
936 | if ( (MHD_str_equal_caseless_ (end, | 931 | if ( (NULL == connection->response) || |
937 | "upgrade")) && | 932 | (NULL == connection->response->upgrade_handler) ) |
938 | ( (NULL == connection->response) || | ||
939 | (NULL == connection->response->upgrade_handler) ) ) | ||
940 | return MHD_NO; | ||
941 | #endif /* UPGRADE_SUPPORT */ | 933 | #endif /* UPGRADE_SUPPORT */ |
934 | return MHD_NO; | ||
935 | } | ||
936 | if (MHD_lookup_header_s_token_ci (connection, | ||
937 | MHD_HTTP_HEADER_CONNECTION, | ||
938 | "close")) | ||
939 | return MHD_NO; | ||
942 | 940 | ||
943 | return MHD_YES; | 941 | return MHD_YES; |
944 | } | 942 | } |
945 | if (MHD_str_equal_caseless_(connection->version, | 943 | if (MHD_str_equal_caseless_(connection->version, |
946 | MHD_HTTP_VERSION_1_0)) | 944 | MHD_HTTP_VERSION_1_0)) |
947 | { | 945 | { |
948 | if (NULL == end) | 946 | if (MHD_lookup_header_s_token_ci (connection, |
947 | MHD_HTTP_HEADER_CONNECTION, | ||
948 | "Keep-Alive")) | ||
949 | return MHD_YES; | ||
950 | |||
949 | return MHD_NO; | 951 | return MHD_NO; |
950 | if (MHD_str_equal_caseless_(end, | 952 | } |
951 | "Keep-Alive")) | ||
952 | return MHD_YES; | ||
953 | return MHD_NO; | ||
954 | } | ||
955 | return MHD_NO; | 953 | return MHD_NO; |
956 | } | 954 | } |
957 | 955 | ||
@@ -1069,7 +1067,7 @@ build_header_response (struct MHD_Connection *connection) | |||
1069 | enum MHD_ValueKind kind; | 1067 | enum MHD_ValueKind kind; |
1070 | const char *reason_phrase; | 1068 | const char *reason_phrase; |
1071 | uint32_t rc; | 1069 | uint32_t rc; |
1072 | const char *client_requested_close; | 1070 | bool client_requested_close; |
1073 | bool response_has_close; | 1071 | bool response_has_close; |
1074 | bool response_has_keepalive; | 1072 | bool response_has_keepalive; |
1075 | const char *have_encoding; | 1073 | const char *have_encoding; |
@@ -1144,13 +1142,9 @@ build_header_response (struct MHD_Connection *connection) | |||
1144 | response_has_keepalive = MHD_check_response_header_s_token_ci (connection->response, | 1142 | response_has_keepalive = MHD_check_response_header_s_token_ci (connection->response, |
1145 | MHD_HTTP_HEADER_CONNECTION, | 1143 | MHD_HTTP_HEADER_CONNECTION, |
1146 | "Keep-Alive"); | 1144 | "Keep-Alive"); |
1147 | client_requested_close = MHD_lookup_connection_value (connection, | 1145 | client_requested_close = MHD_lookup_header_s_token_ci (connection, |
1148 | MHD_HEADER_KIND, | 1146 | MHD_HTTP_HEADER_CONNECTION, |
1149 | MHD_HTTP_HEADER_CONNECTION); | 1147 | "close"); |
1150 | if ( (NULL != client_requested_close) && | ||
1151 | (! MHD_str_equal_caseless_ (client_requested_close, | ||
1152 | "close")) ) | ||
1153 | client_requested_close = NULL; | ||
1154 | 1148 | ||
1155 | if (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY)) | 1149 | if (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY)) |
1156 | connection->keepalive = MHD_CONN_MUST_CLOSE; | 1150 | connection->keepalive = MHD_CONN_MUST_CLOSE; |
@@ -1160,7 +1154,7 @@ build_header_response (struct MHD_Connection *connection) | |||
1160 | 1154 | ||
1161 | if ( (MHD_SIZE_UNKNOWN == connection->response->total_size) && | 1155 | if ( (MHD_SIZE_UNKNOWN == connection->response->total_size) && |
1162 | (! response_has_close) && | 1156 | (! response_has_close) && |
1163 | (NULL == client_requested_close) ) | 1157 | (! client_requested_close) ) |
1164 | { | 1158 | { |
1165 | /* size is unknown, and close was not explicitly requested; | 1159 | /* size is unknown, and close was not explicitly requested; |
1166 | need to either to HTTP 1.1 chunked encoding or | 1160 | need to either to HTTP 1.1 chunked encoding or |
@@ -1199,7 +1193,7 @@ build_header_response (struct MHD_Connection *connection) | |||
1199 | } | 1193 | } |
1200 | 1194 | ||
1201 | /* check for other reasons to add 'close' header */ | 1195 | /* check for other reasons to add 'close' header */ |
1202 | if ( ( (NULL != client_requested_close) || | 1196 | if ( ( (client_requested_close) || |
1203 | (connection->read_closed) || | 1197 | (connection->read_closed) || |
1204 | (MHD_CONN_MUST_CLOSE == connection->keepalive)) && | 1198 | (MHD_CONN_MUST_CLOSE == connection->keepalive)) && |
1205 | (! response_has_close) && | 1199 | (! response_has_close) && |