]> granicus.if.org Git - apache/commitdiff
mod_cache: Honour Cache-Control: no-store in a request.
authorGraham Leggett <minfrin@apache.org>
Sun, 5 May 2013 01:12:48 +0000 (01:12 +0000)
committerGraham Leggett <minfrin@apache.org>
Sun, 5 May 2013 01:12:48 +0000 (01:12 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1479222 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/cache/cache_storage.c
modules/cache/cache_util.c
modules/cache/cache_util.h
modules/cache/mod_cache.c

diff --git a/CHANGES b/CHANGES
index 43817e9e583fe13509cd8a6c958fc2a5a636fca0..2023e14d8189bf91c4dcea0665fb501d84b652d6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_cache: Honour Cache-Control: no-store in a request. [Graham Leggett]
+
   *) mod_cache: RFC2616 14.9.3 The s-maxage directive also implies the
      semantics of the proxy-revalidate directive. [Graham Leggett]
 
index 3d9c3d0b3cf6bd481ec72962eb7b0d3ec500c440..52c371a078c76b14a490a9fa0c2ef0ec8315c3ff 100644 (file)
@@ -199,6 +199,13 @@ int cache_select(cache_request_rec *cache, request_rec *r)
         return DECLINED;
     }
 
+    /* if no-cache, we can't serve from the cache, but we may store to the
+     * cache.
+     */
+    if (!ap_cache_check_no_cache(cache, r)) {
+        return DECLINED;
+    }
+
     if (!cache->key) {
         rv = cache_generate_key(r, r->pool, &cache->key);
         if (rv != APR_SUCCESS) {
@@ -206,10 +213,6 @@ int cache_select(cache_request_rec *cache, request_rec *r)
         }
     }
 
-    if (!ap_cache_check_allowed(cache, r)) {
-        return DECLINED;
-    }
-
     /* go through the cache types till we get a match */
     h = apr_palloc(r->pool, sizeof(cache_handle_t));
 
index f85b1254232314bc35f1b5e59b85b32d67b50e3e..7b7fb45c23af1fb48dd9b2774e9e04c32343b186 100644 (file)
@@ -410,9 +410,9 @@ apr_status_t cache_remove_lock(cache_server_conf *conf,
     return apr_file_remove(lockname, r->pool);
 }
 
-CACHE_DECLARE(int) ap_cache_check_allowed(cache_request_rec *cache, request_rec *r) {
-    const char *cc_req;
-    const char *pragma;
+int ap_cache_check_no_cache(cache_request_rec *cache, request_rec *r)
+{
+
     cache_server_conf *conf =
       (cache_server_conf *)ap_get_module_config(r->server->module_config,
                                                 &cache_module);
@@ -427,16 +427,15 @@ CACHE_DECLARE(int) ap_cache_check_allowed(cache_request_rec *cache, request_rec
      * - 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");
-
-    ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
+    if (!cache->control_in.parsed) {
+        const char *cc_req = cache_table_getm(r->pool, r->headers_in,
+                "Cache-Control");
+        const char *pragma = cache_table_getm(r->pool, r->headers_in, "Pragma");
+        ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
+    }
 
     if (cache->control_in.no_cache) {
 
@@ -451,6 +450,32 @@ CACHE_DECLARE(int) ap_cache_check_allowed(cache_request_rec *cache, request_rec
         }
     }
 
+    return 1;
+}
+
+int ap_cache_check_no_store(cache_request_rec *cache, request_rec *r)
+{
+
+    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.
+     *
+     * - RFC2616 14.9.2 What May be Stored by Caches. If Cache-Control:
+     * no-store arrives, do not serve from or store to the cache.
+     */
+
+    /* This value comes from the client's initial request. */
+    if (!cache->control_in.parsed) {
+        const char *cc_req = cache_table_getm(r->pool, r->headers_in,
+                "Cache-Control");
+        const char *pragma = cache_table_getm(r->pool, r->headers_in, "Pragma");
+        ap_cache_control(r, &cache->control_in, cc_req, pragma, r->headers_in);
+    }
+
     if (cache->control_in.no_store) {
 
         if (!conf->ignorecachecontrol) {
@@ -468,7 +493,6 @@ CACHE_DECLARE(int) ap_cache_check_allowed(cache_request_rec *cache, request_rec
     return 1;
 }
 
-
 int cache_check_freshness(cache_handle_t *h, cache_request_rec *cache,
         request_rec *r)
 {
index c75f20812a25318967c828dd814179a16c446e05..37c3ac3242de0c90e318b4870c7308879ac689e7 100644 (file)
@@ -239,7 +239,16 @@ typedef struct {
  * @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(cache_request_rec *cache, request_rec *r);
+int ap_cache_check_no_cache(cache_request_rec *cache, request_rec *r);
+
+/**
+ * Check the whether the request allows a cached object to be stored as per RFC2616
+ * section 14.9.2 (What May be Stored by Caches)
+ * @param cache cache_request_rec
+ * @param r request_rec
+ * @return 0 ==> cache object may not be served, 1 ==> cache object may be served
+ */
+int ap_cache_check_no_store(cache_request_rec *cache, request_rec *r);
 
 /**
  * Check the freshness of the cache object per RFC2616 section 13.2 (Expiration Model)
index 63378dfdc8e63165540ce7e84278708b9547f093..34d664c73e3888643395ce94e3a545955c26d3db 100644 (file)
@@ -102,6 +102,9 @@ static int cache_quick_handler(request_rec *r, int lookup)
     /*
      * Are we allowed to serve cached info at all?
      */
+    if (!ap_cache_check_no_store(cache, r)) {
+        return DECLINED;
+    }
 
     /* find certain cache controlling headers */
     auth = apr_table_get(r->headers_in, "Authorization");
@@ -401,6 +404,13 @@ static int cache_handler(request_rec *r)
     /* save away the possible providers */
     cache->providers = providers;
 
+    /*
+     * Are we allowed to serve cached info at all?
+     */
+    if (!ap_cache_check_no_store(cache, r)) {
+        return DECLINED;
+    }
+
     /* Are we PUT/POST/DELETE? If so, prepare to invalidate the cached entities.
      */
     switch (r->method_number) {