From cbc7414482da44d98d464ebf8025ae6b467d38d8 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Thu, 31 May 2018 15:10:26 +0000 Subject: [PATCH] Merge r1769718, r1785943, r1786110, r1786119 from trunk: add an config section like It allows a non httpd config file to be used as a marker directly in httpd.conf without hiding logic in a script in front of apachectl to do test -f and pass extra -D's. This is something we've had in IBM's httpd distro for a little bit and hadn't remembered to share. I've seen some questions/config files come up in a few places lately that would benefit from this as an option. Remove duplicate implementations of conditional section function. No functional change. * server/core.c (start_cond_section): Factor out from start_if*. Adjust to use apr_strmemdup. (test_ifmod_section, test_iffile_section, test_ifdefine_section): Move container-specific tests into callbacks from start_if*. (core_cmds): Adjust and : * server/core.c (test_ifdirective_section, test_ifsection_section): New callbacks. (core_cmds): Define new directives. * include/http_config.h, server/config.c (ap_exists_directive): New function. * include/ap_mmn.h: Bump MMN minor for above. * docs/manual/mod/core.xml: Add docs. * server/core.c (start_cond_section): Comment & variable name fixes, no functional change. Submitted by: covener, jorton Reviewed by: jorton, ylavic, covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1832623 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 + STATUS | 2 + docs/manual/mod/core.xml | 154 +++++++++++++++++++++++++++++++++++++-- include/ap_mmn.h | 3 +- include/http_config.h | 8 ++ server/config.c | 10 +++ server/core.c | 92 ++++++++++++----------- 7 files changed, 223 insertions(+), 49 deletions(-) diff --git a/CHANGES b/CHANGES index 491845096a..17338e3410 100644 --- a/CHANGES +++ b/CHANGES @@ -61,6 +61,9 @@ Changes with Apache 2.4.34 *) mod_ssl: Fix cmake-based build. PR 62266. [Rainer Jung] + *) core: Add , and conditional + section containers. [Eric Covener, Joe Orton] + Changes with Apache 2.4.33 *) core: Fix request timeout logging and possible crash for error_log hooks. diff --git a/STATUS b/STATUS index 17aaf3125b..41ec51db66 100644 --- a/STATUS +++ b/STATUS @@ -192,6 +192,8 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK: http://svn.apache.org/r1804531 2.4.x patch: https://svn.apache.org/repos/asf/httpd/httpd/patches/2.4.x/ssl-policy.patch +1: icing + -0: jorton: some unused code paths and legacy of previous iterations still + included in patch? more at msgid <20180523075115.GA4654@redhat.com> *) ap_rgetline()+mod_proxy_http: Add and handle AP_GETLINE_NOSPC_EOL flag, fixes responses header thrown away on APR_ENOSPC, and allow their size to diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index 3d629dfd43..4da8fe4ee1 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -763,12 +763,12 @@ DefaultType None directory -

In its one parameter form, Define is equivalent - to passing the -D argument to httpd. It - can be used to toggle the use of - IfDefine sections - without needing to alter -D arguments in any startup - scripts.

+

In its one parameter form, Define is + equivalent to passing the -D argument to + httpd. It can be used to toggle the use of + IfDefine + sections without needing to alter -D arguments in any + startup scripts.

In addition to that, if the second parameter is given, a config variable is set to this value. The variable can be used in the configuration using @@ -2269,6 +2269,44 @@ if a test is true at startup + +IfFile +Encloses directives that will be processed only +if file exists at startup +<IfFile [!]parameter-name> ... + </IfFile> +server configvirtual host +directory.htaccess + +Available in 2.4.34 and later. + + +

The <IfFile filename>...</IfFile> + section is used to mark directives that are conditional on + the existence of a file on disk. The directives within an + IfFile section are only + processed if the filename exists. If filename + doesn't exist, everything between the start and end markers is + ignored. filename can be an absolute path or a path + relative to the server root.

+ +

The filename in the IfFile + section directive can take the same forms as the + test variable in the IfDefine + section, i.e. the test can be negated if the + ! character is placed directly before filename. +

+ +

If a relative filename is supplied, the check is + ServerRoot relative. In the case where + this directive occurs before the ServerRoot, + the path will be checked relative to the compiled-in server root or + the server root passed in on the command line via the -d + parameter.

+ +
+ + IfModule Encloses directives that are processed conditional on the @@ -2326,6 +2364,110 @@ later. + +IfDirective +Encloses directives that are processed conditional on the +presence or absence of a specific directive +<IfDirective [!]directive-name> ... + </IfDirective> +server configvirtual host +directory.htaccess + +All +Available in 2.4.34 and later. + + +

The <IfDirective test>...</IfDirective> + section is used to mark directives that are conditional on the presence of + a specific directive. The directives within an IfDirective section are only processed if the test + is true. If test is false, everything between the start and + end markers is ignored.

+ +

The test in the IfDirective section can be one of two forms:

+ +
    +
  • directive-name
  • + +
  • !directive-name
  • +
+ +

In the former case, the directives between the start and end + markers are only processed if a directive of the given name is + available at the time of processing. The second format reverses the test, + and only processes the directives if the directive-name is + not defined.

+ + This section should only be used if you need to have one + configuration file that works across multiple versions of + httpd, regardless of whether a particular + directive is available. In normal operation, directives need not + be placed in IfDirective + sections. +
+IfSection +
+ + +IfSection +Encloses directives that are processed conditional on the +presence or absence of a specific section directive +<IfSection [!]section-name> ... + </IfSection> +server configvirtual host +directory.htaccess + +All +Available in 2.4.34 and later. + + +

The <IfSection + test>...</IfSection> section is used + to mark directives that are conditional on the presence of a + specific section directive. A section directive is any directive + such as virtualhost which + encloses other directives, and has a directive name with a leading + "<". The sec + + The directives within an IfSection section are only processed if the test + is true. If test is false, everything between the start and + end markers is ignored.

+ +

The section-name specified must not include the + leading "<". The test in the IfSection section can be one of two + forms:

+ +
    +
  • section-name
  • +
  • !section-name
  • +
+ +

In the former case, the directives between the start and + end markers are only processed if a section directive of the given + name is available at the time of processing. The second format + reverses the test, and only processes the directives if the + section-name is not defined.

+ +

For example:

+ + +<IfSection VirtualHost> + ... +</IfSection> + + + This section should only be used if you need to have one + configuration file that works across multiple versions of httpd, + regardless of whether a particular section directive is + available. In normal operation, directives need not be placed in + IfSection sections. +
+IfDirective +
+ Include Includes other configuration files from within diff --git a/include/ap_mmn.h b/include/ap_mmn.h index f57d64ad1b..539fc1e119 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -512,6 +512,7 @@ * ap_regcomp_default_cflag_by_name * 20120211.75 (2.4.30-dev) Add hostname_ex to proxy_worker_shared * 20120211.76 (2.4.30-dev) Add CONN_STATE_NUM to enum conn_state_e + * 20120211.77 (2.4.34-dev) add ap_exists_directive() */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -519,7 +520,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 76 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 77 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/http_config.h b/include/http_config.h index 9600dd3d62..adc58252d3 100644 --- a/include/http_config.h +++ b/include/http_config.h @@ -1014,6 +1014,14 @@ AP_DECLARE(const char *) ap_setup_prelinked_modules(process_rec *process); */ AP_DECLARE(void) ap_show_directives(void); +/** + * Returns non-zero if a configuration directive of the given name has + * been registered by a module at the time of calling. + * @param p Pool for temporary allocations + * @param name Directive name + */ +AP_DECLARE(int) ap_exists_directive(apr_pool_t *p, const char *name); + /** * Show the preloaded module names. Used for httpd -l. */ diff --git a/server/config.c b/server/config.c index 7f1d50e08d..f815b22d70 100644 --- a/server/config.c +++ b/server/config.c @@ -2687,6 +2687,16 @@ AP_DECLARE(void) ap_show_modules(void) printf(" %s\n", ap_loaded_modules[n]->name); } +AP_DECLARE(int) ap_exists_directive(apr_pool_t *p, const char *name) +{ + char *lname = apr_pstrdup(p, name); + + ap_str_tolower(lname); + + return ap_config_hash && + apr_hash_get(ap_config_hash, lname, APR_HASH_KEY_STRING) != NULL; +} + AP_DECLARE(void *) ap_retained_data_get(const char *key) { void *retained; diff --git a/server/core.c b/server/core.c index 5e9d6501bd..32d19e20ad 100644 --- a/server/core.c +++ b/server/core.c @@ -2710,18 +2710,23 @@ static module *find_module(server_rec *s, const char *name) return found; } +/* Callback function type used by start_cond_section. */ +typedef int (*test_cond_section_fn)(cmd_parms *cmd, const char *arg); -static const char *start_ifmod(cmd_parms *cmd, void *mconfig, const char *arg) +/* Implementation of -style conditional sections. Callback + * to test condition must be in cmd->info, matching function type + * test_cond_section_fn. */ +static const char *start_cond_section(cmd_parms *cmd, void *mconfig, const char *arg) { const char *endp = ap_strrchr_c(arg, '>'); - int not = (arg[0] == '!'); - module *found; + int result, not = (arg[0] == '!'); + test_cond_section_fn testfn = (test_cond_section_fn)cmd->info; if (endp == NULL) { return unclosed_directive(cmd); } - arg = apr_pstrndup(cmd->temp_pool, arg, endp - arg); + arg = apr_pstrmemdup(cmd->temp_pool, arg, endp - arg); if (not) { arg++; @@ -2731,66 +2736,58 @@ static const char *start_ifmod(cmd_parms *cmd, void *mconfig, const char *arg) return missing_container_arg(cmd); } - found = find_module(cmd->server, arg); + result = testfn(cmd, arg); - if ((!not && found) || (not && !found)) { + if ((!not && result) || (not && !result)) { ap_directive_t *parent = NULL; ap_directive_t *current = NULL; const char *retval; retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, - ¤t, &parent, "cmd->name); *(ap_directive_t **)mconfig = current; return retval; } else { *(ap_directive_t **)mconfig = NULL; - return ap_soak_end_container(cmd, "cmd->name); } } +/* Callback to implement test for start_cond_section. */ +static int test_ifmod_section(cmd_parms *cmd, const char *arg) +{ + return find_module(cmd->server, arg) != NULL; +} + AP_DECLARE(int) ap_exists_config_define(const char *name) { return ap_array_str_contains(ap_server_config_defines, name); } -static const char *start_ifdefine(cmd_parms *cmd, void *dummy, const char *arg) +static int test_ifdefine_section(cmd_parms *cmd, const char *arg) { - const char *endp; - int defined; - int not = 0; - - endp = ap_strrchr_c(arg, '>'); - if (endp == NULL) { - return unclosed_directive(cmd); - } - - arg = apr_pstrndup(cmd->temp_pool, arg, endp - arg); + return ap_exists_config_define(arg); +} - if (arg[0] == '!') { - not = 1; - arg++; - } +static int test_iffile_section(cmd_parms *cmd, const char *arg) +{ + const char *relative; + apr_finfo_t sb; - if (!arg[0]) { - return missing_container_arg(cmd); - } + relative = ap_server_root_relative(cmd->temp_pool, arg); + return (apr_stat(&sb, relative, 0, cmd->pool) == APR_SUCCESS); +} - defined = ap_exists_config_define(arg); - if ((!not && defined) || (not && !defined)) { - ap_directive_t *parent = NULL; - ap_directive_t *current = NULL; - const char *retval; +static int test_ifdirective_section(cmd_parms *cmd, const char *arg) +{ + return ap_exists_directive(cmd->temp_pool, arg); +} - retval = ap_build_cont_config(cmd->pool, cmd->temp_pool, cmd, - ¤t, &parent, "temp_pool, "<", arg, NULL); + return ap_exists_directive(cmd->temp_pool, name); } /* httpd.conf commands... beginning with the business */ @@ -4306,10 +4303,21 @@ AP_INIT_RAW_ARGS("