diff --git a/src/Query/HostsExecutor.php b/src/Query/HostsExecutor.php new file mode 100644 index 00000000..68657edb --- /dev/null +++ b/src/Query/HostsExecutor.php @@ -0,0 +1,55 @@ +(?:\d+\.){3}\d+)\s*(?.*?)\s*$/', $line, $matches)) { + $this->add4($matches['ip'], $matches['name']); + } elseif (preg_match('/^(?(?:[:a-f0-9]+))\s*(?.*?)\s*$/', $line, $matches)) { + $this->add6($matches['ip'], $matches['name']); + } + } + } + } + + + public function query($nameserver, Query $query) + { + $result = new Deferred(); + if ($query->type === Message::TYPE_A + && isset($this->ipv4[$query->name])) { + $response = new Message(); + $response->answers[] = new Record($query->name, $query->type, $query->class, 0, $this->ipv4[$query->name]); + $result->resolve($response); + } else { + $result->reject('Name not found in hosts file.'); + } + return $result->promise(); + } + + public function add4($address, $name) + { + $this->ipv4[$name] = $address; + } + + public function add6($address, $name) + { + $this->ipv6[$name] = $address; + + } +} \ No newline at end of file diff --git a/tests/Fixtures/etc/hosts b/tests/Fixtures/etc/hosts new file mode 100644 index 00000000..01d0550f --- /dev/null +++ b/tests/Fixtures/etc/hosts @@ -0,0 +1,9 @@ +127.0.0.1 localhost +127.0.1.1 host-pc + +# The following lines are desirable for IPv6 capable hosts +::1 ip6-localhost ip6-loopback +fe00::0 ip6-localnet +ff00::0 ip6-mcastprefix +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters \ No newline at end of file diff --git a/tests/Query/HostsExecutorTest.php b/tests/Query/HostsExecutorTest.php new file mode 100644 index 00000000..59e876fa --- /dev/null +++ b/tests/Query/HostsExecutorTest.php @@ -0,0 +1,70 @@ +loop = $this->getMock('React\EventLoop\LoopInterface'); + $this->executor = new HostsExecutor(__DIR__.'/../Fixtures/etc/hosts'); + + } + + public function testRegisteredName() + { + $query = new Query('host-pc', Message::TYPE_A, Message::CLASS_IN, 1345656451); + /** @var \React\Promise\Promise$response */ + $response = $this->executor->query(null, $query); + + $success = $this->createCallableMock(); + $success + ->expects($this->once()) + ->method('__invoke') + ->with($this->isInstanceOf('React\Dns\Model\Message')) + ; + $response->then($success, $this->expectCallableNever()); + + } + + public function testUnRegisteredName() + { + $query = new Query('some-host', Message::TYPE_A, Message::CLASS_IN, 1345656451); + /** @var \React\Promise\Promise$response */ + $response = $this->executor->query(null, $query); + + $err = $this->createCallableMock(); + $err + ->expects($this->once()) + ->method('__invoke') + ; + $response->then($this->expectCallableNever(), $err); + + } + + protected function expectCallableNever() + { + $mock = $this->createCallableMock(); + $mock + ->expects($this->never()) + ->method('__invoke'); + + return $mock; + } + + protected function createCallableMock() + { + return $this->getMock('React\Tests\Dns\CallableStub'); + } +}