mirror of
https://github.com/michalcz10/USB-RAID-Array.git
synced 2026-11-11 16:09:03 +00:00
217 lines
9.2 KiB
PHP
217 lines
9.2 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../../includes/auth.php';
|
|
requireLogin('../../index.php');
|
|
requirePermission('downPer', 'You do not have permission to perform this operation.');
|
|
session_write_close();
|
|
|
|
set_time_limit(900); // 15 minutes max execution time
|
|
|
|
ob_start();
|
|
|
|
try {
|
|
require_once __DIR__ . '/../../config/config.php';
|
|
|
|
$logFile = __DIR__ . '/download_log.txt';
|
|
file_put_contents($logFile, "Download started: " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
|
|
|
|
$sftp = null;
|
|
try {
|
|
$sftp = initializeSFTP();
|
|
file_put_contents($logFile, "SFTP connection established\n", FILE_APPEND);
|
|
} catch (Exception $exception) {
|
|
file_put_contents($logFile, "SFTP connection failed: " . $exception->getMessage() . "\n", FILE_APPEND);
|
|
throw new Exception("Failed to connect to SFTP server: " . $exception->getMessage());
|
|
}
|
|
|
|
function zipFolderRecursive($sftp, $remoteBasePath, $currentPath, $zip, $logFile, &$temporaryFiles) {
|
|
file_put_contents($logFile, "Processing directory: $currentPath\n", FILE_APPEND);
|
|
|
|
$files = $sftp->nlist($currentPath);
|
|
|
|
if ($files === false) {
|
|
file_put_contents($logFile, "Failed to list directory contents for: $currentPath\n", FILE_APPEND);
|
|
throw new Exception("Failed to list directory contents for: $currentPath");
|
|
}
|
|
|
|
file_put_contents($logFile, "Found " . count($files) . " items in $currentPath\n", FILE_APPEND);
|
|
|
|
foreach ($files as $fileName) {
|
|
if ($fileName == '.' || $fileName == '..') continue;
|
|
|
|
$remotePath = rtrim($currentPath, '/') . '/' . $fileName;
|
|
|
|
$relativePath = substr($remotePath, strlen(rtrim(remoteDirname($remoteBasePath), '/')) + 1);
|
|
file_put_contents($logFile, "Processing: $remotePath (relative: $relativePath)\n", FILE_APPEND);
|
|
|
|
$isDirectory = $sftp->is_dir($remotePath);
|
|
|
|
if ($isDirectory) {
|
|
file_put_contents($logFile, "Found subdirectory: $remotePath\n", FILE_APPEND);
|
|
$zip->addEmptyDir($relativePath);
|
|
|
|
zipFolderRecursive($sftp, $remoteBasePath, $remotePath, $zip, $logFile, $temporaryFiles);
|
|
} else {
|
|
$temporaryFile = tempnam(sys_get_temp_dir(), 'sftp');
|
|
$temporaryFiles[] = $temporaryFile;
|
|
file_put_contents($logFile, "Downloading to temp file: $temporaryFile\n", FILE_APPEND);
|
|
|
|
$downloadStart = time();
|
|
$downloadSuccess = $sftp->get($remotePath, $temporaryFile);
|
|
$downloadTime = time() - $downloadStart;
|
|
|
|
if ($downloadSuccess) {
|
|
$fileSize = filesize($temporaryFile);
|
|
file_put_contents($logFile, "Download successful ($downloadTime seconds), size: $fileSize bytes\n", FILE_APPEND);
|
|
|
|
$zip->addFile($temporaryFile, $relativePath);
|
|
} else {
|
|
file_put_contents($logFile, "Failed to download file after $downloadTime seconds\n", FILE_APPEND);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function zipFolder($sftp, $folderPath, $zipFilePath, $logFile) {
|
|
file_put_contents($logFile, "Starting to zip folder recursively: $folderPath\n", FILE_APPEND);
|
|
|
|
$zip = new ZipArchive();
|
|
|
|
if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
|
|
file_put_contents($logFile, "Failed to create zip archive\n", FILE_APPEND);
|
|
throw new Exception("Unable to create the zip file.");
|
|
}
|
|
|
|
|
|
$temporaryFiles = [];
|
|
|
|
try {
|
|
zipFolderRecursive($sftp, $folderPath, $folderPath, $zip, $logFile, $temporaryFiles);
|
|
|
|
file_put_contents($logFile, "Closing zip file\n", FILE_APPEND);
|
|
$zipSuccess = $zip->close();
|
|
|
|
foreach ($temporaryFiles as $temporaryFile) {
|
|
if (file_exists($temporaryFile)) {
|
|
@unlink($temporaryFile);
|
|
}
|
|
}
|
|
|
|
if ($zipSuccess) {
|
|
file_put_contents($logFile, "Zip created successfully, size: " . filesize($zipFilePath) . " bytes\n", FILE_APPEND);
|
|
return true;
|
|
} else {
|
|
file_put_contents($logFile, "Failed to create zip\n", FILE_APPEND);
|
|
return false;
|
|
}
|
|
} catch (Exception $exception) {
|
|
foreach ($temporaryFiles as $temporaryFile) {
|
|
if (file_exists($temporaryFile)) {
|
|
@unlink($temporaryFile);
|
|
}
|
|
}
|
|
|
|
file_put_contents($logFile, "Error during zip creation: " . $exception->getMessage() . "\n", FILE_APPEND);
|
|
throw $exception;
|
|
}
|
|
}
|
|
|
|
if (($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['file'])) ||
|
|
($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['file']))) {
|
|
|
|
$filePath = requireRemotePath($_SERVER['REQUEST_METHOD'] === 'POST' ? $_POST['file'] : $_GET['file'], $defaultPath);
|
|
file_put_contents($logFile, "Requested file: $filePath\n", FILE_APPEND);
|
|
|
|
$fileExists = $sftp->file_exists($filePath);
|
|
$isDirectory = $sftp->is_dir($filePath);
|
|
|
|
file_put_contents($logFile, "File exists: " . ($fileExists ? "Yes" : "No") . "\n", FILE_APPEND);
|
|
file_put_contents($logFile, "Is directory: " . ($isDirectory ? "Yes" : "No") . "\n", FILE_APPEND);
|
|
|
|
if (!$fileExists && !$isDirectory) {
|
|
throw new Exception("File not found: $filePath");
|
|
}
|
|
|
|
if ($isDirectory) {
|
|
$zipFilePath = tempnam(sys_get_temp_dir(), 'folder_') . '.zip';
|
|
file_put_contents($logFile, "Creating zip at: $zipFilePath\n", FILE_APPEND);
|
|
|
|
if (zipFolder($sftp, $filePath, $zipFilePath, $logFile)) {
|
|
if (file_exists($zipFilePath) && filesize($zipFilePath) > 0) {
|
|
file_put_contents($logFile, "Sending zip file to browser, size: " . filesize($zipFilePath) . " bytes\n", FILE_APPEND);
|
|
|
|
while (ob_get_level()) {
|
|
ob_end_clean();
|
|
}
|
|
|
|
header('Content-Type: application/zip');
|
|
header('Content-Disposition: attachment; filename="' . basename($filePath) . '.zip"');
|
|
header('Content-Length: ' . filesize($zipFilePath));
|
|
header('Cache-Control: no-cache, must-revalidate');
|
|
header('Pragma: no-cache');
|
|
|
|
readfile($zipFilePath);
|
|
file_put_contents($logFile, "Download completed\n", FILE_APPEND);
|
|
@unlink($zipFilePath);
|
|
exit;
|
|
} else {
|
|
throw new Exception("Failed to create zip file or zip file is empty");
|
|
}
|
|
} else {
|
|
throw new Exception("Failed to create zip archive");
|
|
}
|
|
} else {
|
|
$fileName = basename($filePath);
|
|
file_put_contents($logFile, "Downloading single file: $fileName\n", FILE_APPEND);
|
|
|
|
$temporaryFile = tempnam(sys_get_temp_dir(), 'file_');
|
|
|
|
$downloadStart = time();
|
|
$downloadSuccess = $sftp->get($filePath, $temporaryFile);
|
|
$downloadTime = time() - $downloadStart;
|
|
|
|
file_put_contents($logFile, "Download " . ($downloadSuccess ? "successful" : "failed") . " ($downloadTime seconds)\n", FILE_APPEND);
|
|
|
|
if ($downloadSuccess) {
|
|
$fileSize = filesize($temporaryFile);
|
|
file_put_contents($logFile, "Downloaded file size: $fileSize bytes\n", FILE_APPEND);
|
|
|
|
if ($fileSize > 0) {
|
|
while (ob_get_level()) {
|
|
ob_end_clean();
|
|
}
|
|
|
|
header('Content-Type: application/octet-stream');
|
|
header('Content-Disposition: attachment; filename="' . $fileName . '"');
|
|
header('Content-Length: ' . $fileSize);
|
|
header('Cache-Control: no-cache, must-revalidate');
|
|
header('Pragma: no-cache');
|
|
|
|
readfile($temporaryFile);
|
|
file_put_contents($logFile, "Download completed\n", FILE_APPEND);
|
|
@unlink($temporaryFile);
|
|
exit;
|
|
} else {
|
|
@unlink($temporaryFile);
|
|
throw new Exception("Downloaded file is empty");
|
|
}
|
|
} else {
|
|
@unlink($temporaryFile);
|
|
throw new Exception("Failed to download file from SFTP server");
|
|
}
|
|
}
|
|
} else {
|
|
throw new Exception("Invalid request method or missing file parameter");
|
|
}
|
|
} catch (Exception $exception) {
|
|
$errorMessage = "Error: " . $exception->getMessage();
|
|
file_put_contents($logFile, $errorMessage . "\n", FILE_APPEND);
|
|
|
|
while (ob_get_level()) {
|
|
ob_end_clean();
|
|
}
|
|
|
|
header("HTTP/1.1 500 Internal Server Error");
|
|
echo $errorMessage;
|
|
}
|
|
?>
|