Skip to content

Commit

Permalink
refactor: initialize properties in constructor, not named constructors
Browse files Browse the repository at this point in the history
Adds `$trustedProxies` and `$trustedHeaders` as optional array arguments to the constructor; `trustedProxies()` now passes those.

Signed-off-by: Matthew Weier O'Phinney <matthew@weierophinney.net>
  • Loading branch information
weierophinney committed Jun 27, 2022
1 parent b6a2f32 commit 9429abb
Showing 1 changed file with 58 additions and 58 deletions.
116 changes: 58 additions & 58 deletions src/ServerRequestFilter/FilterUsingXForwardedHeaders.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,62 +33,20 @@ final class FilterUsingXForwardedHeaders implements FilterServerRequestInterface
/**
* @var list<FilterUsingXForwardedHeaders::HEADER_*>
*/
private $trustedHeaders = [];
private $trustedHeaders;

/** @var list<non-empty-string> */
private $trustedProxies = [];
private $trustedProxies;

/**
* Do not trust any proxies, nor any X-FORWARDED-* headers.
*
* This is functionally equivalent to calling `trustProxies([], [])`.
*/
public static function trustNone(): self
{
return new self();
}

/**
* Trust any X-FORWARDED-* headers from any address.
*
* This is functionally equivalent to calling `trustProxies(['*'])`.
*
* WARNING: Only do this if you know for certain that your application
* sits behind a trusted proxy that cannot be spoofed. This should only
* be the case if your server is not publicly addressable, and all requests
* are routed via a reverse proxy (e.g., a load balancer, a server such as
* Caddy, when using Traefik, etc.).
*/
public static function trustAny(): self
{
return self::trustProxies(['*']);
}

/**
* Indicate which proxies and which X-Forwarded headers to trust.
*
* @param list<non-empty-string> $proxyCIDRList Each element may
* be an IP address or a subnet specified using CIDR notation; both IPv4
* and IPv6 are supported. The special string "*" will be translated to
* two entries, "0.0.0.0/0" and "::/0". An empty list indicates no
* proxies are trusted.
* @param list<FilterUsingXForwardedHeaders::HEADER_*> $trustedHeaders If
* the list is empty, all X-Forwarded headers are trusted.
* @throws InvalidProxyAddressException
* @throws InvalidForwardedHeaderNameException
* Only allow construction via named constructors
*/
public static function trustProxies(
array $proxyCIDRList,
array $trustedHeaders = self::X_FORWARDED_HEADERS
): self {
$proxyCIDRList = self::normalizeProxiesList($proxyCIDRList);
self::validateTrustedHeaders($trustedHeaders);

$filter = new self();
$filter->trustedProxies = $proxyCIDRList;
$filter->trustedHeaders = $trustedHeaders;

return $filter;
private function __construct(
array $trustedProxies = [],
array $trustedHeaders = []
) {
$this->trustedProxies = $trustedProxies;
$this->trustedHeaders = $trustedHeaders;
}

public function __invoke(ServerRequestInterface $request): ServerRequestInterface
Expand Down Expand Up @@ -136,6 +94,55 @@ public function __invoke(ServerRequestInterface $request): ServerRequestInterfac
return $request;
}

/**
* Do not trust any proxies, nor any X-FORWARDED-* headers.
*
* This is functionally equivalent to calling `trustProxies([], [])`.
*/
public static function trustNone(): self
{
return new self();
}

/**
* Trust any X-FORWARDED-* headers from any address.
*
* This is functionally equivalent to calling `trustProxies(['*'])`.
*
* WARNING: Only do this if you know for certain that your application
* sits behind a trusted proxy that cannot be spoofed. This should only
* be the case if your server is not publicly addressable, and all requests
* are routed via a reverse proxy (e.g., a load balancer, a server such as
* Caddy, when using Traefik, etc.).
*/
public static function trustAny(): self
{
return self::trustProxies(['*']);
}

/**
* Indicate which proxies and which X-Forwarded headers to trust.
*
* @param list<non-empty-string> $proxyCIDRList Each element may
* be an IP address or a subnet specified using CIDR notation; both IPv4
* and IPv6 are supported. The special string "*" will be translated to
* two entries, "0.0.0.0/0" and "::/0". An empty list indicates no
* proxies are trusted.
* @param list<FilterUsingXForwardedHeaders::HEADER_*> $trustedHeaders If
* the list is empty, all X-Forwarded headers are trusted.
* @throws InvalidProxyAddressException
* @throws InvalidForwardedHeaderNameException
*/
public static function trustProxies(
array $proxyCIDRList,
array $trustedHeaders = self::X_FORWARDED_HEADERS
): self {
$proxyCIDRList = self::normalizeProxiesList($proxyCIDRList);
self::validateTrustedHeaders($trustedHeaders);

return new self($proxyCIDRList, $trustedHeaders);
}

private function isFromTrustedProxy(string $remoteAddress): bool
{
foreach ($this->trustedProxies as $proxy) {
Expand Down Expand Up @@ -224,11 +231,4 @@ private static function validateProxyCIDR($cidr): bool
)
);
}

/**
* Only allow construction via named constructors
*/
private function __construct()
{
}
}

0 comments on commit 9429abb

Please sign in to comment.