<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>
</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>
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;
*/
/* 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,
"%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);
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);
}
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) {
/* 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.
*/
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;
(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
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)
{
"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"),