mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-03 01:39:24 +02:00
Updates
This commit is contained in:
parent
7f1d5e5a98
commit
5ce81cc9be
5 changed files with 146 additions and 85 deletions
|
@ -487,9 +487,14 @@ function execFFMPEGAsyncOrRemote($command, $keyword = null)
|
|||
$obj = AVideoPlugin::getDataObjectIfEnabled('API');
|
||||
if(!empty($obj) && !empty($obj->standAloneFFMPEG)){
|
||||
$url = "{$obj->standAloneFFMPEG}";
|
||||
|
||||
$codeToExec = array('ffmpegCommand'=>$command, 'keyword'=>$keyword, 'time'=>time());
|
||||
|
||||
$codeToExecEncrypted = encryptString(json_encode($codeToExec));
|
||||
|
||||
$url = addQueryStringParameter($url, 'APISecret', $obj->APISecret);
|
||||
$url = addQueryStringParameter($url, 'ffmpegCommand', $command);
|
||||
$url = addQueryStringParameter($url, 'keyword', $keyword);
|
||||
$url = addQueryStringParameter($url, 'codeToExecEncrypted', $codeToExecEncrypted);
|
||||
//var_dump($url);
|
||||
_error_log("execFFMPEGAsyncOrRemote: URL $command");
|
||||
_error_log("execFFMPEGAsyncOrRemote: URL $url");
|
||||
return url_get_contents($url);
|
||||
|
|
|
@ -121,8 +121,11 @@ function getMySQLDate()
|
|||
|
||||
function _mysql_connect($persistent = false, $try = 0)
|
||||
{
|
||||
global $global, $mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, $mysqlPort, $mysql_connect_was_closed, $mysql_connect_is_persistent;
|
||||
|
||||
global $global, $mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, $mysqlPort, $mysql_connect_was_closed, $mysql_connect_is_persistent, $isStandAlone;
|
||||
if(!empty($isStandAlone)){
|
||||
_error_log('StandAlone Mode');
|
||||
return false;
|
||||
}
|
||||
$checkValues = ['mysqlHost', 'mysqlUser', 'mysqlPass', 'mysqlDatabase'];
|
||||
|
||||
foreach ($checkValues as $value) {
|
||||
|
|
|
@ -2907,12 +2907,12 @@ class API extends PluginAbstract
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $parameters return true if the secret is valid and false if it is not
|
||||
* return true if the secret is valid and false if it is not
|
||||
* 'APISecret' mandatory for security reasons - required
|
||||
* @example {webSiteRootURL}plugin/API/{getOrSet}.json.php?APIName={APIName}&APISecret={APISecret}
|
||||
* @return \ApiObject Returns an ApiObject.
|
||||
*/
|
||||
public function get_api_isAPISecretValid($parameters)
|
||||
public function get_api_isAPISecretValid()
|
||||
{
|
||||
global $global;
|
||||
if (!self::isAPISecretValid()) {
|
||||
|
@ -2921,6 +2921,17 @@ class API extends PluginAbstract
|
|||
return new ApiObject("APISecret is valid", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* decrypt a string
|
||||
* 'string' mandatory
|
||||
* @example {webSiteRootURL}plugin/API/{getOrSet}.json.php?APIName={APIName}&string=stringEncryptedToDecrypt
|
||||
* @return \ApiObject Returns an ApiObject.
|
||||
*/
|
||||
public function get_api_decryptString()
|
||||
{
|
||||
return new ApiObject(decryptString($_REQUEST['string']), false);
|
||||
}
|
||||
}
|
||||
|
||||
class ApiObject
|
||||
|
|
|
@ -87,98 +87,140 @@
|
|||
* Replace `https://yourSite.com/` with your actual website URL.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
$global_timeLimit = 300;
|
||||
|
||||
ini_set("memory_limit", -1);
|
||||
ini_set('default_socket_timeout', $global_timeLimit);
|
||||
set_time_limit($global_timeLimit);
|
||||
ini_set('max_execution_time', $global_timeLimit);
|
||||
ini_set("memory_limit", "-1");
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
require_once __DIR__ . "/../../../objects/functionsStandAlone.php";
|
||||
|
||||
if (empty($streamerURL)) {
|
||||
echo json_encode(['error' => true, 'message' => 'streamerURL not defined']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Function to safely get inputs from either command line or request
|
||||
function getInput($key, $default = '') {
|
||||
global $argv;
|
||||
|
||||
// Check if running from command line or HTTP request
|
||||
if (php_sapi_name() === 'cli') {
|
||||
// Look for the parameter in $argv (command line)
|
||||
foreach ($argv as $arg) {
|
||||
if (strpos($arg, "{$key}=") === 0) {
|
||||
return substr($arg, strlen("{$key}="));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fallback to HTTP request ($_REQUEST)
|
||||
return isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Validate and sanitize the ffmpegCommand
|
||||
function sanitizeFFmpegCommand($command) {
|
||||
// Allowable ffmpeg prefixes
|
||||
|
||||
ini_set("memory_limit", -1);
|
||||
ini_set('default_socket_timeout', $global_timeLimit);
|
||||
set_time_limit($global_timeLimit);
|
||||
ini_set('max_execution_time', $global_timeLimit);
|
||||
ini_set("memory_limit", "-1");
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
require_once __DIR__ . "/../../../objects/functionsStandAlone.php";
|
||||
|
||||
if (empty($streamerURL)) {
|
||||
echo json_encode(['error' => true, 'message' => 'streamerURL not defined']);
|
||||
exit;
|
||||
}
|
||||
|
||||
function _decryptString($string)
|
||||
{
|
||||
global $global;
|
||||
$url = "{$global['webSiteRootURL']}plugin/API/get.json.php?APIName=decryptString&string={$string}";
|
||||
|
||||
$content = file_get_contents($url);
|
||||
$json = json_decode($content);
|
||||
|
||||
if (!empty($json) && empty($json->error)) {
|
||||
$json2 = json_decode($json->message);
|
||||
if ($json2->time > strtotime('30 seconds ago')) {
|
||||
return $json2;
|
||||
}
|
||||
}
|
||||
//return $json2;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Function to safely get inputs from either command line or request
|
||||
function getInput($key, $default = '') {
|
||||
global $argv;
|
||||
|
||||
// Check if running from command line or HTTP request
|
||||
if (php_sapi_name() === 'cli') {
|
||||
foreach ($argv as $arg) {
|
||||
if (strpos($arg, "{$key}=") === 0) {
|
||||
return substr($arg, strlen("{$key}="));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Validate and sanitize the ffmpegCommand
|
||||
function sanitizeFFmpegCommand($command) {
|
||||
$allowedPrefixes = ['ffmpeg', '/usr/bin/ffmpeg', '/bin/ffmpeg'];
|
||||
|
||||
|
||||
// Remove dangerous characters
|
||||
$command = str_replace('&&', '', $command);
|
||||
$command = preg_replace('/[;|`<]/', '', $command);
|
||||
|
||||
// Remove existing log file redirection (e.g., '> /path/to/log 2>&1' or '> /path/to/log')
|
||||
$command = preg_replace('/\s*>.*(?:2>&1)?/', '', $command);
|
||||
$command = preg_replace('/[;|`<>]/', '', $command);
|
||||
|
||||
// Ensure it starts with ffmpeg
|
||||
// Ensure it starts with an allowed prefix
|
||||
foreach ($allowedPrefixes as $prefix) {
|
||||
if (strpos(trim($command), $prefix) === 0) {
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
|
||||
// If it doesn't start with an allowed prefix, return an empty string
|
||||
return '';
|
||||
}
|
||||
|
||||
// Fetch and sanitize inputs
|
||||
$ffmpegCommand = sanitizeFFmpegCommand(getInput('ffmpegCommand', ''));
|
||||
$keyword = getInput('keyword', '');
|
||||
|
||||
// Fetch and sanitize inputs
|
||||
$codeToExecEncrypted = getInput('codeToExecEncrypted', '');
|
||||
$codeToExec = _decryptString($codeToExecEncrypted);
|
||||
|
||||
if (empty($codeToExec)) {
|
||||
die('Invalid Request');
|
||||
}
|
||||
|
||||
$ffmpegCommand = sanitizeFFmpegCommand($codeToExec->ffmpegCommand);
|
||||
$keyword = preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword);
|
||||
|
||||
// Kill processes associated with the keyword
|
||||
if (!empty($keyword)) {
|
||||
killProcessFromKeyword($keyword);
|
||||
}
|
||||
|
||||
// Validate that ffmpegCommand is not empty after sanitization
|
||||
if (empty($ffmpegCommand)) {
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
'msg' => 'Invalid or empty ffmpeg command',
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get the system's temporary directory
|
||||
$tempDir = sys_get_temp_dir();
|
||||
|
||||
// Kill processes associated with the keyword
|
||||
if (!empty($keyword)) {
|
||||
killProcessFromKeyword($keyword);
|
||||
}
|
||||
// Ensure the temp directory ends with a directory separator
|
||||
$tempDir = rtrim($tempDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
|
||||
// Validate that ffmpegCommand is not empty after sanitization
|
||||
if (empty($ffmpegCommand)) {
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
'msg' => 'Invalid or empty ffmpeg command',
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
// Create a unique log file path
|
||||
$timestamp = date('YmdHis');
|
||||
$logFile = "{$tempDir}ffmpeg_{$keyword}_{$timestamp}.log";
|
||||
|
||||
// Debug output (optional)
|
||||
error_log("Constructed FFMPEG Command: $ffmpegCommand");
|
||||
|
||||
try {
|
||||
$pid = execAsync($ffmpegCommand, $keyword);
|
||||
echo json_encode([
|
||||
'error' => false,
|
||||
'msg' => 'Command executed',
|
||||
'command' => $ffmpegCommand,
|
||||
'pid' => $pid,
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
'msg' => 'Failed to execute command',
|
||||
'errorMsg' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
exit;
|
||||
|
||||
// Redirect all output to the log file
|
||||
$ffmpegCommand .= " > {$logFile} 2>&1";
|
||||
|
||||
// Debug output (optional)
|
||||
error_log("Constructed FFMPEG Command: $ffmpegCommand");
|
||||
|
||||
try {
|
||||
$pid = execAsync($ffmpegCommand, $keyword);
|
||||
echo json_encode([
|
||||
'error' => false,
|
||||
'msg' => 'Command executed',
|
||||
'command' => $ffmpegCommand,
|
||||
'pid' => $pid,
|
||||
'logFile' => $logFile,
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
'msg' => 'Failed to execute command',
|
||||
'errorMsg' => $e->getMessage(),
|
||||
'logFile' => $logFile,
|
||||
]);
|
||||
}
|
||||
exit;
|
||||
|
|
@ -636,7 +636,7 @@ function startRestream($m3u8, $restreamsDestinations, $logFile, $robj, $tries =
|
|||
file_put_contents($logFile, $command . PHP_EOL);
|
||||
if (empty($isATest)) {
|
||||
// use remote ffmpeg here
|
||||
exec('nohup ' . $command . ' 2>> ' . $logFile . ' > /dev/null &');
|
||||
execFFMPEGAsyncOrRemote($command . ' > ' . $logFile);
|
||||
}
|
||||
error_log("Restreamer.json.php startRestream finish");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue