Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JApplicationWeb::setHeader/sendHeaders behavior #9836

Merged
merged 23 commits into from
Nov 15, 2016
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f2ead45
Update web.php
stutteringp0et Apr 10, 2016
95a7029
JApplicationWeb::setHeader behavior
stutteringp0et Apr 10, 2016
e0eb2c8
JApplicationWeb::setHeader behavior
stutteringp0et Apr 10, 2016
b630e31
JApplicationWeb::setHeader behavior
stutteringp0et Apr 10, 2016
081e39a
Fix testSetHeader
stutteringp0et Apr 10, 2016
d1f22f6
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 11, 2016
d128c39
Returning test to original state
stutteringp0et Apr 11, 2016
04d3a75
JApplicationWeb::setHeader behavior
stutteringp0et Apr 11, 2016
ac35366
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 11, 2016
4963883
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 11, 2016
74e854c
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 11, 2016
3a1a134
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 11, 2016
ea82d1c
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 11, 2016
0ffc9e3
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 11, 2016
8c72577
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 12, 2016
78567ea
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 12, 2016
9033209
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 12, 2016
d249207
Merge branch 'staging' into patch-1
stutteringp0et Apr 12, 2016
e15c8b3
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 12, 2016
cc8eda3
Update web.php
stutteringp0et Apr 13, 2016
c041cf7
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 13, 2016
a05bc9f
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 14, 2016
3ee123a
JApplicationWeb -setHeader and sendHeader upgrade
stutteringp0et Apr 14, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 56 additions & 13 deletions libraries/joomla/application/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,33 @@ class JApplicationWeb extends JApplicationBase
308 => 'Permanent Redirect'
);

/**
* A map of HTTP Response headers which may only send a single value, all others
* are considered to allow multiple
*
* @var object
* @since 3.5.2
* @see https://tools.ietf.org/html/rfc7230
*/
private $singleValueResponseHeaders = array(
'status', // This is not a valid header name, but the representation used by Joomla to identify the HTTP Response Code
'Content-Length',
'Host',
'Content-Type',
'Content-Location',
'Date',
'Location',
'Retry-After',
'Server',
'Mime-Version',
'Last-Modified',
'ETag',
'Accept-Ranges',
'Content-Range',
'Age',
'Expires'
);

/**
* Class constructor.
*
Expand Down Expand Up @@ -625,23 +652,36 @@ public function setHeader($name, $value, $replace = false)
$name = (string) $name;
$value = (string) $value;

// If the replace flag is set, unset all known headers with the given name.
if ($replace)
// Create an array of duplicate header names
$keys = false;
if ($this->response->headers)
{
$names = array();
foreach ($this->response->headers as $key => $header)
{
if ($name == $header['name'])
{
unset($this->response->headers[$key]);
}
$names[$key] = $header['name'];
}
// Find existing headers by name
$keys = array_keys($names, $name);
}

// Clean up the array as unsetting nested arrays leaves some junk.
$this->response->headers = array_values($this->response->headers);
// Remove if $replace is true and there are duplicate names
if ($replace && $keys)
{
$this->response->headers = array_diff_key($this->response->headers, array_flip($keys));
}

// Add the header to the internal array.
$this->response->headers[] = array('name' => $name, 'value' => $value);
/**
* If no keys found, safe to insert (!$keys)
* If ($keys && $replace) it's a replacement and previous have been deleted
* if($keys && !in_array...) it's a multiple value header
*/
$single = in_array($name, $this->singleValueResponseHeaders);
if ($value && (!$keys || ($keys && ($replace || !$single))))
{
// Add the header to the internal array.
$this->response->headers[] = array('name' => $name, 'value' => $value);
}

return $this;
}
Expand All @@ -650,8 +690,8 @@ public function setHeader($name, $value, $replace = false)
* Method to get the array of response headers to be sent when the response is sent
* to the client.
*
* @return array
*
* @return array *
*
* @since 11.3
*/
public function getHeaders()
Expand Down Expand Up @@ -684,6 +724,8 @@ public function sendHeaders()
{
if (!$this->checkHeadersSent())
{
// Creating an array of headers, making arrays of headers with multiple values
$val = array();
foreach ($this->response->headers as $header)
{
if ('status' == strtolower($header['name']))
Expand All @@ -693,7 +735,8 @@ public function sendHeaders()
}
else
{
$this->header($header['name'] . ': ' . $header['value']);
$val[$header['name']] = !isset($val[$header['name']])?$header['value']:implode(', ', array($val[$header['name']], $header['value']));
$this->header($header['name'] . ': ' . $val[$header['name']], true);
}
}
}
Expand Down