0

I have a PHP script packaging some content together with zlib compression turned on, like so:

ini_set('zlib.output_compression', '1');
ini_set('zlib.output_compression_level', '-1');

And HTTP caching enabled like so:

$age = 60 * 60 * 24 * 365;
$expires = time() + $age;
header("Cache-control: max-age={$age}");
header('Pragma: cache');  // to overwrite Zend/PHP's default of `no-cache`
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', $expires));

This normally works fine. But, for one of my larger resources, my cache control headers are getting clobbered, and the following is being sent instead:

Cache-Control: no-store, no-cache, must-revalidate
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache

This occurs in all tested server environments (CentOS/Apache, Raspbian/Apache, Windows/IIS) with a local network and localhost connections. Disabling the zlib compression brings the caching headers back; but, it's not a long-term solution.

What's causing zlib to break my caching headers on some resources? And, how do I ensure that it doesn't clobber my caching headers?

svidgen
  • 13,744
  • 4
  • 33
  • 58

1 Answers1

1

I doubt that zlib is causing this issue. I "grep"ed PHP source (latest version, 7.*), and it seems that Pragma header is affected only in 3 places:

  1. ext/session
  2. ext/phar
  3. sapi/litespeed

Probably you call session_start() after setting the headers. In that case Pragma header will be set to no-cache.

If it's not the case, then provide additional information: PHP version and how to reproduce the issue.

pumbo
  • 3,646
  • 2
  • 25
  • 27
  • PHP 7.0.9. It's _possible_ that the `session_start()` is being called in the course of the request. But, the headers are *not* being clobbered on the same request when compression is disabled with `ini_set('zlib.output_compression', '0');`. ... Unfortunately, I can't really give *precise* steps to reproduce this, since I don't know what's actually triggering the issue. My best guess so far is response bodies over a certain size -- somewhere in the 100k to 150k range. – svidgen Jul 12 '17 at 03:53
  • `Expires: Thu, 19 Nov 1981 08:52:00 GMT` - the exact same string (same time) is used ONLY in `ext/session`. So I'm sure the issue is related to starting session after setting the headers. BTW, it turned out that this date is [the birthday of `session` ext. developer (Sascha Schumann)](https://stackoverflow.com/a/8194500/2919292) – pumbo Jul 12 '17 at 04:40
  • Try setting `ini_set('session.cache_limiter', 'off');` option in the beginning of the script. This should prevent disabling caching. – pumbo Jul 12 '17 at 04:55
  • Ok... And it's worth digging into in my end, because the session probably isn't required on this request. But, even if session_start is getting called, it's only affecting the headers when compression is enabled. **Why!?** ... And suppose I do need caching on a request that's both compressed and related to the session. Are you suggesting that PHP simply can't do that!? – svidgen Jul 12 '17 at 04:57
  • Didn't see your second comment. But, I've already noted that disabling compression fixes the headers. But, I don't know that I understand why. Or how to fix this without disabling the compression, which doesn't seem like a "good" option. – svidgen Jul 12 '17 at 05:00
  • Have you tried `ini_set('session.cache_limiter', 'off');` ? It will not disable compression, but prevent `session` ext. to set `no-cache` header – pumbo Jul 12 '17 at 05:07
  • Take a look at [`session_cache_limiter()`](http://php.net/manual/en/function.session-cache-limiter.php) – pumbo Jul 12 '17 at 05:17
  • OK. Sorry, I misread your 2nd comment above. Setting `session.cache_limiter` to `off` does the trick. Maybe zlib's buffer holds up headers as well as the body, allowing them to be rewritten, whereas they normally get flushed right away? ... I'm not sure if that's a reasonable explanation! But, if you add the `session.cache_limiter` stuff to your answer and give a reasonable explanation for why the compression lets those headers through, I'll accept it... +1 either way. Thanks! – svidgen Jul 12 '17 at 14:08
  • I don't see how `zlib` might be affecting the headers set by `session`. Logically it should not. – pumbo Jul 13 '17 at 05:07
  • Hehe ... I agree. But, it is! – svidgen Jul 13 '17 at 14:25