httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From minf...@apache.org
Subject svn commit: r821333 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_cache.xml modules/cache/cache_util.c
Date Sat, 03 Oct 2009 14:54:00 GMT
Author: minfrin
Date: Sat Oct  3 14:54:00 2009
New Revision: 821333

URL: http://svn.apache.org/viewvc?rev=821333&view=rev
Log:
mod_cache: Fix uri_meets_conditions() so that CacheEnable will
match by scheme, or by a wildcarded hostname.
PR: 40169
Submitted by: Ryan Pendergast <rpender us.ibm.com>
Reviewed by: Graham Leggett

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_cache.xml
    httpd/httpd/trunk/modules/cache/cache_util.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=821333&r1=821332&r2=821333&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sat Oct  3 14:54:00 2009
@@ -10,6 +10,10 @@
      mod_proxy_ftp: NULL pointer dereference on error paths.
      [Stefan Fritsch <sf fritsch.de>, Joe Orton]
 
+  *) mod_cache: Fix uri_meets_conditions() so that CacheEnable will
+     match by scheme, or by a wildcarded hostname. PR 40169
+     [Ryan Pendergast <rpender us.ibm.com>, Graham Leggett]
+
   *) suxec: Allow to log an error if exec fails by setting FD_CLOEXEC
      on the log file instead of closing it. PR 10744. [Nicolas Rachinsky]
 

Modified: httpd/httpd/trunk/docs/manual/mod/mod_cache.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_cache.xml?rev=821333&r1=821332&r2=821333&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_cache.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_cache.xml Sat Oct  3 14:54:00 2009
@@ -262,6 +262,17 @@
       CacheEnable  disk  http://www.apache.org/<br />
     </example>
 
+    <p>A hostname starting with a <strong>"*"</strong> matches all hostnames
with
+    that suffix. A hostname starting with <strong>"."</strong> matches all
+    hostnames containing the domain components that follow.</p>
+
+    <example>
+      # Match www.apache.org, and fooapache.org<br />
+      CacheEnable  disk  http://*apache.org/<br />
+      # Match www.apache.org, but not fooapache.org<br />
+      CacheEnable  disk  http://.apache.org/<br />
+    </example>
+
     <p> The <code>no-cache</code> environment variable can be set to 
     disable caching on a finer grained set of resources in versions
     2.2.12 and later.</p>

Modified: httpd/httpd/trunk/modules/cache/cache_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/cache_util.c?rev=821333&r1=821332&r2=821333&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/cache_util.c (original)
+++ httpd/httpd/trunk/modules/cache/cache_util.c Sat Oct  3 14:54:00 2009
@@ -26,42 +26,79 @@
 
 /* Determine if "url" matches the hostname, scheme and port and path
  * in "filter". All but the path comparisons are case-insensitive.
+ * Note: the 's' parameters is not used currently, but needed for
+ * logging during debugging.
  */
-static int uri_meets_conditions(apr_uri_t filter, int pathlen, apr_uri_t url)
-{
-    /* Compare the hostnames */
-    if(filter.hostname) {
-        if (!url.hostname) {
+static int uri_meets_conditions(const server_rec * const s,
+        const apr_uri_t filter, const int pathlen, const apr_uri_t url) {
+    (void) s;
+
+    /* Scheme, hostname port and local part. The filter URI and the
+     * URI we test may have the following shapes:
+     *   /<path>
+     *   <scheme>[:://<hostname>[:<port>][/<path>]]
+     * That is, if there is no scheme then there must be only the path,
+     * and we check only the path; if there is a scheme, we check the
+     * scheme for equality, and then if present we match the hostname,
+     * and then if present match the port, and finally the path if any.
+     *
+     * Note that this means that "/<path>" only matches local paths,
+     * and to match proxied paths one *must* specify the scheme.
+     */
+
+    /* Is the filter is just for a local path or a proxy URI? */
+    if (!filter.scheme) {
+        if (url.scheme || url.hostname) {
             return 0;
         }
-        else if (strcasecmp(filter.hostname, url.hostname)) {
+    } else {
+        /* The URI scheme must be present and identical except for case. */
+        if (!url.scheme || strcasecmp(filter.scheme, url.scheme)) {
             return 0;
         }
-    }
 
-    /* Compare the schemes */
-    if(filter.scheme) {
-        if (!url.scheme) {
-            return 0;
-        }
-        else if (strcasecmp(filter.scheme, url.scheme)) {
-            return 0;
+        /* If the filter hostname is null or empty it matches any hostname,
+         * if it begins with a "*" it matches the _end_ of the URI hostname
+         * excluding the "*", if it begins with a "." it matches the _end_
+         * of the URI * hostname including the ".", otherwise it must match
+         * the URI hostname exactly. */
+
+        if (filter.hostname && filter.hostname[0]) {
+            if (filter.hostname[0] == '.') {
+                const size_t fhostlen = strlen(filter.hostname);
+                const size_t uhostlen = url.hostname ? strlen(url.hostname) : 0;
+
+                if (fhostlen > uhostlen || strcasecmp(filter.hostname,
+                        url.hostname + uhostlen - fhostlen)) {
+                    return 0;
+                }
+            } else if (filter.hostname[0] == '*') {
+                const size_t fhostlen = strlen(filter.hostname + 1);
+                const size_t uhostlen = url.hostname ? strlen(url.hostname) : 0;
+
+                if (fhostlen > uhostlen || strcasecmp(filter.hostname + 1,
+                        url.hostname + uhostlen - fhostlen)) {
+                    return 0;
+                }
+            } else if (!url.hostname || strcasecmp(filter.hostname, url.hostname)) {
+                return 0;
+            }
         }
-    }
 
-    /* Compare the ports */
-    if(filter.port_str) {
-        if (url.port_str && filter.port != url.port) {
-            return 0;
-        }
-        /* NOTE:  ap_port_of_scheme will return 0 if given NULL input */
-        else if (filter.port != apr_uri_port_of_scheme(url.scheme)) {
-            return 0;
-        }
-    }
-    else if(url.port_str && filter.scheme) {
-        if (apr_uri_port_of_scheme(filter.scheme) == url.port) {
-            return 0;
+        /* If the filter port is empty it matches any URL port.
+         * If the filter or URL port are missing, or the URL port is
+         * empty, they default to the port for their scheme. */
+
+        if (!(filter.port_str && !filter.port_str[0])) {
+            /* NOTE:  ap_port_of_scheme will return 0 if given NULL input */
+            const unsigned fport = filter.port_str ? filter.port
+                    : apr_uri_port_of_scheme(filter.scheme);
+            const unsigned uport = (url.port_str && url.port_str[0])
+                    ? url.port : apr_uri_port_of_scheme(url.scheme);
+
+            if (fport != uport) {
+                return 0;
+            }
         }
     }
 
@@ -71,8 +108,7 @@
     if (!url.path) {
         if (*filter.path == '/' && pathlen == 1) {
             return 1;
-        }
-        else {
+        } else {
             return 0;
         }
     }
@@ -94,7 +130,7 @@
     for (i = 0; i < conf->cacheenable->nelts; i++) {
         struct cache_enable *ent =
                                 (struct cache_enable *)conf->cacheenable->elts;
-        if (uri_meets_conditions(ent[i].url, ent[i].pathlen, uri)) {
+        if (uri_meets_conditions(r->server,ent[i].url, ent[i].pathlen, uri)) {
             /* Fetch from global config and add to the list. */
             cache_provider *provider;
             provider = ap_lookup_provider(CACHE_PROVIDER_GROUP, ent[i].type,
@@ -131,7 +167,7 @@
     for (i = 0; i < conf->cachedisable->nelts; i++) {
         struct cache_disable *ent =
                                (struct cache_disable *)conf->cachedisable->elts;
-        if (uri_meets_conditions(ent[i].url, ent[i].pathlen, uri)) {
+        if (uri_meets_conditions(r->server,ent[i].url, ent[i].pathlen, uri)) {
             /* Stop searching now. */
             return NULL;
         }



Mime
View raw message