[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] 03/05: Added new daemon option MHD_OPTION_CLIENT_DISCIPL
From: |
gnunet |
Subject: |
[libmicrohttpd] 03/05: Added new daemon option MHD_OPTION_CLIENT_DISCIPLINE_LV |
Date: |
Thu, 22 Dec 2022 18:18:33 +0100 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit 5c3a61d68c04ebfd62695fa2a90e6212e42a1cae
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Thu Dec 22 16:30:12 2022 +0300
Added new daemon option MHD_OPTION_CLIENT_DISCIPLINE_LV
Reject URIs with spaces as per RFC.
Fixed check for space before colon in headers (previously it was checked
only when MHD was NOT strict).
Reject HTTP/1.1 requests without host by default (as per RFC).
---
src/examples/connection_close.c | 2 +-
src/examples/minimal_example.c | 1 -
src/examples/minimal_example_empty.c | 1 -
src/examples/minimal_example_empty_tls.c | 2 +-
src/include/microhttpd.h | 74 +++++++++++++++++++++++++++-----
src/microhttpd/connection.c | 18 ++++----
src/microhttpd/daemon.c | 32 +++++++++++---
src/microhttpd/internal.h | 5 ++-
8 files changed, 103 insertions(+), 32 deletions(-)
diff --git a/src/examples/connection_close.c b/src/examples/connection_close.c
index 8558eb46..de79d9f1 100644
--- a/src/examples/connection_close.c
+++ b/src/examples/connection_close.c
@@ -118,7 +118,7 @@ main (int argc, char *const *argv)
MHD_OPTION_NOTIFY_COMPLETED, &request_completed, NULL,
MHD_OPTION_NOTIFY_CONNECTION, &connection_completed, NULL,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+ MHD_OPTION_CLIENT_DISCIPLINE_LVL, (int) 1,
MHD_OPTION_END);
if (d == NULL)
return 1;
diff --git a/src/examples/minimal_example.c b/src/examples/minimal_example.c
index f7a0e64c..f3fb1c88 100644
--- a/src/examples/minimal_example.c
+++ b/src/examples/minimal_example.c
@@ -105,7 +105,6 @@ main (int argc,
(uint16_t) port,
NULL, NULL, &ahc_echo, &data_for_handler,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
MHD_OPTION_END);
if (d == NULL)
return 1;
diff --git a/src/examples/minimal_example_empty.c
b/src/examples/minimal_example_empty.c
index 3556d753..2c76654a 100644
--- a/src/examples/minimal_example_empty.c
+++ b/src/examples/minimal_example_empty.c
@@ -93,7 +93,6 @@ main (int argc,
(uint16_t) port,
NULL, NULL, &ahc_echo, NULL,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
MHD_OPTION_END);
if (d == NULL)
return 1;
diff --git a/src/examples/minimal_example_empty_tls.c
b/src/examples/minimal_example_empty_tls.c
index 465f7492..d0a4d6ff 100644
--- a/src/examples/minimal_example_empty_tls.c
+++ b/src/examples/minimal_example_empty_tls.c
@@ -160,7 +160,7 @@ main (int argc,
(uint16_t) port,
NULL, NULL, &ahc_echo, NULL,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
- MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
+ MHD_OPTION_CLIENT_DISCIPLINE_LVL, (int) 1,
/* Optionally, the gnutls_load_file() can be used to
load the key and the certificate from file. */
MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index b66f4b3d..93967c60 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -96,7 +96,7 @@ extern "C"
* they are parsed as decimal numbers.
* Example: 0x01093001 = 1.9.30-1.
*/
-#define MHD_VERSION 0x00097544
+#define MHD_VERSION 0x00097545
/* If generic headers don't work on your platform, include headers
which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t',
@@ -1291,12 +1291,14 @@ enum MHD_FLAG
* as liberal as possible in what you accept" norm. It is
* recommended to turn this ON if you are testing clients against
* MHD, and OFF in production.
+ * @sa #MHD_OPTION_CLIENT_DISCIPLINE_LVL
*/
MHD_USE_PEDANTIC_CHECKS = 32,
#if 0 /* Will be marked for real deprecation later. */
#define MHD_USE_PEDANTIC_CHECKS \
_MHD_DEPR_IN_MACRO ( \
- "Flag MHD_USE_PEDANTIC_CHECKS is deprecated, use option
MHD_OPTION_STRICT_FOR_CLIENT instead") \
+ "Flag MHD_USE_PEDANTIC_CHECKS is deprecated, " \
+ "use option MHD_OPTION_CLIENT_DISCIPLINE_LVL instead") \
32
#endif /* 0 */
@@ -1939,15 +1941,18 @@ enum MHD_OPTION
* If set to 1 - be strict about the protocol. Use -1 to be
* as tolerant as possible.
*
- * Specifically, at the moment, at 1 this flag
- * causes MHD to reject HTTP 1.1 connections without a "Host" header,
- * and to disallow spaces in the URL or (at -1) in HTTP header key strings.
+ * The more flexible option #MHD_OPTION_CLIENT_DISCIPLINE_LVL is recommended
+ * instead of this option.
*
- * These are required by some versions of the standard, but of
- * course in violation of the "be as liberal as possible in what you
- * accept" norm. It is recommended to set this to 1 if you are
- * testing clients against MHD, and 0 in production. This option
- * should be followed by an `int` argument.
+ * The values mapping table:
+ * #MHD_OPTION_STRICT_FOR_CLIENT | #MHD_OPTION_CLIENT_DISCIPLINE_LVL
+ * -----------------------------:|:---------------------------------
+ * 1 | 1
+ * 0 | 0
+ * -1 | -3
+ *
+ * This option should be followed by an `int` argument.
+ * @sa #MHD_OPTION_CLIENT_DISCIPLINE_LVL
*/
MHD_OPTION_STRICT_FOR_CLIENT = 29,
@@ -2037,7 +2042,54 @@ enum MHD_OPTION
* default priorities.
* @note Available since #MHD_VERSION 0x00097542
*/
- MHD_OPTION_HTTPS_PRIORITIES_APPEND = 37
+ MHD_OPTION_HTTPS_PRIORITIES_APPEND = 37,
+
+ /**
+ * Sets specified client discipline level (i.e. HTTP protocol parsing
+ * strictness level).
+ *
+ * The following basic values are supported:
+ * 0 - default MHD level, a balance between extra security and broader
+ * compatibility, as allowed by RFCs for HTTP servers;
+ * 1 - more strict protocol interpretation, within the limits set by
+ * RFCs for HTTP servers;
+ * -1 - more lenient protocol interpretation, within the limits set by
+ * RFCs for HTTP servers.
+ * The following extended values could be used as well:
+ * 2 - stricter protocol interpretation, even stricter then allowed
+ * by RFCs for HTTP servers, however it should be absolutely compatible
+ * with clients following at least RFCs' "MUST" type of requirements
+ * for HTTP clients;
+ * 3 - strictest protocol interpretation, even stricter then allowed
+ * by RFCs for HTTP servers, however it should be absolutely compatible
+ * with clients following RFCs' "SHOULD" and "MUST" types of
requirements
+ * for HTTP clients;
+ * -2 - more relaxed protocol interpretation, violating RFCs' "SHOULD" type
+ * of requirements for HTTP servers;
+ * -3 - the most flexible protocol interpretation, beyond RFCs' "MUST" type
of
+ * requirements for HTTP server.
+ * Values higher than "3" or lower than "-3" are interpreted as "3" or "-3"
+ * respectively.
+ *
+ * Higher values are more secure, lower values are more compatible with
+ * various HTTP clients.
+ *
+ * The default value ("0") could be used in most cases.
+ * Value "1" is suitable for highly loaded public servers.
+ * Values "2" and "3" are generally recommended only for testing of HTTP
+ * clients against MHD.
+ * Value "2" may be used for security-centric application, however it is
+ * slight violation of RFCs' requirements.
+ * Negative values are not recommended for public servers.
+ * Values "-1" and "-2" could be used for servers in isolated environment.
+ * Value "-3" is not recommended unless it is absolutely necessary to
+ * communicate with some client(s) with badly broken HTTP implementation.
+ *
+ * This option should be followed by an `int` argument.
+ * @note Available since #MHD_VERSION 0x00097545
+ */
+ MHD_OPTION_CLIENT_DISCIPLINE_LVL = 38
+
} _MHD_FIXED_ENUM;
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 5e5c2f13..1c6070e8 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2846,15 +2846,15 @@ parse_cookies_string (char *str,
size_t i;
bool non_strict;
/* Skip extra whitespaces and empty cookies */
- const bool allow_wsp_empty = (0 >= connection->daemon->strict_for_client);
+ const bool allow_wsp_empty = (0 >= connection->daemon->client_discipline);
/* Allow whitespaces around '=' character */
- const bool wsp_around_eq = (0 > connection->daemon->strict_for_client);
+ const bool wsp_around_eq = (-3 >= connection->daemon->client_discipline);
/* Allow whitespaces in quoted cookie value */
- const bool wsp_in_quoted = (0 >= connection->daemon->strict_for_client);
+ const bool wsp_in_quoted = (0 >= connection->daemon->client_discipline);
/* Allow tab as space after semicolon between cookies */
- const bool tab_as_sp = (0 >= connection->daemon->strict_for_client);
+ const bool tab_as_sp = (0 >= connection->daemon->client_discipline);
/* Allow no space after semicolon between cookies */
- const bool allow_no_space = (0 >= connection->daemon->strict_for_client);
+ const bool allow_no_space = (0 >= connection->daemon->client_discipline);
non_strict = false;
i = 0;
@@ -3327,7 +3327,7 @@ parse_initial_message_line (struct MHD_Connection
*connection,
uri_len = line_len - (size_t) (uri - line);
}
/* check for spaces in URI if we are "strict" */
- if ( (1 <= daemon->strict_for_client) &&
+ if ( (-2 < daemon->client_discipline) &&
(NULL != memchr (uri,
' ',
uri_len)) )
@@ -3752,7 +3752,7 @@ process_header_line (struct MHD_Connection *connection,
/* error in header line, die hard */
return MHD_NO;
}
- if (-1 >= connection->daemon->strict_for_client)
+ if (-3 < connection->daemon->client_discipline)
{
/* check for whitespace before colon, which is not allowed
by RFC 7230 section 3.2.4; we count space ' ' and
@@ -3897,7 +3897,7 @@ parse_connection_headers (struct MHD_Connection
*connection)
return;
}
#endif /* COOKIE_SUPPORT */
- if ( (1 <= connection->daemon->strict_for_client) &&
+ if ( (-3 < connection->daemon->client_discipline) &&
(MHD_IS_HTTP_VER_1_1_COMPAT (connection->rq.http_ver)) &&
(MHD_NO ==
MHD_lookup_connection_value_n (connection,
@@ -3946,7 +3946,7 @@ parse_connection_headers (struct MHD_Connection
*connection)
NULL))
{
/* TODO: add individual settings */
- if (1 <= connection->daemon->strict_for_client)
+ if (1 <= connection->daemon->client_discipline)
{
transmit_error_response_static (connection,
MHD_HTTP_BAD_REQUEST,
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index d854de31..746d9493 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -5729,7 +5729,7 @@ unescape_wrapper (void *cls,
(void) cls; /* Mute compiler warning. */
/* TODO: add individual parameter */
- if (1 <= connection->daemon->strict_for_client)
+ if (0 <= connection->daemon->client_discipline)
return MHD_str_pct_decode_in_place_strict_ (val);
res = MHD_str_pct_decode_in_place_lenient_ (val, &broken);
@@ -6653,14 +6653,33 @@ parse_options_va (struct MHD_Daemon *daemon,
unsigned int);
break;
case MHD_OPTION_STRICT_FOR_CLIENT:
- daemon->strict_for_client = va_arg (ap, int);
+ daemon->client_discipline = va_arg (ap, int); /* Temporal assignment */
+ /* Map to correct value */
+ if (-1 >= daemon->client_discipline)
+ daemon->client_discipline = -3;
+ else if (1 <= daemon->client_discipline)
+ daemon->client_discipline = 1;
#ifdef HAVE_MESSAGES
if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
- (1 != daemon->strict_for_client) )
+ (1 != daemon->client_discipline) )
{
MHD_DLOG (daemon,
_ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
- "another behavior is specified by
MHD_OPTION_STRICT_CLIENT.\n"));
+ "another behaviour is specified by "
+ "MHD_OPTION_STRICT_CLIENT.\n"));
+ }
+#endif /* HAVE_MESSAGES */
+ break;
+ case MHD_OPTION_CLIENT_DISCIPLINE_LVL:
+ daemon->client_discipline = va_arg (ap, int);
+#ifdef HAVE_MESSAGES
+ if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
+ (1 != daemon->client_discipline) )
+ {
+ MHD_DLOG (daemon,
+ _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
+ "another behaviour is specified by "
+ "MHD_OPTION_CLIENT_DISCIPLINE_LVL.\n"));
}
#endif /* HAVE_MESSAGES */
break;
@@ -6723,6 +6742,7 @@ parse_options_va (struct MHD_Daemon *daemon,
break;
/* all options taking 'int' */
case MHD_OPTION_STRICT_FOR_CLIENT:
+ case MHD_OPTION_CLIENT_DISCIPLINE_LVL:
case MHD_OPTION_SIGPIPE_HANDLED_BY_APP:
case MHD_OPTION_TLS_NO_ALPN:
if (MHD_NO == parse_options (daemon,
@@ -7102,8 +7122,8 @@ MHD_start_daemon_va (unsigned int flags,
daemon->listening_address_reuse = 0;
daemon->options = *pflags;
pflags = &daemon->options;
- daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 :
- 0;
+ daemon->client_discipline = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ?
+ 1 : 0;
daemon->port = port;
daemon->apc = apc;
daemon->apc_cls = apc_cls;
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 78481b21..9f5ed442 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -2104,9 +2104,10 @@ struct MHD_Daemon
unsigned int per_ip_connection_limit;
/**
- * Be neutral (zero), strict (1) or permissive (-1) to client.
+ * The strictness level for parsing of incoming data.
+ * @see #MHD_OPTION_CLIENT_DISCIPLINE_LVL
*/
- int strict_for_client;
+ int client_discipline;
/**
* True if SIGPIPE is blocked
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [libmicrohttpd] branch master updated (1e7ad301 -> 4dadf8ec), gnunet, 2022/12/22
- [libmicrohttpd] 01/05: Always close connection after reply if both Content-Length and chucked are used, gnunet, 2022/12/22
- [libmicrohttpd] 02/05: connection.c: cosmetics, gnunet, 2022/12/22
- [libmicrohttpd] 05/05: Updated parsing of cookies, reject cookie completely if discipline is very strict, gnunet, 2022/12/22
- [libmicrohttpd] 04/05: Updated W32 resources file, gnunet, 2022/12/22
- [libmicrohttpd] 03/05: Added new daemon option MHD_OPTION_CLIENT_DISCIPLINE_LV,
gnunet <=