Here is the patch that strips the "no-cache=" or "private=" specified
headers after the origin server's validation, leaving the only headers
updated by the origin.
Regards,
Yann.
Index: modules/cache/cache_storage.c
===================================================================
--- modules/cache/cache_storage.c (revision 1456050)
+++ modules/cache/cache_storage.c (working copy)
@@ -156,6 +156,51 @@
apr_table_unset(h->resp_hdrs, "Last-Modified");
}
+ v = apr_table_get(h->resp_hdrs, "Cache-Control");
+ if (v && (h->cache_obj->info.control.no_cache_header ||
+ h->cache_obj->info.control.private_header)) {
+ /*
+ * RFC2616 14.9.1: If the no-cache directive does specify one or more
+ * field-names, then a cache MAY use the response to satisfy a
+ * subsequent request, subject to any other restrictions on caching.
+ * However, the specified field-name(s) MUST NOT be sent in the
+ * response to a subsequent request without successful revalidation
+ * with the origin server.
+ *
+ * Hence we will strip these cached headers (if any) and let the only
+ * ones validated by the origin server.
+ */
+ char *token;
+ apr_size_t len;
+ while ((token = ap_get_list_item(r->pool, &v))) {
+ /* ap_get_list_item() strips the spurious whitespaces and
+ * lowercases anything (but the quoted-strings) */
+ if (strncmp(token, "no-cache=", 9) == 0) {
+ token += 9;
+ }
+ else if (strncmp(token, "private=", 8) == 0) {
+ token += 8;
+ }
+ else {
+ continue;
+ }
+
+ /* RFC2616 14.9: quoted list of field-names */
+ len = strlen(token);
+ if (token[0] == '"' && token[--len] == '"') {
+ (++token)[--len] = '\0';
+ do {
+ const char *name = ap_cache_tokstr(r->pool, token,
+ (const char**)&token);
+ if (name) {
+ /* strip that name header the response */
+ apr_table_unset(h->resp_hdrs, name);
+ }
+ } while (token);
+ }
+ }
+ }
+
/* The HTTP specification says that it is legal to merge duplicate
* headers into one. Some browsers that support Cookies don't like
* merged headers and prefer that each Set-Cookie header is sent