123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\HTTP\Client;
- /**
- * Class to work with HTTP protocol using curl library
- *
- * @author Magento Core Team <core@magentocommerce.com>
- * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
- */
- class Curl implements \Magento\Framework\HTTP\ClientInterface
- {
- /**
- * Max supported protocol by curl CURL_SSLVERSION_TLSv1_2
- * @var int
- */
- private $sslVersion;
- /**
- * Hostname
- * @var string
- */
- protected $_host = 'localhost';
- /**
- * Port
- * @var int
- */
- protected $_port = 80;
- /**
- * Stream resource
- * @var object
- */
- protected $_sock = null;
- /**
- * Request headers
- * @var array
- */
- protected $_headers = [];
- /**
- * Fields for POST method - hash
- * @var array
- */
- protected $_postFields = [];
- /**
- * Request cookies
- * @var array
- */
- protected $_cookies = [];
- /**
- * Response headers
- * @var array
- */
- protected $_responseHeaders = [];
- /**
- * Response body
- * @var string
- */
- protected $_responseBody = '';
- /**
- * Response status
- * @var int
- */
- protected $_responseStatus = 0;
- /**
- * Request timeout
- * @var int type
- */
- protected $_timeout = 300;
- /**
- * TODO
- * @var int
- */
- protected $_redirectCount = 0;
- /**
- * Curl
- * @var resource
- */
- protected $_ch;
- /**
- * User overrides options hash
- * Are applied before curl_exec
- *
- * @var array
- */
- protected $_curlUserOptions = [];
- /**
- * Header count, used while parsing headers
- * in CURL callback function
- * @var int
- */
- protected $_headerCount = 0;
- /**
- * Set request timeout, msec
- *
- * @param int $value
- * @return void
- */
- public function setTimeout($value)
- {
- $this->_timeout = (int)$value;
- }
- /**
- * @param int|null $sslVersion
- */
- public function __construct($sslVersion = null)
- {
- $this->sslVersion = $sslVersion;
- }
- /**
- * Set headers from hash
- *
- * @param array $headers
- * @return void
- */
- public function setHeaders($headers)
- {
- $this->_headers = $headers;
- }
- /**
- * Add header
- *
- * @param string $name name, ex. "Location"
- * @param string $value value ex. "http://google.com"
- * @return void
- */
- public function addHeader($name, $value)
- {
- $this->_headers[$name] = $value;
- }
- /**
- * Remove specified header
- *
- * @param string $name
- * @return void
- */
- public function removeHeader($name)
- {
- unset($this->_headers[$name]);
- }
- /**
- * Authorization: Basic header
- *
- * Login credentials support
- *
- * @param string $login username
- * @param string $pass password
- * @return void
- */
- public function setCredentials($login, $pass)
- {
- $val = base64_encode("{$login}:{$pass}");
- $this->addHeader("Authorization", "Basic {$val}");
- }
- /**
- * Add cookie
- *
- * @param string $name
- * @param string $value
- * @return void
- */
- public function addCookie($name, $value)
- {
- $this->_cookies[$name] = $value;
- }
- /**
- * Remove cookie
- *
- * @param string $name
- * @return void
- */
- public function removeCookie($name)
- {
- unset($this->_cookies[$name]);
- }
- /**
- * Set cookies array
- *
- * @param array $cookies
- * @return void
- */
- public function setCookies($cookies)
- {
- $this->_cookies = $cookies;
- }
- /**
- * Clear cookies
- *
- * @return void
- */
- public function removeCookies()
- {
- $this->setCookies([]);
- }
- /**
- * Make GET request
- *
- * @param string $uri uri relative to host, ex. "/index.php"
- * @return void
- */
- public function get($uri)
- {
- $this->makeRequest("GET", $uri);
- }
- /**
- * Make POST request
- *
- * String type was added to parameter $param in order to support sending JSON or XML requests.
- * This feature was added base on Community Pull Request https://github.com/magento/magento2/pull/8373
- *
- * @param string $uri
- * @param array|string $params
- * @return void
- *
- * @see \Magento\Framework\HTTP\Client#post($uri, $params)
- */
- public function post($uri, $params)
- {
- $this->makeRequest("POST", $uri, $params);
- }
- /**
- * Get response headers
- *
- * @return array
- */
- public function getHeaders()
- {
- return $this->_responseHeaders;
- }
- /**
- * Get response body
- *
- * @return string
- */
- public function getBody()
- {
- return $this->_responseBody;
- }
- /**
- * Get cookies response hash
- *
- * @return array
- */
- public function getCookies()
- {
- if (empty($this->_responseHeaders['Set-Cookie'])) {
- return [];
- }
- $out = [];
- foreach ($this->_responseHeaders['Set-Cookie'] as $row) {
- $values = explode("; ", $row);
- $c = count($values);
- if (!$c) {
- continue;
- }
- list($key, $val) = explode("=", $values[0]);
- if ($val === null) {
- continue;
- }
- $out[trim($key)] = trim($val);
- }
- return $out;
- }
- /**
- * Get cookies array with details
- * (domain, expire time etc)
- *
- * @return array
- */
- public function getCookiesFull()
- {
- if (empty($this->_responseHeaders['Set-Cookie'])) {
- return [];
- }
- $out = [];
- foreach ($this->_responseHeaders['Set-Cookie'] as $row) {
- $values = explode("; ", $row);
- $c = count($values);
- if (!$c) {
- continue;
- }
- list($key, $val) = explode("=", $values[0]);
- if ($val === null) {
- continue;
- }
- $out[trim($key)] = ['value' => trim($val)];
- array_shift($values);
- $c--;
- if (!$c) {
- continue;
- }
- for ($i = 0; $i < $c; $i++) {
- list($subkey, $val) = explode("=", $values[$i]);
- $out[trim($key)][trim($subkey)] = trim($val);
- }
- }
- return $out;
- }
- /**
- * Get response status code
- *
- * @see lib\Magento\Framework\HTTP\Client#getStatus()
- *
- * @return int
- */
- public function getStatus()
- {
- return $this->_responseStatus;
- }
- /**
- * Make request
- *
- * String type was added to parameter $param in order to support sending JSON or XML requests.
- * This feature was added base on Community Pull Request https://github.com/magento/magento2/pull/8373
- *
- * @param string $method
- * @param string $uri
- * @param array|string $params - use $params as a string in case of JSON or XML POST request.
- *
- * @return void
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- protected function makeRequest($method, $uri, $params = [])
- {
- $this->_ch = curl_init();
- $this->curlOption(CURLOPT_URL, $uri);
- if ($method == 'POST') {
- $this->curlOption(CURLOPT_POST, 1);
- $this->curlOption(CURLOPT_POSTFIELDS, is_array($params) ? http_build_query($params) : $params);
- } elseif ($method == "GET") {
- $this->curlOption(CURLOPT_HTTPGET, 1);
- } else {
- $this->curlOption(CURLOPT_CUSTOMREQUEST, $method);
- }
- if (count($this->_headers)) {
- $heads = [];
- foreach ($this->_headers as $k => $v) {
- $heads[] = $k . ': ' . $v;
- }
- $this->curlOption(CURLOPT_HTTPHEADER, $heads);
- }
- if (count($this->_cookies)) {
- $cookies = [];
- foreach ($this->_cookies as $k => $v) {
- $cookies[] = "{$k}={$v}";
- }
- $this->curlOption(CURLOPT_COOKIE, implode(";", $cookies));
- }
- if ($this->_timeout) {
- $this->curlOption(CURLOPT_TIMEOUT, $this->_timeout);
- }
- if ($this->_port != 80) {
- $this->curlOption(CURLOPT_PORT, $this->_port);
- }
- $this->curlOption(CURLOPT_RETURNTRANSFER, 1);
- $this->curlOption(CURLOPT_HEADERFUNCTION, [$this, 'parseHeaders']);
- if ($this->sslVersion !== null) {
- $this->curlOption(CURLOPT_SSLVERSION, $this->sslVersion);
- }
- if (count($this->_curlUserOptions)) {
- foreach ($this->_curlUserOptions as $k => $v) {
- $this->curlOption($k, $v);
- }
- }
- $this->_headerCount = 0;
- $this->_responseHeaders = [];
- $this->_responseBody = curl_exec($this->_ch);
- $err = curl_errno($this->_ch);
- if ($err) {
- $this->doError(curl_error($this->_ch));
- }
- curl_close($this->_ch);
- }
- /**
- * Throw error exception
- *
- * @param string $string
- * @return void
- * @throws \Exception
- */
- public function doError($string)
- {
- throw new \Exception($string);
- }
- /**
- * Parse headers - CURL callback function
- *
- * @param resource $ch curl handle, not needed
- * @param string $data
- * @return int
- * @throws \Exception
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
- */
- protected function parseHeaders($ch, $data)
- {
- if ($this->_headerCount == 0) {
- $line = explode(" ", trim($data), 3);
- if (count($line) < 2) {
- $this->doError("Invalid response line returned from server: " . $data);
- }
- $this->_responseStatus = (int)$line[1];
- } else {
- $name = $value = '';
- $out = explode(": ", trim($data), 2);
- if (count($out) == 2) {
- $name = $out[0];
- $value = $out[1];
- }
- if (strlen($name)) {
- if ("Set-Cookie" == $name) {
- if (!isset($this->_responseHeaders[$name])) {
- $this->_responseHeaders[$name] = [];
- }
- $this->_responseHeaders[$name][] = $value;
- } else {
- $this->_responseHeaders[$name] = $value;
- }
- }
- }
- $this->_headerCount++;
- return strlen($data);
- }
- /**
- * Set curl option directly
- *
- * @param string $name
- * @param string $value
- * @return void
- */
- protected function curlOption($name, $value)
- {
- curl_setopt($this->_ch, $name, $value);
- }
- /**
- * Set curl options array directly
- *
- * @param array $arr
- * @return void
- */
- protected function curlOptions($arr)
- {
- curl_setopt_array($this->_ch, $arr);
- }
- /**
- * Set CURL options overrides array
- *
- * @param array $arr
- * @return void
- */
- public function setOptions($arr)
- {
- $this->_curlUserOptions = $arr;
- }
- /**
- * Set curl option
- *
- * @param string $name
- * @param string $value
- * @return void
- */
- public function setOption($name, $value)
- {
- $this->_curlUserOptions[$name] = $value;
- }
- }
|