Example #1
1
 /**
  * Validate the HTTP response and throw exceptions on errors
  *
  * @throws ServerException
  */
 private function validateResponse()
 {
     if ($this->httpResponse->getStatusCode() !== 200) {
         $statusCode = $this->httpResponse->getStatusCode();
         throw new ServerException('Server responded with HTTP status ' . $statusCode, $statusCode);
     } else {
         if (strpos($this->httpResponse->getHeader('Content-Type'), 'application/json') === false) {
             throw new ServerException('Server did not respond with the expected content-type (application/json)');
         }
     }
     try {
         $this->httpResponse->json();
     } catch (RuntimeException $e) {
         throw new ServerException($e->getMessage());
     }
 }
 /**
  * Parses additional exception information from the response headers
  *
  * @param RequestInterface $request  Request that was issued
  * @param Response         $response The response from the request
  * @param array            $data     The current set of exception data
  */
 protected function parseHeaders(RequestInterface $request, Response $response, array &$data)
 {
     $data['message'] = $response->getStatusCode() . ' ' . $response->getReasonPhrase();
     if ($requestId = $response->getHeader('x-amz-request-id')) {
         $data['request_id'] = $requestId;
         $data['message'] .= " (Request-ID: {$requestId})";
     }
 }
 /**
  * Check the response for an error.
  *
  * @param Response         $response The response received.
  *
  * @param RequestInterface $request  The request sent.
  *
  * @return void
  *
  * @throws \RuntimeException On any error.
  */
 protected function checkError(Response $response, RequestInterface $request)
 {
     if ($response->getStatusCode() == 200 || $response->getStatusCode() == 201) {
         return;
     }
     switch ($response->getHeader('Content-Type')) {
         case 'text/plain':
             throw new \RuntimeException('Error: ' . $response->getBody(true) . ' URI: ' . $request->getUrl());
         case 'application/json':
             $error = json_decode($response->getBody(true));
             if (isset($error->message)) {
                 throw new \RuntimeException($error->message . ' URI: ' . $request->getUrl());
             }
             break;
         default:
             throw new \RuntimeException('Unknown Error: No error message was returned from the server - Code: ' . $response->getStatusCode() . ' URI: ' . $response->getRequest()->getUrl());
     }
 }
 /**
  * Seconds remaining until a new time window opens
  *
  * @return null
  */
 public function getRateReset()
 {
     if (!$this->lastResponse) {
         return null;
     }
     /** @var Header $limit */
     $limit = $this->lastResponse->getHeader('X-Rate-Reset');
     return $limit ? $limit->normalize() : null;
 }
 public function testOnRequestSuccess()
 {
     $event = new Event();
     $response = new Response(200, array('X-RateLimit-Limit' => array(30), 'X-RateLimit-Remaining' => array(29), 'X-RateLimit-Reset' => array(10)));
     $event['response'] = $response;
     $plugin = new RateLimitPlugin();
     $plugin->onRequestSuccess($event);
     $this->assertAttributeEquals((string) $response->getHeader('X-RateLimit-Limit'), 'rateLimitMax', $plugin);
     $this->assertAttributeEquals((string) $response->getHeader('X-RateLimit-Remaining'), 'rateLimitRemaining', $plugin);
     $this->assertAttributeEquals((string) $response->getHeader('X-RateLimit-Reset'), 'rateLimitReset', $plugin);
     $this->assertAttributeEquals(true, 'rateLimitEnabled', $plugin);
 }
Example #6
0
 /**
  * {@inheritdoc}
  */
 public function getLatestResponseHeaders()
 {
     if (null === $this->response) {
         return;
     }
     return ['reset' => (int) (string) $this->response->getHeader('RateLimit-Reset'), 'remaining' => (int) (string) $this->response->getHeader('RateLimit-Remaining'), 'limit' => (int) (string) $this->response->getHeader('RateLimit-Limit')];
 }
 public static function getApiLimit(Response $response)
 {
     $remainingCalls = $response->getHeader('X-RateLimit-Remaining');
     if (null !== $remainingCalls && 1 > $remainingCalls) {
         throw new ApiLimitExceedException($remainingCalls);
     }
 }
 public function cache(RequestInterface $request, Response $response)
 {
     $currentTime = time();
     $ttl = $request->getParams()->get('cache.override_ttl') ?: $response->getMaxAge() ?: $this->defaultTtl;
     if ($cacheControl = $response->getHeader('Cache-Control')) {
         $stale = $cacheControl->getDirective('stale-if-error');
         $ttl += $stale == true ? $ttl : $stale;
     }
     // Determine which manifest key should be used
     $key = $this->getCacheKey($request);
     $persistedRequest = $this->persistHeaders($request);
     $entries = array();
     if ($manifest = $this->cache->fetch($key)) {
         // Determine which cache entries should still be in the cache
         $vary = $response->getVary();
         foreach (unserialize($manifest) as $entry) {
             // Check if the entry is expired
             if ($entry[4] < $currentTime) {
                 continue;
             }
             $entry[1]['vary'] = isset($entry[1]['vary']) ? $entry[1]['vary'] : '';
             if ($vary != $entry[1]['vary'] || !$this->requestsMatch($vary, $entry[0], $persistedRequest)) {
                 $entries[] = $entry;
             }
         }
     }
     // Persist the response body if needed
     $bodyDigest = null;
     if ($response->getBody() && $response->getBody()->getContentLength() > 0) {
         $bodyDigest = $this->getBodyKey($request->getUrl(), $response->getBody());
         $this->cache->save($bodyDigest, (string) $response->getBody(), $ttl);
     }
     array_unshift($entries, array($persistedRequest, $this->persistHeaders($response), $response->getStatusCode(), $bodyDigest, $currentTime + $ttl));
     $this->cache->save($key, serialize($entries));
 }
Example #9
0
 public static function decode(Response $response)
 {
     if (strpos($response->getHeader(Header::CONTENT_TYPE), Mime::JSON) !== false) {
         $string = (string) $response->getBody();
         $response = json_decode($string);
         self::checkJsonError($string);
         return $response;
     }
 }
 /**
  * {@inheritdoc}
  */
 protected function getDelay($retries, RequestInterface $request, Response $response = null, HttpException $e = null)
 {
     if ($response) {
         // Validate the checksum against our computed checksum
         if ($checksum = (string) $response->getHeader('x-amz-crc32')) {
             // Retry the request if the checksums don't match, otherwise, return null
             return $checksum != hexdec(Stream::getHash($response->getBody(), 'crc32b')) ? true : null;
         }
     }
 }
 protected function getDelay($retries, RequestInterface $request, Response $response = null, HttpException $e = null)
 {
     if ($response) {
         //Short circuit the rest of the checks if it was successful
         if ($response->isSuccessful()) {
             return false;
         } else {
             if (isset($this->errorCodes[$response->getStatusCode()])) {
                 if ($response->getHeader("Retry-After")) {
                     return $response->getHeader("Retry-After")->__toString();
                 } else {
                     return self::$defaultRetryAfter;
                 }
             } else {
                 return null;
             }
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function parse(Response $response)
 {
     $data = array('code' => null, 'message' => null, 'type' => $response->isClientError() ? 'client' : 'server', 'request_id' => (string) $response->getHeader('x-amzn-RequestId'), 'parsed' => null);
     if (null !== ($json = json_decode($response->getBody(true), true))) {
         $data['parsed'] = $json;
         $json = array_change_key_case($json);
         $data = $this->doParse($data, $json);
     }
     return $data;
 }
 public static function factory(RequestInterface $request, Response $response)
 {
     $label = 'Bearer error response';
     $bearerReason = self::headerToReason($response->getHeader("WWW-Authenticate"));
     $message = $label . PHP_EOL . implode(PHP_EOL, array('[status code] ' . $response->getStatusCode(), '[reason phrase] ' . $response->getReasonPhrase(), '[bearer reason] ' . $bearerReason, '[url] ' . $request->getUrl()));
     $e = new static($message);
     $e->setResponse($response);
     $e->setRequest($request);
     $e->setBearerReason($bearerReason);
     return $e;
 }
 private function getContextFromResponse(Response $response)
 {
     $extraFields = array();
     $headersToLookFor = array('x-served-by', 'x-backend', 'x-location', 'x-varnish');
     foreach ($headersToLookFor as $headerName) {
         if ($response->hasHeader($headerName)) {
             $extraFields[$headerName] = (string) $response->getHeader($headerName);
         }
     }
     return $extraFields;
 }
Example #15
0
 /**
  * Get the amount of time to delay in seconds before retrying a request
  *
  * @param int              $retries  Number of retries of the request
  * @param RequestInterface $request  Request that was sent
  * @param Response         $response Response that was received. Note that there may not be a response
  * @param HttpException    $e        Exception that was encountered if any
  *
  * @return bool|int Returns false to not retry or the number of seconds to delay between retries
  */
 public function getBackoffPeriod($retries, RequestInterface $request, Response $response = null, HttpException $e = null)
 {
     if (!$response) {
         return false;
     }
     if ($response->getStatusCode() != 429) {
         return false;
     }
     $reset = (string) $response->getHeader('X-Rate-Limit-Reset');
     if (!preg_match('/^[0-9]+$/', $reset)) {
         return false;
     }
     return ((int) $reset + 0.1) * $this->getMultiplier();
 }
 /**
  * {@inheritdoc}
  */
 protected function doParse(array $data, Response $response)
 {
     // Merge in error data from the JSON body
     if ($json = $data['parsed']) {
         $data = array_replace($data, $json);
     }
     // Correct error type from services like Amazon Glacier
     if (!empty($data['type'])) {
         $data['type'] = strtolower($data['type']);
     }
     // Retrieve the error code from services like Amazon Elastic Transcoder
     if ($code = (string) $response->getHeader('x-amzn-ErrorType')) {
         $data['code'] = substr($code, 0, strpos($code, ':'));
     }
     return $data;
 }
 /**
  * {@inheritdoc}
  */
 public function parse(RequestInterface $request, Response $response)
 {
     // Build array of default error data
     $data = array('code' => null, 'message' => null, 'type' => $response->isClientError() ? 'client' : 'server', 'request_id' => (string) $response->getHeader('x-amzn-RequestId'), 'parsed' => null);
     // Parse the json and normalize key casings
     if (null !== ($json = json_decode($response->getBody(true), true))) {
         $data['parsed'] = array_change_key_case($json);
     }
     // Do additional, protocol-specific parsing and return the result
     $data = $this->doParse($data, $response);
     // Remove "Fault" suffix from exception names
     if (isset($data['code']) && strpos($data['code'], 'Fault')) {
         $data['code'] = preg_replace('/^([a-zA-Z]+)Fault$/', '$1', $data['code']);
     }
     return $data;
 }
 /**
  * @param string $errorName
  * @param \Guzzle\Http\Message\Response $response
  * @param int $statusCode
  * @return \Phobetor\Billomat\Exception\ExceptionInterface
  */
 public function createExceptionFromStatusCode($errorName, $response, $statusCode)
 {
     $exception = null;
     switch ($statusCode) {
         case self::STATUS_NOT_FOUND:
             return new NotFoundException($errorName, $statusCode);
         case self::STATUS_BAD_REQUEST:
             return new BadRequestException($errorName, $statusCode);
         case self::STATUS_UNAUTHORIZED:
             return new UnauthorizedException($errorName, $statusCode);
         case self::STATUS_TOO_MANY_REQUESTS:
             $exception = new TooManyRequestsException($errorName, $statusCode);
             if ($response->hasHeader('X-Rate-Limit-Remaining')) {
                 $exception->setRateLimitRemaining((int) (string) $response->getHeader('X-Rate-Limit-Remaining'));
             }
             if ($response->hasHeader('X-Rate-Limit-Reset')) {
                 $exception->setRateLimitReset((int) (string) $response->getHeader('X-Rate-Limit-Reset'));
             }
             return $exception;
         default:
             return new UnknownErrorException($errorName, $statusCode);
     }
 }
Example #19
0
 public function getHeader($name)
 {
     return $this->_response->getHeader($name);
 }
Example #20
0
 public function addCookiesFromResponse(Response $response, RequestInterface $request = null)
 {
     if ($cookieHeader = $response->getHeader('Set-Cookie')) {
         $parser = ParserRegistry::getInstance()->getParser('cookie');
         foreach ($cookieHeader as $cookie) {
             if ($parsed = $request ? $parser->parseCookie($cookie, $request->getHost(), $request->getPath()) : $parser->parseCookie($cookie)) {
                 // Break up cookie v2 into multiple cookies
                 foreach ($parsed['cookies'] as $key => $value) {
                     $row = $parsed;
                     $row['name'] = $key;
                     $row['value'] = $value;
                     unset($row['cookies']);
                     $this->add(new Cookie($row));
                 }
             }
         }
     }
 }
Example #21
0
 /**
  * Add the plugin's headers to a response
  *
  * @param RequestInterface $request  Request
  * @param Response         $response Response to add headers to
  */
 protected function addResponseHeaders(RequestInterface $request, Response $response)
 {
     $params = $request->getParams();
     $response->setHeader('Via', sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION));
     $lookup = ($params['cache.lookup'] === true ? 'HIT' : 'MISS') . ' from GuzzleCache';
     if ($header = $response->getHeader('X-Cache-Lookup')) {
         // Don't add duplicates
         $values = $header->toArray();
         $values[] = $lookup;
         $response->setHeader('X-Cache-Lookup', array_unique($values));
     } else {
         $response->setHeader('X-Cache-Lookup', $lookup);
     }
     if ($params['cache.hit'] === true) {
         $xcache = 'HIT from GuzzleCache';
     } elseif ($params['cache.hit'] == 'error') {
         $xcache = 'HIT_ERROR from GuzzleCache';
     } else {
         $xcache = 'MISS from GuzzleCache';
     }
     if ($header = $response->getHeader('X-Cache')) {
         // Don't add duplicates
         $values = $header->toArray();
         $values[] = $xcache;
         $response->setHeader('X-Cache', array_unique($values));
     } else {
         $response->setHeader('X-Cache', $xcache);
     }
     if ($response->isFresh() === false) {
         $response->addHeader('Warning', sprintf('110 GuzzleCache/%s "Response is stale"', Version::VERSION));
         if ($params['cache.hit'] === 'error') {
             $response->addHeader('Warning', sprintf('111 GuzzleCache/%s "Revalidation failed"', Version::VERSION));
         }
     }
 }
 /**
  * Handle a 304 response and ensure that it is still valid
  *
  * @param RequestInterface $request          Request that was sent
  * @param Response         $validateResponse Response received
  * @param Response         $response         Original cached response
  *
  * @return bool Returns true if valid, false if invalid
  */
 protected function handle304Response(RequestInterface $request, Response $validateResponse, Response $response)
 {
     static $replaceHeaders = array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified');
     // Make sure that this response has the same ETag
     if ($validateResponse->getEtag() != $response->getEtag()) {
         return false;
     }
     // Replace cached headers with any of these headers from the
     // origin server that might be more up to date
     $modified = false;
     foreach ($replaceHeaders as $name) {
         if ($validateResponse->hasHeader($name)) {
             $modified = true;
             $response->setHeader($name, $validateResponse->getHeader($name));
         }
     }
     // Store the updated response in cache
     if ($modified && $this->canCache->canCacheResponse($response)) {
         $this->storage->cache($request, $response);
     }
     return true;
 }
 /**
  * Returns a formatted message
  *
  * @param RequestInterface $request    Request that was sent
  * @param Response         $response   Response that was received
  * @param CurlHandle       $handle     Curl handle associated with the message
  * @param array            $customData Associative array of custom template data
  *
  * @return string
  */
 public function format(RequestInterface $request, Response $response = null, CurlHandle $handle = null, array $customData = array())
 {
     $cache = $customData;
     return preg_replace_callback('/{\\s*([A-Za-z_\\-\\.0-9]+)\\s*}/', function (array $matches) use($request, $response, $handle, &$cache) {
         if (array_key_exists($matches[1], $cache)) {
             return $cache[$matches[1]];
         }
         $result = '';
         switch ($matches[1]) {
             case 'request':
                 $result = (string) $request;
                 break;
             case 'response':
                 $result = (string) $response;
                 break;
             case 'req_body':
                 $result = $request instanceof EntityEnclosingRequestInterface ? (string) $request->getBody() : '';
                 break;
             case 'res_body':
                 $result = $response ? $response->getBody(true) : '';
                 break;
             case 'ts':
                 $result = gmdate('c');
                 break;
             case 'method':
                 $result = $request->getMethod();
                 break;
             case 'url':
                 $result = (string) $request->getUrl();
                 break;
             case 'resource':
                 $result = $request->getResource();
                 break;
             case 'protocol':
                 $result = 'HTTP';
                 break;
             case 'version':
                 $result = $request->getProtocolVersion();
                 break;
             case 'host':
                 $result = $request->getHost();
                 break;
             case 'hostname':
                 $result = gethostname();
                 break;
             case 'port':
                 $result = $request->getPort();
                 break;
             case 'code':
                 $result = $response ? $response->getStatusCode() : '';
                 break;
             case 'phrase':
                 $result = $response ? $response->getReasonPhrase() : '';
                 break;
             case 'connect_time':
                 if ($handle) {
                     $result = $handle->getInfo(CURLINFO_CONNECT_TIME);
                 } elseif ($response) {
                     $result = $response->getInfo('connect_time');
                 }
                 break;
             case 'total_time':
                 if ($handle) {
                     $result = $handle->getInfo(CURLINFO_TOTAL_TIME);
                 } elseif ($response) {
                     $result = $response->getInfo('total_time');
                 }
                 break;
             case 'curl_error':
                 $result = $handle ? $handle->getError() : '';
                 break;
             case 'curl_code':
                 $result = $handle ? $handle->getErrorNo() : '';
                 break;
             case 'curl_stderr':
                 $result = $handle ? $handle->getStderr() : '';
                 break;
             default:
                 if (strpos($matches[1], 'req_header_') === 0) {
                     $result = $request->getHeader(substr($matches[1], 11));
                 } elseif (strpos($matches[1], 'res_header_') === 0) {
                     $result = $response->getHeader(substr($matches[1], 11));
                 }
         }
         $cache[$matches[1]] = $result;
         return $result;
     }, $this->template);
 }
Example #24
0
 /**
  * @param $header
  * @param bool $string
  * @return \Guzzle\Http\Message\Header|null|string
  */
 public function getHeader($header, $string = false)
 {
     return $this->response->getHeader($header, $string);
 }
Example #25
0
 /**
  * {@inheritdoc}
  */
 public function getHeader($header)
 {
     return $this->response->getHeader($header);
 }
 /**
  * Check if a cache response satisfies a failed request's caching constraints
  *
  * @param RequestInterface $request  Request to validate
  * @param Response         $response Response to validate
  *
  * @return bool
  */
 public function canResponseSatisfyFailedRequest(RequestInterface $request, Response $response)
 {
     $reqc = $request->getHeader('Cache-Control');
     $resc = $response->getHeader('Cache-Control');
     $requestStaleIfError = $reqc ? $reqc->getDirective('stale-if-error') : null;
     $responseStaleIfError = $resc ? $resc->getDirective('stale-if-error') : null;
     if (!$requestStaleIfError && !$responseStaleIfError) {
         return false;
     }
     if (is_numeric($requestStaleIfError) && $response->getAge() - $response->getMaxAge() > $requestStaleIfError) {
         return false;
     }
     if (is_numeric($responseStaleIfError) && $response->getAge() - $response->getMaxAge() > $responseStaleIfError) {
         return false;
     }
     return true;
 }
Example #27
0
 /**
  * @param Response $response
  * @return mixed
  */
 protected function decompressGzippedResponse($response)
 {
     $raw_data = $response->getBody();
     if ($response->getHeader('content-encoding') === 'gzip') {
         // return gzip.GzipFile(fileobj=StringIO.StringIO(raw_data)).read();
     }
     return $raw_data;
 }
Example #28
0
 /**
  * @dataProvider parseParamsProvider
  */
 public function testParseParams($header, $result)
 {
     $response = new Response(200, array('Link' => $header));
     $this->assertEquals($result, $response->getHeader('Link')->parseParams());
 }
 /**
  * Prepare the request for redirection and enforce the maximum number of allowed redirects per client
  *
  * @param RequestInterface $original  Origina request
  * @param RequestInterface $request   Request to prepare and validate
  * @param Response         $response  The current response
  *
  * @return RequestInterface
  */
 protected function prepareRedirection(RequestInterface $original, RequestInterface $request, Response $response)
 {
     $params = $original->getParams();
     // This is a new redirect, so increment the redirect counter
     $current = $params->get(self::REDIRECT_COUNT) + 1;
     $params->set(self::REDIRECT_COUNT, $current);
     // Use a provided maximum value or default to a max redirect count of 5
     $max = $params->hasKey(self::MAX_REDIRECTS) ? $params->get(self::MAX_REDIRECTS) : $this->defaultMaxRedirects;
     // Throw an exception if the redirect count is exceeded
     if ($current > $max) {
         $this->throwTooManyRedirectsException($original, $max);
         return false;
     } else {
         // Create a redirect request based on the redirect rules set on the request
         return $this->createRedirectRequest($request, $response->getStatusCode(), trim($response->getHeader('Location')), $original);
     }
 }
Example #30
0
 /**
  * Construct a TransferPart from a HTTP response delivered by the API.
  *
  * @param Response $response
  * @param int      $partNumber
  * @return TransferPart
  */
 public static function fromResponse(Response $response, $partNumber = 1)
 {
     $responseUri = Url::factory($response->getEffectiveUrl());
     $object = new self();
     $object->setPartNumber($partNumber)->setContentLength($response->getHeader(Header::CONTENT_LENGTH))->setETag($response->getHeader(Header::ETAG))->setPath($responseUri->getPath());
     return $object;
 }