2010-05-03 10:40:23 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is part of the Symfony package.
|
|
|
|
*
|
2011-03-06 11:40:06 +00:00
|
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
2010-05-03 10:40:23 +01:00
|
|
|
*
|
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
|
|
|
*/
|
|
|
|
|
2011-01-15 13:29:43 +00:00
|
|
|
namespace Symfony\Component\HttpFoundation;
|
|
|
|
|
2010-05-03 10:40:23 +01:00
|
|
|
/**
|
2010-06-23 15:24:24 +01:00
|
|
|
* HeaderBag is a container for HTTP headers.
|
2010-05-03 10:40:23 +01:00
|
|
|
*
|
2011-03-06 11:40:06 +00:00
|
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
2010-05-03 10:40:23 +01:00
|
|
|
*/
|
2012-03-15 20:41:06 +00:00
|
|
|
class HeaderBag implements \IteratorAggregate, \Countable
|
2010-05-03 10:40:23 +01:00
|
|
|
{
|
2019-01-16 18:24:45 +00:00
|
|
|
protected $headers = [];
|
|
|
|
protected $cacheControl = [];
|
2010-05-06 12:25:53 +01:00
|
|
|
|
2019-01-16 18:24:45 +00:00
|
|
|
public function __construct(array $headers = [])
|
2010-05-03 10:40:23 +01:00
|
|
|
{
|
2011-01-30 14:07:02 +00:00
|
|
|
foreach ($headers as $key => $values) {
|
|
|
|
$this->set($key, $values);
|
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
|
2011-05-15 11:38:12 +01:00
|
|
|
/**
|
|
|
|
* Returns the headers as a string.
|
|
|
|
*
|
|
|
|
* @return string The headers
|
|
|
|
*/
|
|
|
|
public function __toString()
|
|
|
|
{
|
2016-11-19 14:10:17 +00:00
|
|
|
if (!$headers = $this->all()) {
|
2011-05-15 18:44:22 +01:00
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2016-11-19 14:10:17 +00:00
|
|
|
ksort($headers);
|
|
|
|
$max = max(array_map('strlen', array_keys($headers))) + 1;
|
2011-05-15 11:38:12 +01:00
|
|
|
$content = '';
|
2016-11-19 14:10:17 +00:00
|
|
|
foreach ($headers as $name => $values) {
|
2017-10-07 23:59:09 +01:00
|
|
|
$name = ucwords($name, '-');
|
2011-05-15 11:38:12 +01:00
|
|
|
foreach ($values as $value) {
|
2012-03-24 07:17:54 +00:00
|
|
|
$content .= sprintf("%-{$max}s %s\r\n", $name.':', $value);
|
2011-05-15 11:38:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $content;
|
|
|
|
}
|
|
|
|
|
2010-06-23 15:24:24 +01:00
|
|
|
/**
|
|
|
|
* Returns the headers.
|
|
|
|
*
|
2019-06-20 20:59:08 +01:00
|
|
|
* @param string|null $key The name of the headers to return or null to get them all
|
|
|
|
*
|
2010-06-23 15:24:24 +01:00
|
|
|
* @return array An array of headers
|
|
|
|
*/
|
2019-08-08 19:20:00 +01:00
|
|
|
public function all(string $key = null)
|
2010-06-23 15:24:24 +01:00
|
|
|
{
|
2019-08-08 19:20:00 +01:00
|
|
|
if (null !== $key) {
|
2019-06-20 20:59:08 +01:00
|
|
|
$key = str_replace('_', '-', strtolower($key));
|
|
|
|
|
|
|
|
return $this->headers[$key] ?? [];
|
|
|
|
}
|
|
|
|
|
2010-06-23 15:24:24 +01:00
|
|
|
return $this->headers;
|
|
|
|
}
|
|
|
|
|
2010-08-26 09:56:46 +01:00
|
|
|
/**
|
|
|
|
* Returns the parameter keys.
|
|
|
|
*
|
|
|
|
* @return array An array of parameter keys
|
|
|
|
*/
|
|
|
|
public function keys()
|
|
|
|
{
|
2016-11-19 14:10:17 +00:00
|
|
|
return array_keys($this->all());
|
2010-08-26 09:56:46 +01:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Replaces the current HTTP headers by a new set.
|
|
|
|
*/
|
2019-01-16 18:24:45 +00:00
|
|
|
public function replace(array $headers = [])
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
2019-01-16 18:24:45 +00:00
|
|
|
$this->headers = [];
|
2011-01-22 17:34:18 +00:00
|
|
|
$this->add($headers);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds new headers the current HTTP headers set.
|
|
|
|
*/
|
|
|
|
public function add(array $headers)
|
|
|
|
{
|
2010-06-23 15:24:24 +01:00
|
|
|
foreach ($headers as $key => $values) {
|
|
|
|
$this->set($key, $values);
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a header value by name.
|
|
|
|
*
|
2019-06-20 20:59:08 +01:00
|
|
|
* @return string|null The first header value or default value
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function get(string $key, string $default = null)
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
2019-06-28 22:22:42 +01:00
|
|
|
$headers = $this->all($key);
|
2011-02-27 17:28:11 +00:00
|
|
|
|
2019-08-30 13:49:06 +01:00
|
|
|
if (!$headers) {
|
|
|
|
return $default;
|
|
|
|
}
|
2019-08-27 09:31:03 +01:00
|
|
|
|
2019-08-30 13:49:06 +01:00
|
|
|
if (null === $headers[0]) {
|
|
|
|
return null;
|
2010-06-23 15:24:24 +01:00
|
|
|
}
|
2011-02-27 17:28:11 +00:00
|
|
|
|
2019-08-30 13:49:06 +01:00
|
|
|
return (string) $headers[0];
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets a header by name.
|
|
|
|
*
|
2017-11-15 12:24:59 +00:00
|
|
|
* @param string|string[] $values The value or an array of values
|
|
|
|
* @param bool $replace Whether to replace the actual value or not (true by default)
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function set(string $key, $values, bool $replace = true)
|
2010-05-06 12:25:53 +01:00
|
|
|
{
|
2016-01-06 13:34:50 +00:00
|
|
|
$key = str_replace('_', '-', strtolower($key));
|
2010-05-06 12:25:53 +01:00
|
|
|
|
2017-11-07 20:33:43 +00:00
|
|
|
if (\is_array($values)) {
|
|
|
|
$values = array_values($values);
|
2010-05-06 12:25:53 +01:00
|
|
|
|
2017-11-07 20:33:43 +00:00
|
|
|
if (true === $replace || !isset($this->headers[$key])) {
|
|
|
|
$this->headers[$key] = $values;
|
|
|
|
} else {
|
|
|
|
$this->headers[$key] = array_merge($this->headers[$key], $values);
|
|
|
|
}
|
2010-06-23 15:24:24 +01:00
|
|
|
} else {
|
2017-11-07 20:33:43 +00:00
|
|
|
if (true === $replace || !isset($this->headers[$key])) {
|
2019-01-16 18:24:45 +00:00
|
|
|
$this->headers[$key] = [$values];
|
2017-11-07 20:33:43 +00:00
|
|
|
} else {
|
|
|
|
$this->headers[$key][] = $values;
|
|
|
|
}
|
2010-06-23 15:24:24 +01:00
|
|
|
}
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
|
|
|
|
if ('cache-control' === $key) {
|
2017-10-08 15:27:20 +01:00
|
|
|
$this->cacheControl = $this->parseCacheControl(implode(', ', $this->headers[$key]));
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
}
|
2010-05-03 10:40:23 +01:00
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the HTTP header is defined.
|
|
|
|
*
|
2014-11-30 13:33:44 +00:00
|
|
|
* @return bool true if the parameter exists, false otherwise
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function has(string $key)
|
2010-05-03 17:10:24 +01:00
|
|
|
{
|
2019-02-23 15:06:07 +00:00
|
|
|
return \array_key_exists(str_replace('_', '-', strtolower($key)), $this->all());
|
2010-05-03 17:10:24 +01:00
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
|
[HttpKernel] removed Response assertions
They are too magic and they don't really add value:
$this->assertResponseStatusCodeEmpty($client);
$this->assertTrue($client->getResponse()->isEmpty());
$this->assertResponseStatusCodeNotFound($client);
$this->assertTrue($client->getResponse()->isNotFound());
$this->assertResponseStatusCodeForbidden($client);
$this->assertTrue($client->getResponse()->isForbidden());
$this->assertResponseStatusCodeOk($client);
$this->assertTrue($client->getResponse()->isOk());
$this->assertResponseStatusCodeServerError($client);
$this->assertTrue($client->getResponse()->isServerError());
$this->assertResponseStatusCodeClientError($client);
$this->assertTrue($client->getResponse()->isClientError());
$this->assertResponseStatusCodeRedirection($client);
$this->assertTrue($client->getResponse()->isRedirection());
$this->assertResponseStatusCodeSuccessful($client);
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertResponseStatusCodeInformational($client);
$this->assertTrue($client->getResponse()->isInformational());
$this->assertResponseStatusCode(200, $client);
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertResponseStatusCodeRedirect('google.com', $client);
$this->assertTrue($client->getResponse()->isRedirected('google.com'));
$this->assertResponseNotRegExp('/foo/', $client);
$this->assertNotRegExp('/foo', $client->getResponse()->getContent());
$this->assertResponseRegExp('/foo/', $client);
$this->assertRegExp('/foo', $client->getResponse()->getContent());
$this->assertResponseNotSelectExists('h1', $client);
$this->assertTrue($crawler->filter('h1')->isEmpty());
$this->assertResponseSelectExists('h1', $client);
$this->assertFalse($crawler->filter('h1')->isEmpty());
$this->assertResponseSelectCount(3, 'h1', $client);
$this->assertEquals(3, $crawler->filter('h1')->count());
$this->assertResponseSelectEquals($expected, $selector, $arguments, $client);
$this->assertEquals($expected, $crawler->filter($selector)->extract($arguments));
$this->assertResponseHeaderEquals($value, $key, $client);
$this->assertTrue($client->getResponse()->headers->contains($key, $value));
$this->assertResponseNotHeaderEquals($value, $key, $client);
$this->assertFalse($client->getResponse()->headers->contains($key, $value));
$this->assertResponseHeaderRegExp($regex, $key, $client);
$this->assertRegExp($regex, $client->getResponse()->headers->get($key));
$this->assertResponseNotHeaderRegExp($regex, $key, $client);
$this->assertNotRegExp($regex, $client->getResponse()->headers->get($key));
$this->assertResponseCookie($value, $attributes, $name, $client);
$this->assertTrue($client->getResponse()->hasCookie($name));
2010-06-23 09:39:33 +01:00
|
|
|
/**
|
|
|
|
* Returns true if the given HTTP header contains the given value.
|
|
|
|
*
|
2014-11-30 13:33:44 +00:00
|
|
|
* @return bool true if the value is contained in the header, false otherwise
|
[HttpKernel] removed Response assertions
They are too magic and they don't really add value:
$this->assertResponseStatusCodeEmpty($client);
$this->assertTrue($client->getResponse()->isEmpty());
$this->assertResponseStatusCodeNotFound($client);
$this->assertTrue($client->getResponse()->isNotFound());
$this->assertResponseStatusCodeForbidden($client);
$this->assertTrue($client->getResponse()->isForbidden());
$this->assertResponseStatusCodeOk($client);
$this->assertTrue($client->getResponse()->isOk());
$this->assertResponseStatusCodeServerError($client);
$this->assertTrue($client->getResponse()->isServerError());
$this->assertResponseStatusCodeClientError($client);
$this->assertTrue($client->getResponse()->isClientError());
$this->assertResponseStatusCodeRedirection($client);
$this->assertTrue($client->getResponse()->isRedirection());
$this->assertResponseStatusCodeSuccessful($client);
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertResponseStatusCodeInformational($client);
$this->assertTrue($client->getResponse()->isInformational());
$this->assertResponseStatusCode(200, $client);
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertResponseStatusCodeRedirect('google.com', $client);
$this->assertTrue($client->getResponse()->isRedirected('google.com'));
$this->assertResponseNotRegExp('/foo/', $client);
$this->assertNotRegExp('/foo', $client->getResponse()->getContent());
$this->assertResponseRegExp('/foo/', $client);
$this->assertRegExp('/foo', $client->getResponse()->getContent());
$this->assertResponseNotSelectExists('h1', $client);
$this->assertTrue($crawler->filter('h1')->isEmpty());
$this->assertResponseSelectExists('h1', $client);
$this->assertFalse($crawler->filter('h1')->isEmpty());
$this->assertResponseSelectCount(3, 'h1', $client);
$this->assertEquals(3, $crawler->filter('h1')->count());
$this->assertResponseSelectEquals($expected, $selector, $arguments, $client);
$this->assertEquals($expected, $crawler->filter($selector)->extract($arguments));
$this->assertResponseHeaderEquals($value, $key, $client);
$this->assertTrue($client->getResponse()->headers->contains($key, $value));
$this->assertResponseNotHeaderEquals($value, $key, $client);
$this->assertFalse($client->getResponse()->headers->contains($key, $value));
$this->assertResponseHeaderRegExp($regex, $key, $client);
$this->assertRegExp($regex, $client->getResponse()->headers->get($key));
$this->assertResponseNotHeaderRegExp($regex, $key, $client);
$this->assertNotRegExp($regex, $client->getResponse()->headers->get($key));
$this->assertResponseCookie($value, $attributes, $name, $client);
$this->assertTrue($client->getResponse()->hasCookie($name));
2010-06-23 09:39:33 +01:00
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function contains(string $key, string $value)
|
[HttpKernel] removed Response assertions
They are too magic and they don't really add value:
$this->assertResponseStatusCodeEmpty($client);
$this->assertTrue($client->getResponse()->isEmpty());
$this->assertResponseStatusCodeNotFound($client);
$this->assertTrue($client->getResponse()->isNotFound());
$this->assertResponseStatusCodeForbidden($client);
$this->assertTrue($client->getResponse()->isForbidden());
$this->assertResponseStatusCodeOk($client);
$this->assertTrue($client->getResponse()->isOk());
$this->assertResponseStatusCodeServerError($client);
$this->assertTrue($client->getResponse()->isServerError());
$this->assertResponseStatusCodeClientError($client);
$this->assertTrue($client->getResponse()->isClientError());
$this->assertResponseStatusCodeRedirection($client);
$this->assertTrue($client->getResponse()->isRedirection());
$this->assertResponseStatusCodeSuccessful($client);
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertResponseStatusCodeInformational($client);
$this->assertTrue($client->getResponse()->isInformational());
$this->assertResponseStatusCode(200, $client);
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertResponseStatusCodeRedirect('google.com', $client);
$this->assertTrue($client->getResponse()->isRedirected('google.com'));
$this->assertResponseNotRegExp('/foo/', $client);
$this->assertNotRegExp('/foo', $client->getResponse()->getContent());
$this->assertResponseRegExp('/foo/', $client);
$this->assertRegExp('/foo', $client->getResponse()->getContent());
$this->assertResponseNotSelectExists('h1', $client);
$this->assertTrue($crawler->filter('h1')->isEmpty());
$this->assertResponseSelectExists('h1', $client);
$this->assertFalse($crawler->filter('h1')->isEmpty());
$this->assertResponseSelectCount(3, 'h1', $client);
$this->assertEquals(3, $crawler->filter('h1')->count());
$this->assertResponseSelectEquals($expected, $selector, $arguments, $client);
$this->assertEquals($expected, $crawler->filter($selector)->extract($arguments));
$this->assertResponseHeaderEquals($value, $key, $client);
$this->assertTrue($client->getResponse()->headers->contains($key, $value));
$this->assertResponseNotHeaderEquals($value, $key, $client);
$this->assertFalse($client->getResponse()->headers->contains($key, $value));
$this->assertResponseHeaderRegExp($regex, $key, $client);
$this->assertRegExp($regex, $client->getResponse()->headers->get($key));
$this->assertResponseNotHeaderRegExp($regex, $key, $client);
$this->assertNotRegExp($regex, $client->getResponse()->headers->get($key));
$this->assertResponseCookie($value, $attributes, $name, $client);
$this->assertTrue($client->getResponse()->hasCookie($name));
2010-06-23 09:39:33 +01:00
|
|
|
{
|
2019-06-28 22:22:42 +01:00
|
|
|
return \in_array($value, $this->all($key));
|
[HttpKernel] removed Response assertions
They are too magic and they don't really add value:
$this->assertResponseStatusCodeEmpty($client);
$this->assertTrue($client->getResponse()->isEmpty());
$this->assertResponseStatusCodeNotFound($client);
$this->assertTrue($client->getResponse()->isNotFound());
$this->assertResponseStatusCodeForbidden($client);
$this->assertTrue($client->getResponse()->isForbidden());
$this->assertResponseStatusCodeOk($client);
$this->assertTrue($client->getResponse()->isOk());
$this->assertResponseStatusCodeServerError($client);
$this->assertTrue($client->getResponse()->isServerError());
$this->assertResponseStatusCodeClientError($client);
$this->assertTrue($client->getResponse()->isClientError());
$this->assertResponseStatusCodeRedirection($client);
$this->assertTrue($client->getResponse()->isRedirection());
$this->assertResponseStatusCodeSuccessful($client);
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertResponseStatusCodeInformational($client);
$this->assertTrue($client->getResponse()->isInformational());
$this->assertResponseStatusCode(200, $client);
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertResponseStatusCodeRedirect('google.com', $client);
$this->assertTrue($client->getResponse()->isRedirected('google.com'));
$this->assertResponseNotRegExp('/foo/', $client);
$this->assertNotRegExp('/foo', $client->getResponse()->getContent());
$this->assertResponseRegExp('/foo/', $client);
$this->assertRegExp('/foo', $client->getResponse()->getContent());
$this->assertResponseNotSelectExists('h1', $client);
$this->assertTrue($crawler->filter('h1')->isEmpty());
$this->assertResponseSelectExists('h1', $client);
$this->assertFalse($crawler->filter('h1')->isEmpty());
$this->assertResponseSelectCount(3, 'h1', $client);
$this->assertEquals(3, $crawler->filter('h1')->count());
$this->assertResponseSelectEquals($expected, $selector, $arguments, $client);
$this->assertEquals($expected, $crawler->filter($selector)->extract($arguments));
$this->assertResponseHeaderEquals($value, $key, $client);
$this->assertTrue($client->getResponse()->headers->contains($key, $value));
$this->assertResponseNotHeaderEquals($value, $key, $client);
$this->assertFalse($client->getResponse()->headers->contains($key, $value));
$this->assertResponseHeaderRegExp($regex, $key, $client);
$this->assertRegExp($regex, $client->getResponse()->headers->get($key));
$this->assertResponseNotHeaderRegExp($regex, $key, $client);
$this->assertNotRegExp($regex, $client->getResponse()->headers->get($key));
$this->assertResponseCookie($value, $attributes, $name, $client);
$this->assertTrue($client->getResponse()->hasCookie($name));
2010-06-23 09:39:33 +01:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
2010-11-23 08:42:19 +00:00
|
|
|
* Removes a header.
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function remove(string $key)
|
2010-05-03 10:40:23 +01:00
|
|
|
{
|
2016-01-06 13:34:50 +00:00
|
|
|
$key = str_replace('_', '-', strtolower($key));
|
2010-05-03 10:40:23 +01:00
|
|
|
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
unset($this->headers[$key]);
|
2010-05-06 12:25:53 +01:00
|
|
|
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
if ('cache-control' === $key) {
|
2019-01-16 18:24:45 +00:00
|
|
|
$this->cacheControl = [];
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
}
|
2010-05-03 10:40:23 +01:00
|
|
|
}
|
|
|
|
|
2010-05-10 18:40:18 +01:00
|
|
|
/**
|
|
|
|
* Returns the HTTP header value converted to a date.
|
|
|
|
*
|
2019-08-11 10:15:18 +01:00
|
|
|
* @return \DateTimeInterface|null The parsed DateTime or the default value if the header does not exist
|
2012-09-30 09:47:54 +01:00
|
|
|
*
|
|
|
|
* @throws \RuntimeException When the HTTP header is not parseable
|
2010-05-10 18:40:18 +01:00
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function getDate(string $key, \DateTime $default = null)
|
2010-05-10 18:40:18 +01:00
|
|
|
{
|
|
|
|
if (null === $value = $this->get($key)) {
|
|
|
|
return $default;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) {
|
|
|
|
throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $date;
|
|
|
|
}
|
|
|
|
|
2014-05-23 12:34:06 +01:00
|
|
|
/**
|
|
|
|
* Adds a custom Cache-Control directive.
|
|
|
|
*
|
2019-06-28 22:22:42 +01:00
|
|
|
* @param mixed $value The Cache-Control directive value
|
2014-05-23 12:34:06 +01:00
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function addCacheControlDirective(string $key, $value = true)
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
{
|
|
|
|
$this->cacheControl[$key] = $value;
|
|
|
|
|
|
|
|
$this->set('Cache-Control', $this->getCacheControlHeader());
|
|
|
|
}
|
|
|
|
|
2014-05-23 12:34:06 +01:00
|
|
|
/**
|
|
|
|
* Returns true if the Cache-Control directive is defined.
|
|
|
|
*
|
|
|
|
* @return bool true if the directive exists, false otherwise
|
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function hasCacheControlDirective(string $key)
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
{
|
2019-02-23 15:06:07 +00:00
|
|
|
return \array_key_exists($key, $this->cacheControl);
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
}
|
|
|
|
|
2014-05-23 12:34:06 +01:00
|
|
|
/**
|
|
|
|
* Returns a Cache-Control directive value by name.
|
|
|
|
*
|
|
|
|
* @return mixed|null The directive value if defined, null otherwise
|
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function getCacheControlDirective(string $key)
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
{
|
2019-02-23 15:06:07 +00:00
|
|
|
return \array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
}
|
|
|
|
|
2014-05-23 12:34:06 +01:00
|
|
|
/**
|
|
|
|
* Removes a Cache-Control directive.
|
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
public function removeCacheControlDirective(string $key)
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
{
|
|
|
|
unset($this->cacheControl[$key]);
|
|
|
|
|
|
|
|
$this->set('Cache-Control', $this->getCacheControlHeader());
|
|
|
|
}
|
|
|
|
|
2012-03-15 20:41:06 +00:00
|
|
|
/**
|
2012-03-23 12:49:00 +00:00
|
|
|
* Returns an iterator for headers.
|
2012-03-15 20:41:06 +00:00
|
|
|
*
|
2012-03-23 12:49:00 +00:00
|
|
|
* @return \ArrayIterator An \ArrayIterator instance
|
2012-03-15 20:41:06 +00:00
|
|
|
*/
|
|
|
|
public function getIterator()
|
|
|
|
{
|
|
|
|
return new \ArrayIterator($this->headers);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-03-23 12:49:00 +00:00
|
|
|
* Returns the number of headers.
|
2012-03-15 20:41:06 +00:00
|
|
|
*
|
2012-03-23 12:49:00 +00:00
|
|
|
* @return int The number of headers
|
2012-03-15 20:41:06 +00:00
|
|
|
*/
|
|
|
|
public function count()
|
|
|
|
{
|
2018-07-05 12:24:53 +01:00
|
|
|
return \count($this->headers);
|
2012-03-15 20:41:06 +00:00
|
|
|
}
|
|
|
|
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
protected function getCacheControlHeader()
|
|
|
|
{
|
|
|
|
ksort($this->cacheControl);
|
|
|
|
|
2018-04-29 10:29:07 +01:00
|
|
|
return HeaderUtils::toString($this->cacheControl, ',');
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
* Parses a Cache-Control HTTP header.
|
2010-05-06 12:25:53 +01:00
|
|
|
*
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
* @return array An array representing the attribute values
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2019-06-28 22:22:42 +01:00
|
|
|
protected function parseCacheControl(string $header)
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
{
|
2018-04-20 15:29:33 +01:00
|
|
|
$parts = HeaderUtils::split($header, ',=');
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
|
2018-04-29 10:29:07 +01:00
|
|
|
return HeaderUtils::combine($parts);
|
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,
));
2010-11-10 09:48:22 +00:00
|
|
|
}
|
2010-05-03 10:40:23 +01:00
|
|
|
}
|