How to I get control of the Cache-Control header with Wordpress on Apache?

Taylor picture Taylor · Apr 27, 2015 · Viewed 9.9k times · Source

This is driving me absolutely nuts. We're running Wordpress on Apache (we're new to this stack, if that's not obvious). Specifically this is a Bitnami AMI. Since we're pretty much 100% on AWS, I wanted to use Cloudfront dynamic content caching in front of the Wordpress site. I've read tons of docs/posts about how to use W3 Total Cache (or similar) to make this work. But all I really want to do is get a grip on the Cache-Control header so I can get Cloudfront to work the way it's supposed to.

Currently, I have modified functions.php to include code (based on another post here) which is supposed to modify the header.

function varnish_safe_http_headers() {
    session_cache_limiter('');
    header_remove("Cache-Control");
    header("Cache-Control: public, max-age=60");
  if( !session_id() )
  {
    session_start();
  }
}
add_action( 'template_redirect', 'varnish_safe_http_headers' );

Unfortunately, what I wind up with is TWO headers.

Cache-Control:public, max-age=60
Cache-Control:max-age=0, no-cache

The first header is mine. The second header is coming from some other location in the stack that I can't seem to find/configure. I've searched the entire contents of the Wordpress directory for any string that I can think of that would help me find code that does this.

I've also tried changing the "hook" in the add_action call to any number of values, working my way from "send_headers" down through. The only result is that the two cache-control headers change order. I cannot, so far, remove/overwrite the "max-age=0, no-cache" value.

I've also tried modifying .htaccess, the Bitnami-specific htaccess.conf file, etc, etc.

EDIT: After reading here, it seems that the second header must be caused somewhere within Wordpress/PHP. This document makes it appear that the "handler" (in this case PHP) gets the last word on response processing. Once that phase is complete, there is only sending the response to the client and logging.

EDIT 2: I added a foo.php file to the root of the site. It calls no Wordpress functions at all. Both Cache-Control headers still appear. Here are the entire contents of the file.

<?php
header("Cache-Control: public, max-age=60");
?>

Answer

Brian Petro picture Brian Petro · May 4, 2016

Apache's mod_pagespeed is the culprit. It sets Cache-Control: no-cache, max-age=0 by default.

You need to update apache2/conf/pagespeed.conf to include

ModPagespeedModifyCachingHeaders off

then run this to restart apache

$ cd installdir
$ ./ctlscript.sh restart apache

References: