changed Cache-Control default value behavior
The PHP native cache limiter feature has been disabled as this is now managed by the HeaderBag class directly instead (see below.) The HeaderBag class uses the following rules to define a sensible and convervative default value for the Response 'Cache-Control' header: * If no cache header is defined ('Cache-Control', 'ETag', 'Last-Modified', and 'Expires'), 'Cache-Control' is set to 'no-cache'; * If 'Cache-Control' is empty, its value is set to "private, max-age=0, must-revalidate"; * But if at least one 'Cache-Control' directive is set, and no 'public' or 'private' directives have been explicitely added, Symfony2 adds the 'private' directive automatically (except when 's-maxage' is set.) So, remember to explicitly add the 'public' directive to 'Cache-Control' when you want shared caches to store your application resources: // The Response is private by default $response->setEtag($etag); $response->setLastModified($date); $response->setMaxAge(10); // Change the Response to be public $response->setPublic(); // Set cache settings in one call $response->setCache(array( 'etag' => $etag, 'last_modified' => $date, 'max_age' => 10, 'public' => true, ));
This commit is contained in:
parent
d9239d1c64
commit
b6923dd7b9
@ -1,288 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
/*
|
||||
* 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).
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class CacheControl
|
||||
{
|
||||
protected $bag;
|
||||
protected $attributes;
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param 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
|
||||
*
|
||||
* @return 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));
|
||||
}
|
||||
}
|
||||
}
|
@ -20,22 +20,16 @@ class HeaderBag
|
||||
{
|
||||
protected $headers;
|
||||
protected $cacheControl;
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $headers An array of HTTP headers
|
||||
* @param string $type The type (null, request, or response)
|
||||
* @param array $headers An array of HTTP headers
|
||||
*/
|
||||
public function __construct(array $headers = array(), $type = null)
|
||||
public function __construct(array $headers = array())
|
||||
{
|
||||
$this->cacheControl = array();
|
||||
$this->replace($headers);
|
||||
|
||||
if (null !== $type && !in_array($type, array('request', 'response'))) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" type is not supported by the HeaderBag constructor.', $type));
|
||||
}
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,7 +59,6 @@ class HeaderBag
|
||||
*/
|
||||
public function replace(array $headers = array())
|
||||
{
|
||||
$this->cacheControl = null;
|
||||
$this->headers = array();
|
||||
foreach ($headers as $key => $values) {
|
||||
$this->set($key, $values);
|
||||
@ -120,6 +113,10 @@ class HeaderBag
|
||||
} else {
|
||||
$this->headers[$key] = array_merge($this->headers[$key], $values);
|
||||
}
|
||||
|
||||
if ('cache-control' === $key) {
|
||||
$this->cacheControl = $this->parseCacheControl($values[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,21 +151,13 @@ class HeaderBag
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
unset($this->headers[strtr(strtolower($key), '_', '-')]);
|
||||
}
|
||||
$key = strtr(strtolower($key), '_', '-');
|
||||
|
||||
/**
|
||||
* Returns an instance able to manage the Cache-Control header.
|
||||
*
|
||||
* @return CacheControl A CacheControl instance
|
||||
*/
|
||||
public function getCacheControl()
|
||||
{
|
||||
if (null === $this->cacheControl) {
|
||||
$this->cacheControl = new CacheControl($this, $this->get('Cache-Control'), $this->type);
|
||||
unset($this->headers[$key]);
|
||||
|
||||
if ('cache-control' === $key) {
|
||||
$this->cacheControl = array();
|
||||
}
|
||||
|
||||
return $this->cacheControl;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,55 +175,9 @@ class HeaderBag
|
||||
*/
|
||||
public function setCookie($name, $value, $domain = null, $expires = null, $path = '/', $secure = false, $httponly = true)
|
||||
{
|
||||
// from PHP source code
|
||||
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
|
||||
throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
|
||||
}
|
||||
$this->validateCookieName($name, $value);
|
||||
|
||||
if (preg_match("/[,; \t\r\n\013\014]/", $value)) {
|
||||
throw new \InvalidArgumentException(sprintf('The cookie value "%s" contains invalid characters.', $name));
|
||||
}
|
||||
|
||||
if (!$name) {
|
||||
throw new \InvalidArgumentException('The cookie name cannot be empty');
|
||||
}
|
||||
|
||||
$cookie = sprintf('%s=%s', $name, urlencode($value));
|
||||
|
||||
if ('request' === $this->type) {
|
||||
return $this->set('Cookie', $cookie);
|
||||
}
|
||||
|
||||
if (null !== $expires) {
|
||||
if (is_numeric($expires)) {
|
||||
$expires = (int) $expires;
|
||||
} elseif ($expires instanceof \DateTime) {
|
||||
$expires = $expires->getTimestamp();
|
||||
} else {
|
||||
$expires = strtotime($expires);
|
||||
if (false === $expires || -1 == $expires) {
|
||||
throw new \InvalidArgumentException(sprintf('The "expires" cookie parameter is not valid.', $expires));
|
||||
}
|
||||
}
|
||||
|
||||
$cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $expires, new \DateTimeZone('UTC'))->format('D, d-M-Y H:i:s T'), 0, -5);
|
||||
}
|
||||
|
||||
if ($domain) {
|
||||
$cookie .= '; domain='.$domain;
|
||||
}
|
||||
|
||||
$cookie .= '; path='.$path;
|
||||
|
||||
if ($secure) {
|
||||
$cookie .= '; secure';
|
||||
}
|
||||
|
||||
if ($httponly) {
|
||||
$cookie .= '; httponly';
|
||||
}
|
||||
|
||||
$this->set('Set-Cookie', $cookie, false);
|
||||
return $this->set('Cookie', sprintf('%s=%s', $name, urlencode($value)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,15 +201,80 @@ class HeaderBag
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a HTTP header name.
|
||||
*
|
||||
* @param string $key The HTTP header name
|
||||
*
|
||||
* @return string The normalized HTTP header name
|
||||
*/
|
||||
static public function normalizeHeaderName($key)
|
||||
public function addCacheControlDirective($key, $value = true)
|
||||
{
|
||||
return strtr(strtolower($key), '_', '-');
|
||||
$this->cacheControl[$key] = $value;
|
||||
|
||||
$this->set('Cache-Control', $this->getCacheControlHeader());
|
||||
}
|
||||
|
||||
public function hasCacheControlDirective($key)
|
||||
{
|
||||
return array_key_exists($key, $this->cacheControl);
|
||||
}
|
||||
|
||||
public function getCacheControlDirective($key)
|
||||
{
|
||||
return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
|
||||
}
|
||||
|
||||
public function removeCacheControlDirective($key)
|
||||
{
|
||||
unset($this->cacheControl[$key]);
|
||||
|
||||
$this->set('Cache-Control', $this->getCacheControlHeader());
|
||||
}
|
||||
|
||||
protected function getCacheControlHeader()
|
||||
{
|
||||
$parts = array();
|
||||
ksort($this->cacheControl);
|
||||
foreach ($this->cacheControl 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Cache-Control HTTP header.
|
||||
*
|
||||
* @param string $header The value of the Cache-Control HTTP header
|
||||
*
|
||||
* @return array An array representing the attribute values
|
||||
*/
|
||||
protected function parseCacheControl($header)
|
||||
{
|
||||
$cacheControl = array();
|
||||
preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
|
||||
foreach ($matches as $match) {
|
||||
$cacheControl[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true);
|
||||
}
|
||||
|
||||
return $cacheControl;
|
||||
}
|
||||
|
||||
protected function validateCookie($name, $value)
|
||||
{
|
||||
// from PHP source code
|
||||
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
|
||||
throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
|
||||
}
|
||||
|
||||
if (preg_match("/[,; \t\r\n\013\014]/", $value)) {
|
||||
throw new \InvalidArgumentException(sprintf('The cookie value "%s" contains invalid characters.', $name));
|
||||
}
|
||||
|
||||
if (!$name) {
|
||||
throw new \InvalidArgumentException('The cookie name cannot be empty');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ class Request
|
||||
$this->cookies = new ParameterBag(null !== $cookies ? $cookies : $_COOKIE);
|
||||
$this->files = new ParameterBag($this->convertFileInformation(null !== $files ? $files : $_FILES));
|
||||
$this->server = new ParameterBag(null !== $server ? $server : $_SERVER);
|
||||
$this->headers = new HeaderBag($this->initializeHeaders(), 'request');
|
||||
$this->headers = new HeaderBag($this->initializeHeaders());
|
||||
|
||||
$this->languages = null;
|
||||
$this->charsets = null;
|
||||
@ -617,7 +617,7 @@ class Request
|
||||
|
||||
public function isNoCache()
|
||||
{
|
||||
return $this->headers->getCacheControl()->isNoCache() || 'no-cache' == $this->headers->get('Pragma');
|
||||
return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,7 +83,7 @@ class Response
|
||||
$this->setContent($content);
|
||||
$this->setStatusCode($status);
|
||||
$this->setProtocolVersion('1.0');
|
||||
$this->headers = new HeaderBag($headers, 'response');
|
||||
$this->headers = new ResponseHeaderBag($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,7 +244,7 @@ class Response
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->headers->getCacheControl()->isNoStore() || $this->headers->getCacheControl()->isPrivate()) {
|
||||
if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -283,8 +283,8 @@ class Response
|
||||
*/
|
||||
public function setPrivate()
|
||||
{
|
||||
$this->headers->getCacheControl()->setPublic(false);
|
||||
$this->headers->getCacheControl()->setPrivate(true);
|
||||
$this->headers->removeCacheControlDirective('public');
|
||||
$this->headers->addCacheControlDirective('private');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -294,8 +294,8 @@ class Response
|
||||
*/
|
||||
public function setPublic()
|
||||
{
|
||||
$this->headers->getCacheControl()->setPublic(true);
|
||||
$this->headers->getCacheControl()->setPrivate(false);
|
||||
$this->headers->addCacheControlDirective('public');
|
||||
$this->headers->removeCacheControlDirective('private');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -310,7 +310,7 @@ class Response
|
||||
*/
|
||||
public function mustRevalidate()
|
||||
{
|
||||
return $this->headers->getCacheControl()->mustRevalidate() || $this->headers->getCacheControl()->mustProxyRevalidate();
|
||||
return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->has('must-proxy-revalidate');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -395,11 +395,11 @@ class Response
|
||||
*/
|
||||
public function getMaxAge()
|
||||
{
|
||||
if ($age = $this->headers->getCacheControl()->getSharedMaxAge()) {
|
||||
if ($age = $this->headers->getCacheControlDirective('s-maxage')) {
|
||||
return $age;
|
||||
}
|
||||
|
||||
if ($age = $this->headers->getCacheControl()->getMaxAge()) {
|
||||
if ($age = $this->headers->getCacheControlDirective('max-age')) {
|
||||
return $age;
|
||||
}
|
||||
|
||||
@ -419,7 +419,7 @@ class Response
|
||||
*/
|
||||
public function setMaxAge($value)
|
||||
{
|
||||
$this->headers->getCacheControl()->setMaxAge($value);
|
||||
$this->headers->addCacheControlDirective('max-age', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -431,7 +431,7 @@ class Response
|
||||
*/
|
||||
public function setSharedMaxAge($value)
|
||||
{
|
||||
$this->headers->getCacheControl()->setSharedMaxAge($value);
|
||||
$this->headers->addCacheControlDirective('s-maxage', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
141
src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
Normal file
141
src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ResponseHeaderBag is a container for Response HTTP headers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class ResponseHeaderBag extends HeaderBag
|
||||
{
|
||||
protected $computedCacheControl = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function replace(array $headers = array())
|
||||
{
|
||||
parent::replace($headers);
|
||||
|
||||
if (!isset($this->headers['cache-control'])) {
|
||||
$this->set('cache-control', '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($key, $values, $replace = true)
|
||||
{
|
||||
parent::set($key, $values, $replace);
|
||||
|
||||
if ('cache-control' === strtr(strtolower($key), '_', '-')) {
|
||||
$computed = $this->computeCacheControlValue();
|
||||
$this->headers['cache-control'] = array($computed);
|
||||
$this->computedCacheControl = $this->parseCacheControl($computed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
parent::delete($key);
|
||||
|
||||
if ('cache-control' === strtr(strtolower($key), '_', '-')) {
|
||||
$this->computedCacheControl = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setCookie($name, $value, $domain = null, $expires = null, $path = '/', $secure = false, $httponly = true)
|
||||
{
|
||||
$this->validateCookieName($name, $value);
|
||||
|
||||
$cookie = sprintf('%s=%s', $name, urlencode($value));
|
||||
|
||||
if (null !== $expires) {
|
||||
if (is_numeric($expires)) {
|
||||
$expires = (int) $expires;
|
||||
} elseif ($expires instanceof \DateTime) {
|
||||
$expires = $expires->getTimestamp();
|
||||
} else {
|
||||
$expires = strtotime($expires);
|
||||
if (false === $expires || -1 == $expires) {
|
||||
throw new \InvalidArgumentException(sprintf('The "expires" cookie parameter is not valid.', $expires));
|
||||
}
|
||||
}
|
||||
|
||||
$cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $expires, new \DateTimeZone('UTC'))->format('D, d-M-Y H:i:s T'), 0, -5);
|
||||
}
|
||||
|
||||
if ($domain) {
|
||||
$cookie .= '; domain='.$domain;
|
||||
}
|
||||
|
||||
$cookie .= '; path='.$path;
|
||||
|
||||
if ($secure) {
|
||||
$cookie .= '; secure';
|
||||
}
|
||||
|
||||
if ($httponly) {
|
||||
$cookie .= '; httponly';
|
||||
}
|
||||
|
||||
$this->set('Set-Cookie', $cookie, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasCacheControlDirective($key)
|
||||
{
|
||||
return array_key_exists($key, $this->computedCacheControl);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheControlDirective($key)
|
||||
{
|
||||
return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null;
|
||||
}
|
||||
|
||||
protected function computeCacheControlValue()
|
||||
{
|
||||
if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
|
||||
return 'no-cache';
|
||||
}
|
||||
|
||||
if (!$this->cacheControl) {
|
||||
// conservative by default
|
||||
return 'private, max-age=0, must-revalidate';
|
||||
}
|
||||
|
||||
$header = $this->getCacheControlHeader();
|
||||
if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
|
||||
return $header;
|
||||
}
|
||||
|
||||
// public if s-maxage is defined, private otherwise
|
||||
if (!isset($this->cacheControl['s-maxage'])) {
|
||||
return $header.', private';
|
||||
}
|
||||
|
||||
return $header;
|
||||
}
|
||||
}
|
@ -49,7 +49,6 @@ class NativeSessionStorage implements SessionStorageInterface
|
||||
'domain' => $cookieDefaults['domain'],
|
||||
'secure' => $cookieDefaults['secure'],
|
||||
'httponly' => isset($cookieDefaults['httponly']) ? $cookieDefaults['httponly'] : false,
|
||||
'cache_limiter' => 'none',
|
||||
), $options);
|
||||
|
||||
session_name($this->options['name']);
|
||||
@ -72,9 +71,8 @@ class NativeSessionStorage implements SessionStorageInterface
|
||||
$this->options['httponly']
|
||||
);
|
||||
|
||||
if (null !== $this->options['cache_limiter']) {
|
||||
session_cache_limiter($this->options['cache_limiter']);
|
||||
}
|
||||
// disable native cache limiter as this is managed by HeaderBag directly
|
||||
session_cache_limiter(false);
|
||||
|
||||
if (!ini_get('session.use_cookies') && $this->options['id'] && $this->options['id'] != session_id()) {
|
||||
session_id($this->options['id']);
|
||||
|
@ -343,9 +343,9 @@ class Cache implements HttpKernelInterface
|
||||
|
||||
$response = $this->forward($subRequest);
|
||||
|
||||
if ($this->isPrivateRequest($request) && !$response->headers->getCacheControl()->isPublic()) {
|
||||
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
|
||||
$response->setPrivate(true);
|
||||
} elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControl()->mustRevalidate()) {
|
||||
} elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) {
|
||||
$response->setTtl($this->options['default_ttl']);
|
||||
}
|
||||
|
||||
@ -377,7 +377,7 @@ class Cache implements HttpKernelInterface
|
||||
|
||||
// we don't implement the stale-if-error on Requests, which is nonetheless part of the RFC
|
||||
if (null !== $entry && in_array($response->getStatusCode(), array(500, 502, 503, 504))) {
|
||||
if (null === $age = $entry->headers->getCacheControl()->getStaleIfError()) {
|
||||
if (null === $age = $entry->headers->getCacheControlDirective('stale-if-error')) {
|
||||
$age = $this->options['stale_if_error'];
|
||||
}
|
||||
|
||||
@ -407,7 +407,7 @@ class Cache implements HttpKernelInterface
|
||||
return $this->lock($request, $entry);
|
||||
}
|
||||
|
||||
if ($this->options['allow_revalidate'] && null !== $maxAge = $request->headers->getCacheControl()->getMaxAge()) {
|
||||
if ($this->options['allow_revalidate'] && null !== $maxAge = $request->headers->getCacheControlDirective('max-age')) {
|
||||
return $maxAge > 0 && $maxAge >= $entry->getAge();
|
||||
}
|
||||
|
||||
@ -430,7 +430,7 @@ class Cache implements HttpKernelInterface
|
||||
// there is already another process calling the backend
|
||||
if (true !== $lock) {
|
||||
// check if we can serve the stale entry
|
||||
if (null === $age = $entry->headers->getCacheControl()->getStaleWhileRevalidate()) {
|
||||
if (null === $age = $entry->headers->getCacheControlDirective('stale-while-revalidate')) {
|
||||
$age = $this->options['stale_while_revalidate'];
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ class Store
|
||||
}
|
||||
|
||||
foreach (preg_split('/[\s,]+/', $vary) as $header) {
|
||||
$key = HeaderBag::normalizeHeaderName($header);
|
||||
$key = strtr(strtolower($header), '_', '-');
|
||||
$v1 = isset($env1[$key]) ? $env1[$key] : null;
|
||||
$v2 = isset($env2[$key]) ? $env2[$key] : null;
|
||||
if ($v1 !== $v2) {
|
||||
|
@ -75,7 +75,7 @@ class RequestDataCollector extends DataCollector
|
||||
|
||||
public function getResponseHeaders()
|
||||
{
|
||||
return new HeaderBag($this->data['response_headers']);
|
||||
return new ResponseHeaderBag($this->data['response_headers']);
|
||||
}
|
||||
|
||||
public function getSessionAttributes()
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
@ -20,24 +21,7 @@ class HeaderBagTest extends \PHPUnit_Framework_TestCase
|
||||
public function testConstructor()
|
||||
{
|
||||
$bag = new HeaderBag(array('foo' => 'bar'));
|
||||
$this->assertTrue( $bag->has('foo'));
|
||||
try {
|
||||
$bag = new HeaderBag(array('foo' => 'bar'), 'nope');
|
||||
$this->assertFalse(TRUE,'nope is not a valid type'); // --> enfore request or response
|
||||
} catch ( \InvalidArgumentException $e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
$bag = new HeaderBag(array('foo' => 'bar'), 'request');
|
||||
} catch ( \Exception $e) {
|
||||
$this->assertFalse(TRUE,'request should be a valid type'); // --> enforce request or response
|
||||
}
|
||||
try {
|
||||
$bag = new HeaderBag(array('foo' => 'bar'), 'response');
|
||||
} catch ( \Exception $e) {
|
||||
$this->assertFalse(TRUE,'response should be a valid type'); // --> enforce request or response
|
||||
}
|
||||
|
||||
$this->assertTrue($bag->has('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +48,6 @@ class HeaderBagTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($bag->has('foo'), '->replace() overrides previously set the input');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers Symfony\Component\HttpFoundation\HeaderBag::get
|
||||
*/
|
||||
@ -103,5 +86,45 @@ class HeaderBagTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse( $bag->contains('foo', 'nope'), '->contains unknown value');
|
||||
}
|
||||
|
||||
public function testCacheControlDirectiveAccessors()
|
||||
{
|
||||
$bag = new HeaderBag();
|
||||
$bag->addCacheControlDirective('public');
|
||||
|
||||
$this->assertTrue($bag->hasCacheControlDirective('public'));
|
||||
$this->assertEquals(true, $bag->getCacheControlDirective('public'));
|
||||
$this->assertEquals('public', $bag->get('cache-control'));
|
||||
|
||||
$bag->addCacheControlDirective('max-age', 10);
|
||||
$this->assertTrue($bag->hasCacheControlDirective('max-age'));
|
||||
$this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
|
||||
$this->assertEquals('max-age=10, public', $bag->get('cache-control'));
|
||||
|
||||
$bag->removeCacheControlDirective('max-age');
|
||||
$this->assertFalse($bag->hasCacheControlDirective('max-age'));
|
||||
}
|
||||
|
||||
public function testCacheControlDirectiveParsing()
|
||||
{
|
||||
$bag = new HeaderBag(array('cache-control' => 'public, max-age=10'));
|
||||
$this->assertTrue($bag->hasCacheControlDirective('public'));
|
||||
$this->assertEquals(true, $bag->getCacheControlDirective('public'));
|
||||
|
||||
$this->assertTrue($bag->hasCacheControlDirective('max-age'));
|
||||
$this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
|
||||
|
||||
$bag->addCacheControlDirective('s-maxage', 100);
|
||||
$this->assertEquals('max-age=10, public, s-maxage=100', $bag->get('cache-control'));
|
||||
}
|
||||
|
||||
public function testCacheControlDirectiveOverrideWithReplace()
|
||||
{
|
||||
$bag = new HeaderBag(array('cache-control' => 'private, max-age=100'));
|
||||
$bag->replace(array('cache-control' => 'public, max-age=10'));
|
||||
$this->assertTrue($bag->hasCacheControlDirective('public'));
|
||||
$this->assertEquals(true, $bag->getCacheControlDirective('public'));
|
||||
|
||||
$this->assertTrue($bag->hasCacheControlDirective('max-age'));
|
||||
$this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Tests\Component\HttpFoundation;
|
||||
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
|
||||
class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCacheControlHeader()
|
||||
{
|
||||
$bag = new ResponseHeaderBag(array(), 'response');
|
||||
$this->assertEquals('no-cache', $bag->get('Cache-Control'));
|
||||
$this->assertTrue($bag->hasCacheControlDirective('no-cache'));
|
||||
|
||||
$bag = new ResponseHeaderBag(array('Cache-Control' => 'public'), 'response');
|
||||
$this->assertEquals('public', $bag->get('Cache-Control'));
|
||||
$this->assertTrue($bag->hasCacheControlDirective('public'));
|
||||
|
||||
$bag = new ResponseHeaderBag(array('ETag' => 'abcde'), 'response');
|
||||
$this->assertEquals('private, max-age=0, must-revalidate', $bag->get('Cache-Control'));
|
||||
$this->assertTrue($bag->hasCacheControlDirective('private'));
|
||||
$this->assertTrue($bag->hasCacheControlDirective('must-revalidate'));
|
||||
$this->assertEquals(0, $bag->getCacheControlDirective('max-age'));
|
||||
|
||||
$bag = new ResponseHeaderBag(array('Last-Modified' => 'abcde'), 'response');
|
||||
$this->assertEquals('private, max-age=0, must-revalidate', $bag->get('Cache-Control'));
|
||||
|
||||
$bag = new ResponseHeaderBag(array('Etag' => 'abcde', 'Last-Modified' => 'abcde'), 'response');
|
||||
$this->assertEquals('private, max-age=0, must-revalidate', $bag->get('Cache-Control'));
|
||||
|
||||
$bag = new ResponseHeaderBag(array('cache-control' => 'max-age=100'), 'response');
|
||||
$this->assertEquals('max-age=100, private', $bag->get('Cache-Control'));
|
||||
|
||||
$bag = new ResponseHeaderBag(array('cache-control' => 's-maxage=100'), 'response');
|
||||
$this->assertEquals('s-maxage=100', $bag->get('Cache-Control'));
|
||||
|
||||
$bag = new ResponseHeaderBag(array('cache-control' => 'private, max-age=100'), 'response');
|
||||
$this->assertEquals('max-age=100, private', $bag->get('Cache-Control'));
|
||||
|
||||
$bag = new ResponseHeaderBag(array('cache-control' => 'public, max-age=100'), 'response');
|
||||
$this->assertEquals('max-age=100, public', $bag->get('Cache-Control'));
|
||||
}
|
||||
}
|
@ -65,16 +65,16 @@ class ResponseTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$response = new Response();
|
||||
$response->headers->set('Cache-Control', 'max-age=100');
|
||||
$response->setPrivate(true);
|
||||
$this->assertEquals(100, $response->headers->getCacheControl()->getMaxAge(), '->isPrivate() adds the private Cache-Control directive when set to true');
|
||||
$this->assertTrue($response->headers->getCacheControl()->isPrivate(), '->isPrivate() adds the private Cache-Control directive when set to true');
|
||||
$response->setPrivate();
|
||||
$this->assertEquals(100, $response->headers->getCacheControlDirective('max-age'), '->isPrivate() adds the private Cache-Control directive when set to true');
|
||||
$this->assertTrue($response->headers->getCacheControlDirective('private'), '->isPrivate() adds the private Cache-Control directive when set to true');
|
||||
|
||||
$response = new Response();
|
||||
$response->headers->set('Cache-Control', 'public, max-age=100');
|
||||
$response->setPrivate(true);
|
||||
$this->assertEquals(100, $response->headers->getCacheControl()->getMaxAge(), '->isPrivate() adds the private Cache-Control directive when set to true');
|
||||
$this->assertTrue($response->headers->getCacheControl()->isPrivate(), '->isPrivate() adds the private Cache-Control directive when set to true');
|
||||
$this->assertFalse($response->headers->getCacheControl()->isPublic(), '->isPrivate() removes the public Cache-Control directive');
|
||||
$response->setPrivate();
|
||||
$this->assertEquals(100, $response->headers->getCacheControlDirective('max-age'), '->isPrivate() adds the private Cache-Control directive when set to true');
|
||||
$this->assertTrue($response->headers->getCacheControlDirective('private'), '->isPrivate() adds the private Cache-Control directive when set to true');
|
||||
$this->assertFalse($response->headers->hasCacheControlDirective('public'), '->isPrivate() removes the public Cache-Control directive');
|
||||
}
|
||||
|
||||
public function testExpire()
|
||||
|
@ -95,7 +95,7 @@ class CacheTest extends CacheTestCase
|
||||
{
|
||||
$time = new \DateTime();
|
||||
|
||||
$this->setNextResponse(200, array('Last-Modified' => $time->format(DATE_RFC2822), 'Content-Type' => 'text/plain'), 'Hello World');
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'Last-Modified' => $time->format(DATE_RFC2822), 'Content-Type' => 'text/plain'), 'Hello World');
|
||||
$this->request('GET', '/', array('HTTP_IF_MODIFIED_SINCE' => $time->format(DATE_RFC2822)));
|
||||
|
||||
$this->assertHttpKernelIsCalled();
|
||||
@ -109,7 +109,7 @@ class CacheTest extends CacheTestCase
|
||||
|
||||
public function testRespondsWith304WhenIfNoneMatchMatchesETag()
|
||||
{
|
||||
$this->setNextResponse(200, array('ETag' => '12345', 'Content-Type' => 'text/plain'), 'Hello World');
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'ETag' => '12345', 'Content-Type' => 'text/plain'), 'Hello World');
|
||||
$this->request('GET', '/', array('HTTP_IF_NONE_MATCH' => '12345'));
|
||||
|
||||
$this->assertHttpKernelIsCalled();
|
||||
@ -201,7 +201,7 @@ class CacheTest extends CacheTestCase
|
||||
{
|
||||
$time = \DateTime::createFromFormat('U', time() + 5);
|
||||
|
||||
$this->setNextResponse(200, array('Expires' => $time->format(DATE_RFC2822)));
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'Expires' => $time->format(DATE_RFC2822)));
|
||||
$this->request('GET', '/', array('HTTP_CACHE_CONTROL' => 'no-cache'));
|
||||
|
||||
$this->assertHttpKernelIsCalled();
|
||||
@ -213,7 +213,7 @@ class CacheTest extends CacheTestCase
|
||||
{
|
||||
$count = 0;
|
||||
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'max-age=10000'), '', function ($request, $response) use (&$count)
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public, max-age=10000'), '', function ($request, $response) use (&$count)
|
||||
{
|
||||
++$count;
|
||||
$response->setContent(1 == $count ? 'Hello World' : 'Goodbye World');
|
||||
@ -241,7 +241,7 @@ class CacheTest extends CacheTestCase
|
||||
{
|
||||
$count = 0;
|
||||
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'max-age=10000'), '', function ($request, $response) use (&$count)
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public, max-age=10000'), '', function ($request, $response) use (&$count)
|
||||
{
|
||||
++$count;
|
||||
$response->setContent(1 == $count ? 'Hello World' : 'Goodbye World');
|
||||
@ -276,7 +276,7 @@ class CacheTest extends CacheTestCase
|
||||
$this->setNextResponse(200, array(), '', function ($request, $response) use (&$count)
|
||||
{
|
||||
++$count;
|
||||
$response->headers->set('Cache-Control', 'max-age=10000');
|
||||
$response->headers->set('Cache-Control', 'public, max-age=10000');
|
||||
$response->setETag($count);
|
||||
$response->setContent(1 == $count ? 'Hello World' : 'Goodbye World');
|
||||
});
|
||||
@ -307,7 +307,7 @@ class CacheTest extends CacheTestCase
|
||||
$this->setNextResponse(200, array(), '', function ($request, $response) use (&$count)
|
||||
{
|
||||
++$count;
|
||||
$response->headers->set('Cache-Control', 'max-age=10000');
|
||||
$response->headers->set('Cache-Control', 'public, max-age=10000');
|
||||
$response->setETag($count);
|
||||
$response->setContent(1 == $count ? 'Hello World' : 'Goodbye World');
|
||||
});
|
||||
@ -341,7 +341,7 @@ class CacheTest extends CacheTestCase
|
||||
public function testFetchesResponseFromBackendWhenCacheMisses()
|
||||
{
|
||||
$time = \DateTime::createFromFormat('U', time() + 5);
|
||||
$this->setNextResponse(200, array('Expires' => $time->format(DATE_RFC2822)));
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'Expires' => $time->format(DATE_RFC2822)));
|
||||
|
||||
$this->request('GET', '/');
|
||||
$this->assertEquals(200, $this->response->getStatusCode());
|
||||
@ -384,7 +384,7 @@ class CacheTest extends CacheTestCase
|
||||
public function testCachesResponesWithExplicitNoCacheDirective()
|
||||
{
|
||||
$time = \DateTime::createFromFormat('U', time() + 5);
|
||||
$this->setNextResponse(200, array('Expires' => $time->format(DATE_RFC2822), 'Cache-Control' => 'no-cache'));
|
||||
$this->setNextResponse(200, array('Expires' => $time->format(DATE_RFC2822), 'Cache-Control' => 'public, no-cache'));
|
||||
|
||||
$this->request('GET', '/');
|
||||
$this->assertTraceContains('store');
|
||||
@ -394,7 +394,7 @@ class CacheTest extends CacheTestCase
|
||||
public function testCachesResponsesWithAnExpirationHeader()
|
||||
{
|
||||
$time = \DateTime::createFromFormat('U', time() + 5);
|
||||
$this->setNextResponse(200, array('Expires' => $time->format(DATE_RFC2822)));
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'Expires' => $time->format(DATE_RFC2822)));
|
||||
|
||||
$this->request('GET', '/');
|
||||
$this->assertEquals(200, $this->response->getStatusCode());
|
||||
@ -410,7 +410,7 @@ class CacheTest extends CacheTestCase
|
||||
|
||||
public function testCachesResponsesWithAMaxAgeDirective()
|
||||
{
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'max-age=5'));
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public, max-age=5'));
|
||||
|
||||
$this->request('GET', '/');
|
||||
$this->assertEquals(200, $this->response->getStatusCode());
|
||||
@ -443,7 +443,7 @@ class CacheTest extends CacheTestCase
|
||||
public function testCachesResponsesWithALastModifiedValidatorButNoFreshnessInformation()
|
||||
{
|
||||
$time = \DateTime::createFromFormat('U', time());
|
||||
$this->setNextResponse(200, array('Last-Modified' => $time->format(DATE_RFC2822)));
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'Last-Modified' => $time->format(DATE_RFC2822)));
|
||||
|
||||
$this->request('GET', '/');
|
||||
$this->assertEquals(200, $this->response->getStatusCode());
|
||||
@ -454,7 +454,7 @@ class CacheTest extends CacheTestCase
|
||||
|
||||
public function testCachesResponsesWithAnETagValidatorButNoFreshnessInformation()
|
||||
{
|
||||
$this->setNextResponse(200, array('ETag' => '"123456"'));
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'ETag' => '"123456"'));
|
||||
|
||||
$this->request('GET', '/');
|
||||
$this->assertEquals(200, $this->response->getStatusCode());
|
||||
@ -467,7 +467,7 @@ class CacheTest extends CacheTestCase
|
||||
{
|
||||
$time1 = \DateTime::createFromFormat('U', time() - 5);
|
||||
$time2 = \DateTime::createFromFormat('U', time() + 5);
|
||||
$this->setNextResponse(200, array('Date' => $time1->format(DATE_RFC2822), 'Expires' => $time2->format(DATE_RFC2822)));
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'Date' => $time1->format(DATE_RFC2822), 'Expires' => $time2->format(DATE_RFC2822)));
|
||||
|
||||
$this->request('GET', '/');
|
||||
$this->assertHttpKernelIsCalled();
|
||||
@ -491,7 +491,7 @@ class CacheTest extends CacheTestCase
|
||||
public function testHitsCachedResponseWithMaxAgeDirective()
|
||||
{
|
||||
$time = \DateTime::createFromFormat('U', time() - 5);
|
||||
$this->setNextResponse(200, array('Date' => $time->format(DATE_RFC2822), 'Cache-Control' => 'max-age=10'));
|
||||
$this->setNextResponse(200, array('Date' => $time->format(DATE_RFC2822), 'Cache-Control' => 'public, max-age=10'));
|
||||
|
||||
$this->request('GET', '/');
|
||||
$this->assertHttpKernelIsCalled();
|
||||
@ -574,7 +574,7 @@ class CacheTest extends CacheTestCase
|
||||
public function testFetchesFullResponseWhenCacheStaleAndNoValidatorsPresent()
|
||||
{
|
||||
$time = \DateTime::createFromFormat('U', time() + 5);
|
||||
$this->setNextResponse(200, array('Expires' => $time->format(DATE_RFC2822)));
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'public', 'Expires' => $time->format(DATE_RFC2822)));
|
||||
|
||||
// build initial request
|
||||
$this->request('GET', '/');
|
||||
@ -613,6 +613,7 @@ class CacheTest extends CacheTestCase
|
||||
$time = \DateTime::createFromFormat('U', time());
|
||||
$this->setNextResponse(200, array(), 'Hello World', function ($request, $response) use ($time)
|
||||
{
|
||||
$response->headers->set('Cache-Control', 'public');
|
||||
$response->headers->set('Last-Modified', $time->format(DATE_RFC2822));
|
||||
if ($time->format(DATE_RFC2822) == $request->headers->get('IF_MODIFIED_SINCE')) {
|
||||
$response->setStatusCode(304);
|
||||
@ -649,6 +650,7 @@ class CacheTest extends CacheTestCase
|
||||
{
|
||||
$this->setNextResponse(200, array(), 'Hello World', function ($request, $response)
|
||||
{
|
||||
$response->headers->set('Cache-Control', 'public');
|
||||
$response->headers->set('ETag', '"12345"');
|
||||
if ($response->getETag() == $request->headers->get('IF_NONE_MATCH')) {
|
||||
$response->setStatusCode(304);
|
||||
@ -739,7 +741,7 @@ class CacheTest extends CacheTestCase
|
||||
$that = $this;
|
||||
$this->setNextResponse(200, array(), 'Hello World', function ($request, $response) use ($that)
|
||||
{
|
||||
$response->headers->set('Cache-Control', 'max-age=10');
|
||||
$response->headers->set('Cache-Control', 'public, max-age=10');
|
||||
$response->setContent('Hello World');
|
||||
$response->setStatusCode(200);
|
||||
$that->assertNotEquals('HEAD', $request->getMethod());
|
||||
@ -811,7 +813,7 @@ class CacheTest extends CacheTestCase
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'max-age=10000'), '', function ($request, $response) use (&$count)
|
||||
{
|
||||
$response->headers->set('Vary', 'Accept User-Agent Foo');
|
||||
$response->headers->set('Cache-Control', 'max-age=10');
|
||||
$response->headers->set('Cache-Control', 'public, max-age=10');
|
||||
$response->headers->set('X-Response-Count', ++$count);
|
||||
$response->setContent($request->headers->get('USER_AGENT'));
|
||||
});
|
||||
@ -836,7 +838,7 @@ class CacheTest extends CacheTestCase
|
||||
$this->setNextResponse(200, array('Cache-Control' => 'max-age=10000'), '', function ($request, $response) use (&$count)
|
||||
{
|
||||
$response->headers->set('Vary', 'Accept User-Agent Foo');
|
||||
$response->headers->set('Cache-Control', 'max-age=10');
|
||||
$response->headers->set('Cache-Control', 'public, max-age=10');
|
||||
$response->headers->set('X-Response-Count', ++$count);
|
||||
$response->setContent($request->headers->get('USER_AGENT'));
|
||||
});
|
||||
|
@ -16,7 +16,6 @@ require_once __DIR__.'/CacheTestCase.php';
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Cache\Store;
|
||||
use Symfony\Tests\Component\HttpKernel\Cache\CacheTestCase;
|
||||
|
||||
class CacheStoreTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
Reference in New Issue
Block a user