From: Ruediger Pluem Date: Wed, 29 Dec 2010 10:21:13 +0000 (+0000) Subject: Merge r992625 from trunk: X-Git-Tag: 2.2.18~210 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0e00493a860a696103dbcc5707ccd9fb948a7ac;p=thirdparty%2Fapache%2Fhttpd.git Merge r992625 from trunk: 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". Submitted by: minfrin Reviewed by: minfrin, jim, covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1053600 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 6c62e206020..ad5d4265fb6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.18 + *) 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_mem_cache: Add a debug msg when a streaming response exceeds MCacheMaxStreamingBuffer, since mod_cache will follow up with a scary 'memory allocation failed' debug message. PR 49604. [Eric Covener] diff --git a/STATUS b/STATUS index fd789dd50a2..e3d1d60210c 100644 --- a/STATUS +++ b/STATUS @@ -89,15 +89,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * 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". - PR49200 - Trunk patch: http://svn.apache.org/viewvc?view=revision&revision=992625 - 2.2.x patch: trunk patch works - +1: minfrin, jim - +1 covener (needs r996311 MMN bump) PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index ba1ca0bfe6a..3658fb73fa3 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -140,6 +140,7 @@ * and conditional cmdtype member of piped_log struct * 20051115.24 (2.2.15) Add forward member to proxy_conn_rec * 20051115.25 (2.2.17) Add errstatuses member to proxy_balancer + * 20051115.26 (2.2.18) Add ap_cache_check_allowed() */ #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ @@ -147,7 +148,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20051115 #endif -#define MODULE_MAGIC_NUMBER_MINOR 25 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 26 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/modules/cache/cache_storage.c b/modules/cache/cache_storage.c index f87f9c9ddb6..c9d362719d7 100644 --- a/modules/cache/cache_storage.c +++ b/modules/cache/cache_storage.c @@ -193,6 +193,11 @@ int cache_select(request_rec *r) if (rv != APR_SUCCESS) { return rv; } + + if (!ap_cache_check_allowed(r)) { + return DECLINED; + } + /* go through the cache types till we get a match */ h = apr_palloc(r->pool, sizeof(cache_handle_t)); diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c index cb3d56537d6..14c1165e0b6 100644 --- a/modules/cache/cache_util.c +++ b/modules/cache/cache_util.c @@ -338,6 +338,64 @@ CACHE_DECLARE(apr_status_t) ap_cache_remove_lock(cache_server_conf *conf, return apr_file_remove(lockname, r->pool); } +CACHE_DECLARE(int) ap_cache_check_allowed(request_rec *r) { + const char *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, request_rec *r) { @@ -360,10 +418,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 * on a few things, in this order: * - * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache. no-cache in - * either the request or the cached response means that we must - * revalidate the request unconditionally, overriding any expiration - * mechanism. It's equivalent to max-age=0,must-revalidate. + * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache. no-cache + * in either the request or the cached response means that we must + * perform the request unconditionally, and ignore cached content. We + * 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 * Cache-Control: no-cache. @@ -403,7 +462,8 @@ CACHE_DECLARE(int) ap_cache_check_freshness(cache_handle_t *h, ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, "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); } diff --git a/modules/cache/mod_cache.h b/modules/cache/mod_cache.h index eca42c01f06..e20fa72e9c4 100644 --- a/modules/cache/mod_cache.h +++ b/modules/cache/mod_cache.h @@ -270,6 +270,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); +/** + * 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. *