You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by je...@apache.org on 2005/02/02 08:10:22 UTC

svn commit: r149492 - in httpd/httpd/trunk: CHANGES docs/manual/mod/mod_cache.xml modules/cache/mod_cache.c modules/cache/mod_cache.h

Author: jerenkrantz
Date: Tue Feb  1 23:10:20 2005
New Revision: 149492

URL: http://svn.apache.org/viewcvs?view=rev&rev=149492
Log:
Add CacheStorePrivate, CacheStoreNoStore, and clarify CacheIgnoreCacheControl.

* docs/manual/mod/mod_cache.xml: Update documentation for
  CacheIgnoreCacheControl and add documentation for two new directives.
* modules/cache/mod_cache.c
  (cache_url_handler): Honor 'Cache-Control: no-cache' request header.
  (cache_save_filter): Only honor no-store or private when their respective
                       directives are Off (which is the default).
  rest of file: add in standard configuration syntax stuff...
* modules/cache/mod_cache.h: Minor formatting tweak and add new fields.

Suggested by: Pier Fumagalli

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

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/CHANGES?view=diff&r1=149491&r2=149492
==============================================================================
--- httpd/httpd/trunk/CHANGES (original)
+++ httpd/httpd/trunk/CHANGES Tue Feb  1 23:10:20 2005
@@ -2,6 +2,9 @@
 
   [Remove entries to the current 2.0 section below, when backported]
 
+  *) mod_cache: Add CacheStorePrivate and CacheStoreNoStore directive.
+     [Justin Erenkrantz]
+
   *) Remove compiled-in upper limit on LimitRequestFieldSize.
      [Bill Stoddard]
 

Modified: httpd/httpd/trunk/docs/manual/mod/mod_cache.xml
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/docs/manual/mod/mod_cache.xml?view=diff&r1=149491&r2=149492
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_cache.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_cache.xml Tue Feb  1 23:10:20 2005
@@ -235,24 +235,33 @@
 
 <directivesynopsis>
 <name>CacheIgnoreCacheControl</name>
-<description>Ignore the fact that the client requested the content not be
-cached.</description>
+<description>Ignore request to not serve cached content to client</description>
 <syntax>CacheIgnoreCacheControl On|Off</syntax>
 <default>CacheIgnoreCacheControl Off</default>
 <contextlist><context>server config</context><context>virtual host</context>
 </contextlist>
 
 <usage>
-    <p>Ordinarily, documents with no-cache or no-store header values will not be stored in the cache.
-    The <directive>CacheIgnoreCacheControl</directive> directive allows this behavior to be overridden.
-    <directive>CacheIgnoreCacheControl</directive> On tells the server to attempt to cache the document
-    even if it contains no-cache or no-store header values. Documents requiring authorization will
-    <em>never</em> be cached.</p>
+    <p>Ordinarily, requests containing a Cache-Control: no-cache or
+    Pragma: no-cache header value will not be served from the cache.  The
+    <directive>CacheIgnoreCacheControl</directive> directive allows this
+    behavior to be overridden.  <directive>CacheIgnoreCacheControl</directive>
+    On tells the server to attempt to serve the resource from the cache even
+    if the request contains no-cache header values.  Resources requiring
+    authorization will <em>never</em> be cached.</p>
 
     <example>
       CacheIgnoreCacheControl On
     </example>
+
+    <note type="warning"><title>Warning:</title>
+       This directive will allow serving from the cache even if the client has
+       requested that the document not be served from the cache.  This might
+       result in stale content being served.
+    </note>
 </usage>
+<seealso><directive module="mod_cache">CacheStorePrivate</directive></seealso>
+<seealso><directive module="mod_cache">CacheStoreNoStore</directive></seealso>
 </directivesynopsis>
 
 <directivesynopsis>
@@ -343,4 +352,66 @@
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>CacheStorePrivate</name>
+<description>Attempt to cache responses that the server has marked as private</description>
+<syntax>CacheStorePrivate On|Off</syntax>
+<default>CacheStorePrivate Off</default>
+<contextlist><context>server config</context><context>virtual host</context>
+</contextlist>
+
+<usage>
+    <p>Ordinarily, responses with Cache-Control: private header values will not
+       be stored in the cache.  The <directive>CacheStorePrivate</directive>
+       directive allows this behavior to be overridden.
+       <directive>CacheStorePrivate</directive> On
+       tells the server to attempt to cache the resource even if it contains
+       private header values.  Resources requiring authorization will
+       <em>never</em> be cached.</p>
+
+    <example>
+      CacheStorePrivate On
+    </example>
+
+    <note type="warning"><title>Warning:</title>
+       This directive will allow caching even if the upstream server has
+       requested that the resource not be cached.  This directive is only
+       ideal for a 'private' cache.
+    </note>
+</usage>
+<seealso><directive module="mod_cache">CacheIgnoreCacheControl</directive></seealso>
+<seealso><directive module="mod_cache">CacheStoreNoStore</directive></seealso>
+</directivesynopsis>
+
+<directivesynopsis>
+<name>CacheStoreNoStore</name>
+<description>Attempt to cache requests or responses that have been marked as no-store.</description>
+<syntax>CacheStoreNoStore On|Off</syntax>
+<default>CacheStoreNoStore Off</default>
+<contextlist><context>server config</context><context>virtual host</context>
+</contextlist>
+
+<usage>
+    <p>Ordinarily, requests or responses with Cache-Control: no-store header
+       values will not be stored in the cache.  The
+       <directive>CacheStoreNoCache</directive> directive allows this
+       behavior to be overridden.  <directive>CacheStoreNoCache</directive> On
+       tells the server to attempt to cache the resource even if it contains
+       no-store header values.  Resources requiring authorization will
+       <em>never</em> be cached.</p>
+
+    <example>
+      CacheStoreNoStore On
+    </example>
+
+    <note type="warning"><title>Warning:</title>
+       As described in RFC 2616, the no-store directive is intended to
+       "prevent the inadvertent release or retention of sensitive information
+       (for example, on backup tapes)."  Enabling this option could store
+       sensitive information in the cache.  You are hereby warned.
+    </note>
+</usage>
+<seealso><directive module="mod_cache">CacheIgnoreCacheControl</directive></seealso>
+<seealso><directive module="mod_cache">CacheStorePrivate</directive></seealso>
+</directivesynopsis>
 </modulesynopsis>

Modified: httpd/httpd/trunk/modules/cache/mod_cache.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/cache/mod_cache.c?view=diff&r1=149491&r2=149492
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_cache.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_cache.c Tue Feb  1 23:10:20 2005
@@ -47,7 +47,7 @@
 static int cache_url_handler(request_rec *r, int lookup)
 {
     apr_status_t rv;
-    const char *pragma, *auth;
+    const char *auth;
     apr_uri_t uri;
     char *url;
     char *path;
@@ -93,21 +93,23 @@
      */
 
     /* find certain cache controlling headers */
-    pragma = apr_table_get(r->headers_in, "Pragma");
     auth = apr_table_get(r->headers_in, "Authorization");
 
     /* first things first - does the request allow us to return
      * cached information at all? If not, just decline the request.
      *
      * Note that there is a big difference between not being allowed
-     * to cache a request (no-store) and not being allowed to return
+     * to cache a response (no-store) and not being allowed to return
      * a cached request without revalidation (max-age=0).
      *
-     * Caching is forbidden under the following circumstances:
+     * Serving from a cache is forbidden under the following circumstances:
      *
-     * - RFC2616 14.9.2 Cache-Control: no-store
+     * - RFC2616 14.9.1 Cache-Control: no-cache
      * - Pragma: no-cache
      * - Any requests requiring authorization.
+     *
+     * Updating a cache is forbidden under the following circumstances:
+     * - RFC2616 14.9.2 Cache-Control: no-store
      */
     if (conf->ignorecachecontrol == 1 && auth == NULL) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
@@ -115,8 +117,14 @@
                      "%s, but we know better and are ignoring it", url);
     }
     else {
-        if (ap_cache_liststr(NULL, pragma, "no-cache", NULL) ||
-            auth != NULL) {
+        const char *pragma, *cc_in;
+
+        pragma = apr_table_get(r->headers_in, "Pragma");
+        cc_in = apr_table_get(r->headers_in, "Cache-Control");
+
+        if (auth != NULL ||
+            ap_cache_liststr(NULL, pragma, "no-cache", NULL) ||
+            ap_cache_liststr(NULL, cc_in, "no-cache", NULL)) {
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                          "cache: no-cache or authorization forbids caching "
                          "of %s", url);
@@ -263,10 +271,16 @@
     char *reason;
     apr_pool_t *p;
 
-    /* check first whether running this filter has any point or not */
-    /* If the user has Cache-Control: no-store from RFC 2616, don't store! */
+    conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
+                                                      &cache_module);
+
+    /* If the request has Cache-Control: no-store from RFC 2616, don't store
+     * unless CacheStoreNoStore is active.
+     */
     cc_in = apr_table_get(r->headers_in, "Cache-Control");
-    if (r->no_cache || ap_cache_liststr(NULL, cc_in, "no-store", NULL)) {
+    if (r->no_cache ||
+        (!conf->store_nostore &&
+         ap_cache_liststr(NULL, cc_in, "no-store", NULL))) {
         ap_remove_output_filter(f);
         return ap_pass_brigade(f->next, in);
     }
@@ -349,7 +363,6 @@
         lastmod = APR_DATE_BAD;
     }
 
-    conf = (cache_server_conf *) ap_get_module_config(r->server->module_config, &cache_module);
     /* read the etag and cache-control from the entity */
     etag = apr_table_get(r->err_headers_out, "Etag");
     if (etag == NULL) {
@@ -410,14 +423,16 @@
         /* HEAD requests */
         reason = "HTTP HEAD request";
     }
-    else if (ap_cache_liststr(NULL, cc_out, "no-store", NULL)) {
+    else if (!conf->store_nostore &&
+             ap_cache_liststr(NULL, cc_out, "no-store", NULL)) {
         /* RFC2616 14.9.2 Cache-Control: no-store response
          * indicating do not cache, or stop now if you are
          * trying to cache it */
         reason = "Cache-Control: no-store present";
     }
-    else if (ap_cache_liststr(NULL, cc_out, "private", NULL)) {
-        /* RFC2616 14.9.1 Cache-Control: private
+    else if (!conf->store_private &&
+             ap_cache_liststr(NULL, cc_out, "private", NULL)) {
+        /* RFC2616 14.9.1 Cache-Control: private response
          * this object is marked for this user's eyes only. Behave
          * as a tunnel.
          */
@@ -705,7 +720,11 @@
     ps->no_last_mod_ignore_set = 0;
     ps->no_last_mod_ignore = 0;
     ps->ignorecachecontrol = 0;
-    ps->ignorecachecontrol_set = 0 ;
+    ps->ignorecachecontrol_set = 0;
+    ps->store_private = 0;
+    ps->store_private_set = 0;
+    ps->store_nostore = 0;
+    ps->store_nostore_set = 0;
     /* array of headers that should not be stored in cache */
     ps->ignore_headers = apr_array_make(p, 10, sizeof(char *));
     ps->ignore_headers_set = CACHE_IGNORE_HEADERS_UNSET;
@@ -742,6 +761,14 @@
         (overrides->ignorecachecontrol_set == 0)
         ? base->ignorecachecontrol
         : overrides->ignorecachecontrol;
+    ps->store_private  =
+        (overrides->store_private_set == 0)
+        ? base->store_private
+        : overrides->store_private;
+    ps->store_nostore  =
+        (overrides->store_nostore_set == 0)
+        ? base->store_nostore
+        : overrides->store_nostore;
     ps->ignore_headers =
         (overrides->ignore_headers_set == CACHE_IGNORE_HEADERS_UNSET)
         ? base->ignore_headers
@@ -775,6 +802,32 @@
     return NULL;
 }
 
+static const char *set_cache_store_private(cmd_parms *parms, void *dummy,
+                                           int flag)
+{
+    cache_server_conf *conf;
+
+    conf =
+        (cache_server_conf *)ap_get_module_config(parms->server->module_config,
+                                                  &cache_module);
+    conf->store_private = flag;
+    conf->store_private_set = 1;
+    return NULL;
+}
+
+static const char *set_cache_store_nostore(cmd_parms *parms, void *dummy,
+                                           int flag)
+{
+    cache_server_conf *conf;
+
+    conf =
+        (cache_server_conf *)ap_get_module_config(parms->server->module_config,
+                                                  &cache_module);
+    conf->store_nostore = flag;
+    conf->store_nostore_set = 1;
+    return NULL;
+}
+
 static const char *add_ignore_header(cmd_parms *parms, void *dummy,
                                      const char *header)
 {
@@ -909,15 +962,20 @@
                   "A partial URL prefix below which caching is disabled"),
     AP_INIT_TAKE1("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF,
                   "The maximum time in seconds to cache a document"),
-     AP_INIT_TAKE1("CacheDefaultExpire", set_cache_defex, NULL, RSRC_CONF,
-                   "The default time in seconds to cache a document"),
-     AP_INIT_FLAG("CacheIgnoreNoLastMod", set_cache_ignore_no_last_mod, NULL, 
-                  RSRC_CONF, 
-                  "Ignore Responses where there is no Last Modified Header"),
-     AP_INIT_FLAG("CacheIgnoreCacheControl", set_cache_ignore_cachecontrol,
-                  NULL, 
-                  RSRC_CONF, 
-                  "Ignore requests from the client for uncached content"),
+    AP_INIT_TAKE1("CacheDefaultExpire", set_cache_defex, NULL, RSRC_CONF,
+                  "The default time in seconds to cache a document"),
+    AP_INIT_FLAG("CacheIgnoreNoLastMod", set_cache_ignore_no_last_mod, NULL,
+                 RSRC_CONF,
+                 "Ignore Responses where there is no Last Modified Header"),
+    AP_INIT_FLAG("CacheIgnoreCacheControl", set_cache_ignore_cachecontrol,
+                 NULL, RSRC_CONF,
+                 "Ignore requests from the client for uncached content"),
+    AP_INIT_FLAG("CacheStorePrivate", set_cache_store_private,
+                 NULL, RSRC_CONF,
+                 "Ignore 'Cache-Control: private' and store private content"),
+    AP_INIT_FLAG("CacheStoreNoStore", set_cache_store_nostore,
+                 NULL, RSRC_CONF,
+                 "Ignore 'Cache-Control: no-store' and store sensitive content"),
     AP_INIT_ITERATE("CacheIgnoreHeaders", add_ignore_header, NULL, RSRC_CONF,
                     "A space separated list of headers that should not be "
                     "stored by the cache"),

Modified: httpd/httpd/trunk/modules/cache/mod_cache.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/cache/mod_cache.h?view=diff&r1=149491&r2=149492
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_cache.h (original)
+++ httpd/httpd/trunk/modules/cache/mod_cache.h Tue Feb  1 23:10:20 2005
@@ -115,13 +115,16 @@
 
 /* static information about the local cache */
 typedef struct {
-    apr_array_header_t *cacheenable;	/* URLs to cache */
-    apr_array_header_t *cachedisable;	/* URLs not to cache */
-    apr_time_t maxex;			/* Maximum time to keep cached files in msecs */
+    apr_array_header_t *cacheenable;    /* URLs to cache */
+    apr_array_header_t *cachedisable;   /* URLs not to cache */
+    /* Maximum time to keep cached files in msecs */
+    apr_time_t maxex;
     int maxex_set;
-    apr_time_t defex;           /* default time to keep cached file in msecs */
+    /* default time to keep cached file in msecs */
+    apr_time_t defex;
     int defex_set;
-    double factor;              /* factor for estimating expires date */
+    /* factor for estimating expires date */
+    double factor;
     int factor_set;
     /** ignore the last-modified header when deciding to cache this request */
     int no_last_mod_ignore_set;
@@ -129,6 +132,12 @@
     /** ignore client's requests for uncached responses */
     int ignorecachecontrol;
     int ignorecachecontrol_set;
+    /** ignore Cache-Control: private header from server */
+    int store_private;
+    int store_private_set;
+    /** ignore Cache-Control: no-store header from client or server */
+    int store_nostore;
+    int store_nostore_set;
     /** store the headers that should not be stored in the cache */
     apr_array_header_t *ignore_headers;
     /* flag if CacheIgnoreHeader has been set */
@@ -144,7 +153,7 @@
     char *content_type;
     char *etag;
     char *lastmods;         /* last modified of cache entity */
-    char *filename;   
+    char *filename;
     apr_time_t date;
     apr_time_t lastmod;
     char lastmod_str[APR_RFC822_DATE_LEN];