mod_cache: Preserve non-cacheable headers forwarded from an origin 304
response. PR 55547.
When mod_cache asks for a revalidation of a stale entry and the origin responds
with a 304 (not that stale), the module strips the non-cacheable headers from
the origin response and merges the stale headers to update the cache.
The problem is that mod_cache won't forward the non-cacheable headers to the
client, for example if the 304 response contains both Set-Cookie and
'Cache-Control: no-cache="Set-Cookie"' headers, or CacheIgnoreHeaders is used.
mod_cache: follow up to r1591328.
Define the cache_merge_headers_out() function to merge r->err_headers_out into
r->headers_out and add the ones from r->content_type/encoding if available.
Use it in ap_cache_cacheable_headers_out() where the same is done and in
cache_save_filter() where this has to be done before updating the entry.
mod_cache: follow up to r1594643.
Avoid table lookup if not necessary (fast path first).
Submitted by: ylavic
Reviewed/backported by: jim
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@
1598604 13f79535-47bb-0310-9956-
ffa450edef68
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * mod_cache: Preserve non-cacheable headers forwarded from an origin 304
- response. PR 55547.
- trunk patch: http://svn.apache.org/r1591328
- http://svn.apache.org/r1594643
- http://svn.apache.org/r1594648
- 2.4.x patch: http://people.apache.org/~ylavic/httpd-2.4.x-mod_cache-preserve_304_headers.patch
- +1: ylavic, minfrin, jim
-
* minor proxy_util cleanups:
. get rid of unnecessary block scope
. Clarify an existing requirement of the server_portstr parameter
{
apr_table_t *headers_out;
- headers_out = apr_table_overlay(r->pool, r->headers_out,
- r->err_headers_out);
-
- apr_table_clear(r->err_headers_out);
-
- headers_out = ap_cache_cacheable_headers(r->pool, headers_out,
- r->server);
+ headers_out = ap_cache_cacheable_headers(r->pool,
+ cache_merge_headers_out(r),
+ r->server);
cache_control_remove(r,
cache_table_getm(r->pool, headers_out, "Cache-Control"),
headers_out);
- if (!apr_table_get(headers_out, "Content-Type")
- && r->content_type) {
+ return headers_out;
+}
+
+apr_table_t *cache_merge_headers_out(request_rec *r)
+{
+ apr_table_t *headers_out;
+
+ headers_out = apr_table_overlay(r->pool, r->headers_out,
+ r->err_headers_out);
+ apr_table_clear(r->err_headers_out);
+
+ if (r->content_type
+ && !apr_table_get(headers_out, "Content-Type")) {
apr_table_setn(headers_out, "Content-Type",
ap_make_content_type(r, r->content_type));
}
- if (!apr_table_get(headers_out, "Content-Encoding")
- && r->content_encoding) {
+ if (r->content_encoding
+ && !apr_table_get(headers_out, "Content-Encoding")) {
apr_table_setn(headers_out, "Content-Encoding",
r->content_encoding);
}
*/
char *cache_strqtok(char *str, const char *sep, char **last);
+/**
+ * Merge err_headers_out into headers_out and add request's Content-Type and
+ * Content-Encoding if available.
+ */
+apr_table_t *cache_merge_headers_out(request_rec *r);
+
#ifdef __cplusplus
}
#endif
* 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 */