mirror of
https://github.com/apache/httpd.git
synced 2025-11-05 05:30:39 +03:00
mod_cache: Check the request to determine whether we are allowed
to return cached content at all, and respect a "Cache-Control: no-cache" header from a client. Previously, "no-cache" would behave like "max-age=0". git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@992625 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
Changes with Apache 2.3.9
|
Changes with Apache 2.3.9
|
||||||
|
|
||||||
|
*) mod_cache: Check the request to determine whether we are allowed
|
||||||
|
to return cached content at all, and respect a "Cache-Control:
|
||||||
|
no-cache" header from a client. Previously, "no-cache" would
|
||||||
|
behave like "max-age=0". [Graham Leggett]
|
||||||
|
|
||||||
*) mod_cache: Use a proper filter context to hold filter data instead
|
*) mod_cache: Use a proper filter context to hold filter data instead
|
||||||
of misusing the per-request configuration. Fixes a segfault on trunk
|
of misusing the per-request configuration. Fixes a segfault on trunk
|
||||||
when the normal handler is used. [Graham Leggett]
|
when the normal handler is used. [Graham Leggett]
|
||||||
|
|||||||
5
modules/cache/cache_storage.c
vendored
5
modules/cache/cache_storage.c
vendored
@@ -203,6 +203,11 @@ int cache_select(request_rec *r)
|
|||||||
if (rv != APR_SUCCESS) {
|
if (rv != APR_SUCCESS) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ap_cache_check_allowed(r)) {
|
||||||
|
return DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
/* go through the cache types till we get a match */
|
/* go through the cache types till we get a match */
|
||||||
h = apr_palloc(r->pool, sizeof(cache_handle_t));
|
h = apr_palloc(r->pool, sizeof(cache_handle_t));
|
||||||
|
|
||||||
|
|||||||
70
modules/cache/cache_util.c
vendored
70
modules/cache/cache_util.c
vendored
@@ -380,6 +380,64 @@ CACHE_DECLARE(apr_status_t) ap_cache_remove_lock(cache_server_conf *conf,
|
|||||||
return apr_file_remove(lockname, r->pool);
|
return apr_file_remove(lockname, r->pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CACHE_DECLARE(int) ap_cache_check_allowed(request_rec *r) {
|
||||||
|
const char *cc_cresp, *cc_req;
|
||||||
|
const char *pragma;
|
||||||
|
cache_server_conf *conf =
|
||||||
|
(cache_server_conf *)ap_get_module_config(r->server->module_config,
|
||||||
|
&cache_module);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At this point, we may have data cached, but the request may have
|
||||||
|
* specified that cached data may not be used in a response.
|
||||||
|
*
|
||||||
|
* This is covered under RFC2616 section 14.9.4 (Cache Revalidation and
|
||||||
|
* Reload Controls).
|
||||||
|
*
|
||||||
|
* - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache, or Pragma:
|
||||||
|
* no-cache. The server MUST NOT use a cached copy when responding to such
|
||||||
|
* a request.
|
||||||
|
*
|
||||||
|
* - RFC2616 14.9.2 What May be Stored by Caches. If Cache-Control:
|
||||||
|
* no-store arrives, do not serve from the cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This value comes from the client's initial request. */
|
||||||
|
cc_req = apr_table_get(r->headers_in, "Cache-Control");
|
||||||
|
pragma = apr_table_get(r->headers_in, "Pragma");
|
||||||
|
|
||||||
|
if (ap_cache_liststr(NULL, pragma, "no-cache", NULL)
|
||||||
|
|| ap_cache_liststr(NULL, cc_req, "no-cache", NULL)) {
|
||||||
|
|
||||||
|
if (!conf->ignorecachecontrol) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
|
||||||
|
"Incoming request is asking for an uncached version of "
|
||||||
|
"%s, but we have been configured to ignore it and serve "
|
||||||
|
"cached content anyway", r->unparsed_uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap_cache_liststr(NULL, cc_req, "no-store", NULL)) {
|
||||||
|
|
||||||
|
if (!conf->ignorecachecontrol) {
|
||||||
|
/* We're not allowed to serve a cached copy */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
|
||||||
|
"Incoming request is asking for a no-store version of "
|
||||||
|
"%s, but we have been configured to ignore it and serve "
|
||||||
|
"cached content anyway", r->unparsed_uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
|
CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
|
||||||
request_rec *r)
|
request_rec *r)
|
||||||
{
|
{
|
||||||
@@ -402,10 +460,11 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
|
|||||||
* We now want to check if our cached data is still fresh. This depends
|
* We now want to check if our cached data is still fresh. This depends
|
||||||
* on a few things, in this order:
|
* on a few things, in this order:
|
||||||
*
|
*
|
||||||
* - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache. no-cache in
|
* - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache. no-cache
|
||||||
* either the request or the cached response means that we must
|
* in either the request or the cached response means that we must
|
||||||
* revalidate the request unconditionally, overriding any expiration
|
* perform the request unconditionally, and ignore cached content. We
|
||||||
* mechanism. It's equivalent to max-age=0,must-revalidate.
|
* should never reach here, but if we do, mark the content as stale,
|
||||||
|
* as this is the best we can do.
|
||||||
*
|
*
|
||||||
* - RFC2616 14.32 Pragma: no-cache This is treated the same as
|
* - RFC2616 14.32 Pragma: no-cache This is treated the same as
|
||||||
* Cache-Control: no-cache.
|
* Cache-Control: no-cache.
|
||||||
@@ -445,7 +504,8 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h,
|
|||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
|
ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
|
||||||
"Incoming request is asking for a uncached version of "
|
"Incoming request is asking for a uncached version of "
|
||||||
"%s, but we know better and are ignoring it",
|
"%s, but we have been configured to ignore it and "
|
||||||
|
"serve a cached response anyway",
|
||||||
r->unparsed_uri);
|
r->unparsed_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
modules/cache/mod_cache.h
vendored
9
modules/cache/mod_cache.h
vendored
@@ -287,6 +287,15 @@ CACHE_DECLARE(apr_time_t) ap_cache_current_age(cache_info *info, const apr_time_
|
|||||||
*/
|
*/
|
||||||
CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h, request_rec *r);
|
CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h, request_rec *r);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the whether the request allows a cached object to be served as per RFC2616
|
||||||
|
* section 14.9.4 (Cache Revalidation and Reload Controls)
|
||||||
|
* @param h cache_handle_t
|
||||||
|
* @param r request_rec
|
||||||
|
* @return 0 ==> cache object may not be served, 1 ==> cache object may be served
|
||||||
|
*/
|
||||||
|
CACHE_DECLARE(int) ap_cache_check_allowed(request_rec *r);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try obtain a cache wide lock on the given cache key.
|
* Try obtain a cache wide lock on the given cache key.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user