diff --git a/src/Http/RequestFactory.php b/src/Http/RequestFactory.php index f6ed6140..bae0d2e8 100644 --- a/src/Http/RequestFactory.php +++ b/src/Http/RequestFactory.php @@ -273,26 +273,22 @@ private function getMethod(): string private function getClient(Url $url): array { - $remoteAddr = !empty($_SERVER['REMOTE_ADDR']) - ? $_SERVER['REMOTE_ADDR'] - : null; - $remoteHost = !empty($_SERVER['REMOTE_HOST']) - ? $_SERVER['REMOTE_HOST'] - : null; + $remoteAddr = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null; // use real client address and host if trusted proxy is used - $usingTrustedProxy = $remoteAddr && Arrays::some($this->proxies, fn(string $proxy): bool => Helpers::ipMatch($remoteAddr, $proxy)); - if ($usingTrustedProxy) { - empty($_SERVER['HTTP_FORWARDED']) - ? $this->useNonstandardProxy($url, $remoteAddr, $remoteHost) - : $this->useForwardedProxy($url, $remoteAddr, $remoteHost); + if ($remoteAddr && Arrays::some($this->proxies, fn(string $proxy): bool => Helpers::ipMatch($remoteAddr, $proxy))) { + $remoteHost = null; + $remoteAddr = empty($_SERVER['HTTP_FORWARDED']) ? $this->useNonstandardProxy($url) : $this->useForwardedProxy($url); + + } else { + $remoteHost = !empty($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : null; } return [$remoteAddr, $remoteHost]; } - private function useForwardedProxy(Url $url, &$remoteAddr, &$remoteHost): void + private function useForwardedProxy(Url $url): ?string { $forwardParams = preg_split('/[,;]/', $_SERVER['HTTP_FORWARDED']); foreach ($forwardParams as $forwardParam) { @@ -311,19 +307,17 @@ private function useForwardedProxy(Url $url, &$remoteAddr, &$remoteHost): void $host = $proxyParams['host'][0]; $startingDelimiterPosition = strpos($host, '['); if ($startingDelimiterPosition === false) { //IPv4 - $remoteHostArr = explode(':', $host); - $remoteHost = $remoteHostArr[0]; - $url->setHost($remoteHost); - if (isset($remoteHostArr[1])) { - $url->setPort((int) $remoteHostArr[1]); + $pair = explode(':', $host); + $url->setHost($pair[0]); + if (isset($pair[1])) { + $url->setPort((int) $pair[1]); } } else { //IPv6 $endingDelimiterPosition = strpos($host, ']'); - $remoteHost = substr($host, strpos($host, '[') + 1, $endingDelimiterPosition - 1); - $url->setHost($remoteHost); - $remoteHostArr = explode(':', substr($host, $endingDelimiterPosition)); - if (isset($remoteHostArr[1])) { - $url->setPort((int) $remoteHostArr[1]); + $url->setHost(substr($host, strpos($host, '[') + 1, $endingDelimiterPosition - 1)); + $pair = explode(':', substr($host, $endingDelimiterPosition)); + if (isset($pair[1])) { + $url->setPort((int) $pair[1]); } } } @@ -332,10 +326,11 @@ private function useForwardedProxy(Url $url, &$remoteAddr, &$remoteHost): void ? $proxyParams['proto'][0] : 'http'; $url->setScheme(strcasecmp($scheme, 'https') === 0 ? 'https' : 'http'); + return $remoteAddr ?? null; } - private function useNonstandardProxy(Url $url, &$remoteAddr, &$remoteHost): void + private function useNonstandardProxy(Url $url): ?string { if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) { $url->setScheme(strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0 ? 'https' : 'http'); @@ -361,10 +356,11 @@ private function useNonstandardProxy(Url $url, &$remoteAddr, &$remoteHost): void if (isset($xForwardedForRealIpKey) && !empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { $xForwardedHost = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']); if (isset($xForwardedHost[$xForwardedForRealIpKey])) { - $remoteHost = trim($xForwardedHost[$xForwardedForRealIpKey]); - $url->setHost($remoteHost); + $url->setHost(trim($xForwardedHost[$xForwardedForRealIpKey])); } } + + return $remoteAddr ?? null; } diff --git a/tests/Http/RequestFactory.proxy.forwarded.phpt b/tests/Http/RequestFactory.proxy.forwarded.phpt index d4cb4ede..b8ed7851 100644 --- a/tests/Http/RequestFactory.proxy.forwarded.phpt +++ b/tests/Http/RequestFactory.proxy.forwarded.phpt @@ -25,7 +25,7 @@ test('', function () { $factory->setProxy('127.0.0.1/8'); Assert::same('23.75.45.200', $factory->fromGlobals()->getRemoteAddress()); - Assert::same('192.168.0.1', @$factory->fromGlobals()->getRemoteHost()); // deprecated + Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated $url = $factory->fromGlobals()->getUrl(); Assert::same('http', $url->getScheme()); @@ -43,7 +43,7 @@ test('', function () { $factory->setProxy('127.0.0.3'); Assert::same('23.75.45.200', $factory->fromGlobals()->getRemoteAddress()); - Assert::same('192.168.0.1', @$factory->fromGlobals()->getRemoteHost()); // deprecated + Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated $url = $factory->fromGlobals()->getUrl(); Assert::same(8080, $url->getPort()); @@ -62,7 +62,7 @@ test('', function () { $factory->setProxy('127.0.0.3'); Assert::same('2001:db8:cafe::17', $factory->fromGlobals()->getRemoteAddress()); - Assert::same('2001:db8:cafe::18', @$factory->fromGlobals()->getRemoteHost()); // deprecated + Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated $url = $factory->fromGlobals()->getUrl(); Assert::same('2001:db8:cafe::18', $url->getHost()); @@ -79,7 +79,7 @@ test('', function () { $factory->setProxy('127.0.0.3'); Assert::same('2001:db8:cafe::17', $factory->fromGlobals()->getRemoteAddress()); - Assert::same('2001:db8:cafe::18', @$factory->fromGlobals()->getRemoteHost()); // deprecated + Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated $url = $factory->fromGlobals()->getUrl(); Assert::same(47832, $url->getPort()); diff --git a/tests/Http/RequestFactory.proxy.x-forwarded.phpt b/tests/Http/RequestFactory.proxy.x-forwarded.phpt index c13e2032..ec7a0ad4 100644 --- a/tests/Http/RequestFactory.proxy.x-forwarded.phpt +++ b/tests/Http/RequestFactory.proxy.x-forwarded.phpt @@ -27,7 +27,7 @@ test('', function () { $factory->setProxy('127.0.0.1/8'); Assert::same('23.75.45.200', $factory->fromGlobals()->getRemoteAddress()); - Assert::same('otherhost', @$factory->fromGlobals()->getRemoteHost()); // deprecated + Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated $url = $factory->fromGlobals()->getUrl(); Assert::same('otherhost', $url->getHost()); @@ -44,12 +44,11 @@ test('', function () { $factory = new RequestFactory; $factory->setProxy('10.0.0.0/24'); Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteAddress()); - Assert::same('real', @$factory->fromGlobals()->getRemoteHost()); // deprecated + Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated + Assert::same('real', $factory->fromGlobals()->getUrl()->getHost()); $factory->setProxy(['10.0.0.1', '10.0.0.2']); Assert::same('172.16.0.1', $factory->fromGlobals()->getRemoteAddress()); - Assert::same('real', @$factory->fromGlobals()->getRemoteHost()); // deprecated - - $url = $factory->fromGlobals()->getUrl(); - Assert::same('real', $url->getHost()); + Assert::null(@$factory->fromGlobals()->getRemoteHost()); // deprecated + Assert::same('real', $factory->fromGlobals()->getUrl()->getHost()); });