https://bz.apache.org/bugzilla/show_bug.cgi?id=61820
--- Comment #23 from Matt McCutchen <[email protected]> --- Thanks to everyone who worked or is working on this issue! While we wait for the fix to be committed and deployed to our web hosts (which I'm guessing may take years), here's a workaround I plan to use on my site: For each request, compute a "salt" string that uniquely identifies the relevant response header values, and then emulate a resource whose ETag incorporates the salt. Thus, if a request returns a salted ETag that is found in the client's cache, then the response headers in the cache are guaranteed to equal those that would have appeared in the actual response if Apache didn't strip them. Since a last-modified time cannot accommodate salt, the If-Modified-Since request header must be dropped so that a 304 is not returned on that basis. In general, the response headers and thus the salt could depend on both the server configuration and the request headers. In most scenarios, it's probably easiest to represent the server configuration by an integer that is manually incremented for each relevant change. Request headers can just be concatenated into the salt with any problematic characters suitably encoded. Of course, we must ensure the client sends the request to the server in the first place rather than fulfilling it from cache. This is independent of the current issue but probably worth reminding people about. For a dependency on a request header, we just merge its name into the Vary response header. For a change in server configuration, the best we can do is set the Cache-Control max-age to ensure clients eventually find out about the change. Here's a code example for a .htaccess file where, if the Origin request header specifies an allowed origin, we want to set an equal Access-Control-Allow-Origin response header. The server configuration revision is 42; we would increment the number if we changed the logic for generating response headers. I'm assuming no browser sends an Origin header with nasty characters; this might need more research. Please let me know if anything is wrong with this example! ~~~~~~~~ SetEnv HEADER_CONFIG_REV 42 RewriteRule ^ - [E=ETAG_SALT:%{ENV:HEADER_CONFIG_REV}-%{HTTP:Origin}] Header merge Vary Origin Header set Cache-Control max-age=1200 # Our goal is to strip the salt from the If-None-Match and If-Match headers if # it equals the current salt. However, %{ETAG_SALT}e expansion in the regular # expression is not supported, so we use the following hack: append the current # salt to all ETags, and then if an ETag ends in two equal salts (as determined # by a regular expression with a \1 backreference), strip both of them. ETags # that did not originally end with the current salt will be left with at least # one salt and won't be able to match the real ETag, so their presence does not # matter. RequestHeader edit* If-None-Match "([^\ ])\"" "$1+%{ETAG_SALT}e\"" RequestHeader edit* If-None-Match "(\+[^+\" ]*)\1\"" "\"" RequestHeader edit* If-Match "([^\ ])\"" "$1+%{ETAG_SALT}e\"" RequestHeader edit* If-Match "(\+[^+\" ]*)\1\"" "\"" RequestHeader unset If-Modified-Since # Always add the salt to the ETag response header. Header edit ETag "\"$" "+%{ETAG_SALT}e\"" RewriteCond %{HTTP:Origin} ^https://(.+\.)?example\.com$ RewriteRule ^ - [E=ACAO:%{HTTP:Origin}] Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO ~~~~~~~~ When calling a CGI, some of this processing could probably be done in the CGI, but I haven't tested that. -- You are receiving this mail because: You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
