libmicrohttpd

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

commit 5d35f4f7f93fcec65aee8d12944ad1105bf9b196
parent 4169e7b6cc46209e0fc3ab4f794d47afffe3b9cb
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Fri, 20 Aug 2021 15:42:34 +0300

replies: fixed HTTP/1.0 keep-alive replies

Always send "Connection:" headers when replying with keep-alive HTTP/1.0

Diffstat:
Msrc/include/microhttpd.h | 4+++-
Msrc/microhttpd/connection.c | 49++++++++++++++++++++++++++++++++++++-------------
2 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -1,7 +1,7 @@ /* This file is part of libmicrohttpd Copyright (C) 2006-2021 Christian Grothoff (and other contributing authors) - Copyright (C) 2015-2021 Evgeny Grin (Karlson2k) + Copyright (C) 2014-2021 Evgeny Grin (Karlson2k) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -3138,6 +3138,8 @@ enum MHD_ResponseFlags * Contrary to the #MHD_RF_HTTP_1_0_COMPATIBLE_STRICT flag, the response's * HTTP version will always be set to 1.0 and keep-alive connections * will be used if explicitly requested by the client. + * The "Connection:" header will be added for both "close" and "keep-alive" + * connections. * Chunked encoding will not be used for the response. * Due to backward compatibility, responses still can be used with * HTTP/1.1 clients. diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -1830,6 +1830,8 @@ build_header_response (struct MHD_Connection *connection) size_t buf_size; /**< the size of the @a buf */ size_t el_size; /**< the size of current element to be added to the @a buf */ unsigned rcode; /**< the response code */ + bool use_conn_close; /**< Use "Connection: close" header */ + bool use_conn_k_alive; /**< Use "Connection: Keep-Alive" header */ mhd_assert (NULL != r); @@ -1856,6 +1858,32 @@ build_header_response (struct MHD_Connection *connection) #endif /* UPGRADE_SUPPORT */ rcode = (unsigned) (c->responseCode & (~MHD_ICY_FLAG)); + if (MHD_CONN_MUST_CLOSE == c->keepalive) + { + /* The closure of connection must be always indicated by header + * to avoid hung connections */ + use_conn_close = true; + use_conn_k_alive = false; + } + else if (MHD_CONN_USE_KEEPALIVE == c->keepalive) + { + use_conn_close = false; + /* As "Keep-Alive" is default for HTTP/1.1, add "Connection: keep-alive" + * header only if explicitly requested by app (by using reponse flag), + * if request is HTTP/1.0 or if reply is HTTP/1.0. */ + if ((0 != (r->flags & MHD_RF_SEND_KEEP_ALIVE_HEADER)) || + (MHD_HTTP_VER_1_0 == c->http_ver) || + (0 != (r->flags & MHD_RF_HTTP_1_0_SERVER))) + use_conn_k_alive = true; + else + use_conn_k_alive = false; + } + else + { + use_conn_close = false; + use_conn_k_alive = false; + } + /* ** Actually build the response header ** */ @@ -1930,23 +1958,20 @@ build_header_response (struct MHD_Connection *connection) pos += 37; } /* The "Connection:" header */ + mhd_assert (! use_conn_close || ! use_conn_k_alive); if (0 == (r->flags_auto & MHD_RAF_HAS_CONNECTION_HDR)) { - if (MHD_CONN_MUST_CLOSE == c->keepalive) + if (use_conn_close) { if (! buffer_append_s (buf, &pos, buf_size, MHD_HTTP_HEADER_CONNECTION ": close\r\n")) return MHD_NO; } - else if (MHD_CONN_USE_KEEPALIVE == c->keepalive) + else if (use_conn_k_alive) { - if ((MHD_HTTP_VER_1_0 == c->http_ver) || - (0 != (r->flags & MHD_RF_SEND_KEEP_ALIVE_HEADER))) - { - if (! buffer_append_s (buf, &pos, buf_size, - MHD_HTTP_HEADER_CONNECTION ": Keep-Alive\r\n")) - return MHD_NO; - } + if (! buffer_append_s (buf, &pos, buf_size, + MHD_HTTP_HEADER_CONNECTION ": Keep-Alive\r\n")) + return MHD_NO; } } @@ -1954,10 +1979,8 @@ build_header_response (struct MHD_Connection *connection) if (! add_user_headers (buf, &pos, buf_size, r, MHD_HEADER_KIND, ! c->rp_props.chunked, - (MHD_CONN_MUST_CLOSE == c->keepalive), - ((MHD_HTTP_VER_1_0 == c->http_ver) || - (0 != (r->flags & MHD_RF_SEND_KEEP_ALIVE_HEADER))) && - (MHD_CONN_USE_KEEPALIVE == c->keepalive))) + use_conn_close, + use_conn_k_alive)) return MHD_NO; /* Other automatic headers */