private function createResponseObject(RequestInterface $request, array $headers, TransactionInterface $transaction, StreamInterface $stream) { $parts = explode(' ', array_shift($headers), 3); $options = ['protocol_version' => substr($parts[0], -3)]; if (isset($parts[2])) { $options['reason_phrase'] = $parts[2]; } $response = $this->messageFactory->createResponse($parts[1], $this->headersFromLines($headers), null, $options); // Automatically decode responses when instructed. if ($request->getConfig()->get('decode_content')) { switch ($response->getHeader('Content-Encoding')) { case 'gzip': case 'deflate': $stream = new InflateStream($stream); break; } } // Drain the stream immediately if 'stream' was not enabled. if (!$request->getConfig()['stream']) { $stream = $this->getSaveToBody($request, $stream); } $response->setBody($stream); $transaction->setResponse($response); RequestEvents::emitHeaders($transaction); return $response; }
/** * Creates a cURL handle based on a transaction. * * @param TransactionInterface $transaction Holds a request and response * @param MessageFactoryInterface $messageFactory Used to create responses * @param null|resource $handle Optionally provide a curl handle to modify * * @return resource Returns a prepared cURL handle * @throws AdapterException when an option cannot be applied */ public function __invoke( TransactionInterface $transaction, MessageFactoryInterface $messageFactory, $handle = null ) { $request = $transaction->getRequest(); $mediator = new RequestMediator($transaction, $messageFactory); $options = $this->getDefaultOptions($request, $mediator); $this->applyMethod($request, $options); $this->applyTransferOptions($request, $mediator, $options); $this->applyHeaders($request, $options); unset($options['_headers']); // Add adapter options from the request's configuration options if ($config = $request->getConfig()['curl']) { $options = $this->applyCustomCurlOptions($config, $options); } if (!$handle) { $handle = curl_init(); } curl_setopt_array($handle, $options); return $handle; }
private function createResponseObject(array $headers, TransactionInterface $transaction, $stream) { $parts = explode(' ', array_shift($headers), 3); $options = ['protocol_version' => substr($parts[0], -3)]; if (isset($parts[2])) { $options['reason_phrase'] = $parts[2]; } $response = $this->messageFactory->createResponse($parts[1], $this->headersFromLines($headers), $stream, $options); $transaction->setResponse($response); RequestEvents::emitHeaders($transaction); return $response; }
private function createResponseObject(array $headers, TransactionInterface $transaction, $stream) { $parts = explode(' ', array_shift($headers), 3); $options = ['protocol_version' => substr($parts[0], -3)]; if (isset($parts[2])) { $options['reason_phrase'] = $parts[2]; } // Set the size on the stream if it was returned in the response $responseHeaders = []; foreach ($headers as $header) { $headerParts = explode(':', $header, 2); $responseHeaders[$headerParts[0]] = isset($headerParts[1]) ? $headerParts[1] : ''; } $response = $this->messageFactory->createResponse($parts[1], $responseHeaders, $stream, $options); $transaction->setResponse($response); RequestEvents::emitHeaders($transaction); return $response; }
/** * Emits an error event for a request and accounts for the propagation * of an error event being stopped to prevent the exception from being * thrown. * * @param TransactionInterface $transaction * @param \Exception $e * @param array $stats * * @throws \GuzzleHttp\Exception\RequestException */ public static function emitError(TransactionInterface $transaction, \Exception $e, array $stats = []) { $request = $transaction->getRequest(); // Convert non-request exception to a wrapped exception if (!$e instanceof RequestException) { $e = new RequestException($e->getMessage(), $request, null, $e); } // Mark the exception as having been emitted for an error event. This // works in tandem with the emitBefore method to prevent the error // event from being triggered twice for the same exception. $e->emittedError(true); // Dispatch an event and allow interception if (!$request->getEmitter()->emit('error', new ErrorEvent($transaction, $e, $stats))->isPropagationStopped()) { throw $e; } }
private function getDefaultTimeout(TransactionInterface $transaction) { $timeout = $transaction->getRequest()->getConfig()->get('timeout'); if ($timeout !== null) { return $timeout; } $timeout = $transaction->getClient()->getDefaultOption('timeout'); if (null == $timeout) { $timeout = ini_get('default_socket_timeout'); } return $timeout; }
/** * This function ensures that a response was set on a transaction. If one * was not set, then the request is retried if possible. This error * typically means you are sending a payload, curl encountered a * "Connection died, retrying a fresh connect" error, tried to rewind the * stream, and then encountered a "necessary data rewind wasn't possible" * error, causing the request to be sent through curl_multi_info_read() * without an error status. * * @param TransactionInterface $transaction * @param BatchContext $context * * @return bool Returns true if it's OK, and false if it failed. * @throws \GuzzleHttp\Exception\RequestException If it failed and cannot * recover. */ private function validateResponseWasSet(TransactionInterface $transaction, BatchContext $context) { if ($transaction->getResponse()) { return true; } $body = $transaction->getRequest()->getBody(); if (!$body) { // This is weird and should probably never happen. RequestEvents::emitError($transaction, new RequestException('No response was received for a request with no body. This' . ' could mean that you are saturating your network.', $transaction->getRequest())); } elseif (!$body->isSeekable() || !$body->seek(0)) { // Nothing we can do with this. Sorry! RequestEvents::emitError($transaction, new RequestException('The connection was unexpectedly closed. The request would' . ' have been retried, but attempting to rewind the' . ' request body failed. Consider wrapping your request' . ' body in a CachingStream decorator to work around this' . ' issue if necessary.', $transaction->getRequest())); } else { $this->retryFailedConnection($transaction, $context); } return false; }
public static function GetResponse(TransactionInterface $trans) { /** * Get the GuzzleHttp\Message\Request so that we can pick * out the information we need to generate a MockResponse */ $request = $trans->getRequest(); /** * Normally, I wouldn't condone this sort of weird URL munging * but the FantasyData service always formats its urls as * /<subscription>/<format>/<Resource>/ so I know I can always * ignore the first three elements (2 params) of the getPath * call for this service. * * Getting the resource here allows me to use that as a path * element for creating a "MockResponse" object on the fly */ list(, , , $resource) = explode('/', $request->getPath()); switch ($resource) { case 'ActiveBoxScores': $response = new ActiveBoxScores\Response\Mock($request); break; case 'AreAnyGamesInProgress': $response = new AreAnyGamesInProgress\Response\Mock($request); break; case 'BoxScore': $response = new BoxScore\Response\Mock($request); break; case 'BoxScores': $response = new BoxScores\Response\Mock($request); break; case 'Byes': $response = new Byes\Response\Mock($request); break; case 'FantasyDefenseByGame': $response = new FantasyDefenseByGame\Response\Mock($request); break; case 'FantasyDefenseBySeason': $response = new FantasyDefenseBySeason\Response\Mock($request); break; case 'FantasyDefenseProjectionsByGame': $response = new FantasyDefenseProjectionsByGame\Response\Mock($request); break; case 'FantasyPlayers': $response = new FantasyPlayers\Response\Mock($request); break; case 'FinalBoxScores': $response = new FinalBoxScores\Response\Mock($request); break; case 'FreeAgents': $response = new FreeAgents\Response\Mock($request); break; case 'GameLeagueLeaders': $response = new GameLeagueLeaders\Response\Mock($request); break; case 'GameStats': $response = new GameStats\Response\Mock($request); break; case 'GameStatsByWeek': $response = new GameStatsByWeek\Response\Mock($request); break; case 'Injuries': $response = new Injuries\Response\Mock($request); break; case 'LiveBoxScores': $response = new LiveBoxScores\Response\Mock($request); break; case 'News': $response = new News\Response\Mock($request); break; case 'NewsByPlayerID': $response = new NewsByPlayerID\Response\Mock($request); break; case 'NewsByTeam': $response = new NewsByTeam\Response\Mock($request); break; case 'Player': $response = new Player\Response\Mock($request); break; case 'PlayerGameProjectionStatsByTeam': $response = new PlayerGameProjectionStatsByTeam\Response\Mock($request); break; case 'PlayerGameStatsByPlayerID': $response = new PlayerGameStatsByPlayerID\Response\Mock($request); break; case 'PlayerGameStatsByTeam': $response = new PlayerGameStatsByTeam\Response\Mock($request); break; case 'PlayerGameStatsByWeek': $response = new PlayerGameStatsByWeek\Response\Mock($request); break; case 'Players': $response = new Players\Response\Mock($request); break; case 'PlayerSeasonStatsByPlayerID': $response = new PlayerSeasonStatsByPlayerID\Response\Mock($request); break; case 'PlayerSeasonStatsByTeam': $response = new PlayerSeasonStatsByTeam\Response\Mock($request); break; case 'Schedules': $response = new Schedules\Response\Mock($request); break; case 'Scores': $response = new Scores\Response\Mock($request); break; case 'ScoresByWeek': $response = new ScoresByWeek\Response\Mock($request); break; case 'SeasonLeagueLeaders': $response = new SeasonLeagueLeaders\Response\Mock($request); break; case 'Stadiums': $response = new Stadiums\Response\Mock($request); break; case 'Standings': $response = new Standings\Response\Mock($request); break; case 'TeamGameStats': $response = new TeamGameStats\Response\Mock($request); break; case 'Teams': $response = new Teams\Response\Mock($request); break; case 'TeamSeasonStats': $response = new TeamSeasonStats\Response\Mock($request); break; case 'Timeframes': $response = new Timeframes\Response\Mock($request); break; default: throw new \Exception("Unrecognized resource requested, {$resource}"); break; } return $response; }
private function isCurlException(TransactionInterface $transaction, array $curl, BatchContext $context, array $info) { if (CURLM_OK == $curl['result'] || CURLM_CALL_MULTI_PERFORM == $curl['result']) { return false; } $request = $transaction->getRequest(); try { // Send curl stats along if they are available $stats = ['curl_result' => $curl['result']] + $info; RequestEvents::emitError($transaction, new RequestException(sprintf('[curl] (#%s) %s [url] %s', $curl['result'], function_exists('curl_strerror') ? curl_strerror($curl['result']) : self::ERROR_STR, $request->getUrl()), $request), $stats); } catch (RequestException $e) { $this->throwException($e, $context); } return true; }
/** * Read data from the request body and send it to curl * * @param resource $ch Curl handle * @param resource $fd File descriptor * @param int $length Amount of data to read * * @return string */ public function readRequestBody($ch, $fd, $length) { return (string) $this->transaction->getRequest()->getBody()->read($length); }
/** * Get the request object * * @return RequestInterface */ public function getRequest() { return $this->transaction->getRequest(); }