/src/HttpClient/Curl.php
PHP | 316 lines | 158 code | 43 blank | 115 comment | 10 complexity | b58e3a620c461690b4a8abb0dcc2dfc4 MD5 | raw file
- <?php
- /*!
- * Hybridauth
- * https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
- * (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
- */
- namespace Hybridauth\HttpClient;
- /**
- * Hybridauth default Http client
- */
- class Curl implements HttpClientInterface
- {
- /**
- * Default curl options
- *
- * These defaults options can be overwritten when sending requests.
- *
- * See setCurlOptions()
- *
- * @var array
- */
- protected $curlOptions = [
- CURLOPT_TIMEOUT => 30,
- CURLOPT_CONNECTTIMEOUT => 30,
- CURLOPT_SSL_VERIFYPEER => false,
- CURLOPT_SSL_VERIFYHOST => false,
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_MAXREDIRS => 5,
- CURLINFO_HEADER_OUT => true,
- CURLOPT_ENCODING => 'identity',
- // phpcs:ignore
- CURLOPT_USERAGENT => 'Hybridauth, PHP Social Authentication Library (https://github.com/hybridauth/hybridauth)',
- ];
- /**
- * Method request() arguments
- *
- * This is used for debugging.
- *
- * @var array
- */
- protected $requestArguments = [];
- /**
- * Default request headers
- *
- * @var array
- */
- protected $requestHeader = [
- 'Accept' => '*/*',
- 'Cache-Control' => 'max-age=0',
- 'Connection' => 'keep-alive',
- 'Expect' => '',
- 'Pragma' => '',
- ];
- /**
- * Raw response returned by server
- *
- * @var string
- */
- protected $responseBody = '';
- /**
- * Headers returned in the response
- *
- * @var array
- */
- protected $responseHeader = [];
- /**
- * Response HTTP status code
- *
- * @var int
- */
- protected $responseHttpCode = 0;
- /**
- * Last curl error number
- *
- * @var mixed
- */
- protected $responseClientError = null;
- /**
- * Information about the last transfer
- *
- * @var mixed
- */
- protected $responseClientInfo = [];
- /**
- * Hybridauth logger instance
- *
- * @var object
- */
- protected $logger = null;
- /**
- * {@inheritdoc}
- */
- public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
- {
- $this->requestHeader = array_replace($this->requestHeader, (array)$headers);
- $this->requestArguments = [
- 'uri' => $uri,
- 'method' => $method,
- 'parameters' => $parameters,
- 'headers' => $this->requestHeader,
- ];
- $curl = curl_init();
- switch ($method) {
- case 'GET':
- case 'DELETE':
- unset($this->curlOptions[CURLOPT_POST]);
- unset($this->curlOptions[CURLOPT_POSTFIELDS]);
- $uri = $uri . (strpos($uri, '?') ? '&' : '?') . http_build_query($parameters);
- if ($method === 'DELETE') {
- $this->curlOptions[CURLOPT_CUSTOMREQUEST] = 'DELETE';
- }
- break;
- case 'PUT':
- case 'POST':
- case 'PATCH':
- $body_content = $multipart ? $parameters : http_build_query($parameters);
- if (isset($this->requestHeader['Content-Type'])
- && $this->requestHeader['Content-Type'] == 'application/json'
- ) {
- $body_content = json_encode($parameters);
- }
- if ($method === 'POST') {
- $this->curlOptions[CURLOPT_POST] = true;
- } else {
- $this->curlOptions[CURLOPT_CUSTOMREQUEST] = $method;
- }
- $this->curlOptions[CURLOPT_POSTFIELDS] = $body_content;
- break;
- }
- $this->curlOptions[CURLOPT_URL] = $uri;
- $this->curlOptions[CURLOPT_HTTPHEADER] = $this->prepareRequestHeaders();
- $this->curlOptions[CURLOPT_HEADERFUNCTION] = [$this, 'fetchResponseHeader'];
- foreach ($this->curlOptions as $opt => $value) {
- curl_setopt($curl, $opt, $value);
- }
- $response = curl_exec($curl);
- $this->responseBody = $response;
- $this->responseHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
- $this->responseClientError = curl_error($curl);
- $this->responseClientInfo = curl_getinfo($curl);
- if ($this->logger) {
- // phpcs:ignore
- $this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse());
- if (false === $response) {
- // phpcs:ignore
- $this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]);
- }
- }
- curl_close($curl);
- return $this->responseBody;
- }
- /**
- * Get response details
- *
- * @return array Map structure of details
- */
- public function getResponse()
- {
- $curlOptions = $this->curlOptions;
- $curlOptions[CURLOPT_HEADERFUNCTION] = '*omitted';
- return [
- 'request' => $this->getRequestArguments(),
- 'response' => [
- 'code' => $this->getResponseHttpCode(),
- 'headers' => $this->getResponseHeader(),
- 'body' => $this->getResponseBody(),
- ],
- 'client' => [
- 'error' => $this->getResponseClientError(),
- 'info' => $this->getResponseClientInfo(),
- 'opts' => $curlOptions,
- ],
- ];
- }
- /**
- * Reset curl options
- *
- * @param array $curlOptions
- */
- public function setCurlOptions($curlOptions)
- {
- foreach ($curlOptions as $opt => $value) {
- $this->curlOptions[$opt] = $value;
- }
- }
- /**
- * Set logger instance
- *
- * @param object $logger
- */
- public function setLogger($logger)
- {
- $this->logger = $logger;
- }
- /**
- * {@inheritdoc}
- */
- public function getResponseBody()
- {
- return $this->responseBody;
- }
- /**
- * {@inheritdoc}
- */
- public function getResponseHeader()
- {
- return $this->responseHeader;
- }
- /**
- * {@inheritdoc}
- */
- public function getResponseHttpCode()
- {
- return $this->responseHttpCode;
- }
- /**
- * {@inheritdoc}
- */
- public function getResponseClientError()
- {
- return $this->responseClientError;
- }
- /**
- * @return array
- */
- protected function getResponseClientInfo()
- {
- return $this->responseClientInfo;
- }
- /**
- * Returns method request() arguments
- *
- * This is used for debugging.
- *
- * @return array
- */
- protected function getRequestArguments()
- {
- return $this->requestArguments;
- }
- /**
- * Fetch server response headers
- *
- * @param mixed $curl
- * @param string $header
- *
- * @return int
- */
- protected function fetchResponseHeader($curl, $header)
- {
- $pos = strpos($header, ':');
- if (!empty($pos)) {
- $key = str_replace('-', '_', strtolower(substr($header, 0, $pos)));
- $value = trim(substr($header, $pos + 2));
- $this->responseHeader[$key] = $value;
- }
- return strlen($header);
- }
- /**
- * Convert request headers to the expect curl format
- *
- * @return array
- */
- protected function prepareRequestHeaders()
- {
- $headers = [];
- foreach ($this->requestHeader as $header => $value) {
- $headers[] = trim($header) . ': ' . trim($value);
- }
- return $headers;
- }
- }