291 lines
7.7 KiB
PHP
291 lines
7.7 KiB
PHP
<?php
|
|
|
|
namespace Symfony\Components\HttpKernel;
|
|
|
|
/*
|
|
* This file is part of the Symfony framework.
|
|
*
|
|
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
|
*
|
|
* This source file is subject to the MIT license that is bundled
|
|
* with this source code in the file LICENSE.
|
|
*/
|
|
|
|
/**
|
|
* CacheControl is a wrapper for the Cache-Control HTTP header.
|
|
*
|
|
* This class knows about allowed attributes
|
|
* (and those that only apply to requests or responses).
|
|
*
|
|
* @package Symfony
|
|
* @subpackage Components_HttpKernel
|
|
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
|
*/
|
|
class CacheControl
|
|
{
|
|
protected $bag;
|
|
protected $attributes;
|
|
protected $type;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param Symfony\Components\HttpKernel\HeaderBag $bag A HeaderBag instance
|
|
* @param string $header The value of the Cache-Control HTTP header
|
|
* @param string $type The type (null, request, or response)
|
|
*/
|
|
public function __construct(HeaderBag $bag, $header, $type = null)
|
|
{
|
|
if (null !== $type && !in_array($type, array('request', 'response'))) {
|
|
throw new \InvalidArgumentException(sprintf('The "%s" type is not supported by the CacheControl constructor.', $type));
|
|
}
|
|
$this->type = $type;
|
|
|
|
$this->bag = $bag;
|
|
$this->attributes = $this->parse($header);
|
|
}
|
|
|
|
public function __toString()
|
|
{
|
|
$parts = array();
|
|
ksort($this->attributes);
|
|
foreach ($this->attributes as $key => $value) {
|
|
if (true === $value) {
|
|
$parts[] = $key;
|
|
} else {
|
|
if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
|
|
$value = '"'.$value.'"';
|
|
}
|
|
|
|
$parts[] = "$key=$value";
|
|
}
|
|
}
|
|
|
|
return implode(',', $parts);
|
|
}
|
|
|
|
public function getMaxStale()
|
|
{
|
|
$this->checkAttribute('max-stale', 'request');
|
|
|
|
return array_key_exists('max-stale', $this->attributes) ? $this->attributes['max-stale'] : false;
|
|
}
|
|
|
|
public function setMaxStale($value)
|
|
{
|
|
$this->checkAttribute('max-stale', 'request');
|
|
|
|
$this->setValue('max-stale', $value);
|
|
}
|
|
|
|
public function getMinFresh()
|
|
{
|
|
$this->checkAttribute('min-fresh', 'request');
|
|
|
|
return array_key_exists('min-fresh', $this->attributes) ? $this->attributes['min-fresh'] : false;
|
|
}
|
|
|
|
public function setMinFresh($value)
|
|
{
|
|
$this->checkAttribute('min-fresh', 'request');
|
|
|
|
$this->setValue('min-fresh', $value);
|
|
}
|
|
|
|
public function isOnlyIfCached()
|
|
{
|
|
$this->checkAttribute('only-if-cached', 'request');
|
|
|
|
return array_key_exists('only-if-cached', $this->attributes);
|
|
}
|
|
|
|
public function setOnlyIfCached($value)
|
|
{
|
|
$this->checkAttribute('only-if-cached', 'request');
|
|
|
|
$this->setValue('only-if-cached', $value, true);
|
|
}
|
|
|
|
public function isPublic()
|
|
{
|
|
$this->checkAttribute('public', 'response');
|
|
|
|
return array_key_exists('public', $this->attributes);
|
|
}
|
|
|
|
public function setPublic($value)
|
|
{
|
|
$this->checkAttribute('public', 'response');
|
|
|
|
$this->setValue('public', $value, true);
|
|
}
|
|
|
|
public function isPrivate()
|
|
{
|
|
$this->checkAttribute('private', 'response');
|
|
|
|
return array_key_exists('private', $this->attributes);
|
|
}
|
|
|
|
public function getPrivate()
|
|
{
|
|
$this->checkAttribute('private', 'response');
|
|
|
|
return array_key_exists('private', $this->attributes) ? $this->attributes['private'] : false;
|
|
}
|
|
|
|
public function setPrivate($value)
|
|
{
|
|
$this->checkAttribute('private', 'response');
|
|
|
|
$this->setValue('private', $value, true);
|
|
}
|
|
|
|
public function isNoCache()
|
|
{
|
|
return array_key_exists('no-cache', $this->attributes);
|
|
}
|
|
|
|
public function getNoCache()
|
|
{
|
|
return array_key_exists('no-cache', $this->attributes) ? $this->attributes['no-cache'] : false;
|
|
}
|
|
|
|
public function setNoCache($value)
|
|
{
|
|
$this->setValue('no-cache', $value, true);
|
|
}
|
|
|
|
public function isNoStore()
|
|
{
|
|
return array_key_exists('no-store', $this->attributes);
|
|
}
|
|
|
|
public function setNoStore($value)
|
|
{
|
|
$this->setValue('no-store', $value, true);
|
|
}
|
|
|
|
public function isNoTransform()
|
|
{
|
|
return array_key_exists('no-tranform', $this->attributes);
|
|
}
|
|
|
|
public function setNoTransform($value)
|
|
{
|
|
$this->setValue('no-transform', $value, true);
|
|
}
|
|
|
|
public function getMaxAge()
|
|
{
|
|
return array_key_exists('max-age', $this->attributes) ? $this->attributes['max-age'] : null;
|
|
}
|
|
|
|
public function setMaxAge($age)
|
|
{
|
|
$this->setValue('max-age', (integer) $age);
|
|
}
|
|
|
|
public function getSharedMaxAge()
|
|
{
|
|
$this->checkAttribute('s-maxage', 'response');
|
|
|
|
return array_key_exists('s-maxage', $this->attributes) ? $this->attributes['s-maxage'] : null;
|
|
}
|
|
|
|
public function setSharedMaxAge($age)
|
|
{
|
|
$this->checkAttribute('s-maxage', 'response');
|
|
|
|
$this->setValue('s-maxage', (integer) $age);
|
|
}
|
|
|
|
public function setStaleWhileRevalidate($age)
|
|
{
|
|
$this->checkAttribute('stale-while-revalidate', 'response');
|
|
|
|
$this->setValue('stale-while-revalidate', (integer) $age);
|
|
}
|
|
|
|
public function getStaleWhileRevalidate()
|
|
{
|
|
$this->checkAttribute('stale-while-revalidate', 'response');
|
|
|
|
return array_key_exists('stale-while-revalidate', $this->attributes) ? $this->attributes['stale-while-revalidate'] : null;
|
|
}
|
|
|
|
public function setStaleIfError($age)
|
|
{
|
|
$this->setValue('stale-if-error', (integer) $age);
|
|
}
|
|
|
|
public function getStaleIfError()
|
|
{
|
|
return array_key_exists('stale-if-error', $this->attributes) ? $this->attributes['stale-if-error'] : null;
|
|
}
|
|
|
|
public function mustRevalidate()
|
|
{
|
|
$this->checkAttribute('must-revalidate', 'response');
|
|
|
|
return array_key_exists('must-revalidate', $this->attributes);
|
|
}
|
|
|
|
public function setMustRevalidate($value)
|
|
{
|
|
$this->checkAttribute('must-revalidate', 'response');
|
|
|
|
$this->setValue('must-revalidate', $value);
|
|
}
|
|
|
|
public function mustProxyRevalidate()
|
|
{
|
|
$this->checkAttribute('proxy-revalidate', 'response');
|
|
|
|
return array_key_exists('proxy-revalidate', $this->attributes);
|
|
}
|
|
|
|
public function setProxyRevalidate($value)
|
|
{
|
|
$this->checkAttribute('proxy-revalidate', 'response');
|
|
|
|
$this->setValue('proxy-revalidate', $value);
|
|
}
|
|
|
|
/**
|
|
* Parses a Cache-Control HTTP header.
|
|
*
|
|
* @param string $header The value of the Cache-Control HTTP header
|
|
*
|
|
* @param array An array representing the attribute values
|
|
*/
|
|
protected function parse($header)
|
|
{
|
|
$attributes = array();
|
|
preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
|
|
foreach ($matches as $match) {
|
|
$attributes[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true);
|
|
}
|
|
|
|
return $attributes;
|
|
}
|
|
|
|
protected function setValue($key, $value, $isBoolean = false)
|
|
{
|
|
if (false === $value) {
|
|
unset($this->attributes[$key]);
|
|
} else {
|
|
$this->attributes[$key] = $isBoolean ? true : $value;
|
|
}
|
|
|
|
$this->bag->set('Cache-Control', (string) $this);
|
|
}
|
|
|
|
protected function checkAttribute($name, $expected)
|
|
{
|
|
if (null !== $this->type && $expected !== $this->type) {
|
|
throw new \LogicException(sprintf("The property %s only applies to the %s Cache-Control.", $name, $expected));
|
|
}
|
|
}
|
|
}
|