776 lines
21 KiB
PHP
Executable File
776 lines
21 KiB
PHP
Executable File
<?php declare(strict_types=1); namespace IR\Http; if (!defined('IR_START')) exit('<pre>No direct script access allowed</pre>');
|
|
/**
|
|
* @framework Wevads Framework
|
|
* @version 1.0
|
|
* @author Amine Idrissi <contact@iresponse.tech>
|
|
* @date 2019
|
|
* @name Request.php
|
|
*/
|
|
|
|
# utilities
|
|
use IR\Utils\Types\Arrays as Arrays;
|
|
|
|
# exceptions
|
|
use IR\Exceptions\Types\HTTPException as HTTPException;
|
|
|
|
/**
|
|
* @name Request
|
|
* @description http requests class
|
|
*/
|
|
class Request
|
|
{
|
|
/**
|
|
* @name getInstance
|
|
* @description singleton access to constructor
|
|
* @access public | static
|
|
* @return Request
|
|
*/
|
|
public static function getInstance() : Request
|
|
{
|
|
if(self::$_instance == null)
|
|
{
|
|
self::$_instance = new Request();
|
|
}
|
|
|
|
return self::$_instance;
|
|
}
|
|
|
|
/**
|
|
* @name exists
|
|
* @description check if a data exists by a key
|
|
* @access public
|
|
* @param string $key the key to check with
|
|
* @return mixed
|
|
*/
|
|
public function exists(string $key,string $method = self::GET)
|
|
{
|
|
$data = null;
|
|
|
|
switch ($method)
|
|
{
|
|
case self::GET :
|
|
{
|
|
$data = $_GET;
|
|
break;
|
|
}
|
|
case self::POST :
|
|
{
|
|
$data = $_POST;
|
|
break;
|
|
}
|
|
case self::SERVER :
|
|
{
|
|
$data = $_SERVER;
|
|
break;
|
|
}
|
|
case self::ENV :
|
|
{
|
|
$data = $_ENV;
|
|
break;
|
|
}
|
|
case self::FILES :
|
|
{
|
|
$data = $_FILES;
|
|
break;
|
|
}
|
|
case self::COOKIE :
|
|
{
|
|
$data = $_COOKIE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return is_array($data) && key_exists($key,$data) && $data[$key] != null;
|
|
}
|
|
|
|
/**
|
|
* @name get
|
|
* @description get data by a key
|
|
* @access public
|
|
* @param string $key the key to get data with
|
|
* @param mixed $default the default data to get in case of empty results
|
|
* @return mixed
|
|
*/
|
|
public function retrieve(string $key = self::ALL,string $method = self::GET,$default = null)
|
|
{
|
|
$data = null;
|
|
|
|
switch ($method)
|
|
{
|
|
case self::GET :
|
|
{
|
|
$data = $_GET;
|
|
break;
|
|
}
|
|
case self::POST :
|
|
{
|
|
$data = $_POST;
|
|
break;
|
|
}
|
|
case self::SERVER :
|
|
{
|
|
$data = $_SERVER;
|
|
break;
|
|
}
|
|
case self::ENV :
|
|
{
|
|
$data = $_ENV;
|
|
break;
|
|
}
|
|
case self::FILES :
|
|
{
|
|
$data = $_FILES;
|
|
break;
|
|
}
|
|
case self::COOKIE :
|
|
{
|
|
$data = $_COOKIE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if($key == self::ALL)
|
|
{
|
|
return $data;
|
|
}
|
|
|
|
if(is_array($data) && key_exists($key,$data))
|
|
{
|
|
return $data[$key];
|
|
}
|
|
|
|
return $default;
|
|
}
|
|
|
|
/**
|
|
* @name post
|
|
* @description set data by a key from / inside $_POST
|
|
* @access public
|
|
* @param string $key the key to get data with
|
|
* @param mixed $value
|
|
* @return mixed
|
|
*/
|
|
public function insert(string $key,$value,string $method = self::GET)
|
|
{
|
|
switch ($method)
|
|
{
|
|
case self::GET :
|
|
{
|
|
$_GET[$key] = $value;
|
|
break;
|
|
}
|
|
case self::POST :
|
|
{
|
|
$_POST[$key] = $value;
|
|
break;
|
|
}
|
|
case self::FILES :
|
|
{
|
|
$_FILES[$key] = $value;
|
|
break;
|
|
}
|
|
case self::SERVER :
|
|
{
|
|
$_SERVER[$key] = $value;
|
|
break;
|
|
}
|
|
case self::ENV :
|
|
{
|
|
$_ENV[$key] = $value;
|
|
break;
|
|
}
|
|
case self::COOKIE :
|
|
{
|
|
$_COOKIE[$key] = $value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @name getMethod
|
|
* @description gets the request method either _GET or _POST or nothing in case of error
|
|
* @access public
|
|
* @return string
|
|
*/
|
|
public function getMethod() : string
|
|
{
|
|
$method = strtoupper($this->retrieve('REQUEST_METHOD',self::SERVER));
|
|
|
|
if (!in_array($method, self::HTTP_METHODS))
|
|
{
|
|
throw new HTTPException('Unknown request method');
|
|
}
|
|
|
|
return $method;
|
|
}
|
|
|
|
/**
|
|
* @name getBaseURL
|
|
* @description gets the base URL
|
|
* @access public
|
|
* @return string
|
|
*/
|
|
public function getBaseURL() : string
|
|
{
|
|
$protocol = $this->retrieve('HTTPS',self::SERVER) != null && $this->retrieve('HTTPS',self::SERVER) != 'off' ? 'https://' : 'http://';
|
|
$host = $this->retrieve('HTTP_HOST',self::SERVER);
|
|
return $protocol . $host;
|
|
}
|
|
|
|
/**
|
|
* @name getCurrentURL
|
|
* @description gets the current URL
|
|
* @access public
|
|
* @return string
|
|
*/
|
|
public function getCurrentURL() : string
|
|
{
|
|
$protocol = $this->retrieve('HTTPS',self::SERVER) != null && $this->retrieve('HTTPS',self::SERVER) != 'off' ? 'https://' : 'http://';
|
|
$host = $this->retrieve('HTTP_HOST',self::SERVER);
|
|
return $protocol . $host .$this->retrieve('REQUEST_URI',self::SERVER);
|
|
}
|
|
|
|
/**
|
|
* @name parseURL
|
|
* @description parses the give url
|
|
* @param string $url
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function parseURL(string $url) : array
|
|
{
|
|
$result = [];
|
|
|
|
if(filter_var($url,FILTER_VALIDATE_URL))
|
|
{
|
|
$result = parse_url($url);
|
|
}
|
|
|
|
return $result == false ? [] : $result;
|
|
}
|
|
|
|
/**
|
|
* @name getRequestURL
|
|
* @description get the current request url
|
|
* @access public
|
|
* @return string
|
|
*/
|
|
public function getRequestURL()
|
|
{
|
|
$url = $this->exists('request_url',self::GET) ? explode(RDS,$this->retrieve('request_url',self::GET)) : [DEFAULT_CONTROLLER,DEFAULT_ACTION];
|
|
$controller = count($url) < 1 || empty($url[0]) ? DEFAULT_CONTROLLER : $url[0];
|
|
$action = count($url) < 2 || empty($url[1]) ? DEFAULT_ACTION : $url[1];
|
|
$final = $controller . RDS . $action;
|
|
|
|
if(count($url) > 2)
|
|
{
|
|
for ($index = 2; $index < count($url); $index++)
|
|
{
|
|
$final .= RDS . $url[$index];
|
|
}
|
|
}
|
|
|
|
return $final;
|
|
}
|
|
|
|
/**
|
|
* @name getRequestExtension
|
|
* @description get the current request extension
|
|
* @access public
|
|
* @return string
|
|
*/
|
|
public function getRequestExtension()
|
|
{
|
|
return self::exists('extension',self::GET) ? $this->retrieve('extension',self::GET) : DEFAULT_EXTENSION;
|
|
}
|
|
|
|
/**
|
|
* @name soap
|
|
* @description soap query executor
|
|
* @access public
|
|
* @return mixed
|
|
*/
|
|
public function soap(string $wsdl,string $function,array $parameters = [])
|
|
{
|
|
$client = new \soapclient($wsdl);
|
|
$result = $client->{$function}($parameters);
|
|
return Arrays::getInstance()->get(json_decode(json_encode($result),true),'return',[]);
|
|
}
|
|
|
|
/**
|
|
* @name rest
|
|
* @description rest query executor
|
|
* @access public
|
|
* @return mixed
|
|
*/
|
|
public function rest(string $url,$parameters = [],string $method = Request::GET,string $username = '',$password = '',$headers = []) : string
|
|
{
|
|
# construct the URL
|
|
if($method == Request::GET && count($parameters))
|
|
{
|
|
$url .= '?' . http_build_query($parameters);
|
|
}
|
|
|
|
$ch = curl_init($url);
|
|
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0");
|
|
curl_setopt($ch, CURLOPT_FAILONERROR, true);
|
|
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
curl_setopt($ch, CURLOPT_VERBOSE, false);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
|
|
|
|
// Optional Authentication:
|
|
if(strlen($username) > 0 && strlen($password) > 0)
|
|
{
|
|
curl_setopt($ch, CURLOPT_HTTPAUTH,CURLAUTH_BASIC);
|
|
curl_setopt($ch, CURLOPT_USERPWD,"{$username}:{$password}");
|
|
}
|
|
|
|
switch ($method)
|
|
{
|
|
case Request::POST :
|
|
{
|
|
curl_setopt($ch,CURLOPT_POST,true);
|
|
|
|
# check for parameters if any ( and if it's an array or json
|
|
if(is_array($parameters))
|
|
{
|
|
if(count($parameters)) curl_setopt($ch,CURLOPT_POSTFIELDS,$parameters);
|
|
}
|
|
else
|
|
{
|
|
if(is_string($parameters) && strlen($parameters) > 0) curl_setopt($ch,CURLOPT_POSTFIELDS,$parameters);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case Request::PUT :
|
|
{
|
|
curl_setopt($ch,CURLOPT_PUT,true);
|
|
|
|
# check for parameters if any ( and if it's an array or json
|
|
if(is_array($parameters))
|
|
{
|
|
if(count($parameters)) curl_setopt($ch,CURLOPT_POSTFIELDS,$parameters);
|
|
}
|
|
else
|
|
{
|
|
if(is_string($parameters) && strlen($parameters) > 0) curl_setopt($ch,CURLOPT_POSTFIELDS,$parameters);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(count($headers))
|
|
{
|
|
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
|
|
}
|
|
|
|
# Execute the REST call
|
|
$result = curl_exec($ch);
|
|
|
|
ob_start();
|
|
|
|
# free resources
|
|
curl_close($ch);
|
|
|
|
ob_end_clean();
|
|
|
|
# send back the data
|
|
return strval($result);
|
|
}
|
|
|
|
/**
|
|
* @name curl
|
|
* @description curl query executor
|
|
* @access public
|
|
* @return mixed
|
|
*/
|
|
public function curl(string $url,$parameters = [],string $method = Request::GET,$headers = false, bool $followRedirects = true,string $cookiesFile = '',$userpass = '')
|
|
{
|
|
# construct the URL
|
|
if($method == Request::GET && count($parameters))
|
|
{
|
|
$url .= '?' . http_build_query($parameters);
|
|
}
|
|
|
|
$properties = [
|
|
CURLOPT_USERAGENT => "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0",
|
|
CURLOPT_FAILONERROR => true,
|
|
CURLOPT_AUTOREFERER => true,
|
|
CURLOPT_SSL_VERIFYPEER => false,
|
|
CURLOPT_SSL_VERIFYHOST => false,
|
|
CURLOPT_RETURNTRANSFER => true
|
|
];
|
|
|
|
if($userpass != null && $userpass != '' && \IR\Utils\Types\Strings::getInstance()->contains($userpass,':'))
|
|
{
|
|
$properties[CURLOPT_USERPWD] = $userpass;
|
|
}
|
|
|
|
if($cookiesFile != '')
|
|
{
|
|
$properties[CURLOPT_COOKIEJAR] = $cookiesFile;
|
|
$properties[CURLOPT_COOKIEFILE] = $cookiesFile;
|
|
}
|
|
|
|
switch ($method)
|
|
{
|
|
case Request::GET :
|
|
{
|
|
$properties[CURLOPT_CUSTOMREQUEST] = 'GET';
|
|
break;
|
|
}
|
|
case Request::POST :
|
|
{
|
|
$properties[CURLOPT_CUSTOMREQUEST] = 'POST';
|
|
|
|
if(is_array($parameters))
|
|
{
|
|
$properties[CURLOPT_POSTFIELDS] = http_build_query($parameters);
|
|
}
|
|
else
|
|
{
|
|
if(json_decode($parameters) !== FALSE || json_decode($parameters) !== null)
|
|
{
|
|
$properties[CURLOPT_POSTFIELDS] = $parameters;
|
|
}
|
|
else
|
|
{
|
|
$properties[CURLOPT_POSTFIELDS] = http_build_query($parameters);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case Request::PUT :
|
|
{
|
|
$properties[CURLOPT_CUSTOMREQUEST] = 'PUT';
|
|
|
|
if(is_array($parameters))
|
|
{
|
|
$properties[CURLOPT_POSTFIELDS] = http_build_query($parameters);
|
|
}
|
|
else
|
|
{
|
|
if(json_decode($parameters) !== FALSE || json_decode($parameters) !== null)
|
|
{
|
|
$properties[CURLOPT_POSTFIELDS] = $parameters;
|
|
}
|
|
else
|
|
{
|
|
$properties[CURLOPT_POSTFIELDS] = http_build_query($parameters);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(is_array($headers))
|
|
{
|
|
$properties[CURLOPT_HTTPHEADER] = $headers;
|
|
}
|
|
|
|
# return headers as requested
|
|
elseif ($headers == true)
|
|
{
|
|
$properties[CURLOPT_HEADER] = true;
|
|
}
|
|
|
|
# only return headers
|
|
elseif ($headers == 'headers only')
|
|
{
|
|
$properties[CURLOPT_NOBODY] = true;
|
|
}
|
|
|
|
# follow redirects
|
|
if ($followRedirects == true)
|
|
{
|
|
$properties[CURLOPT_FOLLOWLOCATION] = true;
|
|
}
|
|
|
|
# Execute the REST call
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch,$properties);
|
|
$response = curl_exec($ch);
|
|
|
|
if ($response === false)
|
|
{
|
|
$response = curl_error($ch);
|
|
}
|
|
|
|
ob_start();
|
|
|
|
# free resources
|
|
curl_close($ch);
|
|
|
|
ob_end_clean();
|
|
|
|
# send back the data
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* @name download
|
|
* @description downloads a file into a path
|
|
* @access public
|
|
* @param string $request
|
|
* @param string $fileName
|
|
* @return bool
|
|
*/
|
|
public function download(string $request, string $fileName) : bool
|
|
{
|
|
$result = 0;
|
|
|
|
$fh = fopen($fileName, 'w');
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $request);
|
|
curl_setopt($ch, CURLOPT_FILE, $fh);
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
|
$result = curl_exec($ch);
|
|
curl_close($ch);
|
|
fclose($fh);
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @name parseCookieJar
|
|
* @description parse a cookie jar file
|
|
* @access public
|
|
* @param string $fileName
|
|
* @return array
|
|
*/
|
|
public function parseCookieJar(string $fileName) : array
|
|
{
|
|
$cookie = [];
|
|
$lines = explode(PHP_EOL,FileSystem::readFile($fileName));
|
|
|
|
foreach ($lines as $line)
|
|
{
|
|
if (substr($line, 0, 10) == '#HttpOnly_')
|
|
{
|
|
$line = substr($line, 10);
|
|
$cookie['httponly'] = true;
|
|
}
|
|
else
|
|
{
|
|
$cookie['httponly'] = false;
|
|
}
|
|
|
|
if( strlen( $line ) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6)
|
|
{
|
|
$tokens = explode("\t", $line);
|
|
$tokens = array_map('trim', $tokens);
|
|
|
|
# Extract the data
|
|
$cookie['domain'] = $tokens[0]; # The domain that created AND can read the variable.
|
|
$cookie['flag'] = $tokens[1]; # A TRUE/FALSE value indicating if all machines within a given domain can access the variable.
|
|
$cookie['path'] = $tokens[2]; # The path within the domain that the variable is valid for.
|
|
$cookie['secure'] = $tokens[3]; # A TRUE/FALSE value indicating if a secure connection with the domain is needed to access the variable.
|
|
|
|
$cookie['expiration-epoch'] = $tokens[4]; # The UNIX time that the variable will expire on.
|
|
$cookie['name'] = urldecode($tokens[5]); # The name of the variable.
|
|
$cookie['value'] = urldecode($tokens[6]); # The value of the variable.
|
|
|
|
# Convert date to a readable format
|
|
$cookie['expiration'] = intval($tokens[4]);
|
|
|
|
# Record the cookie.
|
|
$cookies[] = $cookie;
|
|
}
|
|
}
|
|
|
|
return $cookies;
|
|
}
|
|
|
|
/**
|
|
* @name checkConnectivity
|
|
* @description gets browser default language
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function checkConnectivity(string $host,int $port = 22,int $timeOut = 30) : bool
|
|
{
|
|
$connected = false;
|
|
|
|
$errorCode = null;
|
|
$errorMessage = null;
|
|
|
|
# open a socket
|
|
$socket = \fsockopen($host,$port,$errorCode,$errorMessage,$timeOut);
|
|
|
|
if(!empty($socket) && $socket !== false)
|
|
{
|
|
$connected = true;
|
|
fclose($socket);
|
|
}
|
|
else
|
|
{
|
|
throw new HTTPException('Error trying to connect to : ' . $host . ' with port : ' . $port . ' , error (' . $errorCode . ') : ' . $errorMessage,500);
|
|
}
|
|
|
|
return $connected;
|
|
}
|
|
|
|
/**
|
|
* @name getURLRedirects
|
|
* @description get URL redirects
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getURLRedirects(string $url,int $timeOut = 10,int $maxRedirects = 10) : array
|
|
{
|
|
$redirects = [];
|
|
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1");
|
|
curl_setopt($ch, CURLOPT_URL,str_replace("&", "&", urldecode(trim($url))));
|
|
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeOut);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, $timeOut);
|
|
curl_setopt($ch, CURLOPT_MAXREDIRS,$maxRedirects);
|
|
curl_setopt($ch,CURLOPT_HEADER,true);
|
|
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
//curl_setopt($ch, CURLOPT_AUTOREFERER, true);
|
|
$response = curl_exec($ch);
|
|
//$response = curl_getinfo($ch);
|
|
curl_close($ch);
|
|
\IR\Core\Application::getCurrent()->utils->printer->printValue($response);
|
|
if ($response['http_code'] == 301 || $response['http_code'] == 302)
|
|
{
|
|
ini_set("user_agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1");
|
|
$headers = get_headers($response['url']);
|
|
|
|
foreach ($headers as $value)
|
|
{
|
|
if (substr(strtolower($value), 0, 9) == "location:")
|
|
{
|
|
$redirects[] = trim(substr($value, 9, strlen($value)));
|
|
}
|
|
}
|
|
}
|
|
|
|
return $redirects;
|
|
}
|
|
|
|
/**
|
|
* @name getBrowserLanguage
|
|
* @description gets browser default language
|
|
* @access static
|
|
* @return string
|
|
*/
|
|
public function getBrowserLanguage() : string
|
|
{
|
|
$lang = $this->retrieve('HTTP_ACCEPT_LANGUAGE',self::SERVER);
|
|
return $lang != null && strlen($lang) > 0 ? strtoupper(substr($lang, 0, 2)) : 'en';
|
|
}
|
|
|
|
/**
|
|
* @name getBrowserLanguage
|
|
* @description gets browser default language
|
|
* @access public
|
|
* @return string
|
|
*/
|
|
public function getUserAgent() : string
|
|
{
|
|
$agent = $this->retrieve('HTTP_USER_AGENT',self::SERVER);
|
|
return $agent == null ? '' : $agent;
|
|
}
|
|
|
|
/**
|
|
* @name __construct
|
|
* @description class constructor
|
|
* @access private
|
|
* @return Request
|
|
*/
|
|
private function __construct() {}
|
|
|
|
/**
|
|
* @name __clone
|
|
* @description preventing cloning object
|
|
* @access public
|
|
* @return Request
|
|
*/
|
|
public function __clone()
|
|
{
|
|
return (self::$_instance != null) ? self::$_instance : new Request();
|
|
}
|
|
|
|
/**
|
|
* @readwrite
|
|
* @access private
|
|
* @var Request
|
|
*/
|
|
private static $_instance;
|
|
|
|
/**
|
|
* @access static
|
|
* @var array
|
|
*/
|
|
const HTTP_METHODS = ['GET','POST','COOKIE','HEAD','PUT','DELETE'];
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const GET = 'GET';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const POST = 'POST';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const FILES = 'FILES';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const COOKIE = 'COOKIE';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const SERVER = 'SERVER';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const ENV = 'ENV';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const HEAD = 'HEAD';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const PUT = 'PUT';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const DELETE = 'DELETE';
|
|
|
|
/**
|
|
* @access static
|
|
* @var string
|
|
*/
|
|
const ALL = 'ALL_RECORDS';
|
|
} |