I have added the following line in my Apache httpd.conf: -
AddOutputFilterByType DEFLATE text/html text/css application/javascript application/x-javascript a
This is a known bug in Apache. See Apache bug #45023, and summary of Apache 304 etags and mod_deflate.
Rebuilding from svn will fix the issue. The resolution was to revert the change that appended "-gzip" to the etag. However, there are associated HTTP compliance problems.
If you can't rebuild Apache, there is a suggested runtime configuration workaround in the bug report:
RequestHeader edit "If-None-Match" "^\"(.*)-gzip\"$" "\"$1\""
Header edit "ETag" "^\"(.*[^g][^z][^i][^p])\"$" "\"$1-gzip\""
I know this is a very old question, but it appears there's a more up-to-date answer.
To have Apache not append the -gzip
suffix, you must use the DeflateAlterETag
directive with a value of NoChange
.
See the documentation for this here: http://httpd.apache.org/docs/trunk/mod/mod_deflate.html#deflatealteretag
"I've also decided that ETags aren't that useful in Apache anyway."
Wrong,
for example you have a file with modification date set to'2016.07.27 05:00:00'
, you upload it to your site, browser gets this file with HTTP code 200, then caches it and revalidates every time with HTTP 304.
Next you upload a file with the same filename again, but with older timestamp'2013.07.27 05:00:00'
and with other content.
If ETag is disabled on server, browser will use onlyIf-Modified-Since:
request to determine if file was changed on server, so the request will beIf-Modified-Since: 2016.07.27 05:00:00
, but the file is not modified after this date, so a HTTP 304 is returned, even if the file has changed.
If ETag is enabled on server, besidesIf-Modified-Since:
, there will be aIf-None-Match:
header coming from browser that will detect that file was changed(by default - timestamp mismatch+size mismatch) and the file will be redownloaded.
This problem still exists in Apache 2.4.23, so, I've written a better code than above to fix this issue. Expanation line by line:
You can use either negative lookahead or negative lookbehind, regex speed is the same, Apache supports both
\"(.+(?<!-gzip))\" #using negative lookbehind
\"((?:.(?!-gzip\"))+)\" #using negative lookahead
Test cases:
Copy-Paste this code into Apache .conf
SetEnvIf If-None-Match "-gzip\"$" request_etag=gzip
RequestHeader edit If-None-Match "(.+)-gzip\"$" "$1\""
Header edit ETag "(.+(?<!-gzip))\"$" "$1-gzip\"" "expr=reqenv('request_etag') == 'gzip' || resp('Content-Encoding') == 'gzip'"
I personally use the following code, that strips '-gzip' part initially if it's a gzip response, and doesn't reappend it, so the browser will never send a '-gzip'
'If-None-Match'
header.
Header edit ETag "(.+)-gzip\"$" "$1\"" "expr=resp('Content-Encoding') == 'gzip'"
Maybe you use a (squid) proxy which manipulates the HTTP Requests?