Skip to content

Commit ebcaeea

Browse files
[HttpClient] Filter private IPs before connecting when Host == IP
1 parent 54118c6 commit ebcaeea

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

NoPrivateNetworkHttpClient.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,20 @@ public function request(string $method, string $url, array $options = []): Respo
7777
}
7878

7979
$subnets = $this->subnets;
80+
$lastUrl = '';
8081
$lastPrimaryIp = '';
8182

82-
$options['on_progress'] = function (int $dlNow, int $dlSize, array $info) use ($onProgress, $subnets, &$lastPrimaryIp): void {
83+
$options['on_progress'] = function (int $dlNow, int $dlSize, array $info) use ($onProgress, $subnets, &$lastUrl, &$lastPrimaryIp): void {
84+
if ($info['url'] !== $lastUrl) {
85+
$host = trim(parse_url($info['url'], PHP_URL_HOST) ?: '', '[]');
86+
87+
if ($host && IpUtils::checkIp($host, $subnets ?? self::PRIVATE_SUBNETS)) {
88+
throw new TransportException(sprintf('Host "%s" is blocked for "%s".', $host, $info['url']));
89+
}
90+
91+
$lastUrl = $info['url'];
92+
}
93+
8394
if ($info['primary_ip'] !== $lastPrimaryIp) {
8495
if ($info['primary_ip'] && IpUtils::checkIp($info['primary_ip'], $subnets ?? self::PRIVATE_SUBNETS)) {
8596
throw new TransportException(sprintf('IP "%s" is blocked for "%s".', $info['primary_ip'], $info['url']));

Tests/NoPrivateNetworkHttpClientTest.php

+25-2
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ public static function getExcludeData(): array
6565
/**
6666
* @dataProvider getExcludeData
6767
*/
68-
public function testExclude(string $ipAddr, $subnets, bool $mustThrow)
68+
public function testExcludeByIp(string $ipAddr, $subnets, bool $mustThrow)
6969
{
7070
$content = 'foo';
71-
$url = sprintf('http://%s/', 0 < substr_count($ipAddr, ':') ? sprintf('[%s]', $ipAddr) : $ipAddr);
71+
$url = sprintf('http://%s/', strtr($ipAddr, '.:', '--'));
7272

7373
if ($mustThrow) {
7474
$this->expectException(TransportException::class);
@@ -85,6 +85,29 @@ public function testExclude(string $ipAddr, $subnets, bool $mustThrow)
8585
}
8686
}
8787

88+
/**
89+
* @dataProvider getExcludeData
90+
*/
91+
public function testExcludeByHost(string $ipAddr, $subnets, bool $mustThrow)
92+
{
93+
$content = 'foo';
94+
$url = sprintf('http://%s/', str_contains($ipAddr, ':') ? sprintf('[%s]', $ipAddr) : $ipAddr);
95+
96+
if ($mustThrow) {
97+
$this->expectException(TransportException::class);
98+
$this->expectExceptionMessage(sprintf('Host "%s" is blocked for "%s".', $ipAddr, $url));
99+
}
100+
101+
$previousHttpClient = $this->getHttpClientMock($url, $ipAddr, $content);
102+
$client = new NoPrivateNetworkHttpClient($previousHttpClient, $subnets);
103+
$response = $client->request('GET', $url);
104+
105+
if (!$mustThrow) {
106+
$this->assertEquals($content, $response->getContent());
107+
$this->assertEquals(200, $response->getStatusCode());
108+
}
109+
}
110+
88111
public function testCustomOnProgressCallback()
89112
{
90113
$ipAddr = '104.26.14.6';

0 commit comments

Comments
 (0)