feat: Add comprehensive documentation suite and reorganize project structure
- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
This commit is contained in:
356
f_core/f_classes/class.server.php
Normal file
356
f_core/f_classes/class.server.php
Normal file
@@ -0,0 +1,356 @@
|
||||
<?php
|
||||
/*******************************************************************************************************************
|
||||
| Software Name : EasyStream
|
||||
| Software Description : High End YouTube Clone Script with Videos, Shorts, Streams, Images, Audio, Documents, Blogs
|
||||
| Software Author : (c) Sami Ahmed
|
||||
|*******************************************************************************************************************
|
||||
|
|
||||
|*******************************************************************************************************************
|
||||
| This source file is subject to the EasyStream Proprietary License Agreement.
|
||||
|
|
||||
| By using this software, you acknowledge having read this Agreement and agree to be bound thereby.
|
||||
|*******************************************************************************************************************
|
||||
| Copyright (c) 2025 Sami Ahmed. All rights reserved.
|
||||
|*******************************************************************************************************************/
|
||||
|
||||
defined('_ISVALID') or header('Location: /error');
|
||||
|
||||
class VServer
|
||||
{
|
||||
private static function err()
|
||||
{
|
||||
header("Location: /error");
|
||||
exit;
|
||||
}
|
||||
public static function var_check()
|
||||
{
|
||||
$_gd = array('Smarty_', 'cache_locking', 'cache_dir', 'use_sub_dirs', 'VARCHAR', 'rlike', '(case', '( case', 'concat', 'elt(', 'elt (', 'INFORMATION_SCHEMA', '(select', '( select', 'select(', 'select (', 'union all', 'union select', 'union+all', 'union+select', 'exec(', 'exec (', 'sleep(', 'sleep (', '\x', '\u0', chr(0), 'fromCharCode', 'Set.constructor', 'script:', 'script :', '\00', 'eval(', 'eval (', 'alert(', 'alert (', 'xlink', 'toString', '<?', '#!');
|
||||
$_gp = array('Smarty_', 'cache_locking', 'cache_dir', 'use_sub_dirs', 'VARCHAR', 'rlike', '(case', '( case', 'concat', 'elt(', 'elt (', 'INFORMATION_SCHEMA', '(select', '( select', 'select(', 'select (', 'union all', 'union select', 'union+all', 'union+select', 'exec(', 'exec (', 'sleep(', 'sleep (', '\x', '\u0', chr(0), 'fromCharCode', 'Set.constructor', 'script:', 'script :', '\00', 'eval(', 'eval (', 'alert(', 'alert (', 'xlink', 'toString', '<?');
|
||||
|
||||
if (!empty($_GET)) {
|
||||
foreach ($_GET as $key => $value) {
|
||||
foreach ($_gd as $deny) {
|
||||
if (stripos($value, $deny) !== false) {
|
||||
$p = json_encode($_GET);
|
||||
error_log(date("Y-m-d H:i:s") . ": Get: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": [" . $value . "]:[" . $deny . "]\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_COOKIE)) {
|
||||
foreach ($_COOKIE as $key => $value) {
|
||||
foreach ($_gp as $deny) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $thevalue) {
|
||||
if (stripos($thevalue, $deny) !== false) {
|
||||
$p = json_encode($_COOKIE);
|
||||
error_log(date("Y-m-d H:i:s") . ": Cookie: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": [" . $thevalue . "]:[" . $deny . "]\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stripos($value, $deny) !== false) {
|
||||
$p = json_encode($_COOKIE);
|
||||
error_log(date("Y-m-d H:i:s") . ": Cookie: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": [" . $value . "]:[" . $deny . "]\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_POST)) {
|
||||
foreach ($_POST as $key => $value) {
|
||||
foreach ($_gp as $deny) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $thevalue) {
|
||||
if (is_array($thevalue)) {
|
||||
foreach ($thevalue as $avalue) {
|
||||
if (stripos($avalue, $deny) !== false) {
|
||||
$p = json_encode($_POST);
|
||||
error_log(date("Y-m-d H:i:s") . ": Post: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": [" . $avalue . "]:[" . $deny . "]\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stripos($thevalue, $deny) !== false) {
|
||||
$p = json_encode($_POST);
|
||||
error_log(date("Y-m-d H:i:s") . ": Post: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": [" . $thevalue . "]:[" . $deny . "]\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stripos($value, $deny) !== false) {
|
||||
$p = json_encode($_POST);
|
||||
error_log(date("Y-m-d H:i:s") . ": Post: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": [" . $value . "]:[" . $deny . "]\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_FILES)) {
|
||||
foreach ($_FILES as $key => $value) {
|
||||
$fileName = $_FILES[$key]["name"];
|
||||
|
||||
if (strpos(strtolower($fileName), '.php') !== false or strpos(strtolower($fileName), '.phar') !== false or strpos(strtolower($fileName), '.pl') !== false or strpos(strtolower($fileName), '.asp') !== false or strpos(strtolower($fileName), '.htm') !== false or strpos(strtolower($fileName), '.cgi') !== false or strpos(strtolower($fileName), '.py') !== false or strpos(strtolower($fileName), '.sh') !== false or strpos(strtolower($fileName), '.cin') !== false or strpos(strtolower($fileName), '.bin') !== false) {
|
||||
$p = json_encode($_FILES);
|
||||
error_log(date("Y-m-d H:i:s") . ": Files: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
foreach ($_gp as $deny) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $thevalue) {
|
||||
if (stripos($thevalue, $deny) !== false) {
|
||||
$p = json_encode($_FILES);
|
||||
error_log(date("Y-m-d H:i:s") . ": Files: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": [" . $thevalue . "]:[" . $deny . "]\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stripos($_FILES[$key]['name'], $deny) !== false) {
|
||||
$p = json_encode($_FILES);
|
||||
error_log(date("Y-m-d H:i:s") . ": Files: $p\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": Req: " . self::get_ip() . ": " . $_SERVER["REQUEST_URI"] . "\n", 3, REQUEST_LOG);
|
||||
error_log(date("Y-m-d H:i:s") . ": [" . $_FILES[$key]['name'] . "]:[" . $deny . "]\n\n", 3, REQUEST_LOG);
|
||||
self::err();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function cookie_validation_set()
|
||||
{
|
||||
if (COOKIE_VALIDATION) {
|
||||
$set_cookie_options = SET_COOKIE_OPTIONS;
|
||||
$del_cookie_options = DEL_COOKIE_OPTIONS;
|
||||
|
||||
$_data = trim(substr(str_shuffle(str_repeat('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1, 10))), 1, 3));
|
||||
if (!isset($_SESSION["cname"])) {$_SESSION["cname"] = strrev($_data);}
|
||||
if (!isset($_COOKIE[$_SESSION["cname"]])) {
|
||||
setcookie($_SESSION["cname"], urlencode(secured_encrypt($_data)), $set_cookie_options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function cookie_validation_check()
|
||||
{
|
||||
$allowed_ips = COOKIE_VALIDATION_WHITELIST;
|
||||
|
||||
if (COOKIE_VALIDATION and php_sapi_name() !== 'cli' and $_SERVER["REQUEST_METHOD"] !== "OPTIONS" and !in_array(self::get_ip(), $allowed_ips)) {
|
||||
if (!isset($_SESSION["rcount"])) {$_SESSION["rcount"] = 0;}
|
||||
|
||||
if (!isset($_SESSION["cname"]) and !isset($_COOKIE[$_SESSION["cname"]])) {
|
||||
error_log(date("Y-m-d H:i:s") . ': ' . self::get_ip() . ': no-session-no-cookie' . "\n", 3, COOKIE_LOG);
|
||||
die();
|
||||
} elseif (isset($_SESSION["cname"]) and !isset($_COOKIE[$_SESSION["cname"]])) {
|
||||
if ($_SESSION["rcount"] <= 1 and empty($_GET)) {
|
||||
$_SESSION["rcount"] += 1;
|
||||
header("Refresh:0");
|
||||
exit;
|
||||
} elseif ($_SESSION["rcount"] >= 3 and empty($_GET)) {
|
||||
error_log(date("Y-m-d H:i:s") . ': ' . self::get_ip() . ': multi-reload => ' . $_SESSION["rcount"] . "\n", 3, COOKIE_LOG);
|
||||
die();
|
||||
}
|
||||
} elseif (isset($_COOKIE[$_SESSION["cname"]])) {
|
||||
$cname = trim(secured_decrypt(urldecode($_COOKIE[$_SESSION["cname"]])));
|
||||
if ($cname == '') {
|
||||
error_log(date("Y-m-d H:i:s") . ': ' . self::get_ip() . ': cookie-decrypt ' . "\n", 3, COOKIE_LOG);
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* curl get */
|
||||
public static function curl_tt($url)
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 3);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $data;
|
||||
}
|
||||
/* get free server */
|
||||
public static function getFreeServer($type = 'stream')
|
||||
{
|
||||
global $db;
|
||||
|
||||
switch ($type) {
|
||||
case "bcast":
|
||||
$t = 'lbb';
|
||||
$tt = 'cast';
|
||||
$c = 'freebcastserver';
|
||||
$adr = 'rtmp://##HOST##/live';
|
||||
break;
|
||||
|
||||
case "stream":
|
||||
$t = 'lbs';
|
||||
$tt = 'stream';
|
||||
$c = 'freeserver';
|
||||
$adr = '##PROTOCOL##://##HOST##:##PORT##';
|
||||
break;
|
||||
|
||||
case "chat":
|
||||
$t = 'lbc';
|
||||
$tt = 'chat';
|
||||
$c = 'freeserver';
|
||||
$adr = '##PROTOCOL##://##HOST##:##PORT##';
|
||||
break;
|
||||
}
|
||||
|
||||
$sql = sprintf("SELECT `srv_id`, `srv_host`, `srv_port`, `srv_https` FROM `db_liveservers` WHERE `srv_type`='%s' AND `srv_active`='1' ORDER BY RAND() LIMIT 1;", $t);
|
||||
$rs = $db->execute($sql);
|
||||
|
||||
if ($rs->fields["srv_id"]) {
|
||||
//load balancer found, get most free server
|
||||
$srv_host = $rs->fields["srv_host"];
|
||||
$srv_port = $rs->fields["srv_port"];
|
||||
$srv_https = $rs->fields["srv_https"];
|
||||
|
||||
$lb_srv = sprintf("%s://%s:%s/%s", ($srv_https ? 'https' : 'http'), $srv_host, $srv_port, $c);
|
||||
$vs = json_decode(VServer::curl_tt($lb_srv));
|
||||
|
||||
if (isset($vs->ip)) {
|
||||
$server = str_replace(array('##PROTOCOL##', '##HOST##', '##PORT##'), array($vs->protocol, $vs->ip, $vs->port), $adr);
|
||||
}
|
||||
} else {
|
||||
//without load balancer, get a random server
|
||||
$sql = sprintf("SELECT `srv_id`, `srv_host`, `srv_port`, `srv_https` FROM `db_liveservers` WHERE `srv_type`='%s' AND `srv_active`='1' ORDER BY RAND() LIMIT 1;", $tt);
|
||||
$rs = $db->execute($sql);
|
||||
|
||||
if ($rs->fields["srv_id"]) {
|
||||
$srv_host = $rs->fields["srv_host"];
|
||||
$srv_port = $rs->fields["srv_port"];
|
||||
$srv_https = $rs->fields["srv_https"] == 1 ? 'https' : 'http';
|
||||
|
||||
if ((int) $srv_port == 443) {
|
||||
$server = str_replace(array('##PROTOCOL##', '##HOST##', ':##PORT##'), array($srv_https, $srv_host, ''), $adr);
|
||||
} else {
|
||||
$server = str_replace(array('##PROTOCOL##', '##HOST##', '##PORT##'), array($srv_https, $srv_host, $srv_port), $adr);
|
||||
}
|
||||
} else {
|
||||
$server = $adr;
|
||||
}
|
||||
}
|
||||
|
||||
return $server;
|
||||
}
|
||||
/* memory */
|
||||
public function get_memory()
|
||||
{
|
||||
foreach (file('/proc/meminfo') as $ri) {
|
||||
$m[strtok($ri, ':')] = strtok('');
|
||||
}
|
||||
|
||||
$i = '<div class="left-float">Memory usage: </div>';
|
||||
$i .= '<div class="left-float left-padding10">';
|
||||
$i .= 'MemTotal: ' . $m['MemTotal'] . "<br />";
|
||||
$i .= 'MemFree: ' . $m['MemFree'] . "<br />";
|
||||
$i .= 'Buffers: ' . $m['Buffers'] . "<br />";
|
||||
$i .= 'Cached: ' . $m['Cached'];
|
||||
$i .= '</div>';
|
||||
|
||||
return $i;
|
||||
}
|
||||
/* remote IP */
|
||||
public static function get_remote_ip()
|
||||
{
|
||||
return self::get_ip();
|
||||
}
|
||||
/* remote IP */
|
||||
public static function get_ip()
|
||||
{
|
||||
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
||||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
} else {
|
||||
$ip = $_SERVER[REM_ADDR];
|
||||
}
|
||||
|
||||
return preg_replace('/[^a-zA-Z0-9:.\-]/', '', $ip);
|
||||
}
|
||||
public static function get_ip_old()
|
||||
{
|
||||
global $class_filter;
|
||||
return $class_filter->clr_str($_SERVER['SERVER_ADDR']);
|
||||
}
|
||||
/* log file */
|
||||
public static function logToFile($path, $str)
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
$wm = 'w';
|
||||
switch ($path) {
|
||||
case ".mailer.log":
|
||||
$ddir = 'log_mail/' . date("Y.m.d") . '/';
|
||||
break;
|
||||
default:
|
||||
$ddir = null;
|
||||
break;
|
||||
}
|
||||
$full_path = $cfg["logging_dir"] . '/' . $ddir . $path;
|
||||
$file_dir = dirname($full_path);
|
||||
|
||||
if (!file_exists($full_path)) {
|
||||
@touch($full_path);
|
||||
}
|
||||
|
||||
if ($ddir != '' and !is_dir($cfg["logging_dir"] . '/' . $ddir)) {
|
||||
@mkdir($cfg["logging_dir"] . '/' . $ddir);
|
||||
}
|
||||
|
||||
if (!is_dir($file_dir) or !is_writable($file_dir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_file($full_path) && is_writable($full_path)) {
|
||||
$wm = 'a';
|
||||
}
|
||||
|
||||
if (!$handle = fopen($full_path, $wm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite($handle, $str . "\n") === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@fclose($handle);
|
||||
}
|
||||
/* background process */
|
||||
public static function bgProcess($cmd)
|
||||
{
|
||||
exec($cmd . '>/dev/null &');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user