]> granicus.if.org Git - apache/commitdiff
Retract veto over inconsistent behaviour between directory and file wildcards,
authorGraham Leggett <minfrin@apache.org>
Tue, 30 Mar 2010 22:14:24 +0000 (22:14 +0000)
committerGraham Leggett <minfrin@apache.org>
Tue, 30 Mar 2010 22:14:24 +0000 (22:14 +0000)
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
server/config.c
server/core.c

index 69fe0ccc5b19914a3d43740256310ac9063668a9..4e0beef6fbbbe153e0fd880af42ec5126a6504f4 100644 (file)
@@ -1539,8 +1539,7 @@ later.</compatibility>
 <name>Include</name>
 <description>Includes other configuration files from within
 the server configuration files</description>
-<syntax>Include <var>file-path</var>|<var>directory-path</var>|
-<var>wildcard</var></syntax>
+<syntax>Include [<var>optional</var>|<var>strict</var>] <var>file-path</var>|<var>directory-path</var>|<var>wildcard</var></syntax>
 <contextlist><context>server config</context><context>virtual host</context>
 <context>directory</context>
 </contextlist>
@@ -1562,20 +1561,27 @@ wildcard matching available in 2.3.6 and later</compatibility>
     wildcard syntax shown below, to include files that match a particular
     pattern, such as *.conf, for example.</p>
 
-    <p>When a wildcard is specified for a file or directory component of the
-    path, and no file or directory matches the wildcard, the
-    <directive module="core">Include</directive> directive will be
-    silently ignored. When a directory or file component of the path is
+    <p>When a wildcard is specified for a <strong>file</strong> component of
+    the path, and no file matches the wildcard, the
+    <directive module="core">Include</directive>
+    directive will be <strong>silently ignored</strong>. When a wildcard is
+    specified for a <strong>directory</strong> component of the path, and
+    no directory matches the wildcard, the
+    <directive module="core">Include</directive> directive will
+    <strong>fail with an error</strong> saying the directory cannot be found.
+    </p>
+
+    <p>For further control over the behaviour of the server when no files or
+    directories match, prefix the path with the modifiers <var>optional</var>
+    or <var>strict</var>. If <var>optional</var> is specified, any wildcard
+    file or directory that does not match will be silently ignored. If
+    <var>strict</var> is specified, any wildcard file or directory that does
+    not match at least one file will cause server startup to fail.</p>
+
+    <p>When a directory or file component of the path is
     specified exactly, and that directory or file does not exist,
     <directive module="core">Include</directive> 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.</p>
-
-    <p>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 <directive module="code">IncludeStrict</directive>
-    directive instead.</p>
+    error saying the file or directory cannot be found.</p>
 
     <p>The file path specified may be an absolute path, or may be relative 
     to the <directive module="core">ServerRoot</directive> directory.</p>
@@ -1596,53 +1602,28 @@ wildcard matching available in 2.3.6 and later</compatibility>
     </example>
 
     <p>Wildcards may be included in the directory or file portion of the
-    path:</p>
+    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.</p>
   
     <example>
-      Include conf/vhosts/*/vhost.conf
+      Include conf/vhosts/*/vhost.conf<br />
       Include conf/vhosts/*/*.conf
     </example>
 
-</usage>
-
-<seealso><program>apachectl</program></seealso>
-</directivesynopsis>
-
-<directivesynopsis>
-<name>IncludeStrict</name>
-<description>Includes other configuration files from within the server
-configuration files, throwing an error if no files or directories match
-a wildcard
-</description>
-<syntax>IncludeStrict <var>file-path</var>|<var>directory-path</var>|
-<var>wildcard</var></syntax>
-<contextlist><context>server config</context><context>virtual host</context>
-<context>directory</context>
-</contextlist>
-<compatibility>Available in 2.3.6 and later</compatibility>
-
-<usage>
-      <p>This directive allows inclusion of other configuration files
-      from within the server configuration files.</p>
-
-      <p>It is functionally equivalent to the
-      <directive module="core">Include</directive> directive, with the additional
-      restriction that any wildcards are required to match at least one file or
-      directory.</p>
+    <p>In this example, the server will fail to load if either
+    conf/vhosts/* matches no directories, or if *.conf matches no files:</p>
 
-      <p>The file path specified may be an absolute path, or may be relative 
-      to the <directive module="core">ServerRoot</directive> directory.</p>
-
-      <p>Example:</p>
-
-      <p>The server will fail to load if the wildcard path
-      <var>/usr/local/apache2/conf/vhosts/*.conf</var> does not match at least
-      one file or directory.</p>
+    <example>
+      Include strict conf/vhosts/*/*.conf
+    </example>
+  
+    <p>In this example, the server load successfully if either conf/vhosts/*
+    matches no directories, or if *.conf matches no files:</p>
 
-      <example>
-        IncludeStrict /usr/local/apache2/conf/ssl.conf<br />
-        IncludeStrict /usr/local/apache2/conf/vhosts/*.conf
-      </example>
+    <example>
+      Include optional conf/vhosts/*/*.conf
+    </example>
 
 </usage>
 
index 5c48256236a4bffea4449801dfffd848a1232d5f..54a58b61a2140909bd0abf7194939ce3c0c8e83b 100644 (file)
@@ -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,
index 4e333ace2be7e97c3dc56148822aa4f46387b62e..921bf23c5ee22930eb48c75923d6ae93da98dec4 100644 (file)
@@ -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,