Source for file Response.php
Documentation is available at Response.php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 fdm=marker encoding=utf8 :
* Pxxo - build self-supported and interoperable Web graphical components
* Copyright (c) 2008, Nicolas Thouvenin
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the author nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @copyright Copyright (c) 2008 Nicolas Thouvenin
* @license http://opensource.org/licenses/bsd-license.php
* Classe de Gestion de l'entete HTTP
* Cette classe reprend la classe de Hugo Haas (http://larve.net/2006/08/php-http-caching/)
* et lui ajoute quelques bricoles
* @copyright Copyright (c) 2008 Nicolas Thouvenin
* @license http://opensource.org/licenses/bsd-license.php
* Array containing the list of Cache-Control directives, except max-age and s-maxage
* allowed Cache Control Directives
* Array containing the list of Cache-Control directives, except max-age and s-maxage
* allowed Content Directives
* var array Ages: max-age and s-maxage
* @var string Last-Modified and ETags
* @var array URL et Status Code
* @var array cookies will be send
* Send HTTP caching headers (Expires, Cache-Control, ETags and
* Last-Modified), and returns a 304 if the client has a cached version.
* This function returns a 304 if the client already has the latest version
* of the resource's representation. The PHP
* script will subsequently quit if $die is set to true.
* @param $die if set to true, the program terminates if a 304 is being sent, and if set to false, the call will return and the execution will continue
if ($die ==
true) exit();
$isFresh =
$_SERVER['REQUEST_METHOD'] ==
"GET" ?
$this->isFresh() :
false;
header('HTTP/1.1 304 Not Modified');
if ($isFresh ==
true &&
$die ==
true) exit();
* Send HTTP caching headers (Expires, Cache-Control, ETags and Last-Modified)
* Expires and Cache-Control are sent as set.
* ETag is sent if set. Last-Modified is sent if set or if ETag isn't set,
* defaulting to the current time.
* Indeed, at least you of the two needs to be present for the response
header('X-Powered-By: Pxxo/5.x', false);
foreach($this->cookies as $key =>
$value) {
header('Set-Cookie: '.
$value, false);
// Expires corresponds to max-age
if ($this->ages['max-age'] >=
0) {
header('Expires: ' .
self::formatDate(time() +
$this->ages['max-age']), 1);
foreach($this->ages as $dir =>
$value) {
// At least one of ETags of Last-Modified will be sent for cacheability
} else if (!$this->eTag) {
header('Last-Modified: ' .
self::formatDate($lm));
* Determines whether the client has a fresh representation of the resource.
* This function compares the If-Modified-Since and If-None-Match headers
* provided by the client to the values specified for this resource, and
* returns true if the resource has been modified or false if the client's
* @return true if the version the client has is fresh, false if this is not the case and a new version needs to be returned
if (!isset
($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
!isset
($_SERVER['HTTP_IF_NONE_MATCH'])) {
// No information provided by the client
if (isset
($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
! $this->eTag) {
// Split the If-Modified-Since (Netscape < v6 gets this wrong)
$ifModifiedSince =
explode(';', $_SERVER['HTTP_IF_MODIFIED_SINCE']);
// Turn the client request If-Modified-Since into a timestamp
$ifModifiedSince =
strtotime($ifModifiedSince[0]);
// Compare timestamps (FIXME: make this test '!='?)
if (isset
($_SERVER['HTTP_IF_NONE_MATCH']) &&
$this->eTag) {
if ($_SERVER['HTTP_IF_NONE_MATCH'] ==
'*') {
$etags =
preg_split('/,\s*/', $_SERVER['HTTP_IF_NONE_MATCH']);
* Compares an etag with the resource's entity tag.
* @param $etag Entity tag to compare
* @return true if they match, false if they don't
if ((self::isEtagWeak($this->eTag) ||
self::isEtagWeak($etag))
($_SERVER['REQUEST_METHOD'] !=
"GET" || isset
($_SERVER['HTTP_RANGE'])))
// Weak validation only works for non-subrange GET requests
if (self::etagValidator($this->eTag) ==
self::etagValidator($etag)) {
* Determines if an entity tag is weak
* @param $etag Entity tag
* @return true if the entity tag is weak, false otherwise
* Returns the validator value of an entity tag
* @param $etag Entity tag
* @return The validator value ($etag if the entity tag is strong, or what's after 'W/' otherwise)
if (self::isEtagWeak($etag)) {
* Sets Location header and response code. Forces replacement of any prior redirects.
* Get the max-age or s-maxage cache control directive value
* @param $type "max-age" or "s-maxage"
* @return The value in seconds; if -1 is returned, no max-age directive will be sent
if ($type !=
"max-age" &&
$type !=
"s-maxage") {
return trigger_error('Invalid type in getDuration : `'.
$type.
' is unknown', E_USER_NOTICE);
return $this->ages[$type];
* Set max-age or s-maxage cache control directive value
* @param $type "max-age" or "s-maxage"
* @param $time Duration as a positive number of seconds, a string
* for strtotime(), or a negative number to disable this directive
if ($type !=
"max-age" &&
$type !=
"s-maxage") {
return trigger_error('Invalid type in setDuration : `'.
$type.
' is unknown', E_USER_NOTICE);
return trigger_error('Invalid time in setDuration : Bad interval specified to strtotime()', E_USER_NOTICE);
return $this->ages[$type] =
$time;
* Set max-age and the Expires header value
* @param $time Duration as a positive number of seconds, a string
* for strtotime(), or a negative number to disable this directive
* Set/unset Cache-Control directive
* @param string $type Cache-Control directive (e.g. "public")
* @param boolean $set true or false to set or unset the parameter
return trigger_error('Invalid type in setCacheDirective : `'.
$type.
' is unknown', E_USER_NOTICE);
* Set/unset Content directive
* @param string $type Content directive (e.g. "type")
return trigger_error('Invalid type in setContentDirective : `'.
$type.
' is unknown', E_USER_NOTICE);
* Set value of the ETag header
* The string will be quoted automatically.
* @param string $value Value (string)
$this->eTag =
'"' .
$value .
'"';
* Set value of the ETag header to a weak value
* The string will be quoted automatically.
* @param string $value Value (string)
* Set value of the Last-Modified header
* @param string $value Unix timestamp
* Set value of the Last-Modified header using the last modification date of a file
* @param string $file File whose modification time will be used
* Format a date in RFC 1123 date format
* @param string $time Time since epoch in seconds
* @return string Formatted date (e.g. "Sun, 27 Aug 2006 08:32:28 GMT")
return gmdate("D, d M Y H:i:s", $time) .
' GMT';
* setCookie (RFC 2109 compatible)
* @param string Name of the cookie
* @param string Value of the cookie
* @param int Lifetime of the cookie
* @param string Path where the cookie can be used
* @param string Domain which can read the cookie
* @param bool Secure mode?
* @param bool Only allow HTTP usage?
* @return bool True or false whether the method has successfully run
function addCookie($name, $value=
'', $maxage=
0, $path=
'', $domain=
'', $secure=
false, $HTTPOnly=
false)
// Abort the method if headers have already been sent, except when output buffering has been enabled
// Fix the domain to accept domains with and without 'www.'.
// Add the dot prefix to ensure compatibility with subdomains
if ( substr($domain, 0, 1) !=
'.' ) $domain =
'.'.
$domain;
// Remove port information.
if ( $port !==
false ) $domain =
substr($domain, 0, $port);
.
(empty($domain) ?
'' :
'; Domain='.
$domain)
.
(empty($maxage) ?
'' :
'; Max-Age='.
$maxage)
.
(empty($path) ?
'' :
'; Path='.
$path)
.
(!$secure ?
'' :
'; Secure')
.
(!$HTTPOnly ?
'' :
'; HttpOnly');
Documentation generated on Thu, 13 Mar 2008 22:03:22 +0100 by phpDocumentor 1.4.1