&path= // ───────────────────────────────────────── if ($action === "request_dl") { if (!$id || !$path) { echo json_encode(["error" => "missing params"]); exit; } $token = bin2hex(random_bytes(8)); $reqFile = $uploadDir . "req_{$id}.json"; $reqs = file_exists($reqFile) ? json_decode(file_get_contents($reqFile), true) : []; $reqs[] = ["token" => $token, "path" => $path]; file_put_contents($reqFile, json_encode($reqs), LOCK_EX); echo json_encode(["status" => "ok", "token" => $token]); exit; } // ───────────────────────────────────────── // CLIENTE → consulta si hay solicitudes pendientes de descarga // GET /cloudfile.php?action=requests&id= // ───────────────────────────────────────── if ($action === "requests") { if (!$id) { echo json_encode(["requests" => []]); exit; } $reqFile = $uploadDir . "req_{$id}.json"; if (!file_exists($reqFile)) { echo json_encode(["requests" => []]); exit; } $reqs = json_decode(file_get_contents($reqFile), true) ?? []; // Limpiar después de entregar file_put_contents($reqFile, "[]", LOCK_EX); echo json_encode(["requests" => $reqs]); exit; } // ───────────────────────────────────────── // CLIENTE → sube el archivo solicitado // POST /cloudfile.php?action=store&id=&token=&name= // Body: raw bytes del archivo // ───────────────────────────────────────── if ($action === "store") { if (!$id || !$token) { echo json_encode(["error" => "missing"]); exit; } $name = basename($_GET['name'] ?? "file"); $fname = $uploadDir . "dl_{$id}_{$token}"; $bytes = file_get_contents("php://input"); if (!$bytes) { echo json_encode(["error" => "empty body"]); exit; } file_put_contents($fname, $bytes, LOCK_EX); file_put_contents($fname . ".meta", json_encode(["name" => $name, "size" => strlen($bytes), "time" => time()]), LOCK_EX); echo json_encode(["status" => "ok"]); exit; } // ───────────────────────────────────────── // PANEL → descarga el archivo que subió el cliente // GET /cloudfile.php?action=fetch&id=&token= // ───────────────────────────────────────── if ($action === "fetch") { if (!$id || !$token) { echo json_encode(["error" => "missing"]); exit; } $fname = $uploadDir . "dl_{$id}_{$token}"; $meta = $fname . ".meta"; if (!file_exists($fname)) { echo json_encode(["ready" => false]); exit; } $info = file_exists($meta) ? json_decode(file_get_contents($meta), true) : []; $name = $info['name'] ?? "download"; $b64 = base64_encode(file_get_contents($fname)); // Limpiar tras entregar unlink($fname); if (file_exists($meta)) unlink($meta); echo json_encode(["ready" => true, "name" => $name, "b64" => $b64]); exit; } // ───────────────────────────────────────── // PANEL → sube archivo para que el cliente lo guarde (upload al cliente) // POST /cloudfile.php?action=push&id=&path= // Body: raw bytes // ───────────────────────────────────────── if ($action === "push") { if (!$id || !$path) { echo json_encode(["error" => "missing params"]); exit; } $token = bin2hex(random_bytes(8)); $fname = $uploadDir . "up_{$id}_{$token}"; $bytes = file_get_contents("php://input"); if (!$bytes) { echo json_encode(["error" => "empty body"]); exit; } file_put_contents($fname, $bytes, LOCK_EX); $pendingFile = $uploadDir . "pending_{$id}.json"; $pending = file_exists($pendingFile) ? json_decode(file_get_contents($pendingFile), true) : []; $pending[] = ["token" => $token, "path" => $path, "file" => $fname, "size" => strlen($bytes)]; file_put_contents($pendingFile, json_encode($pending), LOCK_EX); echo json_encode(["status" => "ok", "token" => $token]); exit; } // ───────────────────────────────────────── // CLIENTE → consulta uploads pendientes del panel // GET /cloudfile.php?action=pending&id= // ───────────────────────────────────────── if ($action === "pending") { if (!$id) { echo json_encode(["pending" => []]); exit; } $pendingFile = $uploadDir . "pending_{$id}.json"; if (!file_exists($pendingFile)) { echo json_encode(["pending" => []]); exit; } $pending = json_decode(file_get_contents($pendingFile), true) ?? []; echo json_encode(["pending" => $pending]); exit; } // ───────────────────────────────────────── // CLIENTE → descarga un archivo pendiente de cloudfile // GET /cloudfile.php?action=pull&id=&token= // ───────────────────────────────────────── if ($action === "pull") { if (!$id || !$token) { echo json_encode(["error" => "missing"]); exit; } // El archivo se guardó como up__ $fname = $uploadDir . "up_{$id}_{$token}"; if (!file_exists($fname)) { echo json_encode(["error" => "not found"]); exit; } $b64 = base64_encode(file_get_contents($fname)); // Limpiar archivo temporal unlink($fname); // Quitar de pending $pendingFile = $uploadDir . "pending_{$id}.json"; if (file_exists($pendingFile)) { $pending = json_decode(file_get_contents($pendingFile), true) ?? []; $pending = array_filter($pending, fn($p) => $p["token"] !== $token); file_put_contents($pendingFile, json_encode(array_values($pending)), LOCK_EX); } echo json_encode(["status" => "ok", "b64" => $b64]); exit; } // ───────────────────────────────────────── // GUI → PHP descarga URL y la pone como pending para el cliente // GET /cloudfile.php?action=url_dl&id=&url=&dest= // ───────────────────────────────────────── if ($action === "url_dl") { if (!$id) { echo json_encode(["error" => "missing id"]); exit; } $url_b64 = $_GET['url'] ?? null; $dest_b64 = $_GET['dest'] ?? null; if (!$url_b64 || !$dest_b64) { echo json_encode(["error" => "missing url or dest"]); exit; } $url = base64_decode($url_b64); $dest_path = base64_decode($dest_b64); $filename = basename(parse_url($url, PHP_URL_PATH)); if (!$filename || strpos($filename, ".") === false) { $filename = "downloaded_file"; } $dest_full = rtrim($dest_path, "\/") . DIRECTORY_SEPARATOR . $filename; // Descargar via cURL con SSL flexible y User-Agent $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 120, CURLOPT_SSL_VERIFYPEER => false, // tolerar SSL roto CURLOPT_SSL_VERIFYHOST => false, CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", CURLOPT_ENCODING => "", // aceptar gzip/deflate CURLOPT_HEADER => false, ]); $content = curl_exec($ch); $err = curl_error($ch); $http = curl_getinfo($ch, CURLINFO_HTTP_CODE); // Intentar obtener nombre real desde Content-Disposition $cd_info = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); curl_close($ch); if ($content === false || $err) { echo json_encode(["error" => "curl error: $err"]); exit; } if ($http < 200 || $http >= 400) { echo json_encode(["error" => "HTTP $http"]); exit; } // Guardar temporalmente y poner como pending para el cliente $token = bin2hex(random_bytes(8)); $tmpFile = $uploadDir . "up_{$id}_{$token}"; file_put_contents($tmpFile, $content, LOCK_EX); $pendingFile = $uploadDir . "pending_{$id}.json"; $pending = file_exists($pendingFile) ? json_decode(file_get_contents($pendingFile), true) ?? [] : []; $pending[] = [ "token" => $token, "path" => $dest_full, "size" => strlen($content) ]; file_put_contents($pendingFile, json_encode($pending), LOCK_EX); echo json_encode([ "status" => "ok", "filename" => $filename, "size" => strlen($content), "dest" => $dest_full ]); exit; } echo json_encode(["error" => "invalid action: " . $action]);