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:
SamiAhmed7777
2025-10-21 00:39:45 -07:00
commit 0b7e2d0a5b
6080 changed files with 1332936 additions and 0 deletions

View 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 &');
}
}