如何说服 Zend Framework 发送重复的 headers?
How to convince Zend Framework to send duplicate headers?
对于Content-Security-Policy
header,通常需要发送多个这样的header,或者在发送之前合并这些header。这是因为应用程序的每个 module/package 都可以定义自己的 CSP。
目前ZF3似乎没有办法处理这种情况。如果我尝试添加多个 CSP header,它们会不断相互覆盖,因此只会发送最后添加的 header。
重现问题的代码
$headers = $controller->getResponse()->getHeaders();
$headers->addHeader(new ContentSecurityPolicy($someDirectives));
$headers->addHeader(new ContentSecurityPolicy($someOtherDirectives));
预期结果
预期结果是具有两个 CSP header 的响应(或联合合并的 CSP)。
实际结果
第二次添加会覆盖第一次,响应只包含那个 CSP。
问题
如何让 ZF3 发送具有相同字段名的多个 header?
有关此问题的更多信息,另请参阅我自己在 github https://github.com/zendframework/zend-http/issues/159
上的问题
您应该能够使用 GenericMultipleHeader 作为参考(并将逗号分隔符更改为分号)创建一个简单的解决方法:
class MultiContentSecurityPolicy extends ContentSecurityPolicy implements MultipleHeaderInterface {
public static function fromString($headerLine)
{
list($fieldName, $fieldValue) = GenericHeader::splitHeaderLine($headerLine);
if (strpos($fieldValue, ';')) {
$headers = [];
foreach (explode(';', $fieldValue) as $multiValue) {
$headers[] = new static($fieldName, $multiValue);
}
return $headers;
} else {
$header = new static($fieldName, $fieldValue);
return $header;
}
}
public function toStringMultipleHeaders(array $headers)
{
$name = $this->getFieldName();
$values = [$this->getFieldValue()];
foreach ($headers as $header) {
if (! $header instanceof static) {
throw new Exception\InvalidArgumentException(
'This method toStringMultipleHeaders was expecting an array of headers of the same type'
);
}
$values[] = $header->getFieldValue();
}
return $name . ': ' . implode(';', $values) . "\r\n";
}
}
然后使用 class 而不是 ContentSecurityPolicy
:
$headers = $controller->getResponse()->getHeaders();
$headers->addHeader(new MultiContentSecurityPolicy($someDirectives));
$headers->addHeader(new MultiContentSecurityPolicy($someOtherDirectives));
自 Zend checks the interface rather than the class 以来,应该可以正常工作。
这是公认的 HTTP 标准,PHP 核心支持这一标准。 http://php.net/manual/en/function.header.php
如果您在 PHP header("TESTHeader: Test1"); header("TESTHeader: Test2")
中设置 headers,则只有一个会通过,这符合规范 RFC2616 Section 4.2 Page 31&32
如果您希望发送多个值,您的 header 应该构建为 header("TESTHeader: Test1, Test2");
。虽然可以通过 PHP 发送多个相同名称的 headers,但不推荐,因为浏览器和服务器接收 2 组相同的 header 应该将它们转换为上述样式,这可能会导致问题,因为您无法确定它们的格式。header("TESTHeader: Test1", false); header("TESTHeader: Test2", false)
。取决于服务器或客户端是否遵守 RFC 或 HTTP 版本。
所以这个答案就是为什么你不能在 ZF3 中多次发送相同的 header 的原因,它无法根据你设置的header。要解决这个问题并使用 multi-valued headers 你可以使用 Jim's answer
创建您自己的多页眉 class,添加您需要的功能 (MultipleHeaderInterface),然后在多线程中添加您的页眉,最后在您的
中调用它
$headers = $controller->getResponse()->getHeaders();
(使用新的 fromStringHeaders 调用新函数)
对于Content-Security-Policy
header,通常需要发送多个这样的header,或者在发送之前合并这些header。这是因为应用程序的每个 module/package 都可以定义自己的 CSP。
目前ZF3似乎没有办法处理这种情况。如果我尝试添加多个 CSP header,它们会不断相互覆盖,因此只会发送最后添加的 header。
重现问题的代码
$headers = $controller->getResponse()->getHeaders();
$headers->addHeader(new ContentSecurityPolicy($someDirectives));
$headers->addHeader(new ContentSecurityPolicy($someOtherDirectives));
预期结果
预期结果是具有两个 CSP header 的响应(或联合合并的 CSP)。
实际结果
第二次添加会覆盖第一次,响应只包含那个 CSP。
问题
如何让 ZF3 发送具有相同字段名的多个 header?
有关此问题的更多信息,另请参阅我自己在 github https://github.com/zendframework/zend-http/issues/159
上的问题您应该能够使用 GenericMultipleHeader 作为参考(并将逗号分隔符更改为分号)创建一个简单的解决方法:
class MultiContentSecurityPolicy extends ContentSecurityPolicy implements MultipleHeaderInterface {
public static function fromString($headerLine)
{
list($fieldName, $fieldValue) = GenericHeader::splitHeaderLine($headerLine);
if (strpos($fieldValue, ';')) {
$headers = [];
foreach (explode(';', $fieldValue) as $multiValue) {
$headers[] = new static($fieldName, $multiValue);
}
return $headers;
} else {
$header = new static($fieldName, $fieldValue);
return $header;
}
}
public function toStringMultipleHeaders(array $headers)
{
$name = $this->getFieldName();
$values = [$this->getFieldValue()];
foreach ($headers as $header) {
if (! $header instanceof static) {
throw new Exception\InvalidArgumentException(
'This method toStringMultipleHeaders was expecting an array of headers of the same type'
);
}
$values[] = $header->getFieldValue();
}
return $name . ': ' . implode(';', $values) . "\r\n";
}
}
然后使用 class 而不是 ContentSecurityPolicy
:
$headers = $controller->getResponse()->getHeaders();
$headers->addHeader(new MultiContentSecurityPolicy($someDirectives));
$headers->addHeader(new MultiContentSecurityPolicy($someOtherDirectives));
自 Zend checks the interface rather than the class 以来,应该可以正常工作。
这是公认的 HTTP 标准,PHP 核心支持这一标准。 http://php.net/manual/en/function.header.php
如果您在 PHP header("TESTHeader: Test1"); header("TESTHeader: Test2")
中设置 headers,则只有一个会通过,这符合规范 RFC2616 Section 4.2 Page 31&32
如果您希望发送多个值,您的 header 应该构建为 header("TESTHeader: Test1, Test2");
。虽然可以通过 PHP 发送多个相同名称的 headers,但不推荐,因为浏览器和服务器接收 2 组相同的 header 应该将它们转换为上述样式,这可能会导致问题,因为您无法确定它们的格式。header("TESTHeader: Test1", false); header("TESTHeader: Test2", false)
。取决于服务器或客户端是否遵守 RFC 或 HTTP 版本。
所以这个答案就是为什么你不能在 ZF3 中多次发送相同的 header 的原因,它无法根据你设置的header。要解决这个问题并使用 multi-valued headers 你可以使用 Jim's answer
创建您自己的多页眉 class,添加您需要的功能 (MultipleHeaderInterface),然后在多线程中添加您的页眉,最后在您的
中调用它$headers = $controller->getResponse()->getHeaders();
(使用新的 fromStringHeaders 调用新函数)