Index: modules/cache/mod_cache.c =================================================================== --- modules/cache/mod_cache.c (revision 685045) +++ modules/cache/mod_cache.c (working copy) @@ -763,17 +763,8 @@ ap_cache_accept_headers(cache->handle, r, 1); } - /* Write away header information to cache. It is possible that we are - * trying to update headers for an entity which has already been cached. + /* is it a revalidated response? * - * This may fail, due to an unwritable cache area. E.g. filesystem full, - * permissions problems or a read-only (re)mount. This must be handled - * later. - */ - rv = cache->provider->store_headers(cache->handle, r, info); - - /* Did we just update the cached headers on a revalidated response? - * * If so, we can now decide what to serve to the client. This is done in * the same way as with a regular response, but conditions are now checked * against the cached or merged response headers. @@ -783,6 +774,13 @@ apr_bucket *bkt; int status; + /* Write away header information to cache. + * This may fail, due to an unwritable cache area. E.g. filesystem full, + * permissions problems or a read-only (re)mount. This must be handled + * later. + */ + rv = cache->provider->store_headers(cache->handle, r, info); + bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); /* Restore the original request headers and see if we need to @@ -826,18 +824,31 @@ return ap_pass_brigade(f->next, bb); } - if(rv != APR_SUCCESS) { + + /* First update the body so that we can avoid other clients seeing an + * updated header but unupdated body. In case the clients see an updated + * header while we have already updated body, the worst that can happen + * is that they might overwrite the body and headers again. + */ + rv = cache->provider->store_body(cache->handle, r, in); + if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server, - "cache: store_headers failed"); + "cache: store_body failed"); ap_remove_output_filter(f); - return ap_pass_brigade(f->next, in); } - rv = cache->provider->store_body(cache->handle, r, in); - if (rv != APR_SUCCESS) { + /* Write away header information to cache. + * + * This may fail, due to an unwritable cache area. E.g. filesystem full, + * permissions problems or a read-only (re)mount. This must be handled + * later. + */ + rv = cache->provider->store_headers(cache->handle, r, info); + + if(rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server, - "cache: store_body failed"); + "cache: store_headers failed"); ap_remove_output_filter(f); }