diff --git a/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/ElasticsearchVersionChecker.php b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/ElasticsearchVersionChecker.php index 5e006a0aa1197..5432ed7abeb29 100644 --- a/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/ElasticsearchVersionChecker.php +++ b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/Model/ElasticsearchVersionChecker.php @@ -1,13 +1,13 @@ deploymentConfig = $deploymentConfig ?? \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->get(\Magento\Framework\App\DeploymentConfig::class); - $this->curl = new Curl(); + $this->curl = new \Magento\Framework\HTTP\Client\Curl(); $this->curl->setCredentials( $this->deploymentConfig->get(self::CONFIG_PATH_USER), $this->deploymentConfig->get(self::CONFIG_PATH_PASSWORD) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Helper/Curl.php b/dev/tests/integration/framework/Magento/TestFramework/Helper/Curl.php index 62b753cf5d344..46766477e359d 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Helper/Curl.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Helper/Curl.php @@ -1,30 +1,18 @@ makeRequest("DELETE", $uri); - } } diff --git a/lib/internal/Magento/Framework/HTTP/Client/Curl.php b/lib/internal/Magento/Framework/HTTP/Client/Curl.php index 5379d481289f5..4a342ceab7169 100644 --- a/lib/internal/Magento/Framework/HTTP/Client/Curl.php +++ b/lib/internal/Magento/Framework/HTTP/Client/Curl.php @@ -1,18 +1,30 @@ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * @api */ class Curl implements \Magento\Framework\HTTP\ClientInterface { + /** + * @url https://www.rfc-editor.org/rfc/rfc9110.html + */ + private const HTTP_METHODS_WITH_PAYLOAD = [ + 'POST', + 'PUT', + 'PATCH', + 'OPTIONS' + ]; + /** * Max supported protocol by curl CURL_SSLVERSION_TLSv1_2 * @var int @@ -26,7 +38,6 @@ class Curl implements \Magento\Framework\HTTP\ClientInterface protected $_host = 'localhost'; /** - * Port * @var int */ protected $_port = 80; @@ -56,19 +67,16 @@ class Curl implements \Magento\Framework\HTTP\ClientInterface protected $_cookies = []; /** - * Response headers * @var array */ protected $_responseHeaders = []; /** - * Response body * @var string */ protected $_responseBody = ''; /** - * Response status * @var int */ protected $_responseStatus = 0; @@ -223,6 +231,8 @@ public function removeCookies() * * @param string $uri uri relative to host, ex. "/index.php" * @return void + * + * @url https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.1 */ public function get($uri) { @@ -239,13 +249,108 @@ public function get($uri) * @param array|string $params * @return void * - * @see \Magento\Framework\HTTP\Client#post($uri, $params) + * @see \Magento\Framework\HTTP\Client::post($uri, $params) + * @url https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.3 */ public function post($uri, $params) { $this->makeRequest("POST", $uri, $params); } + /** + * Make PUT request + * + * @param string $uri + * @param array|string $params + * @return void + * + * @url https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.4 + */ + public function put(string $uri, string|array $params): void + { + $this->makeRequest("PUT", $uri, $params); + } + + /** + * Make DELETE request + * + * @param string $uri + * @return void + * + * @url https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.5 + */ + public function delete(string $uri, array|string $params = []): void + { + $this->makeRequest("DELETE", $uri); + } + + /** + * Make PATCH request + * + * @param string $uri + * @param array|string $params + * @return void + * + * @url https://www.rfc-editor.org/info/rfc5789 + */ + public function patch(string $uri, array|string $params): void + { + $this->makeRequest("PATCH", $uri, $params); + } + + /** + * Make OPTIONS request + * + * @param string $uri + * @param array|string $params + * @return void + * + * @url https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.7 + */ + public function options(string $uri, array|string $params = []): void + { + $this->makeRequest("OPTIONS", $uri, $params); + } + + /** + * Make HEAD request + * + * @param string $uri + * @return void + * + * @url https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.2 + */ + public function head(string $uri): void + { + $this->makeRequest("HEAD", $uri); + } + + /** + * Make TRACE request + * + * @param string $uri + * @return void + * + * @url https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.8 + */ + public function trace(string $uri): void + { + $this->makeRequest("TRACE", $uri); + } + + /** + * Make CONNECT request + * + * @param string $uri + * @return void + * + * @url https://www.rfc-editor.org/rfc/rfc9110.html#section-9.3.6 + */ + public function connect(string $uri): void + { + $this->makeRequest("CONNECT", $uri); + } + /** * Get response headers * @@ -278,7 +383,7 @@ public function getCookies() } $out = []; foreach ($this->_responseHeaders['Set-Cookie'] as $row) { - $values = explode("; ", $row); + $values = explode("; ", $row ?? ''); $c = count($values); if (!$c) { continue; @@ -305,7 +410,7 @@ public function getCookiesFull() } $out = []; foreach ($this->_responseHeaders['Set-Cookie'] as $row) { - $values = explode("; ", $row); + $values = explode("; ", $row ?? ''); $c = count($values); if (!$c) { continue; @@ -322,7 +427,7 @@ public function getCookiesFull() } for ($i = 0; $i < $c; $i++) { list($subkey, $val) = explode("=", $values[$i]); - $out[trim($key)][trim($subkey)] = trim($val); + $out[trim($key)][trim($subkey)] = $val !== null ? trim($val) : ''; } } return $out; @@ -359,13 +464,24 @@ protected function makeRequest($method, $uri, $params = []) $this->_ch = curl_init(); $this->curlOption(CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | CURLPROTO_FTPS); $this->curlOption(CURLOPT_URL, $uri); - if ($method == 'POST') { - $this->curlOption(CURLOPT_POST, 1); + + if (in_array($method, self::HTTP_METHODS_WITH_PAYLOAD)) { $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); + } + + switch ($method) { + case 'POST': + $this->curlOption(CURLOPT_POST, 1); + break; + case 'PUT': + $this->curlOption(CURLOPT_PUT, 1); + break; + case "GET": + $this->curlOption(CURLOPT_HTTPGET, 1); + break; + default: + $this->curlOption(CURLOPT_CUSTOMREQUEST, $method); + break; } if (count($this->_headers)) { @@ -438,6 +554,7 @@ public function doError($string) */ protected function parseHeaders($ch, $data) { + $data = $data !== null ? $data : ''; if ($this->_headerCount == 0) { $line = explode(" ", trim($data), 3); if (count($line) < 2) { @@ -469,7 +586,7 @@ protected function parseHeaders($ch, $data) * Set curl option directly * * @param string $name - * @param string $value + * @param mixed $value * @return void */ protected function curlOption($name, $value) @@ -503,7 +620,7 @@ public function setOptions($arr) * Set curl option * * @param string $name - * @param string $value + * @param mixed $value * @return void */ public function setOption($name, $value)