php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #19768 Expires header incorrectly set, cannot be overwritten
Submitted: 2002-10-05 11:46 UTC Modified: 2003-04-11 10:50 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: php at savignano dot de Assigned:
Status: Closed Package: Session related
PHP Version: 4.2.1 OS: Win32, Unix
Private report: No CVE-ID: None
 [2002-10-05 11:46 UTC] php at savignano dot de
When using sessions, the Expires header is set to a date in the past (1981) instead of being correctly calculated from the current date plus the session expire time. This leads to re-loading of the resource instead of using cached data in browsers that obey the Expires header and/or use HTTP 1.0.

Additionally, it is not possible to replace the Expires header using the header() function. Trying to do so results in the new correct date being appended after the old incorrect one (separated by a comma) which makes no sense.

The only way to achieve correct Cache-Control and Expires headers is to switch off the automatic session headers by calling session_cache_control('none'), and then set all headers on one's own. However, this is only a work-around.

Patches

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-10-05 11:50 UTC] php at savignano dot de
session_cache_control('none') was meant to read session_cache_limiter('none'). Sorry.
 [2002-10-20 13:04 UTC] sas@php.net
The default value 'nocache' means that the page should not be cached at all. Have a look at php.ini-dist, you probably want  to set session.cache_limiter to 'private'.
 [2002-10-21 14:55 UTC] php at savignano dot de
There seems to be a misunderstanding:

Using session_cache_limiter("private") will create the malformed Expires headers mentioned in my bug report.
 [2002-10-26 11:08 UTC] php at savignano dot de
I did use "private", but this causes incorrect Expires headers as described. That's why I switched to "none" and created the headers myself.
 [2002-10-26 11:23 UTC] php at savignano dot de
Also see my detailed comment on bug #5415
http://bugs.php.net/bug.php?id=5415
 [2002-10-28 23:23 UTC] yohgaki@php.net
Since HTTP/1.0 lacks cache control feature can be found in HTTP/1.1, past date expire header should be sent. 

It's not a bug, but a intended behavior for HTTP/1.0 clients.

See also header() manual page to replace header, but add new one.


 [2002-11-01 09:26 UTC] php at savignano dot de
Judging from http://www.w3.org/Protocols/HTTP/1.0/spec.html#Expires the Expires header was the intended header in HTTP/1.0 for cache control.

I do not understand why you say, a past header should be sent instead of a correct date.

header() doesn't enable me to replace an Expires header, as stated in my original report.
 [2003-04-07 13:36 UTC] shiflett@php.net
I do not think it has been explained very well yet, but PHP's behavior appears to be correct. The use of an Expires header with an expired date is to ensure backwards compatibility with HTTP/1.0 agents. Since Cache-Control is new, changing the value from nocache to private (or anything else) makes no difference with older agents that ignore it completely. However, for HTTP/1.1 agents, the Cache-Control directives override the Expires header, so that fine-tuned caching is possible.

For more information, look at section 14.9.3 of RFC 2616. Here is the most relevant part:

"If a response includes both an Expires header and a max-age directive, the max-age directive overrides the Expires header, even if the Expires header is more restrictive. This rule allows an origin server to provide, for a given response, a longer expiration time to an HTTP/1.1 (or later) cache than to an HTTP/1.0 cache. This might be useful if certain HTTP/1.0 caches improperly calculate ages or expiration times, perhaps due to desynchronized clocks.

"Many HTTP/1.0 cache implementations will treat an Expires value that is less than or equal to the response Date value as being equivalent to the Cache-Control response directive "no-cache". If an HTTP/1.1 cache receives such a response, and the response does not include a Cache-Control header field, it SHOULD consider the response to be non-cacheable in order to retain compatibility with HTTP/1.0 servers.

"Note: An origin server might wish to use a relatively new HTTP cache control feature, such as the "private" directive, on a network including older caches that do not understand that feature. The origin server will need to combine the new feature with an Expires field whose value is less than or equal to the Date value. This will prevent older caches from improperly caching the response."
 [2003-04-11 10:50 UTC] php at savignano dot de
Very well explained, shiflett@php.net - I see your point, and I have to admit that now this behaviour seems correct to me, too.

Thank you!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Aug 17 15:01:29 2024 UTC