From 33f121a4f6a2d5d47c51d7cbf1d5a750ed369750 Mon Sep 17 00:00:00 2001 From: "Evgeny Grin (Karlson2k)" Date: Thu, 27 Apr 2017 22:36:09 +0300 Subject: Replaced flags MHD_USE_PEDANTIC_CHECKS and MHD_USE_PERMISSIVE_CHECKS by single option MHD_OPTION_STRICT_FOR_CLIENT. --- ChangeLog | 5 +++++ src/examples/minimal_example.c | 3 ++- src/include/microhttpd.h | 37 ++++++++++++++++++++++++++----------- src/microhttpd/connection.c | 4 ++-- src/microhttpd/daemon.c | 22 ++++++++++++++++++++++ src/microhttpd/internal.h | 5 +++++ 6 files changed, 62 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 28452654..a8a87f84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Apr 27 22:31:00 CEST 2017 + Replaced flags MHD_USE_PEDANTIC_CHECKS and MHD_USE_PERMISSIVE_CHECKS by + single option MHD_OPTION_STRICT_FOR_CLIENT. Flag MHD_USE_PEDANTIC_CHECKS + is still supported. -EG + Tue Apr 26 15:11:00 CEST 2017 Fixed shift in HTTP reasons strings. Added test for HTTP reasons strings. -EG diff --git a/src/examples/minimal_example.c b/src/examples/minimal_example.c index c5796fc8..98e7e192 100644 --- a/src/examples/minimal_example.c +++ b/src/examples/minimal_example.c @@ -68,13 +68,14 @@ main (int argc, char *const *argv) return 1; } d = MHD_start_daemon (// MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, - MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_PEDANTIC_CHECKS | MHD_USE_ERROR_LOG, + MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, // MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, // MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, atoi (argv[1]), NULL, NULL, &ahc_echo, PAGE, 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/include/microhttpd.h b/src/include/microhttpd.h index fcb617d8..02bf38ab 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h @@ -957,6 +957,11 @@ enum MHD_FLAG * MHD, and OFF in production. */ 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") \ + 32 +#endif /* 0 */ /** * Use `poll()` instead of `select()`. This allows sockets with `fd >= @@ -1136,16 +1141,7 @@ enum MHD_FLAG * This is combination of #MHD_USE_AUTO and #MHD_USE_INTERNAL_POLLING_THREAD * flags. */ - MHD_USE_AUTO_INTERNAL_THREAD = MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, - - /** - * Be permissive about the protocol, allowing slight deviations that - * are technically not allowed by the RFC. - * Specifically, at the moment, this flag causes MHD to - * allow spaces in header field names. This is - * disallowed by the standard. - */ - MHD_USE_PERMISSIVE_CHECKS = 131072 + MHD_USE_AUTO_INTERNAL_THREAD = MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD }; @@ -1471,7 +1467,26 @@ enum MHD_OPTION * value is used. This option should be followed by an `unsigned int` * argument. */ - MHD_OPTION_LISTEN_BACKLOG_SIZE = 28 + MHD_OPTION_LISTEN_BACKLOG_SIZE = 28, + + /** + * If set to 1 - be strict about the protocol (as opposed to as + * tolerant as possible). Specifically, at the moment, this flag + * causes MHD to reject HTTP 1.1 connections without a "Host" header. + * This is required by 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. + * if set to -1 - be opposite to strict and be permissive about the + * protocol, allowing slight deviations that are technically not + * allowed by the RFC. Specifically, at the moment, this flag + * causes MHD to allow spaces in header field names. This is + * disallowed by the standard. + * It is not recommended to set it to -1 on publicly available + * servers as it may potentially lower level of protection. + * This option should be followed by an `int` argument. + */ + MHD_OPTION_STRICT_FOR_CLIENT = 29 }; diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index 7baee402..228af49b 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c @@ -2213,7 +2213,7 @@ process_header_line (struct MHD_Connection *connection, _("Received malformed line (no colon). Closing connection.\n")); return MHD_NO; } - if (0 == (MHD_USE_PERMISSIVE_CHECKS & connection->daemon->options)) + if (-1 >= connection->daemon->strict_for_client) { /* check for whitespace before colon, which is not allowed by RFC 7230 section 3.2.4; we count space ' ' and @@ -2348,7 +2348,7 @@ parse_connection_headers (struct MHD_Connection *connection) const char *end; parse_cookie_header (connection); - if ( (0 != (MHD_USE_PEDANTIC_CHECKS & connection->daemon->options)) && + if ( (1 <= connection->daemon->strict_for_client) && (NULL != connection->version) && (MHD_str_equal_caseless_(MHD_HTTP_VERSION_1_1, connection->version)) && diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index b528622d..a91d2687 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c @@ -5063,6 +5063,18 @@ parse_options_va (struct MHD_Daemon *daemon, daemon->listen_backlog_size = va_arg (ap, unsigned int); break; + case MHD_OPTION_STRICT_FOR_CLIENT: + daemon->strict_for_client = va_arg (ap, int);; +#ifdef HAVE_MESSAGES + if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) && + (1 != daemon->strict_for_client) ) + { + MHD_DLOG (daemon, + _("Flag MHD_USE_PEDANTIC_CHECKS is ignored because " + "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n")); + } +#endif /* HAVE_MESSAGES */ + break; case MHD_OPTION_ARRAY: oa = va_arg (ap, struct MHD_OptionItem*); i = 0; @@ -5117,6 +5129,15 @@ parse_options_va (struct MHD_Daemon *daemon, MHD_OPTION_END)) return MHD_NO; break; + /* all options taking 'int' */ + case MHD_OPTION_STRICT_FOR_CLIENT: + if (MHD_YES != parse_options (daemon, + servaddr, + opt, + (int) oa[i].value, + MHD_OPTION_END)) + return MHD_NO; + break; /* all options taking one pointer */ case MHD_OPTION_SOCK_ADDR: case MHD_OPTION_HTTPS_MEM_KEY: @@ -5428,6 +5449,7 @@ 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->port = port; daemon->apc = apc; daemon->apc_cls = apc_cls; diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h index 9ced47c1..aac13d6c 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h @@ -1540,6 +1540,11 @@ struct MHD_Daemon */ uint16_t port; + /** + * Be neutral (zero), strict (1) or permissive (-1) to client. + */ + int strict_for_client; + #ifdef HTTPS_SUPPORT #ifdef UPGRADE_SUPPORT /** -- cgit v1.2.3