PayPalCorePayPalHttpConnection

A wrapper class based on the curl extension.

Defined (1)

The class is defined in the following location(s).

/classes/lib/PayPal/Core/PayPalHttpConnection.php  
  1. class PayPalHttpConnection 
  2.  
  3. /** 
  4. * @var PayPalHttpConfig 
  5. */ 
  6. private $httpConfig; 
  7.  
  8. /** 
  9. * HTTP status codes for which a retry must be attempted 
  10. * retry is currently attempted for Request timeout, Bad Gateway,  
  11. * Service Unavailable and Gateway timeout errors. 
  12. */ 
  13. private static $retryCodes = array('408', '502', '503', '504', ); 
  14.  
  15. /** 
  16. * LoggingManager 
  17. * @var PayPalLoggingManager 
  18. */ 
  19. private $logger; 
  20.  
  21. /** 
  22. * Default Constructor 
  23. * @param PayPalHttpConfig $httpConfig 
  24. * @param array $config 
  25. * @throws PayPalConfigurationException 
  26. */ 
  27. public function __construct(PayPalHttpConfig $httpConfig, array $config) 
  28. if (!function_exists("curl_init")) { 
  29. throw new PayPalConfigurationException("Curl module is not available on this system"); 
  30. $this->httpConfig = $httpConfig; 
  31. $this->logger = PayPalLoggingManager::getInstance(__CLASS__); 
  32.  
  33. /** 
  34. * Gets all Http Headers 
  35. * @return array 
  36. */ 
  37. private function getHttpHeaders() 
  38.  
  39. $ret = array(); 
  40. foreach ($this->httpConfig->getHeaders() as $k => $v) { 
  41. $ret[] = "$k: $v"; 
  42. return $ret; 
  43.  
  44. /** 
  45. * Executes an HTTP request 
  46. * @param string $data query string OR POST content as a string 
  47. * @return mixed 
  48. * @throws PayPalConnectionException 
  49. */ 
  50. public function execute($data) 
  51. //Initialize the logger 
  52. $this->logger->info($this->httpConfig->getMethod() . ' ' . $this->httpConfig->getUrl()); 
  53.  
  54. //Initialize Curl Options 
  55. $ch = curl_init($this->httpConfig->getUrl()); 
  56. curl_setopt_array($ch, $this->httpConfig->getCurlOptions()); 
  57. curl_setopt($ch, CURLOPT_URL, $this->httpConfig->getUrl()); 
  58. curl_setopt($ch, CURLOPT_HEADER, true); 
  59. curl_setopt($ch, CURLINFO_HEADER_OUT, true); 
  60. curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHttpHeaders()); 
  61.  
  62. //Determine Curl Options based on Method 
  63. switch ($this->httpConfig->getMethod()) { 
  64. case 'POST': 
  65. curl_setopt($ch, CURLOPT_POST, true); 
  66. curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
  67. break; 
  68. case 'PUT': 
  69. case 'PATCH': 
  70. case 'DELETE': 
  71. curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
  72. break; 
  73.  
  74. //Default Option if Method not of given types in switch case 
  75. if ($this->httpConfig->getMethod() != NULL) { 
  76. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->httpConfig->getMethod()); 
  77.  
  78. //Logging Each Headers for debugging purposes 
  79. foreach ($this->getHttpHeaders() as $header) { 
  80. //TODO: Strip out credentials and other secure info when logging. 
  81. // $this->logger->debug($header); 
  82.  
  83. //Execute Curl Request 
  84. $result = curl_exec($ch); 
  85. //Retrieve Response Status 
  86. $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); 
  87.  
  88. //Retry if Certificate Exception 
  89. if (curl_errno($ch) == 60) { 
  90. $this->logger->info("Invalid or no certificate authority found - Retrying using bundled CA certs file"); 
  91. curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); 
  92. $result = curl_exec($ch); 
  93. //Retrieve Response Status 
  94. $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); 
  95.  
  96. //Retry if Failing 
  97. $retries = 0; 
  98. if (in_array($httpStatus, self::$retryCodes) && $this->httpConfig->getHttpRetryCount() != null) { 
  99. $this->logger->info("Got $httpStatus response from server. Retrying"); 
  100. do { 
  101. $result = curl_exec($ch); 
  102. //Retrieve Response Status 
  103. $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); 
  104. } while (in_array($httpStatus, self::$retryCodes) && (++$retries < $this->httpConfig->getHttpRetryCount())); 
  105.  
  106. //Throw Exception if Retries and Certificates doenst work 
  107. if (curl_errno($ch)) { 
  108. $ex = new PayPalConnectionException( 
  109. $this->httpConfig->getUrl(),  
  110. curl_error($ch),  
  111. curl_errno($ch) 
  112. ); 
  113. curl_close($ch); 
  114. throw $ex; 
  115.  
  116. // Get Request and Response Headers 
  117. $requestHeaders = curl_getinfo($ch, CURLINFO_HEADER_OUT); 
  118. //Using alternative solution to CURLINFO_HEADER_SIZE as it throws invalid number when called using PROXY. 
  119. $responseHeaderSize = strlen($result) - curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD); 
  120. $responseHeaders = substr($result, 0, $responseHeaderSize); 
  121. $result = substr($result, $responseHeaderSize); 
  122.  
  123. $this->logger->debug("Request Headers \t: " . str_replace("\r\n", ", ", $requestHeaders)); 
  124. $this->logger->debug(($data && $data != '' ? "Request Data\t\t: " . $data : "No Request Payload") . "\n" . str_repeat('-', 128) . "\n"); 
  125. $this->logger->info("Response Status \t: " . $httpStatus); 
  126. $this->logger->debug("Response Headers\t: " . str_replace("\r\n", ", ", $responseHeaders)); 
  127.  
  128. //Close the curl request 
  129. curl_close($ch); 
  130.  
  131. //More Exceptions based on HttpStatus Code 
  132. if (in_array($httpStatus, self::$retryCodes)) { 
  133. $ex = new PayPalConnectionException( 
  134. $this->httpConfig->getUrl(),  
  135. "Got Http response code $httpStatus when accessing {$this->httpConfig->getUrl()}. " . 
  136. "Retried $retries times." 
  137. ); 
  138. $ex->setData($result); 
  139. $this->logger->error("Got Http response code $httpStatus when accessing {$this->httpConfig->getUrl()}. " . 
  140. "Retried $retries times." . $result); 
  141. $this->logger->debug("\n\n" . str_repeat('=', 128) . "\n"); 
  142. throw $ex; 
  143. } else if ($httpStatus < 200 || $httpStatus >= 300) { 
  144. $ex = new PayPalConnectionException( 
  145. $this->httpConfig->getUrl(),  
  146. "Got Http response code $httpStatus when accessing {$this->httpConfig->getUrl()}.",  
  147. $httpStatus 
  148. ); 
  149. $ex->setData($result); 
  150. $this->logger->error("Got Http response code $httpStatus when accessing {$this->httpConfig->getUrl()}. " . $result ); 
  151. $this->logger->debug("\n\n" . str_repeat('=', 128) . "\n"); 
  152. throw $ex; 
  153.  
  154. $this->logger->debug(($result && $result != '' ? "Response Data \t: " . $result : "No Response Body") . "\n\n" . str_repeat('=', 128) . "\n"); 
  155.  
  156. //Return result object 
  157. return $result; 
  158.