Final Class Yiisoft\ProxyMiddleware\TrustedHeaderProtocolResolver
| Inheritance | Yiisoft\ProxyMiddleware\TrustedHeaderProtocolResolver |
|---|---|
| Implements | Psr\Http\Server\MiddlewareInterface |
Trusted header protocol resolver sets a server request protocol based on a special header you trust
such as X-Forwarded-Proto.
You can use it if your server is behind a trusted load balancer or a proxy that's always setting the special header itself discarding any header values provided by user.
If you want to trust headers for a certain IP, use {@see \Yiisoft\ProxyMiddleware\TrustedHostsNetworkResolver}.
Public Methods
| Method | Description | Defined By |
|---|---|---|
| process() | Yiisoft\ProxyMiddleware\TrustedHeaderProtocolResolver | |
| withAddedProtocolHeader() | Returns a new instance with the specified protocol header added and protocols mapped to its values. | Yiisoft\ProxyMiddleware\TrustedHeaderProtocolResolver |
| withoutProtocolHeader() | Returns a new instance without the specified protocol header. | Yiisoft\ProxyMiddleware\TrustedHeaderProtocolResolver |
| withoutProtocolHeaders() | Returns a new instance without the specified protocol headers. | Yiisoft\ProxyMiddleware\TrustedHeaderProtocolResolver |
Constants
| Constant | Value | Description | Defined By |
|---|---|---|---|
| DEFAULT_PROTOCOLS_TO_HEADER_VALUES | [ 'http' => [ 'http', ], 'https' => [ 'https', 'on', ], ] | Default mapping of protocol to header values. | Yiisoft\ProxyMiddleware\TrustedHeaderProtocolResolver |
Method Details
| public process ( \Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Server\RequestHandlerInterface $handler ) | ||
| $request | \Psr\Http\Message\ServerRequestInterface | |
| $handler | \Psr\Http\Server\RequestHandlerInterface | |
| throws | RuntimeException |
If URI scheme protocol is wrong. |
|---|---|---|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$newScheme = null;
foreach ($this->protocolHeaders as $header => $data) {
if (!$request->hasHeader($header)) {
continue;
}
$headerValues = $request->getHeader($header);
if (is_callable($data)) {
$newScheme = $data($headerValues, $header, $request);
if ($newScheme === null) {
continue;
}
if (!is_string($newScheme)) {
throw new RuntimeException('The scheme is neither string nor null.');
}
if ($newScheme === '') {
throw new RuntimeException('The scheme cannot be an empty string.');
}
break;
}
$headerValue = strtolower($headerValues[0]);
foreach ($data as $protocol => $acceptedValues) {
if (!in_array($headerValue, $acceptedValues, true)) {
continue;
}
$newScheme = $protocol;
break 2;
}
}
$uri = $request->getUri();
if ($newScheme !== null && $newScheme !== $uri->getScheme()) {
$request = $request->withUri($uri->withScheme($newScheme));
}
return $handler->handle($request);
}
Returns a new instance with the specified protocol header added and protocols mapped to its values.
It's used to check whether the connection is HTTP / HTTPS or any other protocol.
The match of header names and values is case-insensitive. Avoid adding insecure/untrusted headers that a user might set.
Accepted values:
null(default): Default mapping, see {@see \Yiisoft\ProxyMiddleware\DEFAULT_PROTOCOLS_TO_HEADER_VALUES}- callable: custom function for getting the protocol
->withProtocolHeader( 'x-forwarded-proto', function (array $values, string $header, ServerRequestInterface $request): ?string { return $values[0] === 'https' ? 'https' : 'http'; return null; // If you can not decide on the protocol. }, ); - array: The array keys are protocols, and the array values are lists of header values that the header must have for the corresponding protocol.
->withProtocolHeader('x-forwarded-proto', [
'http' => ['http'],
'https' => ['https'],
]);
| public self withAddedProtocolHeader ( string $header, array|callable|null $values = null ) | ||
| $header | string |
The trusted protocol header name. |
| $values | array|callable|null |
The protocol mapping to header values. |
public function withAddedProtocolHeader(string $header, array|callable|null $values = null): self
{
$new = clone $this;
$header = strtolower($header);
if ($values === null) {
$new->protocolHeaders[$header] = self::DEFAULT_PROTOCOLS_TO_HEADER_VALUES;
return $new;
}
if (is_callable($values)) {
$new->protocolHeaders[$header] = $values;
return $new;
}
if (empty($values)) {
throw new RuntimeException('Protocol header values cannot be an empty array.');
}
$protocolHeader = [];
foreach ($values as $protocol => $acceptedValues) {
if (!is_string($protocol)) {
throw new RuntimeException('The protocol must be type of string.');
}
if ($protocol === '') {
throw new RuntimeException('The protocol cannot be an empty string.');
}
$acceptedValues = (array) $acceptedValues;
if (empty($acceptedValues)) {
throw new RuntimeException('Protocol accepted values cannot be an empty array.');
}
$protocolHeader[$protocol] = array_map('\strtolower', $acceptedValues);
}
$new->protocolHeaders[$header] = $protocolHeader;
return $new;
}
Returns a new instance without the specified protocol header.
See also withAddedProtocolHeader().
| public self withoutProtocolHeader ( string $header ) | ||
| $header | string |
The protocol header name. |
public function withoutProtocolHeader(string $header): self
{
$new = clone $this;
unset($new->protocolHeaders[strtolower($header)]);
return $new;
}
Returns a new instance without the specified protocol headers.
See also withoutProtocolHeader().
| public self withoutProtocolHeaders ( string[] $headers = null ) | ||
| $headers | string[] |
The protocol header names. If you specify |
public function withoutProtocolHeaders(?array $headers = null): self
{
$new = clone $this;
if ($headers === null) {
$new->protocolHeaders = [];
return $new;
}
foreach ($headers as $header) {
$new = $new->withoutProtocolHeader($header);
}
return $new;
}
Signup or Login in order to comment.