PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/internal/Magento/Framework/HTTP/Adapter/Curl.php

https://gitlab.com/crazybutterfly815/magento2
PHP | 294 lines | 140 code | 33 blank | 121 comment | 14 complexity | b828d6ca330c3b7d1e4314aa35e39647 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. // @codingStandardsIgnoreFile
  7. /**
  8. * HTTP CURL Adapter
  9. *
  10. * @author Magento Core Team <core@magentocommerce.com>
  11. */
  12. namespace Magento\Framework\HTTP\Adapter;
  13. class Curl implements \Zend_Http_Client_Adapter_Interface
  14. {
  15. /**
  16. * Parameters array
  17. *
  18. * @var array
  19. */
  20. protected $_config = [];
  21. /**
  22. * Curl handle
  23. *
  24. * @var resource
  25. */
  26. protected $_resource;
  27. /**
  28. * Allow parameters
  29. *
  30. * @var array
  31. */
  32. protected $_allowedParams = [
  33. 'timeout' => CURLOPT_TIMEOUT,
  34. 'maxredirects' => CURLOPT_MAXREDIRS,
  35. 'proxy' => CURLOPT_PROXY,
  36. 'ssl_cert' => CURLOPT_SSLCERT,
  37. 'userpwd' => CURLOPT_USERPWD,
  38. 'useragent' => CURLOPT_USERAGENT,
  39. 'referer' => CURLOPT_REFERER
  40. ];
  41. /**
  42. * Array of CURL options
  43. *
  44. * @var array
  45. */
  46. protected $_options = [];
  47. /**
  48. * Apply current configuration array to transport resource
  49. *
  50. * @return \Magento\Framework\HTTP\Adapter\Curl
  51. * @SuppressWarnings(PHPMD.NPathComplexity)
  52. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  53. */
  54. protected function _applyConfig()
  55. {
  56. // apply additional options to cURL
  57. foreach ($this->_options as $option => $value) {
  58. curl_setopt($this->_getResource(), $option, $value);
  59. }
  60. if (empty($this->_config)) {
  61. return $this;
  62. }
  63. $verifyPeer = isset($this->_config['verifypeer']) ? $this->_config['verifypeer'] : true;
  64. curl_setopt($this->_getResource(), CURLOPT_SSL_VERIFYPEER, $verifyPeer);
  65. $verifyHost = isset($this->_config['verifyhost']) ? $this->_config['verifyhost'] : 2;
  66. curl_setopt($this->_getResource(), CURLOPT_SSL_VERIFYHOST, $verifyHost);
  67. foreach ($this->_config as $param => $curlOption) {
  68. if (array_key_exists($param, $this->_allowedParams)) {
  69. curl_setopt($this->_getResource(), $this->_allowedParams[$param], $this->_config[$param]);
  70. }
  71. }
  72. return $this;
  73. }
  74. /**
  75. * Set array of additional cURL options
  76. *
  77. * @param array $options
  78. * @return $this
  79. */
  80. public function setOptions(array $options = [])
  81. {
  82. $this->_options = $options;
  83. return $this;
  84. }
  85. /**
  86. * Add additional option to cURL
  87. *
  88. * @param int $option the CURLOPT_* constants
  89. * @param mixed $value
  90. * @return $this
  91. */
  92. public function addOption($option, $value)
  93. {
  94. $this->_options[$option] = $value;
  95. return $this;
  96. }
  97. /**
  98. * Set the configuration array for the adapter
  99. *
  100. * @param array $config
  101. * @return $this
  102. */
  103. public function setConfig($config = [])
  104. {
  105. $this->_config = $config;
  106. return $this;
  107. }
  108. /**
  109. * Connect to the remote server
  110. *
  111. * @param string $host
  112. * @param int $port
  113. * @param boolean $secure
  114. * @return $this
  115. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  116. */
  117. public function connect($host, $port = 80, $secure = false)
  118. {
  119. return $this->_applyConfig();
  120. }
  121. /**
  122. * Send request to the remote server
  123. *
  124. * @param string $method
  125. * @param \Zend_Uri_Http|string $url
  126. * @param string $http_ver
  127. * @param array $headers
  128. * @param string $body
  129. * @return string Request as text
  130. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  131. */
  132. public function write($method, $url, $http_ver = '1.1', $headers = [], $body = '')
  133. {
  134. if ($url instanceof \Zend_Uri_Http) {
  135. $url = $url->getUri();
  136. }
  137. $this->_applyConfig();
  138. // set url to post to
  139. curl_setopt($this->_getResource(), CURLOPT_URL, $url);
  140. curl_setopt($this->_getResource(), CURLOPT_RETURNTRANSFER, true);
  141. if ($method == \Zend_Http_Client::POST) {
  142. curl_setopt($this->_getResource(), CURLOPT_POST, true);
  143. curl_setopt($this->_getResource(), CURLOPT_POSTFIELDS, $body);
  144. } elseif ($method == \Zend_Http_Client::GET) {
  145. curl_setopt($this->_getResource(), CURLOPT_HTTPGET, true);
  146. }
  147. if (is_array($headers)) {
  148. curl_setopt($this->_getResource(), CURLOPT_HTTPHEADER, $headers);
  149. }
  150. /**
  151. * @internal Curl options setter have to be re-factored
  152. */
  153. $header = isset($this->_config['header']) ? $this->_config['header'] : true;
  154. curl_setopt($this->_getResource(), CURLOPT_HEADER, $header);
  155. return $body;
  156. }
  157. /**
  158. * Read response from server
  159. *
  160. * @return string
  161. */
  162. public function read()
  163. {
  164. $response = curl_exec($this->_getResource());
  165. // Remove 100 and 101 responses headers
  166. while (\Zend_Http_Response::extractCode($response) == 100
  167. || \Zend_Http_Response::extractCode($response) == 101
  168. ) {
  169. $response = preg_split('/^\r?$/m', $response, 2);
  170. $response = trim($response[1]);
  171. }
  172. // CUrl will handle chunked data but leave the header.
  173. $response = preg_replace('/Transfer-Encoding:\s+chunked\r?\n/i', '', $response);
  174. return $response;
  175. }
  176. /**
  177. * Close the connection to the server
  178. *
  179. * @return $this
  180. */
  181. public function close()
  182. {
  183. curl_close($this->_getResource());
  184. $this->_resource = null;
  185. return $this;
  186. }
  187. /**
  188. * Returns a cURL handle on success
  189. *
  190. * @return resource
  191. */
  192. protected function _getResource()
  193. {
  194. if (is_null($this->_resource)) {
  195. $this->_resource = curl_init();
  196. }
  197. return $this->_resource;
  198. }
  199. /**
  200. * Get last error number
  201. *
  202. * @return int
  203. */
  204. public function getErrno()
  205. {
  206. return curl_errno($this->_getResource());
  207. }
  208. /**
  209. * Get string with last error for the current session
  210. *
  211. * @return string
  212. */
  213. public function getError()
  214. {
  215. return curl_error($this->_getResource());
  216. }
  217. /**
  218. * Get information regarding a specific transfer
  219. *
  220. * @param int $opt CURLINFO option
  221. * @return mixed
  222. */
  223. public function getInfo($opt = 0)
  224. {
  225. return curl_getinfo($this->_getResource(), $opt);
  226. }
  227. /**
  228. * curl_multi_* requests support
  229. *
  230. * @param array $urls
  231. * @param array $options
  232. * @return array
  233. */
  234. public function multiRequest($urls, $options = [])
  235. {
  236. $handles = [];
  237. $result = [];
  238. $multihandle = curl_multi_init();
  239. foreach ($urls as $key => $url) {
  240. $handles[$key] = curl_init();
  241. curl_setopt($handles[$key], CURLOPT_URL, $url);
  242. curl_setopt($handles[$key], CURLOPT_HEADER, 0);
  243. curl_setopt($handles[$key], CURLOPT_RETURNTRANSFER, 1);
  244. if (!empty($options)) {
  245. curl_setopt_array($handles[$key], $options);
  246. }
  247. curl_multi_add_handle($multihandle, $handles[$key]);
  248. }
  249. $process = null;
  250. do {
  251. curl_multi_exec($multihandle, $process);
  252. usleep(100);
  253. } while ($process > 0);
  254. foreach ($handles as $key => $handle) {
  255. $result[$key] = curl_multi_getcontent($handle);
  256. curl_multi_remove_handle($multihandle, $handle);
  257. }
  258. curl_multi_close($multihandle);
  259. return $result;
  260. }
  261. }