We use Incapsula as a reverse proxy for some of our sites, and recently ran into an issue with what appears to be a wilful violation of the HTTP specification by Incapsula.
Incapsula’s documentation says the following about how it handles Cache-Control headers:
Cache-Control - if it's set to no-cache / private / must-revalidate / proxy-revalidate/ no-store – then it'll prevent caching by Incapsula, unless site Acceleration Mode is set to Aggressive.
Unfortunately this isn’t the case. The following response headers from an origin server:
Cache-Control: max-age=86400, private Content-Encoding: gzip Content-Length: 2431 Content-Type: text/html; charset=utf-8 ...
Get converted into this by Incapsula’s proxy:
Cache-Control: max-age=86398, public Content-Encoding: gzip Content-Length: 2431 Content-Type: text/html; charset=utf-8 ...
This is a problem because what was meant to be a private resource has been cached and made public by Incapsula.
We contacted Incapsula to report this issue. This was the explanation we received:
private: Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache.
The max-age directive on a response implies that the response is cacheable (i.e., "public") unless some other, more restrictive cache directive is also present.
Since Incapsula is a CDN, which considers as a shared cache, the value of max-age=NUMBER and Cache-Control=private contradict each other and must not configured in this way.
The statement about
max-age implying that a resource is public is false. The HTTP specification explicitly allows private resources to have a max-age:
Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache. This allows an origin server to state that the specified parts of the response are intended for only one user and are not a valid response for requests by other users. A private (non-shared) cache MAY cache the response.
The correct behaviour would be for Incapsula to give the
private directive precendence over
max-age (rather than the other way around). Instead it takes the rather dangerous step of simply removing the
In any case, the point is that Incapsula will violate a
Cache-Control: private directive unless you also set