11

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?

2
  • 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, 2014 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, 2015 at 23:55

2 Answers 2

8

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' );
1
  • this starts a php session - which means varnish will never cache.
    – matpol
    May 11, 2016 at 9:29
5

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;
}
3
  • 1
    Nice. Do you know if it will override any further http header (re)writing by third party plugins?
    – pixeline
    Nov 1, 2014 at 18:20
  • In fact, the proper hook is "send_headers". Will post the final solution as an answer.
    – pixeline
    Nov 1, 2014 at 18:36
  • @pixeline wp_headers and send_headers are both valid hooks...the original question seems like a valid use case for wp_headers. See developer.wordpress.org/reference/hooks/wp_headers. Jul 27, 2020 at 17:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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