Update MediaService.php
This commit is contained in:
+84
-34
@@ -23,7 +23,7 @@ class MediaService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hacer petición GET al Graph API con fallback a wget si curl falla
|
* Hacer petición GET al Graph API con fallback si curl falla
|
||||||
*/
|
*/
|
||||||
private function graphApiRequest($url) {
|
private function graphApiRequest($url) {
|
||||||
// Intentar con curl primero
|
// Intentar con curl primero
|
||||||
@@ -45,24 +45,9 @@ class MediaService {
|
|||||||
return $resp;
|
return $resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback a wget para la petición al Graph API
|
// Fallback: file_get_contents con stream context
|
||||||
error_log("[MediaService::graphApiRequest] curl failed (http={$http} err={$err}), trying wget...");
|
error_log("[MediaService::graphApiRequest] curl failed (http={$http} err={$err}), trying file_get_contents...");
|
||||||
$tmpFile = tempnam(sys_get_temp_dir(), 'graph_');
|
return $this->fileGetContentsWithAuth($url);
|
||||||
$cmd = 'wget -q --prefer-family=IPv4 -O ' . escapeshellarg($tmpFile)
|
|
||||||
. ' --header=' . escapeshellarg('Authorization: Bearer ' . $this->token)
|
|
||||||
. ' ' . escapeshellarg($url) . ' 2>&1';
|
|
||||||
exec($cmd, $output, $exitCode);
|
|
||||||
|
|
||||||
if ($exitCode === 0 && file_exists($tmpFile) && filesize($tmpFile) > 0) {
|
|
||||||
$content = file_get_contents($tmpFile);
|
|
||||||
unlink($tmpFile);
|
|
||||||
error_log("[MediaService::graphApiRequest] wget OK, " . strlen($content) . " bytes");
|
|
||||||
return $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
error_log("[MediaService::graphApiRequest] wget also failed exit={$exitCode}");
|
|
||||||
if (file_exists($tmpFile)) unlink($tmpFile);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchAndStoreFromGraph($mediaId, $subdir = '') {
|
public function fetchAndStoreFromGraph($mediaId, $subdir = '') {
|
||||||
@@ -180,50 +165,115 @@ class MediaService {
|
|||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback a wget cuando curl falla (OpenSSL incompatibilidad con Facebook CDN)
|
// Fallback: file_get_contents con stream context (usa implementación SSL diferente a curl)
|
||||||
error_log("[MediaService::downloadUrl] curl failed (http={$http} errno={$errno} err={$err}), trying wget fallback...");
|
error_log("[MediaService::downloadUrl] curl failed (http={$http} errno={$errno} err={$err}), trying file_get_contents fallback...");
|
||||||
$content = $this->downloadWithWget($url, $headers);
|
$content = $this->fileGetContentsWithAuth($url);
|
||||||
|
if ($content !== false && strlen($content) > 0) {
|
||||||
|
error_log("[MediaService::downloadUrl] file_get_contents OK, " . strlen($content) . " bytes");
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: exec wget (solo funciona en CLI, no en php-fpm con exec deshabilitado)
|
||||||
|
$content = $this->shellDownload($url, $headers);
|
||||||
if ($content !== false) {
|
if ($content !== false) {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_log("[MediaService::downloadUrl] FAIL url=" . substr($url, 0, 120) . " http={$http} err={$err} wget=also_failed");
|
error_log("[MediaService::downloadUrl] FAIL url=" . substr($url, 0, 120) . " http={$http} err={$err} all_fallbacks_failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fallback: descargar con wget (usa GnuTLS en vez de OpenSSL, más compatible con Facebook CDN)
|
* Descargar usando file_get_contents con stream context (usa implementación SSL nativa de PHP, diferente a curl)
|
||||||
*/
|
*/
|
||||||
private function downloadWithWget($url, $headers = []) {
|
private function fileGetContentsWithAuth($url) {
|
||||||
|
$opts = [
|
||||||
|
'http' => [
|
||||||
|
'method' => 'GET',
|
||||||
|
'header' => "Authorization: Bearer {$this->token}\r\nUser-Agent: WhatsAppMediaFetcher/1.0\r\nAccept: */*\r\n",
|
||||||
|
'follow_location' => true,
|
||||||
|
'max_redirects' => 5,
|
||||||
|
'timeout' => 120,
|
||||||
|
'ignore_errors' => false,
|
||||||
|
],
|
||||||
|
'ssl' => [
|
||||||
|
'verify_peer' => true,
|
||||||
|
'verify_peer_name' => true,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$ctx = stream_context_create($opts);
|
||||||
|
$content = @file_get_contents($url, false, $ctx);
|
||||||
|
if ($content === false) {
|
||||||
|
$lastErr = error_get_last();
|
||||||
|
error_log("[MediaService::fileGetContentsWithAuth] FAIL: " . ($lastErr['message'] ?? 'unknown'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
error_log("[MediaService::shellDownload] Neither exec nor proc_open available");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$tmpFile = tempnam(sys_get_temp_dir(), 'wget_');
|
$tmpFile = tempnam(sys_get_temp_dir(), 'wget_');
|
||||||
$headerArgs = '';
|
$headerArgs = '';
|
||||||
foreach ($headers as $h) {
|
foreach ($headers as $h) {
|
||||||
// Solo pasar headers que wget soporte
|
|
||||||
$headerArgs .= ' --header=' . escapeshellarg($h);
|
$headerArgs .= ' --header=' . escapeshellarg($h);
|
||||||
}
|
}
|
||||||
// Intentar con GNU wget primero (soporta --prefer-family=IPv4)
|
|
||||||
$cmd = 'wget -q --prefer-family=IPv4 -O ' . escapeshellarg($tmpFile) . $headerArgs . ' ' . escapeshellarg($url) . ' 2>&1';
|
$cmd = 'wget -q --prefer-family=IPv4 -O ' . escapeshellarg($tmpFile) . $headerArgs . ' ' . escapeshellarg($url) . ' 2>&1';
|
||||||
exec($cmd, $output, $exitCode);
|
exec($cmd, $output, $exitCode);
|
||||||
|
|
||||||
if ($exitCode === 0 && file_exists($tmpFile) && filesize($tmpFile) > 0) {
|
if ($exitCode === 0 && file_exists($tmpFile) && filesize($tmpFile) > 0) {
|
||||||
$content = file_get_contents($tmpFile);
|
$content = file_get_contents($tmpFile);
|
||||||
unlink($tmpFile);
|
unlink($tmpFile);
|
||||||
error_log("[MediaService::downloadWithWget] OK, " . strlen($content) . " bytes");
|
error_log("[MediaService::shellDownload] wget OK, " . strlen($content) . " bytes");
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback sin --prefer-family (BusyBox wget no lo soporta)
|
error_log("[MediaService::shellDownload] wget FAIL exit={$exitCode}");
|
||||||
$cmd2 = 'wget -q -O ' . escapeshellarg($tmpFile) . $headerArgs . ' ' . escapeshellarg($url) . ' 2>&1';
|
if (file_exists($tmpFile)) unlink($tmpFile);
|
||||||
exec($cmd2, $output2, $exitCode2);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($exitCode2 === 0 && file_exists($tmpFile) && filesize($tmpFile) > 0) {
|
/**
|
||||||
|
* Descargar con proc_open (alternativa a exec)
|
||||||
|
*/
|
||||||
|
private function procOpenDownload($url, $headers = []) {
|
||||||
|
$tmpFile = tempnam(sys_get_temp_dir(), 'wget_');
|
||||||
|
$headerArgs = '';
|
||||||
|
foreach ($headers as $h) {
|
||||||
|
$headerArgs .= ' --header=' . escapeshellarg($h);
|
||||||
|
}
|
||||||
|
$cmd = 'wget -q --prefer-family=IPv4 -O ' . escapeshellarg($tmpFile) . $headerArgs . ' ' . escapeshellarg($url);
|
||||||
|
|
||||||
|
$proc = proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes);
|
||||||
|
if (!is_resource($proc)) {
|
||||||
|
error_log("[MediaService::procOpenDownload] proc_open failed");
|
||||||
|
if (file_exists($tmpFile)) unlink($tmpFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$stdout = stream_get_contents($pipes[1]); fclose($pipes[1]);
|
||||||
|
$stderr = stream_get_contents($pipes[2]); fclose($pipes[2]);
|
||||||
|
$exitCode = proc_close($proc);
|
||||||
|
|
||||||
|
if ($exitCode === 0 && file_exists($tmpFile) && filesize($tmpFile) > 0) {
|
||||||
$content = file_get_contents($tmpFile);
|
$content = file_get_contents($tmpFile);
|
||||||
unlink($tmpFile);
|
unlink($tmpFile);
|
||||||
error_log("[MediaService::downloadWithWget] OK (basic), " . strlen($content) . " bytes");
|
error_log("[MediaService::procOpenDownload] OK, " . strlen($content) . " bytes");
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_log("[MediaService::downloadWithWget] FAIL exit={$exitCode}/{$exitCode2} output=" . implode(' ', array_merge($output, $output2)));
|
error_log("[MediaService::procOpenDownload] FAIL exit={$exitCode} err={$stderr}");
|
||||||
if (file_exists($tmpFile)) unlink($tmpFile);
|
if (file_exists($tmpFile)) unlink($tmpFile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user