/** * {@inheritdoc} */ protected function doSendInternalRequest(InternalRequestInterface $internalRequest) { $loop = EventLoopFactory::create(); $dnsResolverFactory = new DnsResolverFactory(); $httpClientFactory = new HttpClientFactory(); $error = null; $response = null; $body = null; $request = $httpClientFactory->create($loop, $dnsResolverFactory->createCached('8.8.8.8', $loop))->request($internalRequest->getMethod(), $url = (string) $internalRequest->getUrl(), $this->prepareHeaders($internalRequest, true, true, true)); $request->on('error', function (\Exception $onError) use(&$error) { $error = $onError; }); $request->on('response', function (Response $onResponse) use(&$response, &$body) { $onResponse->on('data', function ($data) use(&$body) { $body .= $data; }); $response = $onResponse; }); $request->end($this->prepareBody($internalRequest)); $loop->run(); if ($error !== null) { throw HttpAdapterException::cannotFetchUrl($url, $this->getName(), $error->getMessage()); } return $this->getConfiguration()->getMessageFactory()->createResponse((int) $response->getCode(), $response->getReasonPhrase(), $response->getVersion(), $response->getHeaders(), BodyNormalizer::normalize($body, $internalRequest->getMethod())); }
public function assertConnection(array $options, $message = null) { $settings = array_merge(["ip" => "0.0.0.0", "port" => 0, "startServer" => false, "match" => true], $options); // optionally starting server if ($settings["startServer"]) { $serverLoop = EventLoopFactory::create(); $server = new SocketServer($serverLoop); $server->listen($settings["port"]); } // client setup $clientLoop = EventLoopFactory::create(); $dnsResolverFactory = new DnsResolverFactory(); $dns = $dnsResolverFactory->createCached("8.8.8.8", $clientLoop); // dunno why dns is required for this shit $connector = new SocketConnector($clientLoop, $dns); $promise = $connector->create($settings["ip"], $settings["port"])->then(function (SocketStream $stream) { $stream->close(); return true; }, function (SocketConnectionException $e) { return false; }); $clientLoop->run(); // catching the output $out = null; $promise->done(function ($v) use(&$out) { $out = $v; }); // optionally cleaning up the server if ($settings["startServer"]) { $server->shutdown(); } $this->assertEquals($out, $settings["match"], $message); }
/** @test */ public function createCachedShouldCreateResolverWithCachedExecutor() { $loop = $this->getMock('React\\EventLoop\\LoopInterface'); $factory = new Factory(); $resolver = $factory->createCached('8.8.8.8:53', $loop); $this->assertInstanceOf('React\\Dns\\Resolver\\Resolver', $resolver); $this->assertInstanceOf('React\\Dns\\Query\\CachedExecutor', $this->getResolverPrivateMemberValue($resolver, 'executor')); }
/** * @return Resolver */ public function getDns() { if (!$this->dns) { $factory = new DnsFactory(); $this->dns = $factory->createCached($this->resolver, $this->getLoop()); } return $this->dns; }
/** * @param DnsResolver $dnsResolver */ public function setDnsResolver(DnsResolver $dnsResolver = null) { if (!$dnsResolver instanceof DnsResolver) { $dnsResolverFactory = new DnsFactory(); $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $this->loop); } $this->dnsResolver = $dnsResolver; }
/** * @test * @dataProvider factoryShouldAddDefaultPortProvider */ public function factoryShouldAddDefaultPort($input, $expected) { $loop = $this->getMock('React\\EventLoop\\LoopInterface'); $factory = new Factory(); $resolver = $factory->create($input, $loop); $this->assertInstanceOf('React\\Dns\\Resolver\\Resolver', $resolver); $this->assertSame($expected, $this->getResolverPrivateMemberValue($resolver, 'nameserver')); }
/** * @return React\SocketClient\Connector */ public function getConnector() { if ($this->connector === null) { $dnsResolverFactory = new React\Dns\Resolver\Factory(); $dns = $dnsResolverFactory->createCached($this->config['dns'], $this->loop); $this->connector = new React\SocketClient\Connector($this->loop, $dns); } return $this->connector; }
/** * create sender attached to the given event loop and DNS resolver * * @param LoopInterface $loop * @param Resolver|string $dns DNS resolver instance or IP address * @return self */ public static function createFromLoopDns(LoopInterface $loop, $dns) { if (!$dns instanceof Resolver) { $dnsResolverFactory = new ResolverFactory(); $dns = $dnsResolverFactory->createCached($dns, $loop); } $connector = new Connector($loop, $dns); return self::createFromLoopConnectors($loop, $connector); }
private function startConnection() { $loop = \EventLoop\getLoop(); $dnsResolverFactory = new Factory(); $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop); $factory = new \React\HttpClient\Factory(); $client = $factory->create($loop, $dnsResolver); $cNegotiator = new ClientNegotiator($this->url, $this->subProtocols); $headers = $cNegotiator->getRequest()->getHeaders(); $flatHeaders = []; foreach ($headers as $k => $v) { $flatHeaders[$k] = $v[0]; } $request = $client->request("GET", $this->url, $flatHeaders, '1.1'); $request->on('response', function (Response $response, Request $request) use($cNegotiator) { if ($response->getCode() !== 101) { throw new \Exception("Unexpected response code " . $response->getCode()); } // TODO: Should validate response //$cNegotiator->validateResponse($response); $subprotoHeader = ""; $psr7Response = new \GuzzleHttp\Psr7\Response($response->getCode(), $response->getHeaders(), null, $response->getVersion()); if (count($psr7Response->getHeader('Sec-WebSocket-Protocol')) == 1) { $subprotoHeader = $psr7Response->getHeader('Sec-WebSocket-Protocol')[0]; } parent::onNext(new MessageSubject(new AnonymousObservable(function (ObserverInterface $observer) use($response) { $response->on('data', function ($data) use($observer) { $observer->onNext($data); }); $response->on('error', function ($e) use($observer) { $observer->onError($e); }); $response->on('close', function () use($observer) { $observer->onCompleted(); }); $response->on('end', function () use($observer) { $observer->onCompleted(); // complete the parent observer - we only do 1 connection parent::onCompleted(); }); return new CallbackDisposable(function () use($response) { // commented this out because disposal was causing the other // end (the request) to close also - which causes the pending messages // to get tossed //$response->close(); }); }), new CallbackObserver(function ($x) use($request) { $request->write($x); }, function ($e) use($request) { $request->close(); }, function () use($request) { $request->end(); }), true, $this->useMessageObject, $subprotoHeader, $cNegotiator->getRequest(), $psr7Response)); }); $request->writeHead(); }
public function __construct(LoopInterface $loop, Resolver $resolver = null) { if (null === $resolver) { $factory = new DnsFactory(); $resolver = $factory->create('8.8.8.8', $loop); } $this->_loop = $loop; $this->_connector = new Connector($loop, $resolver); $this->_secureConnector = new SecureConnector($this->_connector, $loop); }
public function __construct(LoopInterface $loop, Resolver $resolver = null) { $this->defaultHeaders['User-Agent'] = Guzzle::getUserAgent(); if (null === $resolver) { $factory = new DnsFactory(); $resolver = $factory->create('8.8.8.8', $loop); } $this->_loop = $loop; $this->_connector = new Connector($loop, $resolver); $this->_secureConnector = new SecureConnector($this->_connector, $loop); }
public static function factory($loop, array $options = array()) { $defaultOptions = array('port' => 15672, 'user' => 'guest', 'password' => 'guest', 'scheme' => 'http', 'url' => '127.0.0.1'); $options = array_merge($defaultOptions, $options); $dnsResolverFactory = new DnsResolverFactory(); $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop); $connectionManager = new ConnectionManager($loop, $dnsResolver); $secureConnectionManager = new SecureConnectionManager($loop, $dnsResolver); $client = new Client($loop, $connectionManager, $secureConnectionManager); return new self($client, $options); }
public function __construct(LoopInterface $loop, ConnectorInterface $connector = null, ProtocolFactory $protocol = null) { if ($connector === null) { $resolverFactory = new ResolverFactory(); $connector = new Connector($loop, $resolverFactory->create('8.8.8.8', $loop)); } if ($protocol === null) { $protocol = new ProtocolFactory(); } $this->connector = $connector; $this->protocol = $protocol; }
public function __construct(LoopInterface $loop, Connector $connector = null, SecureConnector $secureConnector = null) { if ($connector === null) { $resolverFactory = new ResolverFactory(); $connector = new Connector($loop, $resolverFactory->create('8.8.8.8', $loop)); } if ($secureConnector === null) { $secureConnector = new SecureConnector($connector, $loop); } $this->loop = $loop; $this->connector = $connector; $this->secureConnector = $secureConnector; }
public function __construct(LoopInterface $loop, ConnectorInterface $connector = null, Prober $prober = null) { if ($connector === null) { $resolverFactory = new ResolverFactory(); $resolver = $resolverFactory->create('8.8.8.8', $loop); $connector = new Connector($loop, $resolver); } if ($prober === null) { $prober = new Prober(); } $this->loop = $loop; $this->connector = $connector; $this->prober = $prober; }
public function __construct($method, $url, $body = null, array $headers = [], $protocolVersion = '1.0', $bufferResults = true, $includeResponse = false) { $this->method = $method; $this->url = $url; $this->body = $body; $this->headers = $headers; $this->protocolVersion = $protocolVersion; $this->bufferResults = $bufferResults; $this->includeResponse = $includeResponse; $loop = \EventLoop\getLoop(); $dnsResolverFactory = new Factory(); $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop); $factory = new \React\HttpClient\Factory(); $this->client = $factory->create($loop, $dnsResolver); }
public function testVerifyPeerDisabledForBadSslResolves() { if (!function_exists('stream_socket_enable_crypto')) { $this->markTestSkipped('Not supported on your platform (outdated HHVM?)'); } if (!class_exists('React\\SocketClient\\TcpConnector')) { $this->markTestSkipped('Test requires SocketClient:0.5'); } $dnsResolverFactory = new DnsFactory(); $resolver = $dnsResolverFactory->createCached('8.8.8.8', $this->loop); $tcp = new DnsConnector(new TcpConnector($this->loop), $resolver); $ssl = new SecureConnector($tcp, $this->loop, array('verify_peer' => false)); $sender = Sender::createFromLoopConnectors($this->loop, $tcp, $ssl); $browser = $this->browser->withSender($sender); Block\await($browser->get('https://self-signed.badssl.com/'), $this->loop); }
/** * Create a new Irto\OAuth2Proxy\Server instance with $config * * @param array $config * * @return Irto\OAuth2Proxy\Server */ public static function create(array $config) { $server = new static(); isset($config['verbose']) && $server->setVerbose($config['verbose']); $server->singleton('config', function ($server) use($config) { return new Collection($config); }); $server->bind('Irto\\OAuth2Proxy\\Server', function ($server) { return $server; }); // Create main loop React\EventLoop based $server->singleton('React\\EventLoop\\LoopInterface', function ($server) { return React\EventLoop\Factory::create(); }); // DNS resolve, used for create async requests $server->singleton('React\\Dns\\Resolver\\Resolver', function ($server) { $dnsResolverFactory = new React\Dns\Resolver\Factory(); return $dnsResolverFactory->createCached('8.8.8.8', $server['React\\EventLoop\\LoopInterface']); //Google DNS }); // HTTP Client $server->singleton('React\\HttpClient\\Client', function ($server) { $factory = new React\HttpClient\Factory(); return $factory->create($server['React\\EventLoop\\LoopInterface'], $server['React\\Dns\\Resolver\\Resolver']); }); // Request handler to React\Http $server->singleton('React\\Socket\\Server', function ($server) { $socket = new React\Socket\Server($server['React\\EventLoop\\LoopInterface']); $socket->listen($server->get('port')); return $socket; }); // HTTP server for handle requests $server->singleton('React\\Http\\Server', function ($server) { return new React\Http\Server($server['React\\Socket\\Server']); }); // HTTP server for handle requests $server->singleton('SessionHandlerInterface', function ($server) { return $server->make('Irto\\OAuth2Proxy\\Session\\AsyncRedisSessionHandler', ['lifetime' => array_get($server['config']->all(), 'session.lifetime')]); }); $server->bind('Illuminate\\Session\\Store', 'Irto\\OAuth2Proxy\\Session\\Store'); $server->boot(); return $server; }
/** @test */ public function gettingEncryptedStuffFromGoogleShouldWork() { $loop = new StreamSelectLoop(); $factory = new Factory(); $dns = $factory->create('8.8.8.8', $loop); $connected = false; $response = null; $secureConnector = new SecureConnector(new Connector($loop, $dns), $loop); $secureConnector->create('google.com', 443)->then(function ($conn) use(&$connected) { $connected = true; $conn->write("GET / HTTP/1.0\r\n\r\n"); return BufferedSink::createPromise($conn); })->then(function ($data) use(&$response) { $response = $data; }); $loop->run(); $this->assertTrue($connected); $this->assertRegExp('#^HTTP/1\\.0#', $response); }
protected function makeHttpRequest($method, $url, array $headers = [], $protocolVersion = '1.0', $body) { $dnsResolverFactory = new Factory(); $dnsResolver = $dnsResolverFactory->createCached("127.0.0.1", \EventLoop\getLoop()); $httpFactory = new \React\HttpClient\Factory(); $httpClient = $httpFactory->create(\EventLoop\getLoop(), $dnsResolver); $deferred = new Deferred(); $request = $httpClient->request($method, $url, $headers, $protocolVersion); $request->writeHead(); $request->write($body); $request->on('response', function ($response) use($deferred) { $responseBody = ""; $response->on('data', function ($data, $response) use(&$responseBody) { $responseBody .= $data; }); $response->on('end', function () use(&$responseBody, $deferred, $response) { $deferred->resolve([$response, $responseBody]); }); }); $request->end(); return $deferred->promise(); }
/** * Get the DNS Resolver, if one isn't set in instance will be created. * * @return Resolver */ public function getResolver() { if ($this->resolver instanceof Resolver) { return $this->resolver; } $factory = new Factory(); $this->resolver = $factory->createCached($this->getDnsServer(), $this->getLoop()); return $this->resolver; }
public function setUp() { $this->loop = LoopFactory::create(); $factory = new Factory(); $this->resolver = $factory->create('8.8.8.8', $this->loop); }
/** * @param Container $container */ public static function setupHttpClient($container) { $container->add('httpClient', function () use($container) { $dnsResolverFactory = new Factory(); $loop = $container->get('eventloop'); $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop); $factory = new HttpFactory(); $client = $factory->create($loop, $dnsResolver); return $client; }, true); }
/** * Build a React Dns Resolver. * * @param LoopInterface $loop * @param string $dns * * @return DnsResolver */ public static function buildDnsResolver(LoopInterface $loop, $dns = '8.8.8.8') { $factory = new DnsResolverFactory(); return $factory->createCached($dns, $loop); }
public function __construct(LoopInterface $loop) { $this->setLoop($loop); $dnsResolverFactory = new ResolverFactory(); $this->setResolver($dnsResolverFactory->createCached('8.8.8.8', $this->getLoop())); }
private function createImapstream(&$imapaccount) { echo 'createImapstream'; //$loop = \React\EventLoop\Factory::create(); $dnsResolverFactory = new Factory(); $dns = $dnsResolverFactory->createCached('8.8.8.8', $this->loop); $imapconnector = new Connector($this->loop, $dns); /** @var Mailaccount $mailaccount */ $mailaccount = $imapaccount['mailaccount']; $imapport = $mailaccount->getImapport() ? $mailaccount->getImapport() : 993; //$imapport=143; if ($imapport == 993) { //secure $secureConnector = new SecureConnector($imapconnector, $this->loop); $conn = $secureConnector->create($mailaccount->getImapserver(), $imapport); } else { $conn = $imapconnector->create($mailaccount->getImapserver(), $imapport); } echo $mailaccount->getImapserver() . $imapport; $conn->then(function (\React\Stream\Stream $imapstream) use(&$imapaccount) { echo 'Jojo'; $uid = uniqid(); echo $imapaccount['mailaccount']->getImapserver() . ': ' . $uid; $imapaccount['imapstream'] = $imapstream; $login = $imapaccount['mailaccount']->getImapusername(); $password = $imapaccount['mailaccount']->getImappassword(); $imapstream->write($uid . " LOGIN {$login} {$password}\r\n"); $status = 'LOGIN'; $imapstream->on('data', function ($data) use($uid, &$status, &$imapstream, &$imapaccount) { echo $imapaccount['mailaccount']->getImapserver() . ': ' . $data; $dataexpl = explode("\r\n", $data); foreach ($dataexpl as $dexpl) { if (preg_match("/^" . $uid . " OK/", $dexpl)) { //login OK: if ($status == 'LOGIN') { $imapstream->write($uid . " SELECT " . $imapaccount['mailaccount']->getImappathprefix() . "\r\n"); $status = 'SELECT'; echo "SEND: SELECT {$status}\r\n"; } else { if ($status == 'SELECT') { $imapstream->write($uid . " IDLE\r\n"); $status = 'IDLE'; echo "SEND: IDLE {$status}\r\n"; } } } if ($status == 'IDLE') { if (preg_match("/^\\* (\\d+) RECENT/", $dexpl, $countrecent)) { //login OK: $countrecent = $countrecent[1]; echo 'RECENT:' . $countrecent; $this->notifychanges($imapaccount, ['mailaccount_id' => $imapaccount['mailaccount']->getId(), 'recent' => $countrecent]); } if (preg_match("/^\\* (\\d+) EXISTS/", $dexpl, $countexists)) { //login OK: $countexists = $countexists[1]; echo 'EXISTS' . $countexists; $this->notifychanges($imapaccount, ['mailaccount_id' => $imapaccount['mailaccount']->getId(), 'exists' => $countexists]); } } } }); $imapstream->on('end', function () use($uid, &$status, &$imapstream, &$imapaccount) { echo 'END!!!!!'; $this->createImapstream($imapaccount); }); }, function (\Exception $error) use(&$imapaccount) { echo "Call Error: \n"; dump($error->getMessage()); echo "trying again...\n"; $this->createImapstream($imapaccount); }); return $imapaccount; }
/** * @param Factory $factory * * @return Resolver */ public function getResolver(Factory $factory = null) { if ($this->resolver instanceof Resolver) { $this->logDebug('Existing Resolver found using it'); return $this->resolver; } if ($factory === null) { $factory = new Factory(); } $this->logDebug('Creating new Resolver'); $this->resolver = $factory->createCached($this->dnsServer, $this->loop); return $this->resolver; }
<?php use React\Dns\Resolver\Factory as DNSResolverFactory; use React\EventLoop\Factory as EventLoopFactory; use React\HttpClient\Factory as HttpClientFactory; require 'vendor/autoload.php'; $loop = EventLoopFactory::create(); $dnsResolverFactory = new DNSResolverFactory(); $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop); $factory = new HttpClientFactory(); $client = $factory->create($loop, $dnsResolver); $request = $client->request('GET', 'https://example.com/'); $request->on('response', function ($response) { $response->on('data', function ($data, $response) { echo $data; }); }); $request->end(); $loop->run();
public function masterServer($bindMasterTo) { cli_set_process_title("mpcmf/console server:run/master -b {$bindMasterTo['host']} -p {$bindMasterTo['port']}"); $output = $this->output; //MPCMF_DEBUG && $output->writeln('<error>[MASTER]</error> Preparing server'); $loop = Factory::create(); $dnsResolverFactory = new reactResolver(); $dns = $dnsResolverFactory->createCached('8.8.8.8', $loop); $connector = new Connector($loop, $dns); $output->writeln('<error>[MASTER]</error> Binding callables and building socketServer'); $socketServer = new reactSocketServer($loop); $clientId = null; $socketServer->on('connection', function (Connection $clientConnection) use($connector, $output, $clientId, $loop) { $clientConnection->pause(); MPCMF_DEBUG && ($clientId = spl_object_hash($clientConnection)); do { $threadKey = array_rand($this->threads); if ($this->threads[$threadKey]->isAlive()) { break; } $loop->tick(); } while (true); $childPort = json_decode($threadKey, true)['port']; //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Client connected, using port {$childPort}"); $clientConnection->on('end', function () use($clientConnection, $clientId, $output) { //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Client connection ending"); }); $clientConnection->on('close', function () use($clientConnection, $clientId, $output) { //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Client connection closed"); }); /** @var \React\Promise\FulfilledPromise|\React\Promise\Promise|\React\Promise\RejectedPromise $childConnection */ $childConnection = $connector->create($this->childHost, $childPort); $childConnection->then(function (reactStream $childStream) use($clientConnection, $childConnection, $output, $clientId) { $childStream->pause(); //MPCMF_DEBUG && $output->writeln('<error>=================== ' . spl_object_hash($childStream) . ' CHILD STREAM OPEN </error>'); $childStream->on('end', function () use($clientConnection, $childConnection, $childStream, $output, $clientId) { //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Child closed connection"); //MPCMF_DEBUG && $output->writeln('<error>=================== ' . spl_object_hash($childStream) . ' CHILD STREAM CLOSE</error>'); $childStream->close(); $clientConnection->getBuffer()->on('full-drain', function () use($clientConnection, $output, $clientId) { //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Buffer is empty, closing client connection"); $clientConnection->close(); }); }); $childStream->on('data', function ($data) use($clientConnection, $childConnection, $childStream, $output, $clientId) { //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Response from child received"); //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Sending response to client"); $clientConnection->write($data); }); $childStream->resume(); $clientConnection->on('data', function ($data) use($clientConnection, $childConnection, $output, $clientId, $childStream) { //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Client data received"); //MPCMF_DEBUG && $output->writeln("<error>[MASTER:{$clientId}]</error> Sending request to child"); $childStream->write($data); }); $clientConnection->resume(); }); }); $output->writeln("<error>[MASTER]</error> Starting server on {$bindMasterTo['host']}:{$bindMasterTo['port']}"); $socketServer->listen($bindMasterTo['port'], $bindMasterTo['host']); $loop->addPeriodicTimer(1.0, [$this, 'checkThreads']); $loop->run(); }
<?php require __DIR__ . '/../vendor/autoload.php'; use Crunch\FastCGI\Client\Client; use Crunch\FastCGI\Client\ClientException; use Crunch\FastCGI\Client\Factory as FastCGIClientFactory; use Crunch\FastCGI\Protocol\RequestParameters; use React\Dns\Resolver\Factory as DnsResolverFactory; use React\EventLoop\Factory as EventLoopFactory; use React\SocketClient\Connector as SocketConnector; use React\Promise as promise; $loop = EventLoopFactory::create(); $dnsResolverFactory = new DnsResolverFactory(); $dns = $dnsResolverFactory->createCached('0.0.0.0', $loop); $connector = new SocketConnector($loop, $dns); $factory = new FastCGIClientFactory($loop, $connector); $factory->createClient('127.0.0.1', 1337)->then(function (Client $client) use($argv) { $name = @$argv[1] ?: 'World'; $data = "name={$name}"; $request = $client->newRequest(new RequestParameters(['REQUEST_METHOD' => 'POST', 'SCRIPT_FILENAME' => __DIR__ . '/docroot/hello-world.php', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'CONTENT_LENGTH' => strlen($data)]), new \Crunch\FastCGI\ReaderWriter\StringReader($data)); $request2 = $client->newRequest(new RequestParameters(['REQUEST_METHOD' => 'POST', 'SCRIPT_FILENAME' => __DIR__ . '/docroot/hello-world.php', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'CONTENT_LENGTH' => strlen($data)]), new \Crunch\FastCGI\ReaderWriter\StringReader($data)); $responseHandler = function ($response) use($client) { echo "\n" . $response->getContent()->read() . \PHP_EOL; }; $failHandler = function (ClientException $fail) { echo "Request failed: {$fail->getMessage()}"; return $fail; }; $x = $client->sendRequest($request)->then($responseHandler, $failHandler); $y = $client->sendRequest($request2)->then($responseHandler, $failHandler); $z = $client->sendRequest($request2)->then($responseHandler, $failHandler);