Sends a HTTP request.

@param string $method
@param Client $httpClient
@param array  $path additional components for the path; e.g.: [$id, 'prices']

@return DorcasResponse
@throws \GuzzleHttp\Exception\GuzzleException
13165
public function send(string $method, Client $httpClient, array $path = []): DorcasResponse
    {
        $this->prefillHeader();
        $this->prefillBody();
        if (strtolower($method) !== 'get') {
            # we don't validate GEt requests
            $this->validate();
        }
        $uri = static::getRequestUrl($path);
        $url = $uri->getScheme() . '://' . $uri->getAuthority() . $uri->getPath();
        # set the URL
        try {
            $options = [];
            # the request data
            if (!empty($this->headers)) {
                $options[RequestOptions::HEADERS] = $this->headers;
            }
            if (!empty($uri->getQuery())) {
                # some query parameters are present in the URL
                $options[RequestOptions::QUERY] = parse_query_parameters($uri->getQuery());
            }
            if (strtolower($method) !== 'get') {
                # not a get request
                if (!empty($this->multipart)) {
                    # check if we have some multipart data first
                    foreach ($this->body as $key => $value) {
                        # add the requested body params to the multipart data
                        $this->multipart[] = ['name' => $key, 'contents' => $value];
                    }
                    $options[RequestOptions::MULTIPART] = $this->multipart;

                } elseif (static::isJsonRequest() && !empty($this->body)) {
                    # a JSON request
                    $options[RequestOptions::JSON] = $this->body;

                } elseif (!empty($this->body)) {
                    # we switch to an application/www-form-urlencoded type
                    $options[RequestOptions::FORM_PARAMS] = $this->body;
                }
            }
            $response = $httpClient->request($method, $url, $options);
            return new DorcasResponse((string) $response->getBody());

        } catch (BadResponseException $e) {
            // in the case of a failure, let's know the status
            return new DorcasResponse((string) $e->getResponse()->getBody(), $e->getResponse()->getStatusCode(), $e->getRequest());

        } catch (ConnectException $e) {
            return new DorcasResponse('{"status": "error", "data": "'.$e->getMessage().'"}', 0);
        }
    }
204203
public function requestPath($path, $method = null) {
        $this->setRequestPath($path);

        if (null === $method) {
            $this->setRequestMethod('GET', false);
        } else {
            $this->setRequestMethod($method);
        }

        return $this->sendRequest();
    }
1211178
private function doRequest($method, $url, array $headers = [], array $data = [])
    {
        $request = new Request($method, $url, $headers, \GuzzleHttp\json_encode($data));
        $response = $this->httpClient->sendRequest($request);

        return new Response(
            $response->getStatusCode(),
            $response->getBody()->getContents(),
            /** @scrutinizer ignore-type */
            $response->getHeaders()
        );
    }
787674
private function __sendCurl($urlPath, $method, $param)
    {
        $url = trim($this->apiBaseUrl, '/') . '/' . trim($urlPath, '/');

        if ($method == 'GET') {
            $query = http_build_query($param);
            $url = $url . '?' . $query;
        }

        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_POSTFIELDS => $method == 'POST' ? json_encode($param) : '',
            CURLOPT_HTTPHEADER => array(
                "Cache-Control: no-cache",
                "Content-Type: application/json",
            ),
        ));

        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $error = curl_error($curl);
        curl_close($curl);

        return (object)array(
            'code' => $httpCode,
            'response' => $error ? $error : json_decode($response),
        );

    }
194256
private function call($method, array $arguments)
    {
        try {

            /**
             * Due to GuzzleHttp not passing a default host header given to the client to _every_ request made by the
             * client we manually check to see if we need to add a hostheader to requests.
             * When the issue is resolved the foreach can be removed (as the function might even?)
             *
             * @see https://github.com/guzzle/guzzle/issues/1297
             */
            if (isset($this->extraHeaders['host'])) {
                $arguments[1]['headers']['Host'] = $this->extraHeaders['host'];
            }

            if ($this->logger) {
                $this->logger->startQuery($method . ' ' . reset($arguments), $arguments);
            }

            $response = call_user_func_array([$this->getClient(), $method], $arguments);

            if ($this->logger) {
                $this->logger->stopQuery();
            }

            return $response;

            // try to catch the Guzzle client exception (404's, validation errors etc) and wrap them into a CB exception
        } catch (ClientException $e) {

            $response = $e->getResponse();
            $response = json_decode($response === null ? '' : $response->getBody(), true);

            throw new Exception(
                $response['message'],
                $response['code'],
                $e,
                (($_ =& $response['errors']) ?: [])
            );

        } catch (ConnectException $e) {

            throw new Exception('Can not connect', 500, $e, []);

        }
    }
65056
protected function createRequest($client, $method, $uri = '', array $parameters = [])
    {
        /**
         * @see \JonnyW\PhantomJs\Http\Request
         **/
        $request = $client->getMessageFactory()->createRequest($uri, $method);
        $request->addHeader(
            'User-Agent',
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0'
        );

        $request->addHeader(
            'Content-Type',
            'application/x-www-form-urlencoded'
        );

        if (isset($parameters['form_params'])) {
            $request->setRequestData($parameters['form_params']);
        }

        return $request;
    }
310009
public function makeRequest($url, $method = 'GET', $data = [], $headers = [])
    {
        //we cant send to the API the array with get GET, JSON, form_params parameters
        //the API doesnt get it taht way, guzzle sends it directly
        //so we extract it
        $rawData = count(array_keys($data)) > 0 ?  $data[array_keys($data)[0]] : [];


        $client = (new ClientSecurity($this->apiPublicKey, $this->apiPrivateKey, $rawData, $headers))->getGuzzle();

        $parse = function ($error) {
            if ($error->hasResponse()) {
                return $error->getResponse();
            }

            return json_decode($error->getMessage());
        };

        try {
            return $client->request($method, $url, $data);
        } catch (\GuzzleHttp\Exception\BadResponseException $error) {
            return $parse($error);
        } catch (\GuzzleHttp\Exception\ClientException $error) {
            return $parse($error);
        } catch (\GuzzleHttp\Exception\ConnectException $error) {
            return $parse($error);
        } catch (\GuzzleHttp\Exception\RequestException $error) {
            return $parse($error);
        }
    }
1128559
public function send(string $method, string $url, array $options)
    {
        try {
            // Guzzle overwrites all query string values in the URI if queries are specified
            // in the 'query' option, so they need to be extracted first.
            $optionsPayload = $this->mergeOptions(
                ['query' => $this->parseQueryParams($url)],
                $options
            );

            $response = $this->buildClient()->request($method, $url, $optionsPayload);

            return $this->buildResponse($response);
        } catch (GuzzleException $exception) {
            // No "custom" exceptions, just rethrow whatever guzzle spits out.
            throw $exception;
        }
    }
787389
protected function request($path, $method, array $data = array()) {
		$request = new Request();
		$response = new Response();
		$transport = $this->getTransport();

		$request->setMethod($method);
		$request->setResource($this->buildPath($path));
		$request->setHost(self::URI);
		$request->addHeader('Authorization: Basic ' . base64_encode($this->getAuthCredentials()));
		$request->addHeader('User-Agent: ' . $this->getUserAgent());

		if (count($data)) {
			$request->addHeader('Content-Type: application/json');
			$request->setContent(json_encode($data));
		}

		$transport->send($request, $response);

		return json_decode($response->getContent());
	}
410522
private function requestAPI($method, $url, array $options = [])
    {
        try {
            return $this->sendRequest((string)$method, (string)$url, $options);
        } catch (SessionWasExpiredException $e) {
            return $this->sendRequest((string)$method, (string)$url, $options);
        } catch (ClientException $e) {
            throw new BunqException($e);
        }
    }
340710
private function request($method, $path = '', array $options = [])
    {
        $options['headers'] = array_merge(
            [
                'User-Agent' => $this->app_client,
            ],
            isset($options['headers']) ? $options['headers'] : []
        );

        try {
            $response = $this->client->request($method, $this->host.$this->prefix.$path, $options);
        } catch (\Exception $e) {
            throw $this->wrapException($e);
        }

        $content = $response->getBody()->getContents();
        $content = $this->detector->detect($content);

        return $content;
    }
440140
public function sendRequest($method ,$uri = null)
    {

        $this->reset();

        try {
            //log request
            $this->setLog(LogLevel::INFO, 'Try to send Request: Method: '.$method.' uri: '.$uri, $this->requestHelper->options);

            //send request
            $this->response->psr7response = $this->httpclient->request($method, $uri, $this->requestHelper->options );

            //log headers
            $this->setLog(LogLevel::INFO, 'Request send with Headers: '.$this->getHeadersString($this->response->psr7response), $this->requestHelper->options);

            // To retrive body, do not use ->getContents()
            // it turns out that this gets the “remaining contents of the body as a string”
            // and since the middleware already accessed the body (for example in order to log it),
            // there isn’t any content remaining to retrieve.
            // The correct way to access the response content is to cast the body to a string.
            // See: https://michaelstivala.com/logging-guzzle-requests/
            $this->response->body = (string) $this->response->psr7response->getBody();

            //log status code
            $this->response->status_code =  $this->response->psr7response->getStatusCode();

            //log response
            $this->setLog(LogLevel::INFO,'Response ',['status code'=>$this->response->status_code,'body'=>$this->response->body]);

        } catch (\GuzzleHttp\Exception\ClientException $e) {

            $responseStatusCode = $this->getResponseStatusCodeFromException($e);
            $this->setLog(LogLevel::ERROR,'\GuzzleHttp\Exception\ClientException',['message'=>$e->getMessage(),'path request'=>$e->getRequest()->getUri()->getPath(),'method'=>$e->getRequest()->getMethod(),'response status code'=>$responseStatusCode]);
                                            $this->setLog(LogLevel::DEBUG,'\GuzzleHttp\Exception\ClientException',['trace'=>$e->getTraceAsString()]);
            throw new \GuzzleHttp\Exception\ClientException($e->getMessage().' '.$responseStatusCode,$e->getRequest(),$e->getResponse(),$e,$e->getHandlerContext());

        } catch (\GuzzleHttp\Exception\ServerException $e) {

            $responseStatusCode = $this->getResponseStatusCodeFromException($e);
            $this->setLog(LogLevel::ERROR,'\GuzzleHttp\Exception\ServerException',['message'=>$e->getMessage(),'path request'=>$e->getRequest()->getUri()->getPath(),'method'=>$e->getRequest()->getMethod(),'response status code'=>$responseStatusCode]);
            $this->setLog(LogLevel::DEBUG,'\GuzzleHttp\Exception\ServerException',['trace'=>$e->getTraceAsString()]);
            throw new \GuzzleHttp\Exception\ServerException($e->getMessage().' '.$responseStatusCode,$e->getRequest(),$e->getResponse(),$e,$e->getHandlerContext());


        } catch (\GuzzleHttp\Exception\BadResponseException $e) {

            $responseStatusCode = $this->getResponseStatusCodeFromException($e);
            $this->setLog(LogLevel::ERROR,'\GuzzleHttp\Exception\BadResponseException',['message'=>$e->getMessage(),'path request'=>$e->getRequest()->getUri()->getPath(),'method'=>$e->getRequest()->getMethod(),'response status code'=>$responseStatusCode]);
            $this->setLog(LogLevel::DEBUG,'\GuzzleHttp\Exception\BadResponseException',['trace'=>$e->getTraceAsString()]);
            throw new \GuzzleHttp\Exception\BadResponseException($e->getMessage().' '.$responseStatusCode,$e->getRequest(),$e->getResponse(),$e,$e->getHandlerContext());

        } catch (\GuzzleHttp\Exception\ConnectException $e) {

            $responseStatusCode = $this->getResponseStatusCodeFromException($e);
            $this->setLog(LogLevel::ERROR,'\GuzzleHttp\Exception\ConnectException',['message'=>$e->getMessage(),'path request'=>$e->getRequest()->getUri()->getPath(),'method'=>$e->getRequest()->getMethod(),'response status code'=>$responseStatusCode]);
            $this->setLog(LogLevel::DEBUG,'\GuzzleHttp\Exception\ConnectException',['trace'=>$e->getTraceAsString()]);
            throw new \GuzzleHttp\Exception\ConnectException($e->getMessage().' '.$responseStatusCode,$e->getRequest(),$e,$e->getHandlerContext());

        } catch (\GuzzleHttp\Exception\TooManyRedirectsException $e) {

            $responseStatusCode = $this->getResponseStatusCodeFromException($e);
            $this->setLog(LogLevel::ERROR,'\GuzzleHttp\Exception\TooManyRedirectsException',['message'=>$e->getMessage(),'path request'=>$e->getRequest()->getUri()->getPath(),'method'=>$e->getRequest()->getMethod(),'response status code'=>$responseStatusCode]);
            $this->setLog(LogLevel::DEBUG,'\GuzzleHttp\Exception\TooManyRedirectsException',['trace'=>$e->getTraceAsString()]);
            throw new \GuzzleHttp\Exception\TooManyRedirectsException($e->getMessage().' '.$responseStatusCode,$e->getRequest(),$e->getResponse(),$e,$e->getHandlerContext());

        } catch (\GuzzleHttp\Exception\RequestException $e) {

            $responseStatusCode = $this->getResponseStatusCodeFromException($e);
            $this->setLog(LogLevel::ERROR,'\GuzzleHttp\Exception\RequestException',['message'=>$e->getMessage(),'path request'=>$e->getRequest()->getUri()->getPath(),'method'=>$e->getRequest()->getMethod(),'response status code'=>$responseStatusCode]);
            $this->setLog(LogLevel::DEBUG,'\GuzzleHttp\Exception\RequestException',['trace'=>$e->getTraceAsString()]);
            throw new \GuzzleHttp\Exception\RequestException($e->getMessage().' '.$responseStatusCode,$e->getRequest(),$e->getResponse(),$e,$e->getHandlerContext());

        } catch (\GuzzleHttp\Exception\TransferException $e) {

            $this->setLog(LogLevel::ERROR,'\GuzzleHttp\Exception\TransferException',['message'=>$e->getMessage(),'code'=>$e->getCode()]);
            $this->setLog(LogLevel::DEBUG,'\GuzzleHttp\Exception\TransferException',['trace'=>$e->getTraceAsString()]);
            throw new \GuzzleHttp\Exception\TransferException($e->getMessage(),$e->getCode(),$e);

        } catch (\RuntimeException $e) {

            $this->setLog(LogLevel::ERROR,'\RuntimeException',['message'=>$e->getMessage(),'code'=>$e->getCode()]);
            $this->setLog(LogLevel::DEBUG,'\RuntimeException',['trace'=>$e->getTraceAsString()]);
            throw new \RuntimeException($e->getMessage(),$e->getCode(),$e);

        }

        return $this->response;
    }
1319947
private function request(string $method, string $path, array $query = [], array $body = []): ResponseInterface
    {
        $request = [
            'base_uri'    => $this->baseUri,
            'auth'        => [$this->username, $this->password, 'digest'],
            'http_errors' => false,
        ];

        if (count($query) > 0) {
            $request['query'] = $query;
        }

        if (count($body) > 0) {
            $request['json'] = $body;
        }

        $response = null;

        // Threefold request attempt to bypass possible non-reproducible errors.
        for ($i = 0; $i < 3; $i++) {

            $response = $this->guzzleClient->request(
                $method,
                $path,
                $request
            );

            if ($response->getStatusCode() < 400) {
                return $response;
            }
        }

        throw new \InvalidArgumentException((string)$response->getBody());
    }
885015
public function prepareRequest($path, $method = 'GET', $data = '')
    {
        $this->responseCode = null;
        $curl = curl_init();

        // General cURL options
        $this->setCurlOption(CURLOPT_VERBOSE, 0);
        $this->setCurlOption(CURLOPT_HEADER, 0);
        $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);

        // HTTP Basic Authentication
        if ($this->apikeyOrUsername && $this->useHttpAuth) {
            if (null === $this->pass) {
                $this->setCurlOption(CURLOPT_USERPWD, $this->apikeyOrUsername.':'.rand(100000, 199999));
            } else {
                $this->setCurlOption(CURLOPT_USERPWD, $this->apikeyOrUsername.':'.$this->pass);
            }
            $this->setCurlOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        }

        // Host and request options
        $this->setCurlOption(CURLOPT_URL, $this->url.$path);
        $this->setCurlOption(CURLOPT_PORT, $this->getPort());
        if (80 !== $this->getPort()) {
            $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, (int) $this->checkSslCertificate);
            $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, (int) $this->checkSslHost);
            $this->setCurlOption(CURLOPT_SSLVERSION, $this->sslVersion);
        }

        // Set the HTTP request headers
        $httpHeader = $this->setHttpHeader($path);
        $this->setCurlOption(CURLOPT_HTTPHEADER, $httpHeader);

        $this->unsetCurlOption(CURLOPT_CUSTOMREQUEST);
        $this->unsetCurlOption(CURLOPT_POST);
        $this->unsetCurlOption(CURLOPT_POSTFIELDS);
        switch ($method) {
            case 'POST':
                $this->setCurlOption(CURLOPT_POST, 1);
                if ($this->isUploadCall($path, $data)) {
                    $this->prepareUploadRequest($data);
                } elseif (isset($data)) {
                    $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
                }
                break;
            case 'PUT':
                $this->setCurlOption(CURLOPT_CUSTOMREQUEST, 'PUT');
                if (isset($data)) {
                    $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
                }
                break;
            case 'DELETE':
                $this->setCurlOption(CURLOPT_CUSTOMREQUEST, 'DELETE');
                break;
            default: // GET
                break;
        }
        // Set all cURL options to the current cURL resource
        curl_setopt_array($curl, $this->getCurlOptions());

        return $curl;
    }
846920
private function http($method, $host, $path, array $parameters)
    {
        $this->resetLastResponse();
        $url = sprintf('%s/%s/%s.json', $host, self::API_VERSION, $path);
        $this->response->setApiPath($path);
        $result = $this->oAuthRequest($url, $method, $parameters);
        $response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
        $this->response->setBody($response);
        return $response;
    }
765779
public function send($method, $url, $payload = null)
    {
        $socket = @fsockopen($this->host, $this->port, $errno, $errstr);

        if (!$socket) {
            throw new RuntimeException($errno.': '.$errstr);
        }

        $request = sprintf(
          "%s %s HTTP/1.1\r\nHost: %s:%d\r\nContent-Type: application/json\r\nConnection: close\r\n",
          $method,
          $url,
          $this->host,
          $this->port
        );

        if ($payload !== null) {
            $request .= 'Content-Length: '.strlen($payload)."\r\n\r\n".
                        $payload;
        }

        $request .= "\r\n";

        // @codeCoverageIgnoreStart
        if ($this->debug) {
            echo $request;
        }
        // @codeCoverageIgnoreEnd

        fwrite($socket, $request);

        $buffer = '';

        while (!feof($socket)) {
            $buffer .= fgets($socket);
        }

        list($headers, $body) = explode("\r\n\r\n", $buffer);

        return ['headers' => $headers, 'body' => $body];
    }
968972
private function sendRequest(string $method, string $uri, array $query = [], array $body = []) : array {
        $uri = sprintf('%s%s', $this->baseUrl, ltrim($uri, '/'));

        $options = [
            'headers' => [
                'Authorization' => (string) $this->authentication
            ],
            'http_errors' => false
        ];

        if (! empty($query)) {
            $options['query'] = $query;
        }

        if (! empty($body)) {
            $options['json'] = $body;
        }

        $response = $this->client->request(
            $method,
            $uri,
            $options
        );

        $json = json_decode((string) $response->getBody(), true);
        if ($json === null) {
            if ($this->throwsExceptions) {
                throw new SDKError();
            }

            return [(string) $response->getBody()];
        }

        if (($json['status'] === false) && ($this->throwsExceptions)) {
            throw new SDKException(
                $json['error']['message'],
                $json['error']['type'],
                $json['error']['link']
            );
        }

        return $json;
    }