libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit db2ab3a5aee00d9716523eb9b478b29dcb332f9a
parent 497a3546bc8e597373ee96c3e6d9849f053fa249
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Sun,  1 Aug 2021 13:24:32 +0300

response: do not allow "Connection: keep-alive" header

Diffstat:
Msrc/microhttpd/response.c | 12+++++++++++-
Msrc/microhttpd/test_response_entries.c | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 174 insertions(+), 1 deletion(-)

diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c @@ -251,6 +251,8 @@ add_response_header_connection (struct MHD_Response *response, old_value_len = 0; value_len = strlen (value); + if (value_len >= SSIZE_MAX) + return MHD_NO; /* Additional space for normalisation and zero-termination*/ norm_len = (ssize_t) (value_len + value_len / 2 + 1); buf_size = old_value_len + (size_t) norm_len; @@ -258,7 +260,7 @@ add_response_header_connection (struct MHD_Response *response, buf = malloc (buf_size); if (NULL == buf) return MHD_NO; - /* Move "close" token (if any) to the front */ + /* Remove "close" token (if any), it will be moved to the front */ value_has_close = MHD_str_remove_token_caseless_ (value, value_len, "close", MHD_STATICSTR_LEN_ ( \ "close"), @@ -267,6 +269,14 @@ add_response_header_connection (struct MHD_Response *response, mhd_assert (0 <= norm_len); if (0 > norm_len) norm_len = 0; /* Must never happen */ + if (0 != norm_len) + { + size_t len = norm_len; + MHD_str_remove_tokens_caseless_ (buf + old_value_len, &len, + "keep-alive", + MHD_STATICSTR_LEN_ ("keep-alive")); + norm_len = (ssize_t) len; + } if (0 == norm_len) { /* New value is empty after normalisation */ if (! value_has_close) diff --git a/src/microhttpd/test_response_entries.c b/src/microhttpd/test_response_entries.c @@ -612,6 +612,169 @@ main (int argc, return 3; } + if (MHD_NO != MHD_add_response_header (r, "Connection", "keep-Alive")) + { + fprintf (stderr, + "Successfully added \"Connection\" header with \"keep-Alive\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), NULL)) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_add_response_header (r, "Connection", "keep-Alive, Close")) + { + fprintf (stderr, + "Cannot add \"Connection\" header with \"keep-Alive, Close\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), "close")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_NO != MHD_add_response_header (r, "Connection", "keep-Alive")) + { + fprintf (stderr, + "Successfully added \"Connection\" header with \"keep-Alive\".\n"); + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_add_response_header (r, "Connection", "keep-Alive, Close")) + { + fprintf (stderr, + "Cannot add \"Connection\" header with \"keep-Alive, Close\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), "close")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_add_response_header (r, "Connection", + "close, additional-token")) + { + fprintf (stderr, "Cannot add \"Connection\" header with " + "\"close, additional-token\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), + "close, additional-token")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_NO != MHD_add_response_header (r, "Connection", "keep-Alive")) + { + fprintf (stderr, + "Successfully added \"Connection\" header with \"keep-Alive\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), + "close, additional-token")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_del_response_header (r, "Connection", + "additional-token,close")) + { + fprintf (stderr, "Cannot remove tokens from \"Connection\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), NULL)) + { + MHD_destroy_response (r); + return 4; + } + + if (MHD_YES != MHD_add_response_header (r, "Connection", + "Keep-aLive, token-1")) + { + fprintf (stderr, + "Cannot add \"Connection\" header with \"Keep-aLive, token-1\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), "token-1")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_add_response_header (r, "Connection", + "Keep-aLive, token-2")) + { + fprintf (stderr, + "Cannot add \"Connection\" header with \"Keep-aLive, token-2\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), + "token-1, token-2")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_add_response_header (r, "Connection", + "Keep-aLive, token-3, close")) + { + fprintf (stderr, + "Cannot add \"Connection\" header with \"Keep-aLive, token-3, close\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), + "close, token-1, token-2, token-3")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_del_response_header (r, "Connection", + "close")) + { + fprintf (stderr, "Cannot remove \"close\" tokens from \"Connection\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), + "token-1, token-2, token-3")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_add_response_header (r, "Connection", "Keep-aLive, close")) + { + fprintf (stderr, + "Cannot add \"Connection\" header with \"Keep-aLive, token-3, close\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), + "close, token-1, token-2, token-3")) + { + MHD_destroy_response (r); + return 4; + } + if (MHD_YES != MHD_del_response_header (r, "Connection", + "close, token-1, Keep-Alive, token-2, token-3")) + { + fprintf (stderr, "Cannot remove \"close\" tokens from \"Connection\".\n"); + MHD_destroy_response (r); + return 4; + } + if (! expect_str (MHD_get_response_header (r, "Connection"), NULL)) + { + MHD_destroy_response (r); + return 4; + } + MHD_destroy_response (r); printf ("All tests has been successfully passed.\n"); return 0;