/** * {@inheritdoc} * * @param callable $callable Pass in a callable that gets passed one argument which is the response body */ protected function performRPCRequest($method, array $arguments, callable $callable) { /** @var AsyncClient $client */ /** @var LibEventReactor|NativeReactor $reactor */ list($reactor, $client) = $this->clientFactory->build(); $request = clone $this->request; /** Callback for response data from client **/ $onResponse = function (Response $response) use($reactor, $method, $callable) { $isJson = function () use($response) { json_decode($response->getBody()); return json_last_error() === JSON_ERROR_NONE; }; if ($response->getStatus() !== 200 || !$isJson()) { $reactor->stop(); throw new HTTPException(sprintf('Did not get back a JSON response body, got "%s" instead', $method, print_r($response->getBody(), true))); } $reactor->stop(); $callable($response->getBody()); }; /** Callback on error for either auth response or response **/ $onError = function (\Exception $e) use($reactor) { $reactor->stop(); throw new HTTPException("Something went wrong..." . $e->getMessage()); }; /** Callback when auth response is returned **/ $onAuthResponse = function (Response $response, Request $request) use($reactor, $client, $onResponse, $onError, $method, $arguments) { if (!$response->hasHeader('Set-Cookie')) { $reactor->stop(); throw new HTTPException("Response from torrent client did not return an Set-Cookie header"); } $response = $response->getHeader('Set-Cookie'); preg_match_all('#_session_id=(.*?);#', $response[0], $matches); $cookie = isset($matches[0][0]) ? $matches[0][0] : ''; $request = clone $request; $request->setMethod('POST'); $request->setHeader('Cookie', array($cookie)); $request->setBody(json_encode(array('method' => $method, 'params' => $arguments, 'id' => rand()))); $client->request($request, $onResponse, $onError); }; /** Let's do this **/ $reactor->immediately(function () use($reactor, $client, $request, $onAuthResponse, $onError) { $request->setUri(sprintf('%s:%s/json', $this->connectionArgs['host'], $this->connectionArgs['port'])); $request->setMethod('POST'); $request->setAllHeaders(array('Content-Type' => 'application/json; charset=utf-8')); $request->setBody(json_encode(array('method' => self::METHOD_AUTH, 'params' => array($this->connectionArgs['password']), 'id' => rand()))); $client->request($request, $onAuthResponse, $onError); }); $reactor->run(); }
/** * {@inheritdoc} * * @param callable $callable Pass in a callable that gets passed one argument which is the response body */ protected function performRPCRequest($method, array $arguments, callable $callable) { $returnFields = array('hashString', 'name', 'sizeWhenDone', 'status', 'rateDownload', 'rateUpload', 'uploadedEver', 'files', 'errorString'); /** @var AsyncClient $client */ /** @var LibEventReactor|NativeReactor $reactor */ list($reactor, $client) = $this->clientFactory->build(); $request = clone $this->request; /** Callback for response data from client **/ $onResponse = function (Response $response) use($reactor, $method, $callable) { $isJson = function () use($response) { json_decode($response->getBody()); return json_last_error() === JSON_ERROR_NONE; }; if ($response->getStatus() !== 200 || !$isJson()) { $reactor->stop(); throw new HTTPException(sprintf('Did not get back a JSON response body, got "%s" instead', $method, print_r($response->getBody(), true))); } $reactor->stop(); $callable($response->getBody()); }; /** Callback on error for either auth response or response **/ $onError = function (\Exception $e) use($reactor) { $reactor->stop(); throw new HTTPException("Something went wrong..." . $e->getMessage()); }; /** Callback when auth response is returned **/ $onAuthResponse = function (Response $response, Request $request) use($reactor, $client, $onResponse, $onError, $method, $returnFields, $arguments) { if (!$response->hasHeader('X-Transmission-Session-Id')) { $reactor->stop(); throw new HTTPException("Response from torrent client did not return an X-Transmission-Session-Id header"); } $sessionId = $response->getHeader('X-Transmission-Session-Id'); $request = clone $request; $request->setMethod('POST'); $request->setHeader('X-Transmission-Session-Id', $sessionId); $request->setBody(json_encode(array('method' => $method, 'arguments' => array_merge(array('fields' => $returnFields), $arguments)))); $client->request($request, $onResponse, $onError); }; /** Let's do this **/ $reactor->immediately(function () use($reactor, $client, $request, $onAuthResponse, $onError) { $request->setUri(sprintf('%s:%s/transmission/rpc', $this->connectionArgs['host'], $this->connectionArgs['port'])); $request->setMethod('GET'); $request->setAllHeaders(array('Content-Type' => 'application/json; charset=utf-8', 'Authorization' => sprintf('Basic %s', base64_encode(sprintf('%s:%s', $this->connectionArgs['username'], $this->connectionArgs['password']))))); $client->request($request, $onAuthResponse, $onError); }); $reactor->run(); }