Q:

Cache-Control Header Modified By PHP Session?

I'm outputting an image to the browser using a Zend_Controller_Response object.  It is my intention to apply caching to the image, however something is causing the Cache-Control header to be overwritten.
My code is as follows:
$this->getResponse()
    ->setHeader('Last-Modified', $modifiedTime, true)
    ->setHeader('ETag', md5($modifiedTime), true)
    ->setHeader('Expires', $expires, true)
    ->setHeader('Pragma', '', true)
    ->setHeader('Cache-Control', 'max-age=3600')
    ->setHeader('Content-Type', $mimeType, true)
    ->setHeader('Content-Length', $size, true)
    ->setBody($data);

The output (as viewed in Firebug) is:
Response Headers

DateWed, 25 Mar 2009 10:34:40 GMT
ServerApache/2.2.3 (Ubuntu) mod_ssl/2.2.3 OpenSSL/0.9.8c
ExpiresThu, 26 Mar 2009 10:34:41 GMT
Cache-Controlno-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=3600
Last-Modified1234872514
Etagd3ef646c640b689b0101f3e03e08a524
Content-Length1452
X-UA-CompatibleIE=EmulateIE7
X-Robots-Tagnoindex
Keep-Alivetimeout=15, max=100
ConnectionKeep-Alive
Content-Typeimage/jpeg

Request Headers

Hostkhall.####.###.######.com
User-AgentMozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009030422 Ubuntu/8.04 (hardy) Firefox/3.0
.7
Accepttext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Languageen-gb,en;q=0.5
Accept-Encodinggzip,deflate
Accept-CharsetISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive300
Connectionkeep-alive
Refererhttp://khall.####.###.######.com/
CookiePHPSESSID=abf5056e1289d3010448107632a1c1bd

As you can see, the cache control is modified to include: 

no-store, no-cache, must-revalidate, post-check=0, pre-check=0

My suspicion is towards the session cookie being sent in the request.  Does anybody know a way to send the header that I require, yet still keep the session in the request?  My application is run through a bootstrap, and sessions are handled using Zend_Session.
Any help would be appreciated.

A:

You're right by assuming that this behaviour is connected to the session mechanism in PHP.  There is a configuration setting session.cache_limiter that controls the caching HTTP headers that will be sent with the response. The default setting here is nocache which sends 
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

You overwrite all of these headers within your controller besides the Cache-Control-header (you only append your max-age=3600 setting here).
Possible solutions are:

changing the PHP configuration (session.cache_limiter) to e.g. none - but this could introduce problems to other PHP applications
set the session.cache_limiter on each request using session_cache_limiter()
overwrite the full Cache-Control-header in your controller with the designated string

The possible values for session.cache_limiter and session_cache_limiter() are:
none: no header will be sent
nocache:
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

private:
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: private, max-age=10800, pre-check=10800

private_no_expire:
Cache-Control: private, max-age=10800, pre-check=10800

public:
Expires: pageload + 3 hours
Cache-Control: public, max-age=10800

A:

From the Zend_Controller documentation, section 10.9. The Response Object

setHeader($name, $value, $replace =
  false) is used to set an individual
  header. By default, it does not
  replace existing headers of the same
  name in the object; however, setting
  $replace to true will force it to do
  so.

The problem you are having is your max-age=3600 is being appended to the cache-control header, as opposed to replacing it. Try setting the $replace parameter to true.

