1
0
mirror of https://github.com/apache/httpd.git synced 2026-01-06 09:01:14 +03:00

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


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@149492 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Justin Erenkrantz
2005-02-02 07:10:20 +00:00
parent de2792bc7d
commit 4743f301f2
4 changed files with 178 additions and 37 deletions

View File

@@ -2,6 +2,9 @@ Changes with Apache 2.1.3
[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]

View File

@@ -235,24 +235,33 @@ header.</description>
<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 @@ LastModified date.</description>
</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>

View File

@@ -47,7 +47,7 @@ static ap_filter_rec_t *cache_out_filter_handle;
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 @@ static int cache_url_handler(request_rec *r, int lookup)
*/
/* 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 @@ static int cache_url_handler(request_rec *r, int lookup)
"%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 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
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 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *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) {
@@ -410,14 +423,16 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
/* 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 @@ static void * create_cache_config(apr_pool_t *p, server_rec *s)
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 @@ static void * merge_cache_config(apr_pool_t *p, void *basev, void *overridesv)
(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 @@ static const char *set_cache_ignore_cachecontrol(cmd_parms *parms,
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 @@ static const command_rec cache_cmds[] =
"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"),

View File

@@ -115,13 +115,16 @@ struct cache_disable {
/* 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 @@ typedef struct {
/** 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 @@ struct cache_info {
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];