CurlClient.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <?php
  2. namespace OAuth\Common\Http\Client;
  3. use OAuth\Common\Http\Exception\TokenResponseException;
  4. use OAuth\Common\Http\Uri\UriInterface;
  5. /**
  6. * Client implementation for cURL
  7. */
  8. class CurlClient extends AbstractClient
  9. {
  10. /**
  11. * If true, explicitly sets cURL to use SSL version 3. Use this if cURL
  12. * compiles with GnuTLS SSL.
  13. *
  14. * @var bool
  15. */
  16. private $forceSSL3 = false;
  17. /**
  18. * Additional parameters (as `key => value` pairs) to be passed to `curl_setopt`
  19. *
  20. * @var array
  21. */
  22. private $parameters = array();
  23. /**
  24. * Additional `curl_setopt` parameters
  25. *
  26. * @param array $parameters
  27. */
  28. public function setCurlParameters(array $parameters)
  29. {
  30. $this->parameters = $parameters;
  31. }
  32. /**
  33. * @param bool $force
  34. *
  35. * @return CurlClient
  36. */
  37. public function setForceSSL3($force)
  38. {
  39. $this->forceSSL3 = $force;
  40. return $this;
  41. }
  42. /**
  43. * Any implementing HTTP providers should send a request to the provided endpoint with the parameters.
  44. * They should return, in string form, the response body and throw an exception on error.
  45. *
  46. * @param UriInterface $endpoint
  47. * @param mixed $requestBody
  48. * @param array $extraHeaders
  49. * @param string $method
  50. *
  51. * @return string
  52. *
  53. * @throws TokenResponseException
  54. * @throws \InvalidArgumentException
  55. */
  56. public function retrieveResponse(
  57. UriInterface $endpoint,
  58. $requestBody,
  59. array $extraHeaders = array(),
  60. $method = 'POST'
  61. ) {
  62. // Normalize method name
  63. $method = strtoupper($method);
  64. $this->normalizeHeaders($extraHeaders);
  65. if ($method === 'GET' && !empty($requestBody)) {
  66. throw new \InvalidArgumentException('No body expected for "GET" request.');
  67. }
  68. if (!isset($extraHeaders['Content-Type']) && $method === 'POST' && is_array($requestBody)) {
  69. $extraHeaders['Content-Type'] = 'Content-Type: application/x-www-form-urlencoded';
  70. }
  71. $extraHeaders['Host'] = 'Host: '.$endpoint->getHost();
  72. $extraHeaders['Connection'] = 'Connection: close';
  73. $ch = curl_init();
  74. curl_setopt($ch, CURLOPT_URL, $endpoint->getAbsoluteUri());
  75. if ($method === 'POST' || $method === 'PUT') {
  76. if ($requestBody && is_array($requestBody)) {
  77. $requestBody = http_build_query($requestBody, '', '&');
  78. }
  79. if ($method === 'PUT') {
  80. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
  81. } else {
  82. curl_setopt($ch, CURLOPT_POST, true);
  83. }
  84. curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
  85. } else {
  86. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
  87. }
  88. if ($this->maxRedirects > 0) {
  89. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  90. curl_setopt($ch, CURLOPT_MAXREDIRS, $this->maxRedirects);
  91. }
  92. curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
  93. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  94. curl_setopt($ch, CURLOPT_HEADER, false);
  95. curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders);
  96. curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
  97. foreach ($this->parameters as $key => $value) {
  98. curl_setopt($ch, $key, $value);
  99. }
  100. if ($this->forceSSL3) {
  101. curl_setopt($ch, CURLOPT_SSLVERSION, 3);
  102. }
  103. $response = curl_exec($ch);
  104. $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  105. if (false === $response) {
  106. $errNo = curl_errno($ch);
  107. $errStr = curl_error($ch);
  108. curl_close($ch);
  109. if (empty($errStr)) {
  110. throw new TokenResponseException('Failed to request resource.', $responseCode);
  111. }
  112. throw new TokenResponseException('cURL Error # '.$errNo.': '.$errStr, $responseCode);
  113. }
  114. curl_close($ch);
  115. return $response;
  116. }
  117. }