Skip to content

Commit 5e3b94b

Browse files
authored
Merge pull request #43 from akrabat/satalaondrej-improvements
Added types to private functions, improved readability, shouldCheckProxyHeaders as separate function
2 parents e28c983 + 718f966 commit 5e3b94b

File tree

1 file changed

+72
-78
lines changed

1 file changed

+72
-78
lines changed

src/IpAddress.php

+72-78
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22
namespace RKA\Middleware;
33

4+
use Psr\Http\Message\MessageInterface;
45
use Psr\Http\Message\ServerRequestInterface;
56
use Psr\Http\Message\ResponseInterface;
67
use Psr\Http\Server\MiddlewareInterface;
@@ -106,11 +107,7 @@ public function __construct(
106107
}
107108
}
108109

109-
/**
110-
* @param string $ipAddress
111-
* @return array
112-
*/
113-
private function parseWildcard(string $ipAddress)
110+
private function parseWildcard(string $ipAddress): array
114111
{
115112
// IPv4 has 4 parts separated by '.'
116113
// IPv6 has 8 parts separated by ':'
@@ -125,11 +122,7 @@ private function parseWildcard(string $ipAddress)
125122
return explode($delim, $ipAddress, $parts);
126123
}
127124

128-
/**
129-
* @param string $ipAddress
130-
* @return array
131-
*/
132-
private function parseCidr(string $ipAddress)
125+
private function parseCidr(string $ipAddress): array
133126
{
134127
list($subnet, $bits) = explode('/', $ipAddress, 2);
135128
$subnet = ip2long($subnet);
@@ -173,7 +166,7 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res
173166
$ipAddress = $this->determineClientIpAddress($request);
174167
$request = $request->withAttribute($this->attributeName, $ipAddress);
175168

176-
return $response = $next($request, $response);
169+
return $next($request, $response);
177170
}
178171

179172
/**
@@ -194,80 +187,86 @@ protected function determineClientIpAddress($request)
194187
}
195188
}
196189

197-
$checkProxyHeaders = false;
198-
if ($this->checkProxyHeaders) {
199-
// Exact Match
200-
if ($this->trustedProxies && in_array($ipAddress, $this->trustedProxies)) {
201-
$checkProxyHeaders = true;
202-
}
203-
204-
// Wildcard Match
205-
if ($this->checkProxyHeaders && $this->trustedWildcards) {
206-
// IPv4 has 4 parts separated by '.'
207-
// IPv6 has 8 parts separated by ':'
208-
if (strpos($ipAddress, '.') > 0) {
209-
$delim = '.';
210-
$parts = 4;
211-
} else {
212-
$delim = ':';
213-
$parts = 8;
214-
}
215-
216-
$ipAddrParts = explode($delim, $ipAddress, $parts);
217-
foreach ($this->trustedWildcards as $proxy) {
218-
if (count($proxy) !== $parts) {
219-
continue; // IP version does not match
220-
}
221-
$match = true;
222-
foreach ($proxy as $i => $part) {
223-
if ($part !== '*' && $part !== $ipAddrParts[$i]) {
224-
$match = false;
225-
break; // IP does not match, move to next proxy
226-
}
227-
}
228-
if ($match) {
229-
$checkProxyHeaders = true;
190+
if ($this->shouldCheckProxyHeaders($ipAddress)) {
191+
foreach ($this->headersToInspect as $header) {
192+
if ($request->hasHeader($header)) {
193+
$ip = $this->getFirstIpAddressFromHeader($request, $header);
194+
if ($this->isValidIpAddress($ip)) {
195+
$ipAddress = $ip;
230196
break;
231197
}
232198
}
233199
}
200+
}
234201

235-
// CIDR Match
236-
if ($this->checkProxyHeaders && $this->trustedCidrs) {
237-
// Only IPv4 is supported for CIDR matching
238-
$ipAsLong = ip2long($ipAddress);
239-
if ($ipAsLong) {
240-
foreach ($this->trustedCidrs as $proxy) {
241-
if ($proxy[0] <= $ipAsLong && $ipAsLong <= $proxy[1]) {
242-
$checkProxyHeaders = true;
243-
break;
244-
}
245-
}
246-
}
247-
}
202+
return empty($ipAddress) ? null : $ipAddress;
203+
}
248204

249-
if (!$this->trustedProxies && !$this->trustedWildcards && !$this->trustedCidrs) {
250-
$checkProxyHeaders = true;
205+
/**
206+
* Determine whether we should check proxy headers for specified ip address
207+
*/
208+
protected function shouldCheckProxyHeaders(string $ipAddress): bool
209+
{
210+
//do not check if configured to not check
211+
if (!$this->checkProxyHeaders) {
212+
return false;
213+
}
214+
215+
//if configured to check but no constraints
216+
if (!$this->trustedProxies && !$this->trustedWildcards && !$this->trustedCidrs) {
217+
return true;
218+
}
219+
220+
// Exact Match for trusted proxies
221+
if ($this->trustedProxies && in_array($ipAddress, $this->trustedProxies)) {
222+
return true;
223+
}
224+
225+
// Wildcard Match
226+
if ($this->trustedWildcards) {
227+
// IPv4 has 4 parts separated by '.'
228+
// IPv6 has 8 parts separated by ':'
229+
if (strpos($ipAddress, '.') > 0) {
230+
$delim = '.';
231+
$parts = 4;
232+
} else {
233+
$delim = ':';
234+
$parts = 8;
251235
}
252236

253-
if ($checkProxyHeaders) {
254-
foreach ($this->headersToInspect as $header) {
255-
if ($request->hasHeader($header)) {
256-
$ip = $this->getFirstIpAddressFromHeader($request, $header);
257-
if ($this->isValidIpAddress($ip)) {
258-
$ipAddress = $ip;
259-
break;
260-
}
237+
$ipAddrParts = explode($delim, $ipAddress, $parts);
238+
foreach ($this->trustedWildcards as $proxy) {
239+
if (count($proxy) !== $parts) {
240+
continue; // IP version does not match
241+
}
242+
$match = true;
243+
foreach ($proxy as $i => $part) {
244+
if ($part !== '*' && $part !== $ipAddrParts[$i]) {
245+
$match = false;
246+
break; // IP does not match, move to next proxy
261247
}
262248
}
249+
if ($match) {
250+
return true;
251+
}
263252
}
264253
}
265254

266-
if (empty($ipAddress)) {
267-
$ipAddress = null;
255+
// CIDR Match
256+
if ($this->trustedCidrs) {
257+
// Only IPv4 is supported for CIDR matching
258+
$ipAsLong = ip2long($ipAddress);
259+
if ($ipAsLong) {
260+
foreach ($this->trustedCidrs as $proxy) {
261+
if ($proxy[0] <= $ipAsLong && $ipAsLong <= $proxy[1]) {
262+
return true;
263+
}
264+
}
265+
}
268266
}
269267

270-
return $ipAddress;
268+
//default - not check
269+
return false;
271270
}
272271

273272
/**
@@ -296,14 +295,9 @@ protected function extractIpAddress($ipAddress)
296295
* @param string $ip
297296
* @return boolean
298297
*/
299-
protected function isValidIpAddress($ip)
298+
protected function isValidIpAddress(string $ip): bool
300299
{
301-
$flags = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
302-
if (filter_var($ip, FILTER_VALIDATE_IP, $flags) === false) {
303-
return false;
304-
}
305-
306-
return true;
300+
return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6) !== false;
307301
}
308302

309303
/**
@@ -313,7 +307,7 @@ protected function isValidIpAddress($ip)
313307
* @param string $header Header name
314308
* @return string
315309
*/
316-
private function getFirstIpAddressFromHeader($request, $header)
310+
private function getFirstIpAddressFromHeader(MessageInterface $request, string $header): string
317311
{
318312
$items = explode(',', $request->getHeaderLine($header));
319313
$headerValue = trim(reset($items));

0 commit comments

Comments
 (0)