diff --git a/classes/MediaService.php b/classes/MediaService.php index 0f4e809..855686a 100644 --- a/classes/MediaService.php +++ b/classes/MediaService.php @@ -215,14 +215,20 @@ class MediaService { * Fallback: descargar con wget via exec/proc_open (solo funciona en CLI) */ private function shellDownload($url, $headers = []) { - // Verificar si exec está disponible - if (!function_exists('exec') || in_array('exec', array_map('trim', explode(',', ini_get('disable_functions'))))) { - // Intentar proc_open como alternativa - if (function_exists('proc_open')) { - return $this->procOpenDownload($url, $headers); + // Verificar si exec está realmente disponible + // php_admin_value[disable_functions] NO aparece en ini_get('disable_functions') + // así que hacemos un test real con try/catch + $execAvailable = function_exists('exec'); + if ($execAvailable) { + try { + @exec('echo 1', $testOut, $testRc); + } catch (\Error $e) { + $execAvailable = false; } - error_log("[MediaService::shellDownload] Neither exec nor proc_open available"); - return false; + } + + if (!$execAvailable) { + return $this->procOpenDownload($url, $headers); } $tmpFile = tempnam(sys_get_temp_dir(), 'wget_'); @@ -231,7 +237,13 @@ class MediaService { $headerArgs .= ' --header=' . escapeshellarg($h); } $cmd = 'wget -q --prefer-family=IPv4 -O ' . escapeshellarg($tmpFile) . $headerArgs . ' ' . escapeshellarg($url) . ' 2>&1'; - exec($cmd, $output, $exitCode); + try { + exec($cmd, $output, $exitCode); + } catch (\Error $e) { + error_log("[MediaService::shellDownload] exec() threw Error: " . $e->getMessage()); + if (file_exists($tmpFile)) unlink($tmpFile); + return $this->procOpenDownload($url, $headers); + } if ($exitCode === 0 && file_exists($tmpFile) && filesize($tmpFile) > 0) { $content = file_get_contents($tmpFile); @@ -249,6 +261,26 @@ class MediaService { * Descargar con proc_open (alternativa a exec) */ private function procOpenDownload($url, $headers = []) { + // Test real de disponibilidad: php_admin_value no se refleja en ini_get + $procAvailable = function_exists('proc_open'); + if ($procAvailable) { + try { + $testProc = @proc_open('echo 1', [1 => ['pipe', 'w']], $testPipes); + if (is_resource($testProc)) { + fclose($testPipes[1]); + proc_close($testProc); + } else { + $procAvailable = false; + } + } catch (\Error $e) { + $procAvailable = false; + } + } + if (!$procAvailable) { + error_log("[MediaService::procOpenDownload] proc_open not available, skipping"); + return false; + } + $tmpFile = tempnam(sys_get_temp_dir(), 'wget_'); $headerArgs = ''; foreach ($headers as $h) { @@ -256,7 +288,13 @@ class MediaService { } $cmd = 'wget -q --prefer-family=IPv4 -O ' . escapeshellarg($tmpFile) . $headerArgs . ' ' . escapeshellarg($url); - $proc = proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes); + try { + $proc = proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes); + } catch (\Error $e) { + error_log("[MediaService::procOpenDownload] proc_open() threw Error: " . $e->getMessage()); + if (file_exists($tmpFile)) unlink($tmpFile); + return false; + } if (!is_resource($proc)) { error_log("[MediaService::procOpenDownload] proc_open failed"); if (file_exists($tmpFile)) unlink($tmpFile);