/**
  * {@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();
 }