| Current Path : /home/rtorresani/www/vendor/laminas/laminas-http/src/Header/ |
| Current File : //home/rtorresani/www/vendor/laminas/laminas-http/src/Header/ContentSecurityPolicy.php |
<?php
namespace Laminas\Http\Header;
use function array_pad;
use function array_walk;
use function explode;
use function implode;
use function in_array;
use function sprintf;
use function str_replace;
use function strcasecmp;
use function trim;
/**
* Content Security Policy Level 3 Header
*
* @link http://www.w3.org/TR/CSP/
*/
class ContentSecurityPolicy implements MultipleHeaderInterface
{
/**
* Valid directive names
*
* @var array
*/
protected $validDirectiveNames = [
// As per http://www.w3.org/TR/CSP/#directives
// Fetch directives
'child-src',
'connect-src',
'default-src',
'font-src',
'frame-src',
'img-src',
'manifest-src',
'media-src',
'object-src',
'prefetch-src',
'script-src',
'script-src-elem',
'script-src-attr',
'style-src',
'style-src-elem',
'style-src-attr',
'worker-src',
// Document directives
'base-uri',
'plugin-types',
'sandbox',
// Navigation directives
'form-action',
'frame-ancestors',
'navigate-to',
// Reporting directives
'report-uri',
'report-to',
// Other directives
'block-all-mixed-content',
'require-sri-for',
'require-trusted-types-for',
'trusted-types',
'upgrade-insecure-requests',
];
/**
* The directives defined for this policy
*
* @var array
*/
protected $directives = [];
/**
* Get the list of defined directives
*
* @return array
*/
public function getDirectives()
{
return $this->directives;
}
/**
* Sets the directive to consist of the source list
*
* Reverses http://www.w3.org/TR/CSP/#parsing-1
*
* @param string $name The directive name.
* @param array $sources The source list.
* @return $this
* @throws Exception\InvalidArgumentException If the name is not a valid directive name.
*/
public function setDirective($name, array $sources)
{
if (! in_array($name, $this->validDirectiveNames, true)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects a valid directive name; received "%s"',
__METHOD__,
(string) $name
));
}
if (
$name === 'block-all-mixed-content'
|| $name === 'upgrade-insecure-requests'
) {
if ($sources) {
throw new Exception\InvalidArgumentException(sprintf(
'Received value for %s directive; none expected',
$name
));
}
$this->directives[$name] = '';
return $this;
}
if (empty($sources)) {
if ('report-uri' === $name) {
if (isset($this->directives[$name])) {
unset($this->directives[$name]);
}
return $this;
}
$this->directives[$name] = "'none'";
return $this;
}
array_walk($sources, [__NAMESPACE__ . '\HeaderValue', 'assertValid']);
$this->directives[$name] = implode(' ', $sources);
return $this;
}
/**
* Create Content Security Policy header from a given header line
*
* @param string $headerLine The header line to parse.
* @return static
* @throws Exception\InvalidArgumentException If the name field in the given header line does not match.
*/
public static function fromString($headerLine)
{
$header = new static();
$headerName = $header->getFieldName();
[$name, $value] = GenericHeader::splitHeaderLine($headerLine);
// Ensure the proper header name
if (strcasecmp($name, $headerName) !== 0) {
throw new Exception\InvalidArgumentException(sprintf(
'Invalid header line for %s string: "%s"',
$headerName,
$name
));
}
// As per http://www.w3.org/TR/CSP/#parsing
$tokens = explode(';', $value);
foreach ($tokens as $token) {
$token = trim($token);
if ($token) {
[$directiveName, $directiveValue] = array_pad(explode(' ', $token, 2), 2, null);
if (! isset($header->directives[$directiveName])) {
$header->setDirective(
$directiveName,
$directiveValue === null ? [] : [$directiveValue]
);
}
}
}
return $header;
}
/**
* Get the header name
*
* @return string
*/
public function getFieldName()
{
return 'Content-Security-Policy';
}
/**
* Get the header value
*
* @return string
*/
public function getFieldValue()
{
$directives = [];
foreach ($this->directives as $name => $value) {
$directives[] = sprintf('%s %s;', $name, $value);
}
return str_replace(' ;', ';', implode(' ', $directives));
}
/**
* Return the header as a string
*
* @return string
*/
public function toString()
{
return sprintf('%s: %s', $this->getFieldName(), $this->getFieldValue());
}
/** @return string */
public function toStringMultipleHeaders(array $headers)
{
$strings = [$this->toString()];
foreach ($headers as $header) {
if (! $header instanceof ContentSecurityPolicy) {
throw new Exception\RuntimeException(
'The ContentSecurityPolicy multiple header implementation can only'
. ' accept an array of ContentSecurityPolicy headers'
);
}
$strings[] = $header->toString();
}
return implode("\r\n", $strings) . "\r\n";
}
}