Added HttpClient
This commit is contained in:
parent
dbf0109700
commit
4f9f78e21d
7 changed files with 390 additions and 1 deletions
|
@ -268,6 +268,11 @@
|
|||
*/
|
||||
const MissingDependencyException = -1751;
|
||||
|
||||
/**
|
||||
* @see HttpException
|
||||
*/
|
||||
const HttpException = -1752;
|
||||
|
||||
/**
|
||||
* All the exception codes from NCC
|
||||
*/
|
||||
|
@ -322,6 +327,7 @@
|
|||
self::ComposerNotAvailableException,
|
||||
self::ComposerException,
|
||||
self::UserAbortedOperationException,
|
||||
self::MissingDependencyException
|
||||
self::MissingDependencyException,
|
||||
self::HttpException
|
||||
];
|
||||
}
|
11
src/ncc/Abstracts/HttpRequestType.php
Normal file
11
src/ncc/Abstracts/HttpRequestType.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Abstracts;
|
||||
|
||||
abstract class HttpRequestType
|
||||
{
|
||||
const GET = 'GET';
|
||||
const POST = 'POST';
|
||||
const PUT = 'PUT';
|
||||
const DELETE = 'DELETE';
|
||||
}
|
104
src/ncc/Abstracts/HttpStatusCodes.php
Normal file
104
src/ncc/Abstracts/HttpStatusCodes.php
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Abstracts;
|
||||
|
||||
abstract class HttpStatusCodes
|
||||
{
|
||||
const OK = 200;
|
||||
const CREATED = 201;
|
||||
const ACCEPTED = 202;
|
||||
const NO_CONTENT = 204;
|
||||
const MOVED_PERMANENTLY = 301;
|
||||
const FOUND = 302;
|
||||
const SEE_OTHER = 303;
|
||||
const NOT_MODIFIED = 304;
|
||||
const TEMPORARY_REDIRECT = 307;
|
||||
const PERMANENT_REDIRECT = 308;
|
||||
const BAD_REQUEST = 400;
|
||||
const UNAUTHORIZED = 401;
|
||||
const FORBIDDEN = 403;
|
||||
const NOT_FOUND = 404;
|
||||
const METHOD_NOT_ALLOWED = 405;
|
||||
const NOT_ACCEPTABLE = 406;
|
||||
const REQUEST_TIMEOUT = 408;
|
||||
const CONFLICT = 409;
|
||||
const GONE = 410;
|
||||
const LENGTH_REQUIRED = 411;
|
||||
const PRECONDITION_FAILED = 412;
|
||||
const PAYLOAD_TOO_LARGE = 413;
|
||||
const URI_TOO_LONG = 414;
|
||||
const UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
const RANGE_NOT_SATISFIABLE = 416;
|
||||
const EXPECTATION_FAILED = 417;
|
||||
const IM_A_TEAPOT = 418;
|
||||
const MISDIRECTED_REQUEST = 421;
|
||||
const UNPROCESSABLE_ENTITY = 422;
|
||||
const LOCKED = 423;
|
||||
const FAILED_DEPENDENCY = 424;
|
||||
const UPGRADE_REQUIRED = 426;
|
||||
const PRECONDITION_REQUIRED = 428;
|
||||
const TOO_MANY_REQUESTS = 429;
|
||||
const REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
|
||||
const UNAVAILABLE_FOR_LEGAL_REASONS = 451;
|
||||
const INTERNAL_SERVER_ERROR = 500;
|
||||
const NOT_IMPLEMENTED = 501;
|
||||
const BAD_GATEWAY = 502;
|
||||
const SERVICE_UNAVAILABLE = 503;
|
||||
const GATEWAY_TIMEOUT = 504;
|
||||
const HTTP_VERSION_NOT_SUPPORTED = 505;
|
||||
const VARIANT_ALSO_NEGOTIATES = 506;
|
||||
const INSUFFICIENT_STORAGE = 507;
|
||||
const LOOP_DETECTED = 508;
|
||||
const NOT_EXTENDED = 510;
|
||||
const NETWORK_AUTHENTICATION_REQUIRED = 511;
|
||||
|
||||
const All = [
|
||||
self::OK,
|
||||
self::CREATED,
|
||||
self::ACCEPTED,
|
||||
self::NO_CONTENT,
|
||||
self::MOVED_PERMANENTLY,
|
||||
self::FOUND,
|
||||
self::SEE_OTHER,
|
||||
self::NOT_MODIFIED,
|
||||
self::TEMPORARY_REDIRECT,
|
||||
self::PERMANENT_REDIRECT,
|
||||
self::BAD_REQUEST,
|
||||
self::UNAUTHORIZED,
|
||||
self::FORBIDDEN,
|
||||
self::NOT_FOUND,
|
||||
self::METHOD_NOT_ALLOWED,
|
||||
self::NOT_ACCEPTABLE,
|
||||
self::REQUEST_TIMEOUT,
|
||||
self::CONFLICT,
|
||||
self::GONE,
|
||||
self::LENGTH_REQUIRED,
|
||||
self::PRECONDITION_FAILED,
|
||||
self::PAYLOAD_TOO_LARGE,
|
||||
self::URI_TOO_LONG,
|
||||
self::UNSUPPORTED_MEDIA_TYPE,
|
||||
self::RANGE_NOT_SATISFIABLE,
|
||||
self::EXPECTATION_FAILED,
|
||||
self::IM_A_TEAPOT,
|
||||
self::MISDIRECTED_REQUEST,
|
||||
self::UNPROCESSABLE_ENTITY,
|
||||
self::LOCKED,
|
||||
self::FAILED_DEPENDENCY,
|
||||
self::UPGRADE_REQUIRED,
|
||||
self::PRECONDITION_REQUIRED,
|
||||
self::TOO_MANY_REQUESTS,
|
||||
self::REQUEST_HEADER_FIELDS_TOO_LARGE,
|
||||
self::UNAVAILABLE_FOR_LEGAL_REASONS,
|
||||
self::INTERNAL_SERVER_ERROR,
|
||||
self::NOT_IMPLEMENTED,
|
||||
self::BAD_GATEWAY,
|
||||
self::SERVICE_UNAVAILABLE,
|
||||
self::GATEWAY_TIMEOUT,
|
||||
self::HTTP_VERSION_NOT_SUPPORTED,
|
||||
self::VARIANT_ALSO_NEGOTIATES,
|
||||
self::INSUFFICIENT_STORAGE,
|
||||
self::LOOP_DETECTED,
|
||||
self::NOT_EXTENDED,
|
||||
self::NETWORK_AUTHENTICATION_REQUIRED
|
||||
];
|
||||
}
|
20
src/ncc/Exceptions/HttpException.php
Normal file
20
src/ncc/Exceptions/HttpException.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class HttpException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::HttpException, $previous);
|
||||
$this->message = $message;
|
||||
}
|
||||
}
|
87
src/ncc/Objects/HttpRequest.php
Normal file
87
src/ncc/Objects/HttpRequest.php
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects;
|
||||
|
||||
use ncc\Abstracts\HttpRequestType;
|
||||
|
||||
class HttpRequest
|
||||
{
|
||||
/**
|
||||
* The HTTP request type.
|
||||
*
|
||||
* @var string|HttpRequestType
|
||||
*/
|
||||
public $Type;
|
||||
|
||||
/**
|
||||
* The URL to send the request to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Url;
|
||||
|
||||
/**
|
||||
* The headers to send with the request.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $Headers;
|
||||
|
||||
/**
|
||||
* The body to send with the request.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Body;
|
||||
|
||||
/**
|
||||
* The authentication username or password to send with the request.
|
||||
*
|
||||
* @var array|string
|
||||
*/
|
||||
public $Authentication;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->Type = HttpRequestType::GET;
|
||||
$this->Body = null;
|
||||
$this->Headers = [
|
||||
'User-Agent: ncc/1.0'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'type' => $this->Type,
|
||||
'url' => $this->Url,
|
||||
'headers' => $this->Headers,
|
||||
'body' => $this->Body,
|
||||
'authentication' => $this->Authentication
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new HttpRequest object from an array representation.
|
||||
*
|
||||
* @param array $data
|
||||
* @return static
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$request = new self();
|
||||
$request->Type = $data['type'];
|
||||
$request->Url = $data['url'];
|
||||
$request->Headers = $data['headers'];
|
||||
$request->Body = $data['body'];
|
||||
$request->Authentication = $data['authentication'];
|
||||
return $request;
|
||||
}
|
||||
}
|
50
src/ncc/Objects/HttpResponse.php
Normal file
50
src/ncc/Objects/HttpResponse.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects;
|
||||
|
||||
class HttpResponse
|
||||
{
|
||||
/**
|
||||
* The HTTP status code.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $StatusCode;
|
||||
|
||||
/**
|
||||
* The headers returned by the server.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $Headers;
|
||||
|
||||
/**
|
||||
* The body returned by the server.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Body;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->StatusCode = 0;
|
||||
$this->Headers = [];
|
||||
$this->Body = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'status_code' => $this->StatusCode,
|
||||
'headers' => $this->Headers,
|
||||
'body' => $this->Body
|
||||
];
|
||||
}
|
||||
}
|
111
src/ncc/Utilities/HttpClient.php
Normal file
111
src/ncc/Utilities/HttpClient.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Utilities;
|
||||
|
||||
use ncc\Abstracts\HttpRequestType;
|
||||
use ncc\Exceptions\HttpException;
|
||||
use ncc\Objects\HttpRequest;
|
||||
use ncc\Objects\HttpResponse;
|
||||
|
||||
class HttpClient
|
||||
{
|
||||
/**
|
||||
* Creates a new HTTP request and returns the response.
|
||||
*
|
||||
* @param HttpRequest $httpRequest
|
||||
* @return HttpResponse
|
||||
* @throws HttpException
|
||||
*/
|
||||
public static function request(HttpRequest $httpRequest): HttpResponse
|
||||
{
|
||||
$curl = curl_init();
|
||||
|
||||
curl_setopt($curl, CURLOPT_URL, $httpRequest->Url);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_HEADER, true);
|
||||
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
|
||||
switch($httpRequest->Type)
|
||||
{
|
||||
case HttpRequestType::GET:
|
||||
curl_setopt($curl, CURLOPT_HTTPGET, true);
|
||||
break;
|
||||
|
||||
case HttpRequestType::POST:
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $httpRequest->Body);
|
||||
break;
|
||||
|
||||
case HttpRequestType::PUT:
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $httpRequest->Body);
|
||||
break;
|
||||
|
||||
case HttpRequestType::DELETE:
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new HttpException(sprintf('Invalid HTTP request type: %s', $httpRequest->Type));
|
||||
}
|
||||
|
||||
if (is_array($httpRequest->Authentication))
|
||||
{
|
||||
curl_setopt($curl, CURLOPT_USERPWD, $httpRequest->Authentication[0] . ':' . $httpRequest->Authentication[1]);
|
||||
}
|
||||
else if (is_string($httpRequest->Authentication))
|
||||
{
|
||||
curl_setopt($curl, CURLOPT_USERPWD, $httpRequest->Authentication);
|
||||
}
|
||||
|
||||
if (count($httpRequest->Headers) > 0)
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $httpRequest->Headers);
|
||||
|
||||
$response = curl_exec($curl);
|
||||
|
||||
if ($response === false)
|
||||
{
|
||||
$error = curl_error($curl);
|
||||
curl_close($curl);
|
||||
throw new HttpException($error);
|
||||
}
|
||||
|
||||
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
|
||||
$headers = substr($response, 0, $headerSize);
|
||||
$body = substr($response, $headerSize);
|
||||
|
||||
$httpResponse = new HttpResponse();
|
||||
$httpResponse->StatusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
$httpResponse->Headers = self::parseHeaders($headers);
|
||||
$httpResponse->Body = $body;
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
return $httpResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the return headers of a cURL request and parses them into an array.
|
||||
*
|
||||
* @param string $headers
|
||||
* @return array
|
||||
*/
|
||||
private static function parseHeaders(string $headers): array
|
||||
{
|
||||
$headers = explode("\r", $headers);
|
||||
$headers = array_filter($headers, function ($header)
|
||||
{
|
||||
return !empty($header);
|
||||
});
|
||||
$headers = array_map(function ($header) {
|
||||
return explode(':', $header, 2);
|
||||
}, $headers);
|
||||
|
||||
return array_combine(array_map(function ($header) { return strtolower($header[0]); }, $headers),
|
||||
array_map(function ($header) { return trim($header[1]); }, $headers)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue