From d4345cb15066f289a0ef8e0628da362462fad850 Mon Sep 17 00:00:00 2001 From: lizandrogd <77708265+lizandrogd@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:56:12 -0500 Subject: [PATCH] Update media-url.php --- api/version/media-url.php | 85 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/api/version/media-url.php b/api/version/media-url.php index 82e07cf..9a52ee4 100644 --- a/api/version/media-url.php +++ b/api/version/media-url.php @@ -127,14 +127,16 @@ if ($download) { $headers = ['User-Agent: WhatsAppMediaProxy/1.0', 'Accept: */*']; if ($token) $headers[] = 'Authorization: Bearer ' . $token; + // Pedimos cabeceras + body para poder extraer Content-Disposition curl_setopt_array($ch, [ CURLOPT_URL => $mediaUrl, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_TIMEOUT => 60, CURLOPT_HTTPHEADER => $headers, + CURLOPT_HEADER => true, ]); - $content = curl_exec($ch); + $response = curl_exec($ch); $info = curl_getinfo($ch); $err = curl_error($ch); curl_close($ch); @@ -146,14 +148,85 @@ if ($download) { exit; } - // Cabeceras para descarga + $headerSize = isset($info['header_size']) ? (int)$info['header_size'] : 0; + $headersText = $headerSize ? substr($response, 0, $headerSize) : ''; + $body = $headerSize ? substr($response, $headerSize) : $response; + + // Parsear cabeceras simples + $parsed = []; + if ($headersText) { + $lines = preg_split('/\r?\n/', $headersText); + foreach ($lines as $line) { + if (strpos($line, ':') !== false) { + list($n, $v) = explode(':', $line, 2); + $parsed[strtolower(trim($n))] = trim($v); + } + } + } + + $contentType = $parsed['content-type'] ?? ($info['content_type'] ?? null); + + // Si la respuesta es JSON, retornar el error en JSON (evitar descargar JSON como archivo) + if ($contentType && stripos($contentType, 'application/json') !== false) { + $decoded = json_decode($body, true); + http_response_code($decoded && isset($decoded['error']) ? 502 : 500); + header('Content-Type: application/json; charset=utf-8'); + echo json_encode(['success' => false, 'error' => 'Remote server returned JSON instead of file', 'remote' => $decoded]); + exit; + } + + // Determinar filename desde Content-Disposition o URL como fallback + $filename = null; + $cd = $parsed['content-disposition'] ?? null; + if ($cd) { + if (preg_match('/filename\*=(?:[^']*'')?(.+)$/i', $cd, $m)) { + $filename = trim($m[1], " \"'\r\n"); + $filename = rawurldecode($filename); + } elseif (preg_match('/filename="?([^";]+)"?/i', $cd, $m)) { + $filename = trim($m[1]); + } + } + + if (!$filename) { + $path = parse_url($mediaUrl, PHP_URL_PATH) ?: ''; + $basename = basename($path); + if ($basename && $basename !== '/') { + $filename = $basename; + } + } + + // Si aún no hay filename, intentar deducir extensión desde content-type + if (!$filename) { + $ext = ''; + $mimeMap = [ + 'application/pdf' => '.pdf', + 'text/csv' => '.csv', + 'image/jpeg' => '.jpg', + 'image/png' => '.png', + 'application/zip' => '.zip', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => '.xlsx', + 'application/vnd.ms-excel' => '.xls', + ]; + if ($contentType && isset($mimeMap[strtolower($contentType)])) { + $ext = $mimeMap[strtolower($contentType)]; + } + $filename = 'download' . $ext; + } + + if ($body === null || $body === '') { + http_response_code(502); + header('Content-Type: application/json; charset=utf-8'); + echo json_encode(['success' => false, 'error' => 'Empty response body from remote']); + exit; + } + + // Enviar body como descarga header_remove('Content-Type'); header('Cache-Control: public, max-age=3600'); - if (!empty($info['content_type'])) header('Content-Type: ' . $info['content_type']); - if (!empty($info['size_download'])) header('Content-Length: ' . $info['size_download']); - $filename = basename(parse_url($mediaUrl, PHP_URL_PATH) ?: 'file'); + if (!empty($contentType)) header('Content-Type: ' . $contentType); + header('Content-Length: ' . strlen($body)); header('Content-Disposition: attachment; filename="' . $filename . '"'); - echo $content; + echo $body; exit; }