Skip to content

Commit 61b603c

Browse files
committed
Windows uses hard-coded defaults for localhost instead of hosts file
1 parent 21c7238 commit 61b603c

4 files changed

Lines changed: 19 additions & 9 deletions

File tree

src/Config/HostsFile.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
*
1313
* Most notably, this file usually contains an entry to map "localhost" to the
1414
* local IP. Windows is a notable exception here, as Windows does not actually
15-
* include "localhost" in this file by default.
15+
* include "localhost" in this file by default. To compensate for this, this
16+
* class may explicitly be wrapped in another HostsFile instance which
17+
* hard-codes these entries for Windows (see also Factory).
1618
*
1719
* This class mostly exists to abstract the parsing/extraction process so this
1820
* can be replaced with a faster alternative in the future.

src/Resolver/Factory.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,24 @@ public function createCached($nameserver, LoopInterface $loop, CacheInterface $c
4848
private function decorateHostsFileExecutor(ExecutorInterface $executor)
4949
{
5050
try {
51-
$hosts = HostsFile::loadFromPathBlocking();
51+
$executor = new HostsFileExecutor(
52+
HostsFile::loadFromPathBlocking(),
53+
$executor
54+
);
5255
} catch (\RuntimeException $e) {
5356
// ignore this file if it can not be loaded
54-
return $executor;
5557
}
5658

57-
return new HostsFileExecutor($hosts, $executor);
59+
// Windows does not store localhost in hosts file by default but handles this internally
60+
// To compensate for this, we explicitly use hard-coded defaults for localhost
61+
if (DIRECTORY_SEPARATOR === '\\') {
62+
$executor = new HostsFileExecutor(
63+
new HostsFile("127.0.0.1 localhost"),
64+
$executor
65+
);
66+
}
67+
68+
return $executor;
5869
}
5970

6071
protected function createExecutor(LoopInterface $loop)

tests/FunctionalResolverTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ public function setUp()
1919

2020
public function testResolveLocalhostResolves()
2121
{
22-
if (DIRECTORY_SEPARATOR === '\\') {
23-
$this->markTestSkipped('Not supported on Windows');
24-
}
25-
2622
$promise = $this->resolver->resolve('localhost');
2723
$promise->then($this->expectCallableOnce(), $this->expectCallableNever());
2824

tests/Resolver/FactoryTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ private function getResolverPrivateExecutor($resolver)
9797
{
9898
$executor = $this->getResolverPrivateMemberValue($resolver, 'executor');
9999

100-
if ($executor instanceof HostsFileExecutor) {
100+
// extract underlying executor that may be wrapped in multiple layers of hosts file executors
101+
while ($executor instanceof HostsFileExecutor) {
101102
$reflector = new \ReflectionProperty('React\Dns\Query\HostsFileExecutor', 'fallback');
102103
$reflector->setAccessible(true);
103104

0 commit comments

Comments
 (0)