init commit
All checks were successful
build-api-image / build (push) Successful in 51s

This commit is contained in:
Antonio Lopes dos Santos
2026-08-04 16:52:02 -03:00
commit afec302c3e
11594 changed files with 1636728 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
<?php
class DefaultHttpClient implements HttpClient{
/**
* @param HttpRequest $request
* @param int $timeout
* @return HttpResponse
* @throws RuntimeException
*/
public function makeRequest($request, $timeout=null){
$response = null;
$httpSocket=null;
try{
$httpString = $this->parseRequest($request);
$httpSocket = $this->createSocket($request->getURL(), $timeout);
$this->makeHttpRequest($httpSocket, $httpString);
$responseString = $this->retrieveHttpResponse($httpSocket);
$response = $this->parseResponse($responseString, $request);
$this->closeSocket($httpSocket);
}catch(Exception $ex){
$this->closeSocket($httpSocket);
$exceptionMessage='Http Request Failed. Request['.$request.'], Response['.$response.'].';
throw new Exception($exceptionMessage, null, $ex);
}
return $response;
}
/**
*
* @param URL $url
* @param int $timeout
* @return resource
* @throws RuntimeException
*/
private function createSocket($url, $timeout=null){
$host=$url->getHost();
$port = $url->getPort() == null ? 80 : $url->getPort();
if($url->getScheme() == 'https'){
$host='ssl://'.$url->getHost();
$port = $url->getPort() == null ? 443 : $url->getPort();
}
$errorCode = null;
$errorDescription = null;
$socket = null;
if (is_null($timeout)){
$socket = fsockopen($host, $port, $errorCode, $errorDescription);
}
else{
$socket = fsockopen($host, $port, $errorCode, $errorDescription, $timeout);
}
if (!is_resource($socket)) {
throw new RuntimeException($errorCode . " (" . $errorDescription . ")");
}
return $socket;
}
private function closeSocket($socket){
if(is_resource($socket)){
fclose($socket);
}
}
private function makeHttpRequest($socket, $httpString){
$this->checkSocket($socket);
fwrite($socket, $httpString);
}
private function checkSocket($socket){
if(!is_resource($socket)){
throw new RuntimeException("Invalid socket resource.");
}
}
/**
*
* @param string $responseString
* @param HttpRequest $request
* @return HttpResponse
*/
private function parseResponse($responseString, $request){
$responseParser = new HttpResponseParser();
$response = $responseParser->parse($responseString);
$response->setRequestOrigin($request);
return $response;
}
/**
* @param HttpRequest $request
* @return string
*/
private function parseRequest($request){
$requestParser = new HttpRequestParser();
$httpString = $requestParser->parse($request);
return $httpString;
}
/**
*
* @param resource $socket
* @return string
* @throws RuntimeException Caso não seja possível ler o recurso do caminho de origem
*/
private function retrieveHttpResponse($socket){
$this->checkSocket($socket);
$responseContent = "";
$line="";
while (!feof($socket)) {
$line=fgets($socket, 128);
$responseContent .= $line;
}
if($responseContent==null || trim($responseContent) == "" ){
throw new RuntimeException("Resource requested not found. Try change the request path.");
}
return $responseContent;
}
}

View File

@@ -0,0 +1,11 @@
<?php
interface HttpClient {
/**
*
* @param HttpRequest $request
* @param int $timeout
* @return HttpResponse
*/
public function makeRequest($request, $timeout=null);
}

View File

@@ -0,0 +1,34 @@
<?php
class HttpHeader {
/**
* @var string
*/
private $name;
/**
* @var mixed
*/
private $value;
public function __construct($name, $value) {
$this->name = $name;
$this->value = $value;
}
public function getName() {
return $this->name;
}
public function getValue() {
return $this->value;
}
public function __toString() {
return "[name=".$this->name.', value='.$this->value.']';
}
}

View File

@@ -0,0 +1,90 @@
<?php
class HttpRequest {
const HTTP_GET="GET";
const HTTP_POST="POST";
const HTTP_PUT="PUT";
const HTTP_DELETE="DELETE";
/**
*
* @var URL
*/
private $url;
/**
* @var array
*/
private $headers=array();
/**
* @var string
*/
private $method;
/**
* @var string
*/
private $body;
public function getMethod() {
return $this->method;
}
public function setMethod($method) {
$this->method = $method;
}
public function getHeaders(){
return $this->headers;
}
/**
* @param HttpHeader $header
*/
public function addHeader($header){
array_push($this->headers, $header);
}
public function hasHeader($name){
$hasHeader = false;
foreach($this->headers as $header){
if($header->getName() == $name){
$hasHeader=true;
}
}
return $hasHeader;
}
/**
* @return URL
*/
public function getUrl() {
return $this->url;
}
public function setUrl($url) {
$this->url = $url;
}
public function getBody() {
return $this->body;
}
public function setBody($body) {
$this->body = $body;
}
public function __toString() {
$requestString = get_class($this).'[url='.$this->url.', method='.$this->method.', body='.$this->body;
return $requestString;
}
}

View File

@@ -0,0 +1,39 @@
<?php
class HttpRequestParser {
/**
*
* @param HttpRequest $request
* @return type
*/
public function parse($request){
$postData= $request->getBody();
$url = $request->getMethod() . " " . $request->getURL()->getUri().'?'.$request->getURL()->getQueryString();
$output = $url . " HTTP/1.1\r\n";
$output .= "Host: " . $request->getURL()->getHost() . "\r\n";
$output .= "User-Agent: Zenvia PHP API\r\n";
$output .= $this->parseCustomHeaders($request);
$output .= "Content-Length: " . strlen($postData) . "\r\n";
$output .= "Connection: close\r\n\r\n";
$output .= $postData;
return $output;
}
/**
* @param HttpRequest $request
* @return string
*/
private function parseCustomHeaders($request){
$headers = $request->getHeaders();
$output = "";
foreach($headers as $header){
$output .= sprintf("%s:%s \r\n", $header->getName(), $header->getValue());
}
$output .= "User-Agent: Zenvia PHP API\r\n";
return $output;
}
}

View File

@@ -0,0 +1,83 @@
<?php
class HttpResponse {
/**
* @var int
*/
private $httpCode;
/**
* @var string
*/
private $httpDescription;
/**
* @var array
*/
private $headers=array();
/**
* @var string
*/
private $body;
/**
* @var HttpRequest
*/
private $requestOrigin;
public function getHttpCode() {
return $this->httpCode;
}
public function getHttpDescription() {
return $this->httpDescription;
}
public function setHttpCode($httpCode) {
$this->httpCode = $httpCode;
}
public function setHttpDescription($httpDescription) {
$this->httpDescription = $httpDescription;
}
public function getHeaders() {
return $this->headers;
}
public function getBody() {
return $this->body;
}
public function getRequestOrigin() {
return $this->requestOrigin;
}
public function setBody($body) {
$this->body = $body;
}
/**
* @param HttpHeader $header
*/
public function addHeader($header){
array_push($this->headers, $header);
}
public function setRequestOrigin(HttpRequest $requestOrigin) {
$this->requestOrigin = $requestOrigin;
}
public function __toString() {
$headers=null;
if(is_array($this->headers)){
$headers = implode(", ", $this->headers);
}
$responseString = get_class($this)."[Http Code=".$this->httpCode.'-'.$this->httpDescription.", \nHeaders=".$headers.", \nBody=".$this->body.", Request Origin=".$this->requestOrigin."]";
return $responseString;
}
}

View File

@@ -0,0 +1,71 @@
<?php
class HttpResponseParser {
/**
* @param string
* @return HttpResponse
*/
public function parse($httpContent) {
$httpResponse = new HttpResponse();
$responseArray = explode("\r\n\r\n", $httpContent);
$headersData = $responseArray[0];
$headersArray = explode("\n", $headersData);
$totalHeaders = count($headersArray);
for ($i = 0; $i < $totalHeaders; $i++) {
$indexHttpHeader = strpos($headersArray[$i], "HTTP");
if ($indexHttpHeader !== false) {
//HTTP/1.1 200 OK
$httpCode = substr($headersArray[$i], $indexHttpHeader + 9, 3);
$httpDescription = substr($headersArray[$i], $indexHttpHeader + 13);
$httpResponse->setHttpCode(intval(trim($httpCode)));
$httpResponse->setHttpDescription(trim($httpDescription));
} else {
$httpResponse->addHeader($this->parseHeader($headersArray[$i]));
}
}
$bodyData = $this->getRequestBody($headersData, $responseArray[1]);
$httpResponse->setBody($bodyData);
return $httpResponse;
}
/**
*
* @param string $headerText
* @return HttpHeader
*/
private function parseHeader($headerText) {
$indexVal = strpos($headerText, ":");
$header=null;
if ($indexVal !== false) {
$headerName = substr($headerText, 0, $indexVal);
$headerValue = substr($headerText, $indexVal + 1);
$header = new HttpHeader($headerName, trim($headerValue));
} else {
$header = new HttpHeader("$i", trim($headerText));
}
return $header;
}
/**
*
* @param string $headersData
* @param string $bodyData
* @return string
*/
private function getRequestBody($headersData, $bodyData) {
$content = $bodyData;
if (!(strpos($headersData, "Transfer-Encoding: chunked") === false)) {
$aux = explode("\r\n", $bodyData);
$countAux = count($aux);
for ($i = 0; $i < $countAux; $i++) {
if ($i == 0 || ($i % 2) == 0) {
$aux[$i] = "";
}
}
$content = implode("", $aux);
}
return $content;
}
}

View File

@@ -0,0 +1,113 @@
<?php
class RestClient {
/**
* @var HttpClient
*/
private $httpClient = null;
const DEFAULT_CONTENT_TYPE="application/x-www-form-urlencoded;charset=UTF-8";
/**
*
* @param HttpClient $httpClient
*/
public function __construct($httpClient=null) {
if($httpClient==null){
$this->httpClient = new DefaultHttpClient();
}
else{
$this->httpClient = $httpClient;
}
}
/**
*
* @param string $url
* @param array $additionalHeaders
* @return HttpResponse
* @throws RuntimeException
*/
public function get($url, $additionalHeaders=array()){
$response = $this->request($url, HttpRequest::HTTP_GET, null, $additionalHeaders);
return $response;
}
/**
*
* @param string $url
* @param string|array $data
* @param array $additionalHeaders
* @return HttpResponse
* @throws RuntimeException
*/
public function post($url, $data=null, $additionalHeaders=array()){
$response = $this->request($url, HttpRequest::HTTP_POST, $data, $additionalHeaders);
return $response;
}
/**
*
* @param string $url
* @param string $method
* @param string|array $data
* @param string $additionalHeaders
* @return HttpResponse
* @throws RuntimeException
*/
private function request($url, $method, $data=null, $additionalHeaders=array()){
$request = $this->createRequest($url, $method, $this->serializeRequestBody($data), $additionalHeaders);
try{
$response = $this->httpClient->makeRequest($request);
}catch(Exception $ex){
throw new RuntimeException($ex);
}
return $response;
}
/**
*
* @param string $data
* return string
*/
private function serializeRequestBody($data){
$serializedData = null;
if($data!= null && is_array($data) ){
$serializedData = http_build_query($data);
}elseif ($data!= null && is_string($data)) {
$serializedData = $data;
}
return $serializedData;
}
/**
*
* @param string $url
* @param string $method
* @param string|array $data
* @param array $additionalHeaders
* @return HttpRequest
*/
private function createRequest($url, $method, $data=null, $additionalHeaders=array()){
$httpRequest = new HttpRequest();
$httpRequest->setUrl(new SMSURL($url));
$httpRequest->setMethod($method);
if(is_array($additionalHeaders) && count($additionalHeaders) > 0){
foreach($additionalHeaders as $headerName=>$headerValue){
$httpRequest->addHeader(new HttpHeader($headerName, $headerValue));
}
}
if(!$httpRequest->hasHeader('Content-Type')){
$httpRequest->addHeader(new HttpHeader('Content-Type', self::DEFAULT_CONTENT_TYPE));
}
$httpRequest->setBody($data);
return $httpRequest;
}
}

View File

@@ -0,0 +1,85 @@
<?php
class SMSURL {
/**
* @var string
*/
private $host;
/**
* @var string
*/
private $uri;
/**
* @var int
*/
private $port;
/**
* @var string
*/
private $queryString;
/**
* @var string
*/
private $scheme;
/**
* @param string $url
*/
public function __construct($url) {
$this->fill($url);
}
private function fill($url){
$parsedUrl = parse_url($url);
$this->host=$parsedUrl['host'];
$this->uri=$parsedUrl['path'];
$this->scheme=$parsedUrl['scheme'];
if(key_exists('port', $parsedUrl)){
$this->port=$parsedUrl['port'];
}
if(key_exists('query', $parsedUrl)){
$this->queryString=$parsedUrl['query'];
}
}
public function getHost() {
return $this->host;
}
public function getUri() {
return $this->uri;
}
public function getPort() {
return $this->port;
}
public function getQueryString() {
return $this->queryString;
}
public function getScheme() {
return $this->scheme;
}
public function __toString() {
$urlString=$this->host;
if($this->port!=null && $this->port!=80){
$urlString.=':'.$this->port;
}
if($this->uri!=null && $this->uri!=""){
$urlString.=$this->uri;
}
if($this->queryString!=null && $this->queryString!=""){
$urlString.='?'.$this->queryString;
}
return $urlString;
}
}