From 3915fb380bd592d01afec1e785047dd432090ad4 Mon Sep 17 00:00:00 2001
From: Graham Leggett
Date: Tue, 30 Mar 2010 22:14:24 +0000
Subject: [PATCH] Retract veto over inconsistent behaviour between directory
and file wildcards, implement wrowe's missing directory wilcard must fail /
missing file wildcard must pass requirement. Introduce 'optional' and
'strict' modifiers to the Include directive for the end user to express their
desired behaviour.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@929318 13f79535-47bb-0310-9956-ffa450edef68
---
docs/manual/mod/core.xml | 89 ++++++++++++++++------------------------
server/config.c | 29 +++++++++----
server/core.c | 44 +++++++++++---------
3 files changed, 82 insertions(+), 80 deletions(-)
diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml
index 69fe0ccc5b..4e0beef6fb 100644
--- a/docs/manual/mod/core.xml
+++ b/docs/manual/mod/core.xml
@@ -1539,8 +1539,7 @@ later.
Include
Includes other configuration files from within
the server configuration files
-Include file-path|directory-path|
-wildcard
+Include [optional|strict] file-path|directory-path|wildcard
server configvirtual host
directory
@@ -1562,20 +1561,27 @@ wildcard matching available in 2.3.6 and later
wildcard syntax shown below, to include files that match a particular
pattern, such as *.conf, for example.
- When a wildcard is specified for a file or directory component of the
- path, and no file or directory matches the wildcard, the
- Include directive will be
- silently ignored. When a directory or file component of the path is
+
When a wildcard is specified for a file component of
+ the path, and no file matches the wildcard, the
+ Include
+ directive will be silently ignored. When a wildcard is
+ specified for a directory component of the path, and
+ no directory matches the wildcard, the
+ Include directive will
+ fail with an error saying the directory cannot be found.
+
+
+ For further control over the behaviour of the server when no files or
+ directories match, prefix the path with the modifiers optional
+ or strict. If optional is specified, any wildcard
+ file or directory that does not match will be silently ignored. If
+ strict is specified, any wildcard file or directory that does
+ not match at least one file will cause server startup to fail.
+
+ When a directory or file component of the path is
specified exactly, and that directory or file does not exist,
Include directive will fail with an
- error saying the file or directory cannot be found. This removes the need
- for placeholder files to exist so that at least one file or directory is
- found by the wildcard.
-
- Under certain circumstances, it may be required for the server to fail
- explicitly when no files or directories match a specific wildcard. In these
- cases, use the IncludeStrict
- directive instead.
+ error saying the file or directory cannot be found.
The file path specified may be an absolute path, or may be relative
to the ServerRoot directory.
@@ -1596,53 +1602,28 @@ wildcard matching available in 2.3.6 and later
Wildcards may be included in the directory or file portion of the
- path:
+ path. In the following example, the server will fail to load if no
+ directories match conf/vhosts/*, but will load successfully if no
+ files match *.conf.
- Include conf/vhosts/*/vhost.conf
+ Include conf/vhosts/*/vhost.conf
Include conf/vhosts/*/*.conf
-
-
-apachectl
-
-
-
-IncludeStrict
-Includes other configuration files from within the server
-configuration files, throwing an error if no files or directories match
-a wildcard
-
-IncludeStrict file-path|directory-path|
-wildcard
-server configvirtual host
-directory
-
-Available in 2.3.6 and later
-
-
- This directive allows inclusion of other configuration files
- from within the server configuration files.
-
- It is functionally equivalent to the
- Include directive, with the additional
- restriction that any wildcards are required to match at least one file or
- directory.
+ In this example, the server will fail to load if either
+ conf/vhosts/* matches no directories, or if *.conf matches no files:
- The file path specified may be an absolute path, or may be relative
- to the ServerRoot directory.
-
- Example:
-
- The server will fail to load if the wildcard path
- /usr/local/apache2/conf/vhosts/*.conf does not match at least
- one file or directory.
+
+ Include strict conf/vhosts/*/*.conf
+
+
+ In this example, the server load successfully if either conf/vhosts/*
+ matches no directories, or if *.conf matches no files:
-
- IncludeStrict /usr/local/apache2/conf/ssl.conf
- IncludeStrict /usr/local/apache2/conf/vhosts/*.conf
-
+
+ Include optional conf/vhosts/*/*.conf
+
diff --git a/server/config.c b/server/config.c
index 5c48256236..54a58b61a2 100644
--- a/server/config.c
+++ b/server/config.c
@@ -1559,7 +1559,7 @@ static const char *process_resource_config_nofnmatch(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
unsigned depth,
- int strict)
+ enum strict_how strict)
{
cmd_parms parms;
ap_configfile_t *cfp;
@@ -1661,7 +1661,7 @@ static const char *process_resource_config_fnmatch(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
unsigned depth,
- int strict)
+ enum strict_how strict)
{
const char *rest;
apr_status_t rv;
@@ -1752,9 +1752,24 @@ static const char *process_resource_config_fnmatch(server_rec *s,
}
}
}
- else if (strict) {
- return apr_psprintf(p, "No matches for the wildcard '%s' in %s",
- fname, path);
+ else {
+
+ /* Support for the three states of strictness:
+ *
+ * AP_OPTIONAL - directory and file wildcards succeed on no-match, we don't
+ * need to do anything here for this case.
+ * AP_MIXED - directory wildcards fail on no match, file wildcards succeed
+ * on no match. Use rest to tell between the two.
+ * AP_STRICT - both directory and file wildcards fail on no-match.
+ */
+ if (AP_STRICT == strict) {
+ return apr_psprintf(p, "No matches for the wildcard '%s' in '%s' with "
+ "strict wildcard matching, failing", fname, path);
+ }
+ else if (AP_MIXED == strict && rest) {
+ return apr_psprintf(p, "No matches for the wildcard '%s' in '%s', failing "
+ "(use Include optional if required)", fname, path);
+ }
}
return NULL;
@@ -1765,7 +1780,7 @@ AP_DECLARE(const char *) ap_process_resource_config_ex(server_rec *s,
ap_directive_t **conftree,
apr_pool_t *p,
apr_pool_t *ptemp,
- int strict)
+ enum strict_how strict)
{
/* XXX: lstat() won't work on the wildcard pattern...
*/
@@ -1814,7 +1829,7 @@ AP_DECLARE(const char *) ap_process_resource_config(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp)
{
- return ap_process_resource_config_ex(s, fname, conftree, p, ptemp, 0);
+ return ap_process_resource_config_ex(s, fname, conftree, p, ptemp, AP_MIXED);
}
AP_DECLARE(int) ap_process_config_tree(server_rec *s,
diff --git a/server/core.c b/server/core.c
index 4e333ace2b..921bf23c5e 100644
--- a/server/core.c
+++ b/server/core.c
@@ -2567,13 +2567,33 @@ static const char *set_use_canonical_phys_port(cmd_parms *cmd, void *d_,
}
static const char *include_config (cmd_parms *cmd, void *dummy,
- const char *name, int strict)
+ const char *arg1, const char *arg2)
{
ap_directive_t *conftree = NULL;
- const char* conffile, *error;
+ const char *name;
+ enum strict_how strict;
+ const char *conffile, *error;
unsigned *recursion;
void *data;
+ if (arg2) {
+ name = arg2;
+ if (!strcmp(arg1, "optional")) {
+ strict = AP_OPTIONAL;
+ }
+ else if (!strcmp(arg1, "strict")) {
+ strict = AP_STRICT;
+ }
+ else {
+ return apr_pstrcat(cmd->pool, "Invalid Include modifier '",
+ arg1, "', should be 'optional' or 'strict'", NULL);
+ }
+ }
+ else {
+ name = arg1;
+ strict = AP_MIXED;
+ }
+
apr_pool_userdata_get(&data, "ap_include_sentinel", cmd->pool);
if (data) {
recursion = data;
@@ -2615,18 +2635,6 @@ static const char *include_config (cmd_parms *cmd, void *dummy,
return NULL;
}
-static const char *include_regular_config(cmd_parms *cmd, void *dummy,
- const char *name)
-{
- return include_config(cmd, dummy, name, 0);
-}
-
-static const char *include_strict_config(cmd_parms *cmd, void *dummy,
- const char *name)
-{
- return include_config(cmd, dummy, name, 1);
-}
-
static const char *set_loglevel(cmd_parms *cmd, void *dummy, const char *arg)
{
char *str;
@@ -3313,12 +3321,10 @@ AP_INIT_TAKE1("UseCanonicalPhysicalPort", set_use_canonical_phys_port, NULL,
"Whether to use the physical Port when constructing URLs"),
/* TODO: RlimitFoo should all be part of mod_cgi, not in the core */
/* TODO: ListenBacklog in MPM */
-AP_INIT_TAKE1("Include", include_regular_config, NULL,
- (RSRC_CONF | ACCESS_CONF | EXEC_ON_READ),
- "Name of the config file to be included, ignore wildcards with no match"),
-AP_INIT_TAKE1("IncludeStrict", include_strict_config, NULL,
+AP_INIT_TAKE12("Include", include_config, NULL,
(RSRC_CONF | ACCESS_CONF | EXEC_ON_READ),
- "Name of the config file to be included, fail if wildcards don't match"),
+ "Name of the config file to be included, ignore file wildcards with no "
+ "matching files, fail directory wildcards with no matching directories"),
AP_INIT_TAKE1("LogLevel", set_loglevel, NULL, RSRC_CONF,
"Level of verbosity in error logging"),
AP_INIT_TAKE1("NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF,
--
2.40.0