498 lines
16 KiB
PHP
498 lines
16 KiB
PHP
<?php
|
|
|
|
use Utility\Str;
|
|
|
|
class Rest {
|
|
const GET = "GET";
|
|
const POST = "POST";
|
|
const PUT = "PUT";
|
|
const PATCH = "PATCH";
|
|
const DELETE = "DELETE";
|
|
const TEXTPLAIN = "TEXT";
|
|
const APPLICATIONJSON = "JSON";
|
|
const FORM = "FORM";
|
|
const MULTIPART = "multipart";
|
|
|
|
public static $protocol = "http";
|
|
|
|
private $endPoint = null;
|
|
private $contentType = null;
|
|
private $method = null;
|
|
private $service = null;
|
|
private $serviceRootPath = null;
|
|
private $authUsername = null;
|
|
private $authPassword = null;
|
|
private $urlData = array();
|
|
private $headers = array();
|
|
private $body = array();
|
|
private $privateKey = null;
|
|
private $publicKey = null;
|
|
private $isDownload = false;
|
|
private $isDirectDownload = false;
|
|
private $downloadType = "inline";
|
|
private $profileDb = null;
|
|
private $timeout = 0;
|
|
private $isDirect = false;
|
|
|
|
// <editor-fold desc="SETTERS" defaultstate="collapsed">
|
|
public function post() {
|
|
return $this->method(self::POST);
|
|
}
|
|
|
|
public function get() {
|
|
return $this->method(self::GET);
|
|
}
|
|
|
|
public function asText() {
|
|
return $this->contentType(self::TEXTPLAIN);
|
|
}
|
|
|
|
public function asJson() {
|
|
return $this->contentType(self::APPLICATIONJSON);
|
|
}
|
|
|
|
public function asForm() {
|
|
return $this->contentType(self::FORM);
|
|
}
|
|
|
|
public function header($key, $value) {
|
|
$this->headers[$key] = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function headers($array) {
|
|
$this->headers = array_merge($this->headers, $array);
|
|
return $this;
|
|
}
|
|
|
|
public function urlData($value) {
|
|
$this->urlData = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function body($value) {
|
|
$this->body = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function contentType($value) {
|
|
$this->contentType = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function endPoint($value) {
|
|
$this->endPoint = $value;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param null $profileDb
|
|
*/
|
|
public function setProfileDb($profileDb) {
|
|
$this->profileDb = $profileDb;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return null
|
|
*/
|
|
public function getProfileDb() {
|
|
return $this->profileDb;
|
|
}
|
|
|
|
public function method($value) {
|
|
$this->method = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function serviceRootPath($value) {
|
|
$this->serviceRootPath = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function service($value) {
|
|
$this->service = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function authUsername($value) {
|
|
$this->authUsername = $value;
|
|
return $this->header("username", $value);
|
|
/********* it memorizes in the object headers the key "username" with the value "$value" ***************/
|
|
}
|
|
|
|
public function authPassword($value) {
|
|
$this->authPassword = $value;
|
|
return $this->header("password", $value);
|
|
}
|
|
|
|
public function privateKey($value) {
|
|
$this->privateKey = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function publicKey($value) {
|
|
$this->publicKey = $value;
|
|
return $this;
|
|
}
|
|
|
|
public function timeout($seconds) {
|
|
$this->timeout = $seconds;
|
|
return $this;
|
|
}
|
|
// </editor-fold>
|
|
|
|
// <editor-fold desc="GETTERS" defaultstate="collapsed">
|
|
public function get_endPoint() {
|
|
$endPoint = null;
|
|
|
|
if (!is_null($this->endPoint)) {
|
|
$endPoint = $this->endPoint;
|
|
} else {
|
|
if (file_exists("classes/Restful.config.json")) {
|
|
$restConfig = @json_decode(file_get_contents("classes/Restful.config.json"), true);
|
|
if (!is_null($restConfig) && isset($restConfig["endPoint"])) {
|
|
$endPoint = Controller::endPointParsed($restConfig["endPoint"]) . "/";
|
|
}
|
|
}
|
|
if (is_null($endPoint)) {
|
|
// if (PVM::isDevClient()) {
|
|
// $endPoint = Controller::endPointParsed("localhost:8080") . "/";
|
|
// } else {
|
|
$endPoint = Config::get_endPoint($this->profileDb) . "/";
|
|
// }
|
|
}
|
|
}
|
|
|
|
if (!is_null($this->serviceRootPath)) {
|
|
$endPoint .= Str::endsWith($endPoint, $this->serviceRootPath) ? "" : $this->serviceRootPath;
|
|
}
|
|
|
|
return $endPoint;
|
|
}
|
|
|
|
public static function get_endPointRemote() {
|
|
$endPoint = null;
|
|
if (file_exists("classes/Restful.config.json")) {
|
|
$restConfig = @json_decode(file_get_contents("classes/Restful.config.json"), true);
|
|
if (!is_null($restConfig) && isset($restConfig["endPointRemote"])) {
|
|
$endPoint = Controller::endPointParsed($restConfig["endPointRemote"]) . "/";
|
|
}
|
|
}
|
|
if (is_null($endPoint)) {
|
|
if (PVM::isDevClient()) {
|
|
$endPoint = Controller::endPointParsed(array_get($_ENV, "SERVICES_BASE_URL")) . "/";
|
|
} else {
|
|
$endPoint = Controller::endPointParsed(Config::get_endPointRemote()) . "/";
|
|
}
|
|
}
|
|
|
|
return $endPoint;
|
|
}
|
|
|
|
private static function get_profileDb() {
|
|
return Config::get_dbNameWeb();
|
|
}
|
|
|
|
|
|
/******************************* SERVICE URL CONSTRUCTION **********************************************************/
|
|
private function get_url() {
|
|
|
|
$url = $this->get_endPoint() . $this->service;
|
|
|
|
$urlData = $this->urlData;
|
|
if (!array_key_exists("profileDb", $urlData)) {
|
|
$profileDb = self::get_profileDb();
|
|
if (!is_null($profileDb)) {
|
|
$urlData["profileDb"] = $profileDb;
|
|
}
|
|
}
|
|
if (count($urlData) > 0) {
|
|
$url = sprintf("%s?%s", $url, preg_replace('/%5B\d+%5D/', '%5B%5D', http_build_query($urlData)));
|
|
}
|
|
|
|
return $url;
|
|
}
|
|
|
|
private function get_authCredentials() {
|
|
return (!is_null($this->authUsername)
|
|
&& !is_null($this->authPassword)) ? array(
|
|
"username" => $this->authUsername, "password" => $this->authPassword
|
|
) : null;
|
|
}
|
|
|
|
// </editor-fold>
|
|
|
|
|
|
/************************************ CONNECTION BETWEEN PHP AND REST APIs *****************************************/
|
|
public function send() {
|
|
$Ret = new Ret;
|
|
$ret = array("headers" => null, "url" => null, "payload" => null, "http_code" => null, "body" => null);
|
|
|
|
try {
|
|
$url = $this->get_url();
|
|
|
|
/************************ creation of REQUEST OBJ ************************/
|
|
switch ($this->method) {
|
|
case self::POST:
|
|
$req = \Httpful\Request::post($url);
|
|
|
|
break;
|
|
case self::PUT:
|
|
$req = \Httpful\Request::put($url);
|
|
|
|
break;
|
|
case self::PATCH:
|
|
$req = \Httpful\Request::patch($url);
|
|
|
|
break;
|
|
case self::DELETE:
|
|
$req = \Httpful\Request::delete($url);
|
|
|
|
break;
|
|
default:
|
|
$req = \Httpful\Request::get($url);
|
|
}
|
|
|
|
$credentials = $this->get_authCredentials();
|
|
if (!is_null($credentials)) {
|
|
$req->authenticateWith($credentials["username"], $credentials["password"]);
|
|
}
|
|
|
|
foreach ($this->headers as $k => $v) {
|
|
$req->addHeader($k, $v);
|
|
}
|
|
/***************** here the body of Rest is passed to Request *******************/
|
|
if (!is_null($this->publicKey)) {
|
|
$req->body(self::encryptRsa(json_encode($this->body), $this->publicKey));
|
|
} else {
|
|
$req->body($this->body);
|
|
}
|
|
|
|
if ($this->contentType == self::APPLICATIONJSON) {
|
|
$req->sendsJson();
|
|
} else if ($this->contentType == self::FORM) {
|
|
$req->sendsType(Httpful\Mime::FORM);
|
|
} else if ($this->contentType == self::MULTIPART) {
|
|
$req->sendsType(Httpful\Mime::UPLOAD);
|
|
}
|
|
|
|
if ($this->timeout > 0) {
|
|
$req->timeoutIn($this->timeout);
|
|
}
|
|
|
|
$ret["headers"] = $req->headers;
|
|
|
|
/************************** if there's password, overwrites it with asterisks in ret *************** */
|
|
if (isset($ret["headers"]["password"])) {
|
|
$ret["headers"]["password"] = str_pad("", strlen($ret["headers"]["password"]), "*");
|
|
/****** last option: STR_PAD_RIGHT default */
|
|
}
|
|
|
|
$ret["payload"] = $req->payload;
|
|
$ret["url"] = $url;
|
|
/**************************** FINALLY SEND *******************************/
|
|
$result = @$req->send();
|
|
/************* no parameters passed!!! ******************/
|
|
|
|
if ($this->isDirect()) {
|
|
$Ret->set_data($result)->displayData();
|
|
}
|
|
|
|
$httpCode = $result->code;
|
|
$rawHeaders = $result->raw_headers;
|
|
$ret["http_code"] = $httpCode;
|
|
$ret["body"] = $result->raw_body;
|
|
$Ret->set_number($httpCode);
|
|
|
|
$rawResponse = $result->raw_body;
|
|
if (!is_null($this->privateKey)) {
|
|
$rawResponse = self::decryptRsa($rawResponse, $this->privateKey);
|
|
}
|
|
$retData = $this->isDownload() ? null : json_decode($rawResponse, true);
|
|
if (!isset($retData[0])) {
|
|
$retData = array($retData);
|
|
}
|
|
if ($httpCode == 200) {
|
|
|
|
if ($this->isDownload()) {
|
|
header("Cache-Control: no-cache");
|
|
header("Cache-Control: private", false); // required for certain browsers
|
|
|
|
$headers = explode("\r\n", $rawHeaders);
|
|
|
|
$headers = array_filter($headers, function ($header) {
|
|
return
|
|
strpos($header, "Content-Disposition:") === 0
|
|
|| strpos($header, "Content-Type:") === 0
|
|
|| strpos($header, "Content-Length:") === 0;
|
|
});
|
|
|
|
$contentDisposition = from($headers)->where(function ($header) {
|
|
return strpos($header, "Content-Disposition:") === 0;
|
|
})->firstOrDefault();
|
|
|
|
if ($this->isDirectDownload) {
|
|
header("Cache-Control: private, max-age=86400, must-revalidate");
|
|
header("Cache-Control: private", false);
|
|
|
|
foreach ($headers as $header) {
|
|
header($header);
|
|
}
|
|
|
|
if ($this->downloadType === "inline") {
|
|
$fileName = strpos($contentDisposition, "filename");
|
|
|
|
if ($fileName) {
|
|
header("Content-Disposition: inline; "
|
|
. substr($contentDisposition, $fileName, strlen($contentDisposition)));
|
|
} else {
|
|
header("Content-Disposition: inline");
|
|
}
|
|
}
|
|
}
|
|
|
|
$retData = $rawResponse;
|
|
$Ret->set_data($retData);
|
|
} else {
|
|
if (isset($retData[0]["esito"])) {
|
|
if ($retData[0]["esito"] == 1) {
|
|
$Ret->set_data($retData);
|
|
} else {
|
|
if ($retData) {
|
|
$Ret->set_data($retData);
|
|
}
|
|
|
|
if (isset($retData[0]["errorMessage"])) {
|
|
$Ret->set_error($retData[0]["errorMessage"]);
|
|
} else {
|
|
$Ret->set_errorCode(ErrorHandler::EMSNOMESSAGE, $this->service);
|
|
}
|
|
}
|
|
} else {
|
|
$Ret->set_errorCode(ErrorHandler::EMSPARSE, $this->service);
|
|
$suffixPath = "EMSPARSE-" . User::get_current_username();
|
|
$logPath = Utility::write_log("Parse error rest call: " . $result->raw_body, $suffixPath);
|
|
if ($logPath !== false && PVM::isDebugEnv()) {
|
|
$Ret->append_errorText("<br/><span class='small text-monospace'>Consulta <a href='{$logPath}' download>"
|
|
. basename($logPath) . "</a></span>");
|
|
}
|
|
}
|
|
}
|
|
} else if ($httpCode == 400) {
|
|
$errorLog = "400";
|
|
$Ret->set_errorCode(ErrorHandler::EMSHTTP400, $this->service, array_get($retData, "0.errorMessage"));
|
|
} else if ($httpCode == 401) {
|
|
$errorLog = "401";
|
|
$Ret->set_errorCode(ErrorHandler::EMSHTTP401, $this->service, array_get($retData, "0.errorMessage"));
|
|
} else if ($httpCode == 550) {
|
|
$errorLog = "550";
|
|
$Ret->set_errorCode(ErrorHandler::EMSHTTP550, $this->service);
|
|
} else if ($httpCode == 551) {
|
|
$errorLog = "551";
|
|
$Ret->set_errorCode(ErrorHandler::EMSHTTP551, $this->service);
|
|
} else {
|
|
$errorLog = $httpCode;
|
|
$Ret->set_errorCode(ErrorHandler::EMSHTTP, $httpCode, $rawHeaders, $this->service);
|
|
}
|
|
|
|
} catch (Httpful\Exception\ConnectionErrorException $e) {
|
|
$errorLog = "EMSCONNECT";
|
|
$Ret
|
|
->set_errorCode(ErrorHandler::EMSCONNECT, $this->service)
|
|
->append_errorText(" su <span class='text-monospace'>" . $this->get_endPoint() . "</span>")
|
|
->set_error($e->getMessage());
|
|
|
|
} catch (Exception $e) {
|
|
$errorLog = "restCatchError";
|
|
$Ret->set_error($e->getMessage());
|
|
}
|
|
|
|
if (!$Ret->is_OK() && isset($errorLog) && !PVM::isDevClient()) { // SE NON VA A BUON FINE SCRIVE SEMPRE NEL LOG
|
|
if (isset($this->body)) {
|
|
$fileName = "Payload_" . $errorLog . "_" . blankIfNull($this->service) . "_"
|
|
. User::get_current_username();
|
|
@Utility::write_log($this->body, $fileName);
|
|
}
|
|
|
|
$suffixPath = isset($suffixPath) ? $suffixPath : $errorLog . "_" . blankIfNull($this->service) . "_"
|
|
. User::get_current_username();
|
|
@Utility::write_log($ret, $suffixPath);
|
|
}
|
|
|
|
return $Ret;
|
|
}
|
|
|
|
private static function encryptRsa($data, $pubKey) {
|
|
$rsa = new Crypt_RSA;
|
|
$rsa->loadKey($pubKey);
|
|
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
|
|
return base64_encode($rsa->encrypt($data));
|
|
}
|
|
|
|
private static function decryptRsa($data, $privKey) {
|
|
$rsa = new Crypt_RSA;
|
|
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
|
|
$ciphertext = base64_decode($data);
|
|
$rsa->loadKey($privKey);
|
|
return $rsa->decrypt($ciphertext);
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function isDownload() {
|
|
return $this->isDownload;
|
|
}
|
|
|
|
/**
|
|
* @param bool $isDownload
|
|
* @return Rest
|
|
*/
|
|
public function setIsDownload($isDownload) {
|
|
$this->isDownload = $isDownload;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function isDirectDownload() {
|
|
return $this->isDirectDownload;
|
|
}
|
|
|
|
/**
|
|
* @param bool $isDownload
|
|
* @return Rest
|
|
*/
|
|
public function setIsDirectDownload($isDirectDownload) {
|
|
$this->isDirectDownload = $isDirectDownload;
|
|
return $this;
|
|
}
|
|
|
|
public function getDownloadType() {
|
|
return $this->downloadType;
|
|
}
|
|
|
|
public function setDownloadType($downloadType) {
|
|
$this->downloadType = $downloadType;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function isDirect() {
|
|
return $this->isDirect;
|
|
}
|
|
|
|
/**
|
|
* @param bool $isDirect
|
|
* @return Rest
|
|
*/
|
|
public function setIsDirect($isDirect) {
|
|
$this->isDirect = $isDirect;
|
|
return $this;
|
|
}
|
|
}
|