如何在 PHP 中解析/验证/处理 http headers
How to parse / validate / handle http headers in PHP
目前我正在构建自己的 php 框架,我现在正在创建 PHP-FIG PSR-7 MessageInterface 的实现。具体来说是 withHeader 方法。它声明该方法可能会引发异常:\InvalidArgumentException for invalid header names or values.
所以我想知道,header 什么时候有效或无效?价值观也一样。
或者我应该接受任何 header 和任何 header 值吗?那可能很危险吧?
我现在一般来说,如果 header 有多个值,它们是用逗号分隔的。但这并不总是适用。例如,如果我查看 user-agent header,值本身有时包含一个逗号。但是你应该把它当作一个单一的值。
您可以在 RFC 7230. Check Zend Diactoro's HeaderSecurity class 中找到实现的方法。
确实,"dangerous" 传递一个 header 名称 - 作为 withHeader()
的参数,
- 是
NULL
- 不是字符串
- 是一个空字符串
这同样适用于 header 值 参数。它必须是一个数组或字符串(代表只有一个值,而不是comma-separated值列表!)。
至于withHeader
方法的实现:
/**
* Return an instance with the provided value replacing the specified header.
*
* ...
*
* @param string $name Case-insensitive header field name.
* @param string|string[] $value Header value(s).
* @return static
* @throws \InvalidArgumentException for invalid header names or values.
*/
public function withHeader($name, $value) {
$this
->validateHeaderName($name)
->validateHeaderValue($value)
;
$clone = clone $this;
$clone->replaceHeader($name, $value);
return $clone;
}
/**
* =================
* Not part of PSR-7
* =================
*
* Validate header name.
*
* @param string $name Case-insensitive header field name.
* @return $this
* @throws \InvalidArgumentException
*/
protected function validateHeaderName($name) {
if (!isset($name)) {
throw new \InvalidArgumentException('No header name provided!');
}
if (!is_string($name)) {
throw new \InvalidArgumentException('The header name must be a string!');
}
if (empty($name)) {
throw new \InvalidArgumentException('Empty header name provided!');
}
return $this;
}
/**
* =================
* Not part of PSR-7
* =================
*
* Validate header value.
*
* @param string|string[] $value Header value(s).
* @return $this
* @throws \InvalidArgumentException
*/
protected function validateHeaderValue($value) {
if (isset($value) && !is_array($value) && !is_string($value)) {
throw new \InvalidArgumentException('The header value must be a string or an array!');
}
return $this;
}
/**
* =================
* Not part of PSR-7
* =================
*
* Replace a header item with a new one.
*
* @param string $name Case-insensitive header field name.
* @param string|string[] $value Header value(s).
* @return $this
* @done
*/
protected function replaceHeader($name, $value) {
$this
->removeHeader($name)
->addHeader($name, $value)
;
return $this;
}
目前我正在构建自己的 php 框架,我现在正在创建 PHP-FIG PSR-7 MessageInterface 的实现。具体来说是 withHeader 方法。它声明该方法可能会引发异常:\InvalidArgumentException for invalid header names or values.
所以我想知道,header 什么时候有效或无效?价值观也一样。 或者我应该接受任何 header 和任何 header 值吗?那可能很危险吧?
我现在一般来说,如果 header 有多个值,它们是用逗号分隔的。但这并不总是适用。例如,如果我查看 user-agent header,值本身有时包含一个逗号。但是你应该把它当作一个单一的值。
您可以在 RFC 7230. Check Zend Diactoro's HeaderSecurity class 中找到实现的方法。
确实,"dangerous" 传递一个 header 名称 - 作为 withHeader()
的参数,
- 是
NULL
- 不是字符串
- 是一个空字符串
这同样适用于 header 值 参数。它必须是一个数组或字符串(代表只有一个值,而不是comma-separated值列表!)。
至于withHeader
方法的实现:
/**
* Return an instance with the provided value replacing the specified header.
*
* ...
*
* @param string $name Case-insensitive header field name.
* @param string|string[] $value Header value(s).
* @return static
* @throws \InvalidArgumentException for invalid header names or values.
*/
public function withHeader($name, $value) {
$this
->validateHeaderName($name)
->validateHeaderValue($value)
;
$clone = clone $this;
$clone->replaceHeader($name, $value);
return $clone;
}
/**
* =================
* Not part of PSR-7
* =================
*
* Validate header name.
*
* @param string $name Case-insensitive header field name.
* @return $this
* @throws \InvalidArgumentException
*/
protected function validateHeaderName($name) {
if (!isset($name)) {
throw new \InvalidArgumentException('No header name provided!');
}
if (!is_string($name)) {
throw new \InvalidArgumentException('The header name must be a string!');
}
if (empty($name)) {
throw new \InvalidArgumentException('Empty header name provided!');
}
return $this;
}
/**
* =================
* Not part of PSR-7
* =================
*
* Validate header value.
*
* @param string|string[] $value Header value(s).
* @return $this
* @throws \InvalidArgumentException
*/
protected function validateHeaderValue($value) {
if (isset($value) && !is_array($value) && !is_string($value)) {
throw new \InvalidArgumentException('The header value must be a string or an array!');
}
return $this;
}
/**
* =================
* Not part of PSR-7
* =================
*
* Replace a header item with a new one.
*
* @param string $name Case-insensitive header field name.
* @param string|string[] $value Header value(s).
* @return $this
* @done
*/
protected function replaceHeader($name, $value) {
$this
->removeHeader($name)
->addHeader($name, $value)
;
return $this;
}