Do the actual HTTP request.

@param string $method HTTP request method
@param string $path Request path without query string
@param array $params Parameters including profile_key, timestamp and signature
@return array

@codeCoverageIgnore
516685
protected function doRequest($method, $path, array $params)
	{
		$ch = curl_init();

		curl_setopt($ch, CURLOPT_HEADER, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_TIMEOUT, 20);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, self::STRICT_SSL);
		curl_setopt($ch, CURLOPT_ENCODING, ''); // Signal that we support gzip

		$api_endpoint = trim($this->api_base_url, '/').'/'.trim($path, '/');

		if ($method == self::METHOD_GET) {
			curl_setopt($ch, CURLOPT_URL, $api_endpoint.'?'.http_build_query($params, '', '&'));
		} else {
			curl_setopt($ch, CURLOPT_URL, $api_endpoint);
			curl_setopt($ch, CURLOPT_POST, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
		}

		$body = curl_exec($ch);

        /* 77 = CURLE_SSL_CACERT_BADFILE (constant not defined in PHP though). */
		if (curl_errno($ch) == CURLE_SSL_CACERT || curl_errno($ch) == CURLE_SSL_PEER_CERTIFICATE || curl_errno($ch) == 77) {
			/*
			 * On some servers, the list of installed certificates is outdated or not present at all (the ca-bundle.crt
			 * is not installed). So we tell cURL which certificates we trust. Then we retry the requests.
			 */
			curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . DIRECTORY_SEPARATOR . "cacert.pem");
			$body = curl_exec($ch);
		}

		if (strpos(curl_error($ch), "certificate subject name 'mollie.nl' does not match target host") !== false) {
			/*
			 * On some servers, the wildcard SSL certificate is not processed correctly. This happens with OpenSSL 0.9.7
			 * from 2003.
			 */
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
			$body = curl_exec($ch);
		}

		$results = [
			'body'         => $body,
			'http_code'    => curl_getinfo($ch, CURLINFO_HTTP_CODE),
			'content_type' => curl_getinfo($ch, CURLINFO_CONTENT_TYPE),
			'code'         => curl_errno($ch), 
			'message'      => curl_error($ch),
		];

		curl_close($ch);

		return $results;
	}
120694
public function route($method, $path, $callback)
    {
        Argument::i()
            //argument 1 should be a string
            ->test(1, 'string')
            //argument 2 should be a string
            ->test(2, 'string')
            //argument 3 should be callable
            ->test(3, 'callable');
        
        $method = strtoupper($method);
        
        if ($method === 'ALL') {
            return $this
                ->route('get', $path, $callback)
                ->route('post', $path, $callback)
                ->route('put', $path, $callback)
                ->route('delete', $path, $callback);
        }
        
        $this->routeMiddleware[$method][] = array($path, $callback);
        
        return $this;
    }
475623
public function request($method, $url, $params = array())
    {
        if (mb_substr($url, 0, 1, 'UTF-8') === '/') {
            $url = $this->api_endpoint . $url;
        }

        $remote_addr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
        $session_id  = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0x0fff) | 0x4000,
            mt_rand(0, 0x3fff) | 0x8000,
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
        $user_agent  = sprintf("%s/%s PHP/%s %s",
            self::USER_AGENT,
            self::VERSION,
            phpversion(),
            $this->platform
        );

        $headers = [
            'Accept: application/json',
            'Session-Id: ' . $session_id,
            'Forwarded: ' . $remote_addr,
            'Authorization:  Bearer ' . $this->merchant_token,
            'Content-Type: application/json'
        ];

        curl_setopt_array($this->curl, [
            CURLOPT_USERAGENT     => $user_agent,
            CURLOPT_HTTPHEADER    => $headers,
            CURLOPT_URL           => $url,
            CURLOPT_CUSTOMREQUEST => $method
        ]);

        if (count($params) > 0) {
            $data      = json_encode($params, JSON_PRETTY_PRINT);
            $headers[] = 'Content-Length: ' . strlen($data);

            curl_setopt($this->curl, CURLOPT_POSTFIELDS, $data);
            curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
        }

        $body = curl_exec($this->curl);
        $info = curl_getinfo($this->curl);
        $code = (int)($info['http_code'] / 100);
        switch ($code) {
            case 0:
                $error = curl_error($this->curl);
                $errno = curl_errno($this->curl);
                throw new Exception(sprintf('Error: %s. Code: %s.', $error, $errno));
            case 1:
                throw new Exception(sprintf('Invalid HTTP Code: %s', $info['http_code']));
            case 2:
            case 3:
                return new Response($body);
            case 4:
            case 5:
                throw new Exception(sprintf('API Error: %s. HTTP Code: %s', $body, $info['http_code']));
            default:
                throw new Exception(sprintf('Invalid HTTP Code: %s', $info['http_code']));
        }
    }
337204
private function createRequest($path, $method, $parameters = [], $headers = [], $body)
    {
        $request =  new Request();

        $request
            ->setPath($path)
            ->setMethod($method)
            ->setParameters(new ParameterBag((array) $parameters))
            ->setHeaders(new ParameterBag((array) $headers))
            ->setBody($body)
            ->setOptions(new ParameterBag((array) $this->options))
        ;

        return $this->lastRequest = $request;
    }
451644
protected function request($api, array $params, $method = 'post')
    {
        $params = array_filter($params);
        $params['mch_id'] = $this->merchant->merchant_id;
        $params['nonce_str'] = uniqid();
        $params['sign'] = \EntWeChat\Payment\generate_sign($params, $this->merchant->key, 'md5');

        $options = [
            'body'    => XML::build($params),
            'cert'    => $this->merchant->get('cert_path'),
            'ssl_key' => $this->merchant->get('key_path'),
        ];

        return $this->parseResponse($this->getHttp()->request($api, $method, $options));
    }
989541
private function request($url, $params = [], $method = 'GET')
    {
        // Set URL & Header
        curl_setopt($this->curl, CURLOPT_URL, $this->url . $url);
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, array());

        //Add post vars
        if($method == 'POST')
        {
            curl_setopt($this->curl, CURLOPT_POST, count($params));
            curl_setopt($this->curl, CURLOPT_POSTFIELDS, $params);
        }

        //Get result
        $result = curl_exec($this->curl);
        if($result === false)
            throw new \Exception('CURL error: ' . curl_error($this->curl));

        // decode results
        $result = json_decode($result, true);

        if(!is_array($result) || json_last_error())
            throw new \Exception('JSON decode error');

        return $result;

    }
816501
public function request($path, $method = Request::GET, $data = [], array $query = [])
    {
        return $this->_client->request('_snapshot/'.$path, $method, $data, $query);
    }
542864
public function getRequestBodyParameter(string $path, string $method)
    {
        foreach ($this->getPath($path)->getOperation($method)->getParameters() as $parameter) {
            if ($parameter->getIn() === Parameter::IN_BODY) {
                return $parameter;
            }
        }

        return null;
    }
1217273
public function signature($method, $path, array $params = array())
    {
        $params = $this->completeParams($params);

        ksort($params);

        if (isset($params['file'])) {
            unset($params['file']);
        }

        $canonicalQueryString = str_replace(
            array('+', '%5B', '%5D'),
            array('%20', '[', ']'),
            http_build_query($params, '', '&')
        );
        $stringToSign = sprintf(
            "%s\n%s\n%s\n%s",
            strtoupper($method),
            $this->account->getApiHost(),
            $path,
            $canonicalQueryString
        );
        $hmac = hash_hmac('sha256', $stringToSign, $this->account->getSecretKey(), true);

        return base64_encode($hmac);
    }
1113714
final private function logRequest($method, $path, array $params, $result)
	{
	    $date = gmdate('Y-m-d\TH:i:s\Z ').substr(microtime(),0,5);
		$this->requestLog[$date] = [
		    "method" => $method,
            "path"   => $path,
            "params" => $params,
            "result" => $result
        ];
	}
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());
    }
1096253
public function request($method, $params = [])
    {
        return $this->getClient()->request($method, array_merge($params, $this->getAuth()->getAuthParams()));
    }
122721
public function request($method, $url, $params = null, $headers = [])
    {
        $headers = array_merge(self::defaultHeaders(), $headers);
        $absUrl = $this->apiBase . $url;
        return $this->httpClient()->request($method, $absUrl, $params, $headers);
    }
1328613
public function request(string $path, array $params = null, string $method = null, $body = null, array $headers = null):ResponseInterface{

		$request = $this->requestFactory
			->createRequest($method ?? 'GET', Psr7\merge_query($this->apiURL.$path, $params ?? []));

		foreach(array_merge($this->apiHeaders, $headers ?? []) as $header => $value){
			$request = $request->withAddedHeader($header, $value);
		}

		if(is_array($body) && $request->hasHeader('content-type')){
			$contentType = strtolower($request->getHeaderLine('content-type'));

			// @todo: content type support
			if($contentType === 'application/x-www-form-urlencoded'){
				$body = $this->streamFactory->createStream(http_build_query($body, '', '&', PHP_QUERY_RFC1738));
			}
			elseif($contentType === 'application/json'){
				$body = $this->streamFactory->createStream(json_encode($body));
			}

		}

		if($body instanceof StreamInterface){
			$request = $request
				->withBody($body)
				->withHeader('Content-length', $body->getSize())
			;
		}

		return $this->sendRequest($request);
	}
318079
private function getResponse($method, $path, $parameters)
    {
        try {
            $response = $this->adapter->request($method, $path, $parameters);
            return $this->getResult($response);
        }
        catch (\Exception $e) {
            return $e->getMessage();
        }
    }
18747
protected function request($url, $method = 'GET', array $params = [])
    {
        $url = $this->sanitizeQuery($url);

        $response = $this->client->request($method, $url, $params);

        if (is_array($response) && isset($response['paging'])) {
            $response = $this->injectPager($response, $method, $url, $params);
        }

        return $response;
    }
433265
protected function execute($path, $method, $queryParams, $httpBody = null, $headers = array())
    {
        $attempts = $this->attempts;
        $response = $this->apiClient->call($path, $method, $queryParams, $httpBody, $headers);

        while ($response->getCode() == 202 && $attempts > 0) {
            $this->delay($response);
            $attempts--;
            $response = $this->apiClient->call($path, $method, $queryParams, $httpBody, $headers);
        }

        return $response;
    }