/libraries/fabrik/vendor/twilio/sdk/src/Twilio/Http/CurlClient.php

https://github.com/trob/fabrik · PHP · 191 lines · 155 code · 36 blank · 0 comment · 26 complexity · 93c957527495183285d163c170a3e2d0 MD5 · raw file

  1. <?php
  2. namespace Twilio\Http;
  3. use Twilio\Exceptions\EnvironmentException;
  4. class CurlClient implements Client {
  5. const DEFAULT_TIMEOUT = 60;
  6. protected $curlOptions = array();
  7. protected $debugHttp = false;
  8. public $lastRequest = null;
  9. public $lastResponse = null;
  10. public function __construct(array $options = array()) {
  11. $this->curlOptions = $options;
  12. $this->debugHttp = \getenv('DEBUG_HTTP_TRAFFIC') === 'true';
  13. }
  14. public function request($method, $url, $params = array(), $data = array(),
  15. $headers = array(), $user = null, $password = null,
  16. $timeout = null) {
  17. $options = $this->options($method, $url, $params, $data, $headers,
  18. $user, $password, $timeout);
  19. $this->lastRequest = $options;
  20. $this->lastResponse = null;
  21. try {
  22. if (!$curl = \curl_init()) {
  23. throw new EnvironmentException('Unable to initialize cURL');
  24. }
  25. if (!\curl_setopt_array($curl, $options)) {
  26. throw new EnvironmentException(\curl_error($curl));
  27. }
  28. if (!$response = \curl_exec($curl)) {
  29. throw new EnvironmentException(\curl_error($curl));
  30. }
  31. $parts = \explode("\r\n\r\n", $response, 3);
  32. list($head, $body) = (
  33. \preg_match('/\AHTTP\/1.\d 100 Continue\Z/', $parts[0])
  34. || \preg_match('/\AHTTP\/1.\d 200 Connection established\Z/', $parts[0])
  35. || \preg_match('/\AHTTP\/1.\d 200 Tunnel established\Z/', $parts[0])
  36. )
  37. ? array($parts[1], $parts[2])
  38. : array($parts[0], $parts[1]);
  39. if ($this->debugHttp) {
  40. $u = \parse_url($url);
  41. $hdrLine = $method . ' ' . $u['path'];
  42. if (isset($u['query']) && \strlen($u['query']) > 0 ) {
  43. $hdrLine = $hdrLine . '?' . $u['query'];
  44. }
  45. \error_log($hdrLine);
  46. foreach ($headers as $key => $value) {
  47. \error_log("$key: $value");
  48. }
  49. if ($method === 'POST') {
  50. \error_log("\n" . $options[CURLOPT_POSTFIELDS] . "\n");
  51. }
  52. }
  53. $statusCode = \curl_getinfo($curl, CURLINFO_HTTP_CODE);
  54. $responseHeaders = array();
  55. $headerLines = \explode("\r\n", $head);
  56. \array_shift($headerLines);
  57. foreach ($headerLines as $line) {
  58. list($key, $value) = \explode(':', $line, 2);
  59. $responseHeaders[$key] = $value;
  60. }
  61. \curl_close($curl);
  62. if (isset($buffer) && \is_resource($buffer)) {
  63. \fclose($buffer);
  64. }
  65. if ($this->debugHttp) {
  66. \error_log("HTTP/1.1 $statusCode");
  67. foreach ($responseHeaders as $key => $value) {
  68. \error_log("$key: $value");
  69. }
  70. \error_log("\n$body");
  71. }
  72. $this->lastResponse = new Response($statusCode, $body, $responseHeaders);
  73. return $this->lastResponse;
  74. } catch (\ErrorException $e) {
  75. if (isset($curl) && \is_resource($curl)) {
  76. \curl_close($curl);
  77. }
  78. if (isset($buffer) && \is_resource($buffer)) {
  79. \fclose($buffer);
  80. }
  81. throw $e;
  82. }
  83. }
  84. public function options($method, $url, $params = array(), $data = array(),
  85. $headers = array(), $user = null, $password = null,
  86. $timeout = null) {
  87. $timeout = \is_null($timeout)
  88. ? self::DEFAULT_TIMEOUT
  89. : $timeout;
  90. $options = $this->curlOptions + array(
  91. CURLOPT_URL => $url,
  92. CURLOPT_HEADER => true,
  93. CURLOPT_RETURNTRANSFER => true,
  94. CURLOPT_INFILESIZE => Null,
  95. CURLOPT_HTTPHEADER => array(),
  96. CURLOPT_TIMEOUT => $timeout,
  97. );
  98. foreach ($headers as $key => $value) {
  99. $options[CURLOPT_HTTPHEADER][] = "$key: $value";
  100. }
  101. if ($user && $password) {
  102. $options[CURLOPT_HTTPHEADER][] = 'Authorization: Basic ' . \base64_encode("$user:$password");
  103. }
  104. $body = $this->buildQuery($params);
  105. if ($body) {
  106. $options[CURLOPT_URL] .= '?' . $body;
  107. }
  108. switch (\strtolower(\trim($method))) {
  109. case 'get':
  110. $options[CURLOPT_HTTPGET] = true;
  111. break;
  112. case 'post':
  113. $options[CURLOPT_POST] = true;
  114. $options[CURLOPT_POSTFIELDS] = $this->buildQuery($data);
  115. break;
  116. case 'put':
  117. $options[CURLOPT_PUT] = true;
  118. if ($data) {
  119. if ($buffer = \fopen('php://memory', 'w+')) {
  120. $dataString = $this->buildQuery($data);
  121. \fwrite($buffer, $dataString);
  122. \fseek($buffer, 0);
  123. $options[CURLOPT_INFILE] = $buffer;
  124. $options[CURLOPT_INFILESIZE] = \strlen($dataString);
  125. } else {
  126. throw new EnvironmentException('Unable to open a temporary file');
  127. }
  128. }
  129. break;
  130. case 'head':
  131. $options[CURLOPT_NOBODY] = true;
  132. break;
  133. default:
  134. $options[CURLOPT_CUSTOMREQUEST] = \strtoupper($method);
  135. }
  136. return $options;
  137. }
  138. public function buildQuery($params) {
  139. $parts = array();
  140. if (\is_string($params)) {
  141. return $params;
  142. }
  143. $params = $params ?: array();
  144. foreach ($params as $key => $value) {
  145. if (\is_array($value)) {
  146. foreach ($value as $item) {
  147. $parts[] = \urlencode((string)$key) . '=' . \urlencode((string)$item);
  148. }
  149. } else {
  150. $parts[] = \urlencode((string)$key) . '=' . \urlencode((string)$value);
  151. }
  152. }
  153. return \implode('&', $parts);
  154. }
  155. }