I recently built Squid 2.6.STABLE9 as a potential replacement for
2.5.STABLE10, but encountered a problem with our local web authentication
system (which worked just fine with the older Squid version).
Investigation showed that the problem was that the new Squid version was
caching the temporary redirects (HTTP status 302) sent by origin servers
to direct unauthenticated requests to our authentication server. When the
authentication server subsequently redirected the (now authenticated)
requests back to the originally-requested URLs, Squid served the
corresponding cached redirects instead of passing the requests through to
the origin servers.
That didn't happen with the old Squid version, and I couldn't see any
mention of relevant-seeming changes in the release notes at
http://www.squid-cache.org/Versions/v2/2.6/squid-2.6.STABLE9-RELEASENOTES.html
or the ChangeLog file in the source kit.
It looked initially like it might be the problem described by Squid
Bugzilla entry 1420 ("302 responses with an Expires header is always
cached"), but I'm not sure about that - it may instead be a related (but
distinct) problem. Hence asking about it here, rather than simply adding a
note to the bugzilla item to suggest it's more serious than an
"enhancement request" (which is how it is currently classified).
The authentication component running on the origin servers currently
includes an Expires: header in all responses (including redirects), using
the same timestamp as the Date: header. That's the specific recommendation
in RFC 2616 (section 14.21) for how to mark a response as "already
expired", which I interpret as meaning it should never be cached (or
perhaps, alternatively, that a cached copy can be stored as long as it is
never be returned to a client (always treated as stale, forcing
re-validation) - which should have the same effect, though with different
implementation.
Section 10.3.3 ("302 Found") of the RFC says "This response is only
cacheable if indicated by a Cache-Control or Expires header field." but
(surely!) an Expires: header marking a response as pre-expired should not
be counted as indicating that a redirect is cacheable. However, that
(caching it and then serving the cached redirect instead of passing a
followup request for the same URL through to the origin server) appears to
be what is happening with Squid 2.6.STABLE9.
One of comments in the bugzilla item notes that
"This bug report is about 302 redirect responses with an explicit expiry
time set. Currently Squid caches these objects even if already expired,
which is not optimal behaviour (but works..)."
Superficially, that appears to be saying "caching all 302 redirects with
an Expires header is just an efficiency issue, and won't break anything",
directly contradicting our experience that it does break things that
expect the RFC-mandated handling of expired content.
I can see, however, that maybe *caching* all redirects is expected to be
safe (though sub-optimal) *if* in addition it is expected that any
(pre-)expired redirects will be ignored when Squid is deciding how to
handle subsequent requests for the same URL, so that such requests would
be passed to the origin server. If so, then it looks like the bug is that
the code which should ignore (pre-)expired cached redirects has got broken
at some point between 2.5.STABLE12 and 2.6.STABLE9.
Any suggestions about where the problem really lies (and whether it's a
known bug, if different from 1420, or if I need to file a new bug report),
would be appreciated.
[I suppose I should mention that we are seeing the problem with Squid
running on x86 PC servers running the 32-bit version of SLES9 Linux - but
that seems rather unlikely to be relevant to the problem.]
John Line
--
John Line - web & news development, University of Cambridge Computing Service