first commit

This commit is contained in:
2026-03-05 13:07:40 +01:00
commit 64ba0721ee
25709 changed files with 4691006 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
{
"name": "wpdesk\/wp-http-client",
"authors": [
{
"name": "Krzysiek",
"email": "krzysiek@wpdesk.pl"
}
],
"require": {
"php": ">=5.5",
"ext-curl": "*",
"ext-json": "*"
},
"require-dev": {
"phpunit\/phpunit": "<7",
"wp-coding-standards\/wpcs": "^0.14.1",
"squizlabs\/php_codesniffer": "^3.0.2",
"mockery\/mockery": "*",
"10up\/wp_mock": "*"
},
"autoload": {
"psr-4": {
"DPDVendor\\WPDesk\\HttpClient\\": "src\/"
}
},
"autoload-dev": {},
"scripts": {
"phpunit-unit": "phpunit --configuration phpunit-unit.xml --coverage-text --colors=never",
"phpunit-unit-fast": "phpunit --configuration phpunit-unit.xml --no-coverage",
"phpunit-integration": "phpunit --configuration phpunit-integration.xml --coverage-text --colors=never",
"phpunit-integration-fast": "phpunit --configuration phpunit-integration.xml --no-coverage"
}
}

View File

@@ -0,0 +1,196 @@
<?php
namespace DPDVendor\WPDesk\HttpClient\Curl;
use DPDVendor\WPDesk\HttpClient\HttpClient;
use DPDVendor\WPDesk\HttpClient\HttpClientResponse;
use DPDVendor\WPDesk\HttpClient\HttpClientRequestException;
class CurlClient implements \DPDVendor\WPDesk\HttpClient\HttpClient
{
/** @var resource */
private $curlResource;
/** @var string|null|boolean */
private $rawResponse;
/** @var int */
private $httpResponseCode;
/** @var array */
private $headers = array();
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
*
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function get($url, $body, array $headers, $timeOut)
{
return $this->send($url, 'GET', $body, $headers, $timeOut);
}
/**
* @param string $url
* @param string $method
* @param string $body
* @param array $headers
* @param int $timeOut
*
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function send($url, $method, $body, array $headers, $timeOut)
{
$this->initResource();
try {
$this->prepareConnection($url, $method, $body, $headers, $timeOut);
$this->sendRequest();
$this->throwExceptionIfError();
$this->closeConnection();
return $this->prepareResponse();
} catch (\Exception $e) {
$this->closeConnection();
if ($e instanceof \DPDVendor\WPDesk\HttpClient\HttpClientRequestException) {
throw $e;
}
throw \DPDVendor\WPDesk\HttpClient\Curl\CurlExceptionFactory::createDefaultException($e->getMessage(), $e->getCode(), $e);
}
}
private function initResource()
{
$this->curlResource = \curl_init();
}
/**
* Opens a new curl connection.
*
* @param string $url The endpoint to send the request to.
* @param string $method The request method.
* @param string $body The body of the request.
* @param array $headers The request headers.
* @param int $timeOut The timeout in seconds for the request.
*/
private function prepareConnection($url, $method, $body, array $headers, $timeOut)
{
$options = [
\CURLOPT_CUSTOMREQUEST => $method,
\CURLOPT_HTTPHEADER => $this->compileRequestHeaders($headers),
\CURLOPT_URL => $url,
\CURLOPT_CONNECTTIMEOUT => 25,
\CURLOPT_TIMEOUT => $timeOut,
\CURLOPT_RETURNTRANSFER => \true,
// Return response as string
\CURLOPT_HEADER => \false,
// Enable header processing
\CURLOPT_SSL_VERIFYHOST => 2,
\CURLOPT_SSL_VERIFYPEER => \true,
\CURLOPT_HEADERFUNCTION => function ($curl, $header) {
$len = \strlen($header);
$this->headers[] = \trim($header);
return $len;
},
];
if (!empty($body)) {
$options[\CURLOPT_POSTFIELDS] = $body;
}
\curl_setopt_array($this->curlResource, $options);
}
/**
* Compiles the request headers into a curl-friendly format.
*
* @param array $headers The request headers.
*
* @return array
*/
private function compileRequestHeaders(array $headers)
{
$return = [];
foreach ($headers as $key => $value) {
$return[] = $key . ': ' . $value;
}
return $return;
}
/**
* Send the request and get the raw response from curl
*/
private function sendRequest()
{
$this->rawResponse = \curl_exec($this->curlResource);
$this->httpResponseCode = $this->getHttpResponseCode();
}
/** @return int */
private function getHttpResponseCode()
{
return \intval(\curl_getinfo($this->curlResource, \CURLINFO_HTTP_CODE));
}
private function throwExceptionIfError()
{
$errorNumber = \curl_errno($this->curlResource);
if ($errorNumber === 0) {
return;
}
$errorMessage = \curl_error($this->curlResource);
throw \DPDVendor\WPDesk\HttpClient\Curl\CurlExceptionFactory::createCurlException($errorMessage, $errorNumber);
}
/**
* Closes an existing curl connection
*/
private function closeConnection()
{
\curl_close($this->curlResource);
$this->curlResource = null;
}
private function prepareResponse()
{
list($rawHeaders, $rawBody) = $this->extractResponseHeadersAndBody();
return new \DPDVendor\WPDesk\HttpClient\HttpClientResponse($rawHeaders, $rawBody, $this->httpResponseCode);
}
/**
* Extracts the headers and the body into a two-part array
*
* @return array
*/
private function extractResponseHeadersAndBody()
{
$rawBody = \trim($this->rawResponse);
$rawHeaders = \trim(\implode("\r\n", $this->headers));
return [$rawHeaders, $rawBody];
}
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
*
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function post($url, $body, array $headers, $timeOut)
{
return $this->send($url, 'POST', $body, $headers, $timeOut);
}
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
*
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function delete($url, $body, array $headers, $timeOut)
{
return $this->send($url, 'DELETE', $body, $headers, $timeOut);
}
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
*
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function put($url, $body, array $headers, $timeOut)
{
return $this->send($url, 'PUT', $body, $headers, $timeOut);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace DPDVendor\WPDesk\HttpClient\Curl;
use DPDVendor\WPDesk\HttpClient\Curl\Exception\CurlException;
use DPDVendor\WPDesk\HttpClient\Curl\Exception\CurlTimedOutException;
class CurlExceptionFactory
{
/**
* Convert curl code to appropriate exception class.
*
* @param int $curlCode Code from https://curl.haxx.se/libcurl/c/libcurl-errors.html
* @param string $curlMessage
* @return CurlException
*/
public static function createCurlException($curlCode, $curlMessage)
{
switch ($curlCode) {
case \CURLE_OPERATION_TIMEDOUT:
return new \DPDVendor\WPDesk\HttpClient\Curl\Exception\CurlTimedOutException($curlMessage, $curlCode);
default:
return self::createDefaultException($curlMessage, $curlCode);
}
}
/**
* Creates default Curl exception
*
* @param $code
* @param $message
* @param \Exception|null $prev
* @return CurlException
*/
public static function createDefaultException($code, $message, \Exception $prev = null)
{
return new \DPDVendor\WPDesk\HttpClient\Curl\Exception\CurlException('Default exception: ' . $message, $code, $prev);
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace DPDVendor\WPDesk\HttpClient\Curl\Exception;
use DPDVendor\WPDesk\HttpClient\HttpClientRequestException;
/**
* Base class for all curl exceptions.
*
* @package WPDesk\HttpClient\Curl\Exception
*/
class CurlException extends \RuntimeException implements \DPDVendor\WPDesk\HttpClient\HttpClientRequestException
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace DPDVendor\WPDesk\HttpClient\Curl\Exception;
class CurlTimedOutException extends \DPDVendor\WPDesk\HttpClient\Curl\Exception\CurlException
{
}

View File

@@ -0,0 +1,53 @@
<?php
namespace DPDVendor\WPDesk\HttpClient;
interface HttpClient
{
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function put($url, $body, array $headers, $timeOut);
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function get($url, $body, array $headers, $timeOut);
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function post($url, $body, array $headers, $timeOut);
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function delete($url, $body, array $headers, $timeOut);
/**
* @param string $url
* @param string $method
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function send($url, $method, $body, array $headers, $timeOut);
}

View File

@@ -0,0 +1,16 @@
<?php
namespace DPDVendor\WPDesk\HttpClient;
class HttpClientFactory
{
/**
* @param HttpClientOptions $options
* @return HttpClient
*/
public function createClient(\DPDVendor\WPDesk\HttpClient\HttpClientOptions $options)
{
$className = $options->getHttpClientClass();
return new $className();
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace DPDVendor\WPDesk\HttpClient;
interface HttpClientOptions
{
/**
* @return string
*/
public function getHttpClientClass();
}

View File

@@ -0,0 +1,12 @@
<?php
namespace DPDVendor\WPDesk\HttpClient;
/**
* Interface for all exceptions that can be thrown by HttpClient
*
* @package WPDesk\HttpClient
*/
interface HttpClientRequestException
{
}

View File

@@ -0,0 +1,52 @@
<?php
namespace DPDVendor\WPDesk\HttpClient;
class HttpClientResponse
{
/** @var string */
private $headers;
/** @var string */
private $body;
/** @var int */
private $code;
/**
* HttpClientResponse constructor.
* @param string $headers
* @param string $body
* @param int $code
*/
public function __construct($headers, $body, $code)
{
$this->headers = $headers;
$this->body = $body;
$this->code = $code;
}
/**
* @return array
*/
public function getHeaders()
{
$headers = array();
$headers_rows = \explode("\r\n", $this->headers);
foreach ($headers_rows as $headers_row) {
$header = \explode(": ", $headers_row);
$headers[$header[0]] = isset($header[1]) ? $header[1] : $header[0];
}
return $headers;
}
/**
* @return string
*/
public function getBody()
{
return $this->body;
}
/**
* @return int
*/
public function getResponseCode()
{
return $this->code;
}
}