Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge branch 'hotfix/190' into develop
Browse files Browse the repository at this point in the history
Forward port #190
  • Loading branch information
michalbundyra committed Nov 29, 2019
2 parents 7a3b70e + 5469925 commit 74d36ca
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ All notable changes to this project will be documented in this file, in reverse

### Changed

- Nothing.
- [#190](https://github.com/zendframework/zend-http/pull/190) changes `ContentSecurityPolicy` to allow multiple values. Before it was not possible to provide multiple headers of that type.

### Deprecated

Expand Down
18 changes: 17 additions & 1 deletion src/Header/ContentSecurityPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
* @link http://www.w3.org/TR/CSP/
*/
class ContentSecurityPolicy implements HeaderInterface
class ContentSecurityPolicy implements MultipleHeaderInterface
{
/**
* Valid directive names
Expand Down Expand Up @@ -154,4 +154,20 @@ public function toString()
{
return sprintf('%s: %s', $this->getFieldName(), $this->getFieldValue());
}

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";
}
}
1 change: 1 addition & 0 deletions src/HeaderLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class HeaderLoader extends PluginClassLoader
'contentlocation' => Header\ContentLocation::class,
'contentmd5' => Header\ContentMD5::class,
'contentrange' => Header\ContentRange::class,
'contentsecuritypolicy' => Header\ContentSecurityPolicy::class,
'contenttransferencoding' => Header\ContentTransferEncoding::class,
'contenttype' => Header\ContentType::class,
'cookie' => Header\Cookie::class,
Expand Down
48 changes: 48 additions & 0 deletions test/Header/ContentSecurityPolicyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
namespace ZendTest\Http\Header;

use PHPUnit\Framework\TestCase;
use Zend\Http\Exception\RuntimeException;
use Zend\Http\Header\ContentSecurityPolicy;
use Zend\Http\Header\Exception\InvalidArgumentException;
use Zend\Http\Header\GenericHeader;
use Zend\Http\Header\HeaderInterface;
use Zend\Http\Header\MultipleHeaderInterface;
use Zend\Http\Headers;

class ContentSecurityPolicyTest extends TestCase
{
Expand All @@ -25,6 +29,7 @@ public function testContentSecurityPolicyFromStringParsesDirectivesCorrectly()
$csp = ContentSecurityPolicy::fromString(
"Content-Security-Policy: default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self';"
);
$this->assertInstanceOf(MultipleHeaderInterface::class, $csp);
$this->assertInstanceOf(HeaderInterface::class, $csp);
$this->assertInstanceOf(ContentSecurityPolicy::class, $csp);
$directives = [
Expand Down Expand Up @@ -139,4 +144,47 @@ public function testContentSecurityPolicySetDirectiveWithEmptyReportUriRemovesEx
$csp->toString()
);
}

public function testToStringMultipleHeaders()
{
$csp = new ContentSecurityPolicy();
$csp->setDirective('default-src', ["'self'"]);

$additional = new ContentSecurityPolicy();
$additional->setDirective('img-src', ['https://*.github.com']);

self::assertSame(
"Content-Security-Policy: default-src 'self';\r\n"
. "Content-Security-Policy: img-src https://*.github.com;\r\n",
$csp->toStringMultipleHeaders([$additional])
);
}

public function testToStringMultipleHeadersExceptionIfDifferent()
{
$csp = new ContentSecurityPolicy();
$csp->setDirective('default-src', ["'self'"]);

$additional = new GenericHeader();

$this->expectException(RuntimeException::class);
$this->expectExceptionMessage(
'The ContentSecurityPolicy multiple header implementation'
. ' can only accept an array of ContentSecurityPolicy headers'
);
$csp->toStringMultipleHeaders([$additional]);
}

public function testMultiple()
{
$headers = new Headers();
$headers->addHeader((new ContentSecurityPolicy())->setDirective('default-src', ["'self'"]));
$headers->addHeader((new ContentSecurityPolicy())->setDirective('img-src', ['https://*.github.com']));

self::assertSame(
"Content-Security-Policy: default-src 'self';\r\n"
. "Content-Security-Policy: img-src https://*.github.com;\r\n",
$headers->toString()
);
}
}

0 comments on commit 74d36ca

Please sign in to comment.