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.c89
1 files changed, 50 insertions, 39 deletions
diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
index 20360553..cd839ed7 100644
--- a/modules/cache/mod_cache.c
+++ b/modules/cache/mod_cache.c
@@ -36,6 +36,22 @@ static ap_filter_rec_t *cache_out_subreq_filter_handle;
static ap_filter_rec_t *cache_remove_url_filter_handle;
static ap_filter_rec_t *cache_invalidate_filter_handle;
+/**
+ * Entity headers' names
+ */
+static const char *MOD_CACHE_ENTITY_HEADERS[] = {
+ "Allow",
+ "Content-Encoding",
+ "Content-Language",
+ "Content-Length",
+ "Content-Location",
+ "Content-MD5",
+ "Content-Range",
+ "Content-Type",
+ "Last-Modified",
+ NULL
+};
+
/*
* CACHE handler
* -------------
@@ -697,7 +713,7 @@ static int cache_save_store(ap_filter_t *f, apr_bucket_brigade *in,
rv = cache->provider->store_body(cache->handle, f->r, in, cache->out);
if (rv != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, f->r, APLOGNO(00765)
- "cache: Cache provider's store_body failed!");
+ "cache: Cache provider's store_body failed for URI %s", f->r->uri);
ap_remove_output_filter(f);
/* give someone else the chance to cache the file */
@@ -756,17 +772,16 @@ static int cache_save_store(ap_filter_t *f, apr_bucket_brigade *in,
/**
* Sanity check for 304 Not Modified responses, as per RFC2616 Section 10.3.5.
*/
-static const char *cache_header_cmp(apr_pool_t *pool, apr_table_t *left,
+static int cache_header_cmp(apr_pool_t *pool, apr_table_t *left,
apr_table_t *right, const char *key)
{
const char *h1, *h2;
if ((h1 = cache_table_getm(pool, left, key))
&& (h2 = cache_table_getm(pool, right, key)) && (strcmp(h1, h2))) {
- return apr_pstrcat(pool, "contradiction: 304 Not Modified, but ", key,
- " modified", NULL);
+ return 1;
}
- return NULL;
+ return 0;
}
/*
@@ -802,7 +817,7 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
apr_time_t exp, date, lastmod, now;
apr_off_t size = -1;
cache_info *info = NULL;
- const char *reason;
+ const char *reason, **eh;
apr_pool_t *p;
apr_bucket *e;
apr_table_t *headers;
@@ -1111,29 +1126,22 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
else if (r->status == HTTP_NOT_MODIFIED && cache->stale_handle) {
apr_table_t *left = cache->stale_handle->resp_hdrs;
apr_table_t *right = r->headers_out;
+ const char *ehs = NULL;
/* and lastly, contradiction checks for revalidated responses
* as per RFC2616 Section 10.3.5
*/
- if (((reason = cache_header_cmp(r->pool, left, right, "Allow")))
- || ((reason = cache_header_cmp(r->pool, left, right,
- "Content-Encoding")))
- || ((reason = cache_header_cmp(r->pool, left, right,
- "Content-Language")))
- || ((reason = cache_header_cmp(r->pool, left, right,
- "Content-Length")))
- || ((reason = cache_header_cmp(r->pool, left, right,
- "Content-Location")))
- || ((reason = cache_header_cmp(r->pool, left, right,
- "Content-MD5")))
- || ((reason = cache_header_cmp(r->pool, left, right,
- "Content-Range")))
- || ((reason = cache_header_cmp(r->pool, left, right,
- "Content-Type")))
- || ((reason = cache_header_cmp(r->pool, left, right, "ETag")))
- || ((reason = cache_header_cmp(r->pool, left, right,
- "Last-Modified")))) {
- /* contradiction: 304 Not Modified, but entity header modified */
+ if (cache_header_cmp(r->pool, left, right, "ETag")) {
+ ehs = "ETag";
+ }
+ for (eh = MOD_CACHE_ENTITY_HEADERS; *eh; ++eh) {
+ if (cache_header_cmp(r->pool, left, right, *eh)) {
+ ehs = (ehs) ? apr_pstrcat(r->pool, ehs, ", ", *eh, NULL) : *eh;
+ }
+ }
+ if (ehs) {
+ reason = apr_pstrcat(r->pool, "contradiction: 304 Not Modified; "
+ "but ", ehs, " modified", NULL);
}
}
@@ -1148,14 +1156,9 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
* inconsistencies between cached entity-bodies and updated headers.
*/
if (r->status == HTTP_NOT_MODIFIED) {
- apr_table_unset(r->headers_out, "Allow");
- apr_table_unset(r->headers_out, "Content-Encoding");
- apr_table_unset(r->headers_out, "Content-Language");
- apr_table_unset(r->headers_out, "Content-Length");
- apr_table_unset(r->headers_out, "Content-MD5");
- apr_table_unset(r->headers_out, "Content-Range");
- apr_table_unset(r->headers_out, "Content-Type");
- apr_table_unset(r->headers_out, "Last-Modified");
+ for (eh = MOD_CACHE_ENTITY_HEADERS; *eh; ++eh) {
+ apr_table_unset(r->headers_out, *eh);
+ }
}
/* Hold the phone. Some servers might allow us to cache a 2xx, but
@@ -1198,7 +1201,7 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
apr_table_unset(r->headers_in, "If-Range");
apr_table_unset(r->headers_in, "If-Unmodified-Since");
- ap_internal_redirect(r->uri, r);
+ ap_internal_redirect(r->unparsed_uri, r);
return APR_SUCCESS;
}
@@ -1439,10 +1442,12 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
* the cached headers.
*
* However, before doing that, we need to first merge in
- * err_headers_out and we also need to strip any hop-by-hop
- * headers that might have snuck in.
+ * err_headers_out (note that store_headers() below already selects
+ * the cacheable only headers using ap_cache_cacheable_headers_out(),
+ * here we want to keep the original headers in r->headers_out and
+ * forward all of them to the client, including non-cacheable ones).
*/
- r->headers_out = ap_cache_cacheable_headers_out(r);
+ r->headers_out = cache_merge_headers_out(r);
/* Merge in our cached headers. However, keep any updated values. */
/* take output, overlay on top of cached */
@@ -1492,6 +1497,13 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
if (status != OK) {
r->status = status;
+ /* Strip the entity headers merged from the cached headers before
+ * updating the entry (see cache_accept_headers() above).
+ */
+ for (eh = MOD_CACHE_ENTITY_HEADERS; *eh; ++eh) {
+ apr_table_unset(r->headers_out, *eh);
+ }
+
bkt = apr_bucket_flush_create(bb->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, bkt);
}
@@ -2071,8 +2083,7 @@ static const char *set_cache_quick_handler(cmd_parms *parms, void *dummy,
cache_server_conf *conf;
conf =
- (cache_server_conf *)ap_get_module_config(parms->server->module_config
-,
+ (cache_server_conf *)ap_get_module_config(parms->server->module_config,
&cache_module);
conf->quick = flag;
conf->quick_set = 1;