7

My site sits on a server that uses Varnish as a (powerful) caching engine. Unfortunately, it seems wordpress is busting the Varnish cache by sending a cache-control http header. If I curl -I domain.com I get:

HTTP/1.1 200 OK
Server: Apache/2.4.10
X-Powered-By: PHP/5.4.4-14+deb7u14
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=e00738aoughg407ljm270kj0l6; path=/
Content-Type: text/html; charset=UTF-8
Accept-Ranges: bytes
Date: Fri, 31 Oct 2014 21:44:16 GMT
Connection: keep-alive
Via: 1.1 varnish
Age: 0

I have other wordpress sites hosted on this server, which work correctly with the Varnish server, so I'm pretty sure the problem is caused by this specific installation. Here is what I tried:

  • disable all plugins. Empty Varnish cache, then curl -I: same result.
  • looked through all my theme files. Nothing suspicious.

Do you have any other idea as to what may cause the problem?

  • From quick search I cannot find a single instance of no-store being used in core. I doubt this is coming from WP itself. – Rarst Nov 1 '14 at 14:28
  • As Rarst notes, no-store isn't used, but if it's helpful for other people WP will send no-cache, must-revalidate, max-age=0 and a few others for logged in users. – El Yobo Aug 11 '15 at 23:55
6

Thanks to @chrisguitarguy's answer, you can control the http headers sent by Wordpress via the "send_headers" hook. Here is the function I added to my theme's functions.php file, and that solved the issue with the Varnish server.

function varnish_safe_http_headers() {
    header( 'X-UA-Compatible: IE=edge,chrome=1' );
    session_cache_limiter('');
    header("Cache-Control: public, s-maxage=120");
  if( !session_id() )
  {
    session_start();
  }
}
add_action( 'send_headers', 'varnish_safe_http_headers' );
  • this starts a php session - which means varnish will never cache. – matpol May 11 '16 at 9:29
1

You can hook into wp_headers and remove the cache control headers. WordPress generally doesn't send Cache-Control except for admin area or ajax requests, however.

add_filter('wp_headers', 'wpse167128_nocache');
function wpse167128_nocache($headers)
{
    unset($headers['Cache-Control']);
    return $headers;
}
  • 1
    Nice. Do you know if it will override any further http header (re)writing by third party plugins? – pixeline Nov 1 '14 at 18:20
  • In fact, the proper hook is "send_headers". Will post the final solution as an answer. – pixeline Nov 1 '14 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.