From: Ruediger Pluem Date: Tue, 8 Feb 2011 10:16:05 +0000 (+0000) Subject: Merge r1001884 from trunk: X-Git-Tag: 2.2.18~154 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6f9c3f5b1b309022a7cc65b19998f4a2e4056a9;p=thirdparty%2Fapache%2Fhttpd.git Merge r1001884 from trunk: 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 Submitted by: minfrin Reviewed by: minfrin, jim, covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1068313 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 1703fad57f1..81e4d597a0a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.18 + *) 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_dav: Send 501 error if unknown Content-* header is received for a PUT request (RFC 2616 9.6). PR 42978. [Stefan Fritsch] diff --git a/STATUS b/STATUS index b03427fa299..5bf71144e29 100644 --- a/STATUS +++ b/STATUS @@ -90,13 +90,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * 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 - Trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1001884 - 2.2.x patch: http://people.apache.org/~minfrin/httpd-mod_cache-304-fix-2.patch - +1: minfrin, jim, covener PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c index 162773f99e5..8aeb3f73ca7 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,