app/Plugin/PayPalCheckout42/Lib/PayPalHttp/HttpClient.php line 34

Open in your IDE?
  1. <?php
  2. namespace Plugin\PayPalCheckout42\Lib\PayPalHttp;
  3. /**
  4.  * Class HttpClient
  5.  * @package Plugin\PayPalCheckout42\Lib\PayPalHttp
  6.  *
  7.  * Client used to make HTTP requests.
  8.  */
  9. class HttpClient
  10. {
  11.     /**
  12.      * @var Environment
  13.      */
  14.     public $environment;
  15.     /**
  16.      * @var Injector[]
  17.      */
  18.     public $injectors = [];
  19.     /**
  20.      * @var Encoder
  21.      */
  22.     public $encoder;
  23.     /**
  24.      * HttpClient constructor. Pass the environment you wish to make calls to.
  25.      *
  26.      * @param $environment Environment
  27.      * @see Environment
  28.      */
  29.     function __construct(Environment $environment)
  30.     {
  31.         $this->environment $environment;
  32.         $this->encoder = new Encoder();
  33.         $this->curlCls Curl::class;
  34.     }
  35.     /**
  36.      * Injectors are blocks that can be used for executing arbitrary pre-flight logic, such as modifying a request or logging data.
  37.      * Executed in first-in first-out order.
  38.      *
  39.      * @param Injector $inj
  40.      */
  41.     public function addInjector(Injector $inj)
  42.     {
  43.         $this->injectors[] = $inj;
  44.     }
  45.     /**
  46.      * The method that takes an HTTP request, serializes the request, makes a call to given environment, and deserialize response
  47.      *
  48.      * @param $httpRequest HttpRequest
  49.      * @return HttpResponse
  50.      */
  51.     public function execute(HttpRequest $httpRequest)
  52.     {
  53.         $requestCpy = clone $httpRequest;
  54.         $curl = new Curl();
  55.         foreach ($this->injectors as $inj) {
  56.             $inj->inject($requestCpy);
  57.         }
  58.         $url $this->environment->baseUrl() . $requestCpy->path;
  59.         $formattedHeaders $this->prepareHeaders($requestCpy->headers);
  60.         if (!array_key_exists("user-agent"$formattedHeaders)) {
  61.             $requestCpy->headers["user-agent"] = $this->userAgent();
  62.         }
  63.         $body "";
  64.         if (!is_null($requestCpy->body)) {
  65.             $rawHeaders $requestCpy->headers;
  66.             $requestCpy->headers $formattedHeaders;
  67.             $body $this->encoder->serializeRequest($requestCpy);
  68.             $requestCpy->headers $this->mapHeaders($rawHeaders,$requestCpy->headers);
  69.         }
  70.         $curl->setOpt(CURLOPT_URL$url);
  71.         $curl->setOpt(CURLOPT_CUSTOMREQUEST$requestCpy->verb);
  72.         $curl->setOpt(CURLOPT_HTTPHEADER$this->serializeHeaders($requestCpy->headers));
  73.         $curl->setOpt(CURLOPT_RETURNTRANSFER1);
  74.         $curl->setOpt(CURLOPT_HEADER0);
  75.         if (!is_null($requestCpy->body)) {
  76.             $curl->setOpt(CURLOPT_POSTFIELDS$body);
  77.         }
  78.         if (strpos($this->environment->baseUrl(), "https://") === 0) {
  79.             $curl->setOpt(CURLOPT_SSL_VERIFYPEERtrue);
  80.             $curl->setOpt(CURLOPT_SSL_VERIFYHOST2);
  81.         }
  82.         if ($caCertPath $this->getCACertFilePath()) {
  83.             $curl->setOpt(CURLOPT_CAINFO$caCertPath);
  84.         }
  85.         $response $this->parseResponse($curl);
  86.         $curl->close();
  87.         return $response;
  88.     }
  89.     /**
  90.      * Returns an array representing headers with their keys
  91.      * to be lower case
  92.      * @param $headers
  93.      * @return array
  94.      */
  95.     public function prepareHeaders($headers){
  96.         return array_change_key_case($headers);
  97.     }
  98.     /**
  99.      * Returns an array representing headers with their key in
  100.      * original cases and updated values
  101.      * @param $rawHeaders
  102.      * @param $formattedHeaders
  103.      * @return array
  104.      */
  105.     public function mapHeaders($rawHeaders$formattedHeaders){
  106.         $rawHeadersKey array_keys($rawHeaders);
  107.         foreach ($rawHeadersKey as $array_key) {
  108.             if(array_key_exists(strtolower($array_key), $formattedHeaders)){
  109.                 $rawHeaders[$array_key] = $formattedHeaders[strtolower($array_key)];
  110.             }
  111.         }
  112.         return $rawHeaders;
  113.     }
  114.     /**
  115.      * Returns default user-agent
  116.      *
  117.      * @return string
  118.      */
  119.     public function userAgent()
  120.     {
  121.         return "PayPalHttp-PHP HTTP/1.1";
  122.     }
  123.     /**
  124.      * Return the filepath to your custom CA Cert if needed.
  125.      * @return string
  126.      */
  127.     protected function getCACertFilePath()
  128.     {
  129.         return null;
  130.     }
  131.     protected function setCurl(Curl $curl)
  132.     {
  133.         $this->curl $curl;
  134.     }
  135.     protected function setEncoder(Encoder $encoder)
  136.     {
  137.         $this->encoder $encoder;
  138.     }
  139.     private function serializeHeaders($headers)
  140.     {
  141.         $headerArray = [];
  142.         if ($headers) {
  143.             foreach ($headers as $key => $val) {
  144.                 $headerArray[] = $key ": " $val;
  145.             }
  146.         }
  147.         return $headerArray;
  148.     }
  149.     private function parseResponse($curl)
  150.     {
  151.         $headers = [];
  152.         $curl->setOpt(CURLOPT_HEADERFUNCTION,
  153.             function($curl$header) use (&$headers)
  154.             {
  155.                 $len strlen($header);
  156.                 $k "";
  157.                 $v "";
  158.                 $this->deserializeHeader($header$k$v);
  159.                 $headers[$k] = $v;
  160.                 return $len;
  161.             });
  162.         $responseData $curl->exec();
  163.         $statusCode $curl->getInfo(CURLINFO_HTTP_CODE);
  164.         $errorCode $curl->errNo();
  165.         $error $curl->error();
  166.         if ($errorCode 0) {
  167.             throw new IOException($error$errorCode);
  168.         }
  169.         $body $responseData;
  170.         if ($statusCode >= 200 && $statusCode 300) {
  171.             $responseBody NULL;
  172.             if (!empty($body)) {
  173.                 $responseBody $this->encoder->deserializeResponse($body$this->prepareHeaders($headers));
  174.             }
  175.             return new HttpResponse(
  176.                 $errorCode === $statusCode $errorCode,
  177.                 $responseBody,
  178.                 $headers
  179.             );
  180.         } else {
  181.             throw new HttpException($body$statusCode$headers);
  182.         }
  183.     }
  184.     private function deserializeHeader($header, &$key, &$value)
  185.     {
  186.         if (strlen($header) > 0) {
  187.             if (empty($header) || strpos($header':') === false) {
  188.                 return NULL;
  189.             }
  190.             list($k$v) = explode(":"$header);
  191.             $key trim($k);
  192.             $value trim($v);
  193.         }
  194.     }
  195. }