summaryrefslogtreecommitdiff
path: root/modules/cache/mod_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/cache/mod_cache.c')
-rw-r--r--modules/cache/mod_cache.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
index 162773f9..8aeb3f73 100644
--- a/modules/cache/mod_cache.c
+++ b/modules/cache/mod_cache.c
@@ -585,6 +585,52 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
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;
+
+ /* let someone else attempt to cache */
+ ap_cache_remove_lock(conf, 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,