public static function create(Cache $cacheProvider = null, $clientOptions = []) { $handlerStack = HandlerStack::create(); // add cache if provided if ($cacheProvider) { $cacheHandler = new CacheMiddleware(new PrivateCacheStrategy(new DoctrineCacheStorage($cacheProvider))); $handlerStack->push($cacheHandler); } // add retry for connection errors as well as HTTP 429 $handlerStack->push(Middleware::retry(__CLASS__ . '::retryDecider', __CLASS__ . '::retryDelay')); $options = array_merge(['handler' => $handlerStack, 'timeout' => 10], $clientOptions); $client = new Client($options); return $client; }
/** * testRetries500Errors. */ public function testRetries500Errors() { $mock = new MockHandler([new Response(500), new Response(200)]); $handler = HandlerStack::create($mock); $handler->push(Middleware::retry(Backoff::decider(), Backoff::delay())); $client = new Client(['handler' => $handler]); $this->assertEquals(200, $client->request('GET', '/')->getStatusCode()); }
/** * @access private * * @param bool $delay default to true, can be false to speed up tests * * @return callable */ public function retry($delay = true) { if ($delay) { return Middleware::retry($this->newRetryDecider(), $this->getRetryDelay()); } else { return Middleware::retry($this->newRetryDecider()); } }
public function create() { if ($this->retries == 0) { return new Client(); } $handlerStack = HandlerStack::create(new CurlHandler()); $handlerStack->push(Middleware::retry($this->retryDecider(), $this->retryDelay())); return new Client(['handler' => $handlerStack]); }
/** * Create a new client instance. * * @param \GuzzleHttp\ClientInterface|null $client * * @return void */ public function __construct(ClientInterface $client = null) { if ($client) { $this->client = $client; } else { $stack = HandlerStack::create(); $stack->push(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, TransferException $exception = null) { return $retries < 3 && ($exception instanceof ConnectException || $response && $response->getStatusCode() >= 500); }, function ($retries) { return (int) pow(2, $retries) * 1000; })); $this->client = new GuzzleClient(['base_uri' => static::BASE_URL, 'handler' => $stack, 'headers' => ['Accept' => 'application/json', 'User-Agent' => 'styleci-sdk/1.1']]); } }
/** * @param array $headers * @param array $config * @return Client */ protected function getClient(array $headers, array $config = []) { if (!isset($config['url'])) { throw new \Exception('url is required. e.g. https://syrup.keboola.com/oauth-v2/'); } // Initialize handlers (start with those supplied in constructor) if (isset($config['handler']) && is_a($config['handler'], HandlerStack::class)) { $handlerStack = HandlerStack::create($config['handler']); } else { $handlerStack = HandlerStack::create(); } $handlerStack->push(Middleware::retry(self::createDefaultDecider(self::$backOffMaxRetries), self::createExponentialDelay())); $client = new Client(['base_uri' => $config['url'], 'headers' => array_merge($headers, $this->defaultHeaders), 'handler' => $handlerStack]); return new ClientWrapper($client); }
/** * @param array $config */ public function __construct(array $config = []) { $this->config = array_merge([], $this->config, $config); // Tratar headers $this->headers = array_merge([], $this->headers, Arr::get($this->config, 'headers', [])); // Middleware $stack = HandlerStack::create(); $stack->push(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, TransferException $exception = null) { return $retries < 3 && ($exception instanceof ConnectException || $response && $response->getStatusCode() >= 500); }, function ($retries) { return (int) pow(2, $retries) * 1000; })); // Client $this->client = new GuzzleClient(['base_uri' => $this->getBaseUrl(), 'handler' => $stack, 'headers' => $this->getHeaders()]); }
public function __construct($api_key, $options = array()) { if (!$api_key) { throw new \Exception("Your project API_KEY is required!"); } $this->api_key = (string) $api_key; // overwrite default settings if (isset($options['base_uri'])) { $this->base_uri = (string) $options['base_uri']; } if (isset($options['logger']) && $options['logger'] instanceof LoggerInterface) { $this->logger = $options['logger']; } if (isset($options['verify_ssl'])) { $this->verify_ssl = (bool) $options['verify_ssl']; } if (isset($options['request_timeout'])) { $this->request_timeout = (double) $options['request_timeout']; } if (isset($options['response_timeout'])) { $this->response_timeout = (double) $options['response_timeout']; } if (isset($options['max_attempts'])) { $this->max_attempts = (int) $options['max_attempts']; } if (isset($options['retry_delay'])) { $this->retry_delay = (double) $options['retry_delay']; } if (isset($options['proxy'])) { $this->proxy = (string) $options['proxy']; } $handlerStack = HandlerStack::create(new CurlHandler()); $retryMiddleware = \GuzzleHttp\Middleware::retry($this->retryHandler(), $this->retryDelay()); $handlerStack->push($retryMiddleware); $guzzleOptions = ['base_uri' => $this->base_uri, 'timeout' => $this->response_timeout, 'connect_timeout' => $this->request_timeout, 'headers' => ['User-Agent' => 'php-client v' . static::$VERSION, 'Accept' => 'application/json', 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $this->api_key], 'verify' => $this->verify_ssl, 'synchronous' => true, 'http_errors' => false]; if ($this->proxy !== NULL) { $guzzleOptions['proxy'] = $this->proxy; } $this->guzzleClient = new Client(array_merge($guzzleOptions, array('handler' => $handlerStack))); if ($this->logger !== NULL) { $this->logger->info('Notifuse client instantiated', array('api_key' => $this->api_key, 'base_uri' => $this->base_uri, 'verify_ssl' => $this->verify_ssl, 'request_timeout' => $this->request_timeout, 'response_timeout' => $this->response_timeout, 'max_attempts' => $this->max_attempts, 'retry_delay' => $this->retry_delay, 'proxy' => $this->proxy)); } if ($this->logger !== NULL) { $this->logger->info('Notifuse client Guzzle options', $guzzleOptions); } $this->contacts = new Contacts($this); $this->messages = new Messages($this); }
/** * @return \Aws\Handler\GuzzleV6\GuzzleHandler */ private function getHttpHandler() { $guzzleStack = \GuzzleHttp\HandlerStack::create(); $guzzleStack->push(\GuzzleHttp\Middleware::retry(function ($retries, \GuzzleHttp\Psr7\Request $request, \GuzzleHttp\Psr7\Response $response = null, \GuzzleHttp\Exception\RequestException $exception = null) { if ($retries >= 5) { return false; } if ($exception instanceof \GuzzleHttp\Exception\ConnectException) { return true; } if ($response) { if ($response->getStatusCode() == 400) { return true; } } return false; })); if ($this->output && $this->output->isVeryVerbose()) { $guzzleStack->push(\GuzzleHttp\Middleware::log(new \Monolog\Logger('main'), new \GuzzleHttp\MessageFormatter('[{code}] {req_body}'))); } return new \Aws\Handler\GuzzleV6\GuzzleHandler(new \GuzzleHttp\Client(['handler' => $guzzleStack])); }
/** * Register the login provider class. * * @return void */ protected function registerLoginProvider() { $this->app->singleton('login.provider', function (Container $app) { $request = $app['request']; $clientId = $app->config->get('login.id'); $clientSecret = $app->config->get('login.secret'); $redirectUrl = $app->config->get('login.redirect'); $allowed = $app->config->get('login.allowed', []); $blocked = $app->config->get('login.blocked', []); $stack = HandlerStack::create(); $stack->push(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, TransferException $exception = null) { return $retries < 3 && ($exception instanceof ConnectException || $response && $response->getStatusCode() >= 500); }, function ($retries) { return (int) pow(2, $retries) * 1000; })); $client = new Client(['handler' => $stack, 'connect_timeout' => 10, 'timeout' => 15]); $provider = new LoginProvider($request, $clientId, $clientSecret, $redirectUrl, $allowed, $blocked, $client); $app->refresh('request', $provider, 'setRequest'); return $provider; }); $this->app->alias('login.provider', LoginProvider::class); }
protected function initClient() { $handlerStack = HandlerStack::create(); /** @noinspection PhpUnusedParameterInspection */ $handlerStack->push(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, $error = null) { return $response && $response->getStatusCode() == 503; }, function ($retries) { return rand(60, 600) * 1000; })); /** @noinspection PhpUnusedParameterInspection */ $handlerStack->push(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, $error = null) { if ($retries >= self::RETRIES_COUNT) { return false; } elseif ($response && $response->getStatusCode() > 499) { return true; } elseif ($error) { return true; } else { return false; } }, function ($retries) { return (int) pow(2, $retries - 1) * 1000; })); $handlerStack->push(Middleware::cookies()); if ($this->logger) { $handlerStack->push(Middleware::log($this->logger, $this->loggerFormatter)); } $this->guzzle = new \GuzzleHttp\Client(array_merge(['handler' => $handlerStack, 'cookies' => true], $this->guzzleOptions)); }
/** * Create the client handler. * * @return \GuzzleHttp\HandlerStack */ protected function createHandler() { $stack = HandlerStack::create(); $stack->push(Middleware::mapRequest(function (RequestInterface $request) { $config = $this->config; return $request->withHeader('Stripe-Version', $config->getApiVersion())->withHeader('Idempotency-Key', $config->getIdempotencyKey())->withHeader('User-Agent', 'Cartalyst-Stripe/' . $config->getVersion())->withHeader('Authorization', 'Basic ' . base64_encode($config->getApiKey())); })); $stack->push(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, TransferException $exception = null) { return $retries < 3 && ($exception instanceof ConnectException || $response && $response->getStatusCode() >= 500); }, function ($retries) { return (int) pow(2, $retries) * 1000; })); return $stack; }
private function initClient() { $handlerStack = HandlerStack::create(); $handlerStack->push(Middleware::retry(self::createDefaultDecider($this->backoffMaxTries), self::createExponentialDelay())); $this->client = new \GuzzleHttp\Client(['base_uri' => $this->apiUrl, 'handler' => $handlerStack]); }
/** * Execute an XML request to Intacct * * @param XMLWriter $xml * @return ResponseInterface */ private function execute($xml) { //this is used for retry logic $calls = []; $decider = function ($retries, $request, $response, $error) use(&$calls) { $calls[] = func_get_args(); if (count($calls) > $this->maxRetries) { return false; } if ($error instanceof \GuzzleHttp\Exception\ServerException) { //retry if receiving http 5xx error codes $response = $error->getResponse(); if (in_array($response->getStatusCode(), $this->noRetryServerErrorCodes) === true) { return false; } else { return true; } } //do not retry otherwise return false; }; //setup the handler if ($this->mockHandler instanceof MockHandler) { $handler = HandlerStack::create($this->mockHandler); } else { $handler = HandlerStack::create(); } //add the retry logic before the http_errors middleware $handler->before('http_errors', Middleware::retry($decider), 'retry_logic'); //push the history middleware to the top of the stack $handler->push(Middleware::history($this->history)); if ($this->logger) { //push the logger middleware to the top of the stack $handler->push(Middleware::log($this->logger, $this->logMessageFormat, $this->logLevel)); } $client = new Client(['handler' => $handler]); $options = ['body' => $xml->flush(), 'verify' => $this->getVerifySSL(), 'headers' => ['content-type' => self::REQUEST_CONTENT_TYPE, 'User-Agent' => $this->getUserAgent()]]; $response = $client->post($this->endpointURL, $options); return $response; }
public function getGuzzleClient() { $handlerStack = HandlerStack::create(); $handlerStack->push(Middleware::retry(self::createDefaultDecider(), self::createExponentialDelay())); return new \GuzzleHttp\Client(['handler' => $handlerStack]); }
/** * Creates a HandlerStack based off of the supplied configuration. * * @param string $handlerClass full class name to use for the HTTP handler implementation * @return HandlerStack configured HandlerStack implementation */ protected function buildHandlerStack($handlerClass) { $stack = new HandlerStack(); $stack->setHandler(new $handlerClass()); $stack->push(Middleware::mapRequest(function (RequestInterface $request) { $timestamp = gmdate('r'); $authorization = $this->getAuthorization($timestamp); $requestInterface = $request->withHeader('Date', $timestamp)->withHeader('x-request-id', (string) Uuid::uuid4()); if (!$this->noAuth) { $requestInterface = $requestInterface->withHeader('Authorization', $authorization); } return $requestInterface; })); $decider = function ($retries, Request $request, Response $response = null, RequestException $exception = null) { // Stop retrying if we have exceeded our max if ($retries > $this->retries) { return false; } // Retry connection exceptions if ($exception instanceof ConnectException) { return true; } if ($response) { // Retry on server errors if ($response->getStatusCode() >= 500) { return true; } } return false; }; if ($this->retries > 0) { $stack->push(Middleware::retry($decider)); } return $stack; }
/** * @param $token * @param $runId * @param $userAgent * @param $maxRetries * @param array $config * @param callable|null $delay * @return GuzzleClient */ protected function initClient($token, $runId, $userAgent, $maxRetries, array $config = [], callable $delay = null) { // Initialize handlers (start with those supplied in constructor) if (isset($config['handler']) && $config['handler'] instanceof HandlerStack) { $handlerStack = HandlerStack::create($config['handler']); } else { $handlerStack = HandlerStack::create(); } // Set exponential backoff for cases where job detail returns error $handlerStack->push(Middleware::retry(self::createDefaultDecider($maxRetries), $delay)); // Set handler to set default headers $handlerStack->push(Middleware::mapRequest(function (RequestInterface $request) use($token, $runId, $userAgent) { $req = $request->withHeader('User-Agent', $userAgent); if ($token) { $req = $req->withHeader('X-StorageApi-Token', $token); } if (!$req->hasHeader('content-type')) { $req = $req->withHeader('Content-type', 'application/json'); } if ($runId) { $req = $req->withHeader('X-KBC-RunId', $runId); } return $req; })); // Set client logger if (isset($config['logger']) && $config['logger'] instanceof LoggerInterface) { $handlerStack->push(Middleware::log($config['logger'], new MessageFormatter("{hostname} {req_header_User-Agent} - [{ts}] \"{method} {resource} {protocol}/{version}\" " . "{code} {res_header_Content-Length}"))); } // finally create the instance return new GuzzleClient(['base_url' => $this->url, 'handler' => $handlerStack]); }
/** * Return retry middleware. * * @return \GuzzleHttp\RetryMiddleware */ protected function retryMiddleware() { return Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, RequestException $exception = null) { // Limit the number of retries to 2 if ($retries <= 2 && $response && ($body = $response->getBody())) { // Retry on server errors if (stripos($body, 'errcode') && (stripos($body, '40001') || stripos($body, '42001'))) { $field = $this->accessToken->getQueryName(); $token = $this->accessToken->getToken(); $request = $request->withUri($newUri = Uri::withQueryValue($request->getUri(), $field, $token)); Log::debug("Retry with Request Token: {$token}"); Log::debug("Retry with Request Uri: {$newUri}"); return true; } } return false; }); }
/** * Set request access_token query. */ protected function attachAccessToken() { if (!$this->accessToken) { return; } // log $this->getHttp()->addMiddleware(function (callable $handler) { return function (RequestInterface $request, array $options) use($handler) { $field = $this->accessToken->getQueryName(); $token = $this->accessToken->getToken(); $request = $request->withUri(Uri::withQueryValue($request->getUri(), $field, $token)); Log::debug("Request Token: {$token}"); Log::debug('Request Uri: ' . $request->getUri()); return $handler($request, $options); }; }); // retry $this->getHttp()->addMiddleware(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, RequestException $exception = null) { // Limit the number of retries to 2 if ($retries <= 2 && $response && ($body = $response->getBody())) { // Retry on server errors if (stripos($body, 'errcode') && (stripos($body, '40001') || stripos($body, '42001'))) { return true; } } return false; })); }
/** * @codeCoverageIgnore */ public static function retry(callable $decider, callable $delay = null) : callable { return GuzzleMiddleware::retry($decider, $delay); }
public function testCanRetryExceptions() { $calls = []; $decider = function ($retries, $request, $response, $error) use(&$calls) { $calls[] = func_get_args(); return $error instanceof \Exception; }; $m = Middleware::retry($decider); $h = new MockHandler([new \Exception(), new Response(201)]); $c = new Client(['handler' => $m($h)]); $p = $c->sendAsync(new Request('GET', 'http://test.com'), []); $this->assertEquals(201, $p->wait()->getStatusCode()); $this->assertCount(2, $calls); $this->assertEquals(0, $calls[0][0]); $this->assertNull($calls[0][2]); $this->assertInstanceOf('Exception', $calls[0][3]); $this->assertEquals(1, $calls[1][0]); $this->assertInstanceOf(Response::class, $calls[1][2]); $this->assertNull($calls[1][3]); }
public function __construct($username, $password, $url = '') { $this->username = $username; $this->password = $password; if ($url && substr($url, -1) != '/') { $url .= '/'; } $this->url = $url ?: self::URL; $handlerStack = HandlerStack::create(); // Retry from maintenance, makes 5-10 hours of waiting /** @noinspection PhpUnusedParameterInspection */ $handlerStack->push(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, $error = null) { return $retries < self::MAINTENANCE_RETRIES_COUNT && $response && ($response->getStatusCode() == 503 || $response->getStatusCode() == 423); }, function ($retries) { return rand(60, 600) * 1000; })); // Retry for server errors /** @noinspection PhpUnusedParameterInspection */ $handlerStack->push(Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null, $error = null) { if ($retries >= self::RETRIES_COUNT) { return false; } elseif ($response && $response->getStatusCode() > 499) { return true; } elseif ($error) { return true; } else { return false; } }, function ($retries) { return (int) pow(2, $retries - 1) * 1000; })); $handlerStack->push(Middleware::cookies()); /*if ($this->logger) { $handlerStack->push(Middleware::log($this->logger, $this->loggerFormatter)); }*/ $this->client = new \GuzzleHttp\Client(['base_uri' => $this->url, 'handler' => $handlerStack, 'auth' => [$username, $password]]); }