Squid proxy refusing to revalidate cache when Vary header present

cachePROXYreverse-proxysquid

squid.conf

cache_effective_user squid

http_access allow all

# Squid normally listens to port 3128
http_port 3128 accel defaultsite=localhost no-vhost ignore-cc

cache_peer localhost parent 80 0 no-query originserver name=myAccel
cache_peer_access myAccel allow all

# Uncomment and adjust the following to add a disk cache directory.
cache_dir ufs /usr/local/var/cache/squid 100 16 256

# Leave coredumps in the first cache dir
coredump_dir /usr/local/var/cache/squid

minimum_expiry_time 0

test.php

<?php

Header( "Cache-Control: max-age=0, must-revalidate" ); 

$headers = getallheaders();
$ims = $headers['If-Modified-Since'];
$lastModified = "Mon, 16 Apr 2012 23:01:32 GMT";
if ($ims == $lastModified) {
    Header( "HTTP/1.1 304 Not Modified" ); 
    exit;
}

Header("Last-Modified: $lastModified");
if ($_GET["vary"]) Header("Vary: Accept-Encoding");

?><html>hi</html>

Squid 3.2.9, installed on OSX via Homebrew

Squid 3.2.9, installed on OSX via Homebrew

localhost: ~ $ squid -v
Squid Cache: Version 3.2.9
configure options:  '--disable-debug' '--disable-dependency-tracking' '--prefix=/usr/local/Cellar/squid/3.2.9' '--localstatedir=/usr/local/var' 'CC=cc' 'CXX=c++' 'PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig'

Started squid with squid -f squid.conf -d 2 -N

When the server omits the "Vary: Accept-Encoding" header, Squid revalidates/refreshes its cache using an If-Modified-Since conditional GET. But when the "Vary: Accept-Encoding" header is present, Squid refuses to use If-Modified-Since, and instead just ignores its cache. Why?

localhost: ~ $ curl --silent -o /dev/null --dump-header /dev/stdout http://localhost:3128/test.php
HTTP/1.1 200 OK
Date: Wed, 17 Apr 2013 00:17:42 GMT
Server: Apache/2.2.22 (Unix) DAV/2 PHP/5.3.15 with Suhosin-Patch mod_ssl/2.2.22 OpenSSL/0.9.8r
X-Powered-By: PHP/5.3.15
Cache-Control: max-age=0, must-revalidate
Last-Modified: Mon, 16 Apr 2012 23:01:32 GMT
Content-Length: 16
Content-Type: text/html
X-Cache: MISS from localhost
Via: 1.1 localhost (squid/3.2.9)
Connection: keep-alive

localhost: ~ $ curl --silent -o /dev/null --dump-header /dev/stdout http://localhost:3128/test.php
HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.15
Last-Modified: Mon, 16 Apr 2012 23:01:32 GMT
Content-Length: 16
Content-Type: text/html
Date: Wed, 17 Apr 2013 00:17:43 GMT
Server: Apache/2.2.22 (Unix) DAV/2 PHP/5.3.15 with Suhosin-Patch mod_ssl/2.2.22 OpenSSL/0.9.8r
Cache-Control: max-age=0, must-revalidate
Age: 0
X-Cache: HIT from localhost
Via: 1.1 localhost (squid/3.2.9)
Connection: keep-alive

localhost: ~ $ curl --silent -o /dev/null --dump-header /dev/stdout "http://localhost:3128/test.php?vary=1"
HTTP/1.1 200 OK
Date: Wed, 17 Apr 2013 00:17:58 GMT
Server: Apache/2.2.22 (Unix) DAV/2 PHP/5.3.15 with Suhosin-Patch mod_ssl/2.2.22 OpenSSL/0.9.8r
X-Powered-By: PHP/5.3.15
Cache-Control: max-age=0, must-revalidate
Last-Modified: Mon, 16 Apr 2012 23:01:32 GMT
Vary: Accept-Encoding
Content-Length: 16
Content-Type: text/html
X-Cache: MISS from localhost
Via: 1.1 localhost (squid/3.2.9)
Connection: keep-alive

localhost: ~ $ curl --silent -o /dev/null --dump-header /dev/stdout "http://localhost:3128/test.php?vary=1"
HTTP/1.1 200 OK
Date: Wed, 17 Apr 2013 00:18:00 GMT
Server: Apache/2.2.22 (Unix) DAV/2 PHP/5.3.15 with Suhosin-Patch mod_ssl/2.2.22 OpenSSL/0.9.8r
X-Powered-By: PHP/5.3.15
Cache-Control: max-age=0, must-revalidate
Last-Modified: Mon, 16 Apr 2012 23:01:32 GMT
Vary: Accept-Encoding
Content-Length: 16
Content-Type: text/html
X-Cache: MISS from localhost
Via: 1.1 localhost (squid/3.2.9)
Connection: keep-alive

Best Answer

For what it's worth, I am seeing the same issue with version 3.3.4 and it appears that this post in squid-users is describing the same problem with 3.2.1. I've noticed that it seems to work with 3.1.10 (which is installed by default with my package manager).

By analyzing the logs I was able to determine that the hash lookup key used during the store (i.e. the initial request) is different than the one used during the subsequent requests. This is why the subsequent lookups are cache misses.

Armed with this information (additional search criteria) I was able to find this bug report that describes the issue. The bug is unresolved.

Hope this helps!

Related Topic