public function get($key) { if (!isset($this->data[$key])) { return When::reject(); } return When::resolve($this->data[$key]); }
public function loadEtcResolvConf($filename) { if (!file_exists($filename)) { return When::reject(new \InvalidArgumentException("The filename for /etc/resolv.conf given does not exist: {$filename}")); } try { $deferred = new Deferred(); $fd = fopen($filename, 'r'); stream_set_blocking($fd, 0); $contents = ''; $stream = new Stream($fd, $this->loop); $stream->on('data', function ($data) use(&$contents) { $contents .= $data; }); $stream->on('end', function () use(&$contents, $deferred) { $deferred->resolve($contents); }); $stream->on('error', function ($error) use($deferred) { $deferred->reject($error); }); return $deferred->promise(); } catch (\Exception $e) { return When::reject($e); } }
public function checkConnectedSocket($socket) { // The following hack looks like the only way to // detect connection refused errors with PHP's stream sockets. if (false === stream_socket_get_name($socket, true)) { return When::reject(new ConnectionException('Connection refused')); } return When::resolve($socket); }
public function createSocketForAddress($address, $port) { $url = $this->getSocketUrl($address, $port); $socket = stream_socket_client($url, $errno, $errstr, 0, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT, $this->createStreamContext()); if (!$socket) { return When::reject(new \RuntimeException(sprintf("connection to %s:%d failed: %s", $address, $port, $errstr), $errno)); } stream_set_blocking($socket, 0); // wait for connection return $this->waitForStreamOnce($socket)->then(array($this, 'checkConnectedSocket'))->then(array($this, 'handleConnectedSocket')); }
public function lookup(Query $query) { $id = $this->serializeQueryToIdentity($query); $expiredAt = $this->expiredAt; return $this->cache->get($id)->then(function ($value) use($query, $expiredAt) { $recordBag = unserialize($value); if (null !== $expiredAt && $expiredAt <= $query->currentTime) { return When::reject(); } return $recordBag->all(); }); }
/** * @covers React\Dns\Query\RetryExecutor * @test */ public function queryShouldForwardNonTimeoutErrors() { $executor = $this->createExecutorMock(); $executor->expects($this->once())->method('query')->with('8.8.8.8', $this->isInstanceOf('React\\Dns\\Query\\Query'))->will($this->returnCallback(function ($domain, $query) { return When::reject(new \Exception()); })); $callback = $this->expectCallableNever(); $errorback = $this->createCallableMock(); $errorback->expects($this->once())->method('__invoke')->with($this->isInstanceOf('Exception')); $retryExecutor = new RetryExecutor($executor, 2); $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451); $retryExecutor->query('8.8.8.8', $query)->then($callback, $errorback); }
public function setAuth($auth) { if (!is_callable($auth)) { throw new InvalidArgumentException('Given authenticator is not a valid callable'); } if ($this->protocolVersion !== null && $this->protocolVersion !== '5') { throw new UnexpectedValueException('Authentication requires SOCKS5. Consider using protocol version 5 or waive authentication'); } // wrap authentication callback in order to cast its return value to a promise $this->auth = function ($username, $password) use($auth) { $ret = call_user_func($auth, $username, $password); if ($ret instanceof PromiseInterface) { return $ret; } return $ret ? When::resolve() : When::reject(); }; }
/** * @covers React\Dns\Query\CachedExecutor * @test */ public function callingQueryTwiceShouldUseCachedResult() { $cachedRecords = array(new Record('igor.io', Message::TYPE_A, Message::CLASS_IN)); $executor = $this->createExecutorMock(); $executor->expects($this->once())->method('query')->will($this->callQueryCallbackWithAddress('178.79.169.131')); $cache = $this->getMockBuilder('React\\Dns\\Query\\RecordCache')->disableOriginalConstructor()->getMock(); $cache->expects($this->at(0))->method('lookup')->with($this->isInstanceOf('React\\Dns\\Query\\Query'))->will($this->returnValue(When::reject())); $cache->expects($this->at(1))->method('storeResponseMessage')->with($this->isType('integer'), $this->isInstanceOf('React\\Dns\\Model\\Message')); $cache->expects($this->at(2))->method('lookup')->with($this->isInstanceOf('React\\Dns\\Query\\Query'))->will($this->returnValue(When::resolve($cachedRecords))); $cachedExecutor = new CachedExecutor($executor, $cache); $query = new Query('igor.io', Message::TYPE_A, Message::CLASS_IN, 1345656451); $cachedExecutor->query('8.8.8.8', $query, function () { }, function () { }); $cachedExecutor->query('8.8.8.8', $query, function () { }, function () { }); }
public function createSocketForAddress($address, $port, $hostName = null) { $url = $this->getSocketUrl($address, $port); $contextOpts = $this->contextOptions; // Fix for SSL in PHP >= 5.6, where peer name must be validated. if ($hostName !== null) { $contextOpts['ssl']['SNI_enabled'] = true; $contextOpts['ssl']['SNI_server_name'] = $hostName; $contextOpts['ssl']['peer_name'] = $hostName; } $flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT; $context = stream_context_create($contextOpts); $socket = stream_socket_client($url, $errno, $errstr, 0, $flags, $context); if (!$socket) { return When::reject(new \RuntimeException(sprintf("connection to %s:%d failed: %s", $address, $port, $errstr), $errno)); } stream_set_blocking($socket, 0); // wait for connection return $this->waitForStreamOnce($socket)->then(array($this, 'checkConnectedSocket'))->then(array($this, 'handleConnectedSocket')); }
public function getConnection($host, $port) { if (strlen($host) > 255 || $port > 65535 || $port < 0) { return When::reject(new InvalidArgumentException('Invalid target specified')); } $deferred = new Deferred(); $timestampTimeout = microtime(true) + $this->timeout; $timerTimeout = $this->loop->addTimer($this->timeout, function () use($deferred) { $deferred->reject(new Exception('Timeout while connecting to socks server')); // TODO: stop initiating connection and DNS query }); // create local references as these settings may change later due to its async nature $auth = $this->auth; $protocolVersion = $this->protocolVersion; // protocol version not explicitly set? if ($protocolVersion === null) { // authentication requires SOCKS5, otherwise use SOCKS4a $protocolVersion = $auth === null ? '4a' : '5'; } $loop = $this->loop; $that = $this; When::all(array($this->connector->create($this->socksHost, $this->socksPort)->then(null, function ($error) { throw new Exception('Unable to connect to socks server', 0, $error); }), $this->resolve($host)->then(null, function ($error) { throw new Exception('Unable to resolve remote hostname', 0, $error); })), function ($fulfilled) use($deferred, $port, $timestampTimeout, $that, $loop, $timerTimeout, $protocolVersion, $auth) { $loop->cancelTimer($timerTimeout); $timeout = max($timestampTimeout - microtime(true), 0.1); $deferred->resolve($that->handleConnectedSocks($fulfilled[0], $fulfilled[1], $port, $timeout, $protocolVersion, $auth)); }, function ($error) use($deferred, $loop, $timerTimeout) { $loop->cancelTimer($timerTimeout); $deferred->reject(new Exception('Unable to connect to socks server', 0, $error)); }); return $deferred->promise(); }