File "CurlMollieHttpAdapter.php"

Full Path: /home/cananyalcin/public_html/core/lib/mollie/src/HttpAdapter/CurlMollieHttpAdapter.php
File size: 7 KB
MIME-type: text/x-php
Charset: utf-8

<?php

namespace Mollie\Api\HttpAdapter;

use _PhpScoper54524b0fd82d\Composer\CaBundle\CaBundle;
use Mollie\Api\Exceptions\ApiException;
use Mollie\Api\Exceptions\CurlConnectTimeoutException;
use Mollie\Api\MollieApiClient;
final class CurlMollieHttpAdapter implements \Mollie\Api\HttpAdapter\MollieHttpAdapterInterface
{
    /**
     * Default response timeout (in seconds).
     */
    const DEFAULT_TIMEOUT = 10;
    /**
     * Default connect timeout (in seconds).
     */
    const DEFAULT_CONNECT_TIMEOUT = 2;
    /**
     * HTTP status code for an empty ok response.
     */
    const HTTP_NO_CONTENT = 204;
    /**
     * The maximum number of retries
     */
    const MAX_RETRIES = 5;
    /**
     * The amount of milliseconds the delay is being increased with on each retry.
     */
    const DELAY_INCREASE_MS = 1000;
    /**
     * @param string $httpMethod
     * @param string $url
     * @param array $headers
     * @param string $httpBody
     * @return \stdClass|void|null
     * @throws \Mollie\Api\Exceptions\ApiException
     * @throws \Mollie\Api\Exceptions\CurlConnectTimeoutException
     */
    public function send($httpMethod, $url, $headers, $httpBody)
    {
        for ($i = 0; $i <= self::MAX_RETRIES; $i++) {
            \usleep($i * self::DELAY_INCREASE_MS);
            try {
                return $this->attemptRequest($httpMethod, $url, $headers, $httpBody);
            } catch (\Mollie\Api\Exceptions\CurlConnectTimeoutException $e) {
                // Nothing
            }
        }
        throw new \Mollie\Api\Exceptions\CurlConnectTimeoutException("Unable to connect to Mollie. Maximum number of retries (" . self::MAX_RETRIES . ") reached.");
    }
    /**
     * @param string $httpMethod
     * @param string $url
     * @param array $headers
     * @param string $httpBody
     * @return \stdClass|void|null
     * @throws \Mollie\Api\Exceptions\ApiException
     */
    protected function attemptRequest($httpMethod, $url, $headers, $httpBody)
    {
        $curl = \curl_init($url);
        $headers["Content-Type"] = "application/json";
        \curl_setopt($curl, \CURLOPT_RETURNTRANSFER, \true);
        \curl_setopt($curl, \CURLOPT_HTTPHEADER, $this->parseHeaders($headers));
        \curl_setopt($curl, \CURLOPT_CONNECTTIMEOUT, self::DEFAULT_CONNECT_TIMEOUT);
        \curl_setopt($curl, \CURLOPT_TIMEOUT, self::DEFAULT_TIMEOUT);
        \curl_setopt($curl, \CURLOPT_SSL_VERIFYPEER, \true);
        \curl_setopt($curl, \CURLOPT_CAINFO, \_PhpScoper54524b0fd82d\Composer\CaBundle\CaBundle::getBundledCaBundlePath());
        switch ($httpMethod) {
            case \Mollie\Api\MollieApiClient::HTTP_POST:
                \curl_setopt($curl, \CURLOPT_POST, \true);
                \curl_setopt($curl, \CURLOPT_POSTFIELDS, $httpBody);
                break;
            case \Mollie\Api\MollieApiClient::HTTP_GET:
                break;
            case \Mollie\Api\MollieApiClient::HTTP_PATCH:
                \curl_setopt($curl, \CURLOPT_CUSTOMREQUEST, 'PATCH');
                \curl_setopt($curl, \CURLOPT_POSTFIELDS, $httpBody);
                break;
            case \Mollie\Api\MollieApiClient::HTTP_DELETE:
                \curl_setopt($curl, \CURLOPT_CUSTOMREQUEST, 'DELETE');
                \curl_setopt($curl, \CURLOPT_POSTFIELDS, $httpBody);
                break;
            default:
                throw new \InvalidArgumentException("Invalid http method: " . $httpMethod);
        }
        $startTime = \microtime(\true);
        $response = \curl_exec($curl);
        $endTime = \microtime(\true);
        if ($response === \false) {
            $executionTime = $endTime - $startTime;
            $curlErrorNumber = \curl_errno($curl);
            $curlErrorMessage = "Curl error: " . \curl_error($curl);
            if ($this->isConnectTimeoutError($curlErrorNumber, $executionTime)) {
                throw new \Mollie\Api\Exceptions\CurlConnectTimeoutException("Unable to connect to Mollie. " . $curlErrorMessage);
            }
            throw new \Mollie\Api\Exceptions\ApiException($curlErrorMessage);
        }
        $statusCode = \curl_getinfo($curl, \CURLINFO_RESPONSE_CODE);
        \curl_close($curl);
        return $this->parseResponseBody($response, $statusCode, $httpBody);
    }
    /**
     * The version number for the underlying http client, if available.
     * @example Guzzle/6.3
     *
     * @return string|null
     */
    public function versionString()
    {
        return 'Curl/*';
    }
    /**
     * Whether this http adapter provides a debugging mode. If debugging mode is enabled, the
     * request will be included in the ApiException.
     *
     * @return false
     */
    public function supportsDebugging()
    {
        return \false;
    }
    /**
     * @param int $curlErrorNumber
     * @param string|float $executionTime
     * @return bool
     */
    protected function isConnectTimeoutError($curlErrorNumber, $executionTime)
    {
        $connectErrors = [\CURLE_COULDNT_RESOLVE_HOST => \true, \CURLE_COULDNT_CONNECT => \true, \CURLE_SSL_CONNECT_ERROR => \true, \CURLE_GOT_NOTHING => \true];
        if (isset($connectErrors[$curlErrorNumber])) {
            return \true;
        }
        if ($curlErrorNumber === \CURLE_OPERATION_TIMEOUTED) {
            if ($executionTime > self::DEFAULT_TIMEOUT) {
                return \false;
            }
            return \true;
        }
        return \false;
    }
    /**
     * @param string $response
     * @param int $statusCode
     * @param string $httpBody
     * @return \stdClass|null
     * @throws \Mollie\Api\Exceptions\ApiException
     */
    protected function parseResponseBody($response, $statusCode, $httpBody)
    {
        if (empty($response)) {
            if ($statusCode === self::HTTP_NO_CONTENT) {
                return null;
            }
            throw new \Mollie\Api\Exceptions\ApiException("No response body found.");
        }
        $body = @\json_decode($response);
        // GUARDS
        if (\json_last_error() !== \JSON_ERROR_NONE) {
            throw new \Mollie\Api\Exceptions\ApiException("Unable to decode Mollie response: '{$response}'.");
        }
        if (isset($body->error)) {
            throw new \Mollie\Api\Exceptions\ApiException($body->error->message);
        }
        if ($statusCode >= 400) {
            $message = "Error executing API call ({$body->status}: {$body->title}): {$body->detail}";
            $field = null;
            if (!empty($body->field)) {
                $field = $body->field;
            }
            if (isset($body->_links, $body->_links->documentation)) {
                $message .= ". Documentation: {$body->_links->documentation->href}";
            }
            if ($httpBody) {
                $message .= ". Request body: {$httpBody}";
            }
            throw new \Mollie\Api\Exceptions\ApiException($message, $statusCode, $field);
        }
        return $body;
    }
    protected function parseHeaders($headers)
    {
        $result = [];
        foreach ($headers as $key => $value) {
            $result[] = $key . ': ' . $value;
        }
        return $result;
    }
}