httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From minf...@apache.org
Subject svn commit: r1001884 - in /httpd/httpd/trunk: CHANGES modules/cache/mod_cache.c
Date Mon, 27 Sep 2010 19:28:40 GMT
Author: minfrin
Date: Mon Sep 27 19:28:40 2010
New Revision: 1001884

URL: http://svn.apache.org/viewvc?rev=1001884&view=rev
Log:
mod_cache: Make sure that we never allow a 304 Not Modified response
that we asked for to leak to the client should the 304 response be
uncacheable. PR45341

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/modules/cache/mod_cache.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1001884&r1=1001883&r2=1001884&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Mon Sep 27 19:28:40 2010
@@ -2,6 +2,10 @@
 
 Changes with Apache 2.3.9
 
+  *) mod_cache: Make sure that we never allow a 304 Not Modified response
+     that we asked for to leak to the client should the 304 response be
+     uncacheable. PR45341 [Graham Leggett]
+
   *) mod_cache: Add the cache_status hook to register the final cache
      decision hit/miss/revalidate. Add optional support for an X-Cache
      and/or an X-Cache-Detail header to add the cache status to the

Modified: httpd/httpd/trunk/modules/cache/mod_cache.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/mod_cache.c?rev=1001884&r1=1001883&r2=1001884&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/cache/mod_cache.c (original)
+++ httpd/httpd/trunk/modules/cache/mod_cache.c Mon Sep 27 19:28:40 2010
@@ -904,6 +904,62 @@ static int cache_save_filter(ap_filter_t
         reason = "r->no_cache present";
     }
 
+    /* Hold the phone. Some servers might allow us to cache a 2xx, but
+     * then make their 304 responses non cacheable. This leaves us in a
+     * sticky position. If the 304 is in answer to our own conditional
+     * request, we cannot send this 304 back to the client because the
+     * client isn't expecting it. Instead, our only option is to respect
+     * the answer to the question we asked (has it changed, answer was
+     * no) and return the cached item to the client, and then respect
+     * the uncacheable nature of this 304 by allowing the remove_url
+     * filter to kick in and remove the cached entity.
+     */
+    if (reason && r->status == HTTP_NOT_MODIFIED &&
+             cache->stale_handle) {
+        apr_bucket_brigade *bb;
+        apr_bucket *bkt;
+        int status;
+
+        cache->handle = cache->stale_handle;
+        info = &cache->handle->cache_obj->info;
+
+        /* Load in the saved status and clear the status line. */
+        r->status = info->status;
+        r->status_line = NULL;
+
+        bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+
+        r->headers_in = cache->stale_headers;
+        status = ap_meets_conditions(r);
+        if (status != OK) {
+            r->status = status;
+
+            bkt = apr_bucket_flush_create(bb->bucket_alloc);
+            APR_BRIGADE_INSERT_TAIL(bb, bkt);
+        }
+        else {
+            cache->provider->recall_body(cache->handle, r->pool, bb);
+        }
+
+        cache->block_response = 1;
+
+        /* we've got a cache conditional hit! tell anyone who cares */
+        cache_run_cache_status(
+                cache->handle,
+                r,
+                AP_CACHE_REVALIDATE,
+                apr_psprintf(
+                        r->pool,
+                        "conditional cache hit: 304 was uncacheable though (%s); entity removed",
+                        reason));
+
+        /* let someone else attempt to cache */
+        cache_remove_lock(conf, cache, r, cache->handle ?
+                (char *)cache->handle->cache_obj->key : NULL, NULL);
+
+        return ap_pass_brigade(f->next, bb);
+    }
+
     if (reason) {
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                      "cache: %s not cached. Reason: %s", r->unparsed_uri,



Mime
View raw message