Skip to content

Commit

Permalink
Map normalized header names to original capitalization
Browse files Browse the repository at this point in the history
  • Loading branch information
gigablah committed Oct 5, 2012
1 parent 2be4720 commit 63a228c
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/Symfony/Component/HttpFoundation/Response.php
Expand Up @@ -259,7 +259,7 @@ public function sendHeaders()
header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));

// headers
foreach ($this->headers->all() as $name => $values) {
foreach ($this->headers->allPreserveCase() as $name => $values) {
foreach ($values as $value) {
header($name.': '.$value, false);
}
Expand Down
32 changes: 28 additions & 4 deletions src/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
Expand Up @@ -36,6 +36,11 @@ class ResponseHeaderBag extends HeaderBag
*/
protected $cookies = array();

/**
* @var array
*/
protected $headerNames = array();

/**
* Constructor.
*
Expand All @@ -48,7 +53,7 @@ public function __construct(array $headers = array())
parent::__construct($headers);

if (!isset($this->headers['cache-control'])) {
$this->set('cache-control', '');
$this->set('Cache-Control', '');
}
}

Expand All @@ -65,17 +70,29 @@ public function __toString()
return parent::__toString().$cookies;
}

/**
* Returns the headers, with original capitalizations.
*
* @return array An array of headers
*/
public function allPreserveCase()
{
return array_combine($this->headerNames, $this->headers);
}

/**
* {@inheritdoc}
*
* @api
*/
public function replace(array $headers = array())
{
$this->headerNames = array();

parent::replace($headers);

if (!isset($this->headers['cache-control'])) {
$this->set('cache-control', '');
$this->set('Cache-Control', '');
}
}

Expand All @@ -88,10 +105,14 @@ public function set($key, $values, $replace = true)
{
parent::set($key, $values, $replace);

$uniqueKey = strtr(strtolower($key), '_', '-');
$this->headerNames[$uniqueKey] = $key;

// ensure the cache-control header has sensible defaults
if (in_array(strtr(strtolower($key), '_', '-'), array('cache-control', 'etag', 'last-modified', 'expires'))) {
if (in_array($uniqueKey, array('cache-control', 'etag', 'last-modified', 'expires'))) {
$computed = $this->computeCacheControlValue();
$this->headers['cache-control'] = array($computed);
$this->headerNames['cache-control'] = 'Cache-Control';
$this->computedCacheControl = $this->parseCacheControl($computed);
}
}
Expand All @@ -105,7 +126,10 @@ public function remove($key)
{
parent::remove($key);

if ('cache-control' === strtr(strtolower($key), '_', '-')) {
$uniqueKey = strtr(strtolower($key), '_', '-');
unset($this->headerNames[$uniqueKey]);

if ('cache-control' === $uniqueKey) {
$this->computedCacheControl = array();
}
}
Expand Down
Expand Up @@ -16,6 +16,51 @@

class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
{
/**
* @covers Symfony\Component\HttpFoundation\ResponseHeaderBag::allPreserveCase
* @dataProvider provideAllPreserveCase
*/
public function testAllPreserveCase($headers, $expected)
{
$bag = new ResponseHeaderBag($headers);

$this->assertEquals($expected, $bag->allPreserveCase(), '->allPreserveCase() gets all input keys in original case');
}

public function provideAllPreserveCase()
{
return array(
array(
array('fOo' => 'BAR'),
array('fOo' => array('BAR'), 'Cache-Control' => array('no-cache'))
),
array(
array('ETag' => 'xyzzy'),
array('ETag' => array('xyzzy'), 'Cache-Control' => array('private, must-revalidate'))
),
array(
array('Content-MD5' => 'Q2hlY2sgSW50ZWdyaXR5IQ=='),
array('Content-MD5' => array('Q2hlY2sgSW50ZWdyaXR5IQ=='), 'Cache-Control' => array('no-cache'))
),
array(
array('P3P' => 'CP="CAO PSA OUR"'),
array('P3P' => array('CP="CAO PSA OUR"'), 'Cache-Control' => array('no-cache'))
),
array(
array('WWW-Authenticate' => 'Basic realm="WallyWorld"'),
array('WWW-Authenticate' => array('Basic realm="WallyWorld"'), 'Cache-Control' => array('no-cache'))
),
array(
array('X-UA-Compatible' => 'IE=edge,chrome=1'),
array('X-UA-Compatible' => array('IE=edge,chrome=1'), 'Cache-Control' => array('no-cache'))
),
array(
array('X-XSS-Protection' => '1; mode=block'),
array('X-XSS-Protection' => array('1; mode=block'), 'Cache-Control' => array('no-cache'))
),
);
}

public function testCacheControlHeader()
{
$bag = new ResponseHeaderBag(array());
Expand Down

0 comments on commit 63a228c

Please sign in to comment.