11

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

Date
Wed, 25 Mar 2009 10:34:40 GMT
Server
Apache/2.2.3 (Ubuntu) mod_ssl/2.2.3 OpenSSL/0.9.8c
Expires
Thu, 26 Mar 2009 10:34:41 GMT
Cache-Control
no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=3600
Last-Modified
1234872514
Etag
d3ef646c640b689b0101f3e03e08a524
Content-Length
1452
X-UA-Compatible
IE=EmulateIE7
X-Robots-Tag
noindex
Keep-Alive
timeout=15, max=100
Connection
Keep-Alive
Content-Type
image/jpeg

Request Headers

Host
khall.####.###.######.com
User-Agent
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009030422 Ubuntu/8.04 (hardy) Firefox/3.0 .7
Accept
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language
en-gb,en;q=0.5
Accept-Encoding
gzip,deflate
Accept-Charset
ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive
300
Connection
keep-alive
Referer
http://khall.####.###.######.com/
Cookie
PHPSESSID=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.

2 Answers 2

29

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:

  1. changing the PHP configuration (session.cache_limiter) to e.g. none - but this could introduce problems to other PHP applications
  2. set the session.cache_limiter on each request using session_cache_limiter()
  3. 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
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply. The problem was my hasty coding, as karim79 pointed out: the problem is more Zend Framework based. Thanks for the insight, though.
13

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.

2 Comments

GAH! I should smack myself in the face. I thought I was passing that parameter! You are quite right though, that is the answer.
Hehe, I do it all the time! Proof? see stackoverflow.com/questions/657600/…

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.