Return the Guzzle Middleware responsible for ensuring the API key is
always present in a request.

@return callable
439206
protected function getApiKeyMiddleware()
    {
        $handleRequest = function (RequestInterface $request) {
            return $request->withUri(Uri::withQueryValue(
                $request->getUri(),
                static::PARAM_API_KEY,
                $this->apiKey
            ));
        };

        return Middleware::mapRequest($handleRequest);
    }
243905
public function getClient(): ClientInterface
    {
        if (! isset($this->client)) {
            $this->client = new GuzzleClient();
        }

        return $this->client;
    }
1199663
private static function guzzle(string $name = null, bool $strict = false) : Client
    {
        list($container, $config, $return) = DI::detect(__METHOD__, 'guzzle', $name, $strict);

        if ($return) {
            return $return;
        }

        $stack = HandlerStack::create();
        $stack->setHandler(new CurlHandler());
        $config['handler'] = $stack;

        if (isset($config['middlewares'])) {
            foreach ($config['middlewares'] as $class => $options) {
                $stack->push(new $class($options ?? []));
            }

            unset($config['middlewares']);
        }

        return DI::set(__METHOD__, $container, new Client($config));
    }
551929
final public function invoker()
    {
        $beforeCallEvent = $this->dispatchEvent(
            self::EVENT_BEFORE_CALL_METHOD,
            $this,
            ['request' => $this->getRequest()]
        );

        if ($beforeCallEvent->getResult() instanceof Response) {
            return $beforeCallEvent->getResult();
        }

        $response = call_user_func_array($this, func_get_args());

        $this->dispatchEvent(
            self::EVENT_AFTER_CALL_METHOD,
            $this,
            ['request' => $this->getRequest(), 'response' => $response]
        );

        return $response;
    }
1298248
public function getGuzzleClient()
    {
        $guzzle = $this->guzzleClient;

        if ($this->retry) {
            $guzzle = $this->addRetrySubscriber($guzzle);
        }

        return $guzzle;
    }
1350894
protected function returnHandlers()
    {
        // Create a handler stack that has all of the default middlewares attached
        $handler = HandlerStack::create();

        //Add the Authorization header to requests.
        $handler->push(Middleware::mapRequest(function (RequestInterface $request) {
            if ($this->getConfig('auth') == 'oauth2') {
                $token = $this->getAccessToken();

                if ($token !== null) {
                    $request = $request->withHeader('Authorization', 'Bearer '.$token->getToken());

                    return $request;
                }
            }

            return $request;
        }), 'add_oauth_header');

        $handler->before('add_oauth_header', $this->retry_modify_request(function ($retries, RequestInterface $request, ResponseInterface $response = null, $error = null) {
            if ($retries > 0) {
                return false;
            }
            if ($response instanceof ResponseInterface) {
                if (in_array($response->getStatusCode(), [400, 401])) {
                    return true;
                }
            }

            return false;
        },
            function (RequestInterface $request, ResponseInterface $response) {
                if ($response instanceof ResponseInterface) {
                    if (in_array($response->getStatusCode(), [400, 401])) {
                        $token = $this->acquireAccessToken();
                        $this->setAccessToken($token, 'Bearer');

                        $modify['set_headers']['Authorization'] = 'Bearer '.$token->getToken();

                        return Psr7\modify_request($request, $modify);
                    }
                }

                return $request;
            }
        ));

        return $handler;
    }
1286323
public function getHttpClient()
    {
        if (!isset($this->_httpClient)) {
            $this->_httpClient = Yii::createObject($this->guzzleClass, [$this->guzzleConfig]);
        }
        return $this->_httpClient;
    }
1066029
public static function mpxErrors(): \Closure
    {
        // Guzzle's built-in middlewares also have this level of nested
        // functions, so we follow the same pattern even though it's difficult
        // to read.
        return function (callable $handler) {
            return function (RequestInterface $request, array $options) use ($handler) {
                // We only need to process after the request has been sent.
                return $handler($request, $options)->then(
                    function (ResponseInterface $response) use ($request, $handler) {
                        // While it's not documented, we want to be sure that
                        // any 4XX or 5XX errors that break through suppression
                        // are still parsed. In other words, this handler should
                        // be executed before the normal Guzzle error handler.

                        // If our response isn't JSON, we can't parse it.
                        $contentType = $response->getHeaderLine('Content-Type');
                        if (0 === preg_match('!^(application|text)\/json!', $contentType)) {
                            return $response;
                        }

                        $data = \GuzzleHttp\json_decode($response->getBody(), true);

                        // Notification responses have a different exception format.
                        if (isset($data[0]) && isset($data[0]['type']) && 'Exception' == $data[0]['type']) {
                            throw MpxExceptionFactory::createFromNotificationException($request, $response);
                        }

                        if (empty($data['responseCode']) && empty($data['isException'])) {
                            return $response;
                        }

                        throw MpxExceptionFactory::create($request, $response);
                    }
                );
            };
        };
    }
451304
private function decorate($middleware): MiddlewareInterface
    {
        if ($middleware instanceof MiddlewareInterface) {
            return $middleware;
        } elseif ($middleware instanceof RequestHandlerInterface) {
            return new RequestHandlerMiddleware($middleware);
        } elseif ($middleware instanceof ResponseInterface) {
            return new FixedResponseMiddleware($middleware);
        } elseif (is_callable($middleware)) {
            return new CallableMiddleware($middleware);
        } elseif (is_string($middleware)) {
            return new LazyLoadingMiddleware($middleware, $this->container);
        } else {
            throw new InvalidArgumentException(sprintf(
                'Middleware "%s" is neither a string service name, an autoloadable class name, a PHP callable, or an instance of %s/%s/%s',
                is_object($middleware) ? get_class($middleware) : gettype($middleware),
                MiddlewareInterface::class, ResponseInterface::class, RequestHandlerInterface::class
            ));
        }
    }
1162220
public function getApi()
    {
        if (!isset($this->_api)) {
            $this->_api = ComConnectHelperApi::getApi($this->get('api'));
            $this->_api->setToken($this->tokenKey, $this->tokenSecret);
        }

        return $this->_api;
    }
553282
protected function initHttpClient()
    {

        // Middleware
        $obj_stack = HandlerStack::create();
        $obj_stack->push(ApplicationDefaultCredentials::getMiddleware(['https://www.googleapis.com/auth/datastore']));

        $str_base_url = self::DEFAULT_BASE_URL;

        if (getenv("DATASTORE_EMULATOR_HOST") !== FALSE) {
            $str_base_url = getenv("DATASTORE_EMULATOR_HOST");
        }

        // Create the HTTP client
        return new Client([
            'handler' => $obj_stack,
            'base_url' => $str_base_url,
            'auth' => 'google_auth'  // authorize all requests
        ]);
    }
883164
protected function sendRequest()
    {
        $parameters = $this->parameters->toArray();
        $parameters['key'] = $this->config['api_key'];

        $response = $this->guzzle->get($this->getRequestUrl(), [
            'query' => $parameters,
        ]);

        return json_decode((string)$response->getBody());
    }
840275
protected function getBucketManager()
    {
        if (!$this->bucketManager) {
            $this->bucketManager = new BucketManager($this->auth);
        }
        return $this->bucketManager;
    }
474491
protected function push(callable $newTopMiddleware)
    {
        $oldStack = $this->middlewareStack;

        if ($oldStack === null) {
            $this->middlewareStack = $newTopMiddleware;

            return $this;
        }

        $this->middlewareStack = function ($request, $response, callable $next) use ($oldStack, $newTopMiddleware) {
            return $newTopMiddleware($request, $response, function ($req, $res) use ($next, $oldStack) {
                return $oldStack($req, $res, $next);
            });
        };

        return $this;
    }
950264
public function getAuctionApi()
    {
        if (!$this->apis->has('auction')) {
            $this->apis->set('auction', new Auction($this));
        }

        return $this->apis->get('auction');
    }
804652
protected function retryMiddleware()
    {
        return Middleware::retry(function (
            $retries,
            RequestInterface $request,
            ResponseInterface $response = null
        ) {
            // Limit the number of retries to 2
            if ($retries < $this->app->config->get('http.max_retries', 1) && $response && $body = $response->getBody()) {
                // Retry on server errors
                $response = json_decode($body, true);

                if (!empty($response['errcode']) && in_array(abs($response['errcode']), [40001, 40014, 42001], true)) {
                    $this->accessToken->refresh();
                    $this->app['logger']->debug('Retrying with refreshed access token.');

                    return true;
                }
            }

            return false;
        }, function () {
            return abs($this->app->config->get('http.retry_delay', 500));
        });
    }
753179
public static function request()
    {
        $container = Container::instance();
        if (!$container->has('request')) {
            $request = new Request(Kernel::options('strict'));
            $container->register('request', $request->fromServer());
        }
        return $container->get('request');
    }