libmicrohttpd

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

commit a96eaaaa25421eb0a2ce7b907168c74458b0ea5e
parent f5fc702a4d2ddf67eb1eb7dd29a0924a2aab2096
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Thu, 19 Aug 2021 16:40:11 +0300

Response flags: clarified functionality, added synonymous names

Fixed support for explicitly requested Keep-Alive with
responses with MHD_RF_HTTP_VERSION_1_0_RESPONSE flag

Diffstat:
Msrc/include/microhttpd.h | 46+++++++++++++++++++++++++++++++++-------------
Msrc/microhttpd/connection.c | 27++++++++++++++-------------
2 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -131,7 +131,7 @@ typedef intptr_t ssize_t; * they are parsed as decimal numbers. * Example: 0x01093001 = 1.9.30-1. */ -#define MHD_VERSION 0x00097307 +#define MHD_VERSION 0x00097308 #ifdef __has_attribute @@ -3110,34 +3110,54 @@ enum MHD_ResponseFlags { /** * Default: no special flags. + * @note Available since #MHD_VERSION 0x00093701 */ MHD_RF_NONE = 0, /** - * Only respond in conservative HTTP 1.0-mode. In particular, - * do not (automatically) sent "Connection" headers and always - * close the connection after generating the response. - * By default, MHD will respond using the same HTTP version which - * was set in the request. You can also set the - * #MHD_RF_HTTP_VERSION_1_0_RESPONSE flag to force version 1.0 - * in the response. + * Only respond in conservative (dumb) HTTP/1.0-compatible mode. + * Response still use HTTP/1.1 version in header, but always close + * the connection after generating the response and do not use chunked + * encoding for the response. + * You can also set the #MHD_RF_HTTP_1_0_SERVER flag to force + * HTTP/1.0 version in the response. + * Responses are still compatible with HTTP/1.1. + * This option can be used to communicate with some broken client, which + * does not implement HTTP/1.1 features, but advertises HTTP/1.1 support. + * @note Available since #MHD_VERSION 0x00097308 + */ + MHD_RF_HTTP_1_0_COMPATIBLE_STRICT = 1, + /** + * The same as #MHD_RF_HTTP_1_0_COMPATIBLE_STRICT + * @note Available since #MHD_VERSION 0x00093701 */ MHD_RF_HTTP_VERSION_1_0_ONLY = 1, /** - * Only respond in HTTP 1.0-mode. Contrary to the - * #MHD_RF_HTTP_VERSION_1_0_ONLY flag, the response's HTTP version will - * always be set to 1.0 and "Connection" headers are still supported. + * Only respond in HTTP 1.0-mode. + * 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. + * Chunked encoding will not be used for the response. + * Due to backward compatibility, responses still can be used with + * HTTP/1.1 clients. + * This option can be used to emulate HTTP/1.0 server (for response only + * as chunked encoding in requests will be supported still). + * @note Available since #MHD_VERSION 0x00097308 + */ + MHD_RF_HTTP_1_0_SERVER = 2, + /** + * The same as #MHD_RF_HTTP_1_0_SERVER + * @note Available since #MHD_VERSION 0x00096000 */ MHD_RF_HTTP_VERSION_1_0_RESPONSE = 2, /** * Disable sanity check preventing clients from manually * setting the HTTP content length option. + * @note Available since #MHD_VERSION 0x00096702 */ MHD_RF_INSANITY_HEADER_CONTENT_LENGTH = 4 - - } _MHD_FIXED_FLAGS_ENUM; diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -1187,7 +1187,7 @@ keepalive_possible (struct MHD_Connection *connection) if (c->read_closed) return MHD_CONN_MUST_CLOSE; - if (0 != (r->flags & MHD_RF_HTTP_VERSION_1_0_ONLY)) + if (0 != (r->flags & MHD_RF_HTTP_1_0_COMPATIBLE_STRICT)) return MHD_CONN_MUST_CLOSE; if (0 != (r->flags_auto & MHD_RAF_HAS_CONNECTION_CLOSE)) return MHD_CONN_MUST_CLOSE; @@ -1200,11 +1200,8 @@ keepalive_possible (struct MHD_Connection *connection) "close")) return MHD_CONN_MUST_CLOSE; - if (MHD_IS_HTTP_VER_1_1_COMPAT (c->http_ver) && - (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_RESPONSE)) ) - return MHD_CONN_USE_KEEPALIVE; - - if (MHD_HTTP_VER_1_0 == connection->http_ver) + if ((MHD_HTTP_VER_1_0 == connection->http_ver) || + (0 != (connection->response->flags & MHD_RF_HTTP_1_0_SERVER))) { if (MHD_lookup_header_s_token_ci (connection, MHD_HTTP_HEADER_CONNECTION, @@ -1213,6 +1210,10 @@ keepalive_possible (struct MHD_Connection *connection) return MHD_CONN_MUST_CLOSE; } + + if (MHD_IS_HTTP_VER_1_1_COMPAT (c->http_ver)) + return MHD_CONN_USE_KEEPALIVE; + return MHD_CONN_MUST_CLOSE; } @@ -1631,8 +1632,8 @@ setup_reply_properties (struct MHD_Connection *connection) if (! MHD_IS_HTTP_VER_1_1_COMPAT (c->http_ver)) use_chunked = false; /* Check whether chunked encoding is allowed for the reply */ - else if (0 != (r->flags & (MHD_RF_HTTP_VERSION_1_0_ONLY - | MHD_RF_HTTP_VERSION_1_0_RESPONSE))) + else if (0 != (r->flags & (MHD_RF_HTTP_1_0_COMPATIBLE_STRICT + | MHD_RF_HTTP_1_0_SERVER))) use_chunked = false; else /* If chunked encoding is supported and allowed, and response size @@ -1869,16 +1870,16 @@ build_header_response (struct MHD_Connection *connection) /* The HTTP version */ if (0 == (c->responseCode & MHD_ICY_FLAG)) { /* HTTP reply */ - if (0 != (r->flags & MHD_RF_HTTP_VERSION_1_0_RESPONSE)) + if (0 == (r->flags & MHD_RF_HTTP_1_0_SERVER)) { /* HTTP/1.1 reply */ /* Use HTTP/1.1 responses for HTTP/1.0 clients. * See https://datatracker.ietf.org/doc/html/rfc7230#section-2.6 */ - if (! buffer_append_s (buf, &pos, buf_size, MHD_HTTP_VERSION_1_0)) + if (! buffer_append_s (buf, &pos, buf_size, MHD_HTTP_VERSION_1_1)) return MHD_NO; } else { /* HTTP/1.0 reply */ - if (! buffer_append_s (buf, &pos, buf_size, MHD_HTTP_VERSION_1_1)) + if (! buffer_append_s (buf, &pos, buf_size, MHD_HTTP_VERSION_1_0)) return MHD_NO; } } @@ -4801,8 +4802,8 @@ MHD_queue_response (struct MHD_Connection *connection, #endif return MHD_NO; } - if (0 != (response->flags & (MHD_RF_HTTP_VERSION_1_0_ONLY - | MHD_RF_HTTP_VERSION_1_0_RESPONSE))) + if (0 != (response->flags & (MHD_RF_HTTP_1_0_COMPATIBLE_STRICT + | MHD_RF_HTTP_1_0_SERVER))) { #ifdef HAVE_MESSAGES MHD_DLOG (daemon,