Files
simple-file-share/merge_chunks.php
2025-06-13 14:59:47 +03:00

189 lines
5.7 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// Включаем отображение всех ошибок для отладки
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
session_start();
try {
error_log("=== MERGE CHUNKS START ===");
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/functions.php';
// Проверка авторизации
if (!isset($_SESSION['logged_in'])) {
error_log("ERROR: User not logged in");
http_response_code(403);
echo "Not authorized";
exit;
}
// Получение и проверка JSON данных
$input = file_get_contents('php://input');
error_log("Input data: " . $input);
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
error_log("ERROR: JSON decode error: " . json_last_error_msg());
http_response_code(400);
echo "Invalid JSON data";
exit;
}
error_log("Decoded data: " . print_r($data, true));
// Проверка CSRF токена
$csrf_token = $data['csrf_token'] ?? '';
if (!verifyCSRFToken($csrf_token)) {
error_log("ERROR: CSRF token verification failed");
http_response_code(403);
echo "CSRF token verification failed";
exit;
}
$filename = getSafeFileName($data['filename'] ?? '');
$total = intval($data['total'] ?? 0);
error_log("Processing merge: filename='$filename', total=$total");
// Валидация данных
if (empty($filename) || $total <= 0) {
error_log("ERROR: Invalid parameters");
http_response_code(400);
echo "Invalid parameters";
exit;
}
// Валидация имени файла
if (!validateFileName($filename)) {
error_log("ERROR: Invalid filename: $filename");
http_response_code(400);
echo "Invalid filename";
exit;
}
$tmpDir = CHUNK_DIR . $filename;
$finalPath = UPLOAD_DIR . $filename;
error_log("Chunk directory: $tmpDir");
error_log("Final path: $finalPath");
// Проверка существования директории с чанками
if (!file_exists($tmpDir)) {
error_log("ERROR: Chunk directory does not exist: $tmpDir");
http_response_code(400);
echo "Chunk directory not found";
exit;
}
// Проверка всех чанков и подсчет общего размера
$totalSize = 0;
$missingChunks = [];
for ($i = 0; $i < $total; $i++) {
$partPath = "$tmpDir/$i.part";
if (!file_exists($partPath)) {
$missingChunks[] = $i;
} else {
$chunkSize = filesize($partPath);
$totalSize += $chunkSize;
error_log("Chunk $i size: $chunkSize bytes");
}
}
if (!empty($missingChunks)) {
error_log("ERROR: Missing chunks: " . implode(', ', $missingChunks));
http_response_code(400);
echo "Missing chunks: " . implode(', ', $missingChunks);
exit;
}
error_log("Total file size: $totalSize bytes");
error_log("Max allowed size: " . getMaxFileSize() . " bytes");
// Проверка размера файла
if ($totalSize > getMaxFileSize()) {
error_log("ERROR: File too large");
// Очистка чанков
for ($i = 0; $i < $total; $i++) {
@unlink("$tmpDir/$i.part");
}
@rmdir($tmpDir);
http_response_code(413); // Payload Too Large
echo "File too large";
exit;
}
// Проверка прав на запись в директорию загрузок
if (!is_writable(UPLOAD_DIR)) {
error_log("ERROR: Upload directory is not writable: " . UPLOAD_DIR);
http_response_code(500);
echo "Upload directory is not writable";
exit;
}
// Объединение чанков
error_log("Starting file merge");
$out = fopen($finalPath, 'wb');
if (!$out) {
error_log("ERROR: Cannot create final file: $finalPath");
http_response_code(500);
echo "Cannot create final file";
exit;
}
for ($i = 0; $i < $total; $i++) {
$partPath = "$tmpDir/$i.part";
error_log("Merging chunk $i from $partPath");
$in = fopen($partPath, 'rb');
if (!$in) {
error_log("ERROR: Cannot open chunk $i");
fclose($out);
@unlink($finalPath);
http_response_code(500);
echo "Cannot open chunk $i";
exit;
}
$copied = stream_copy_to_stream($in, $out);
fclose($in);
error_log("Copied $copied bytes from chunk $i");
// Удаление чанка после успешного копирования
if (!unlink($partPath)) {
error_log("WARNING: Cannot delete chunk $i");
}
}
fclose($out);
// Удаление директории чанков
if (!rmdir($tmpDir)) {
error_log("WARNING: Cannot delete chunk directory: $tmpDir");
}
$finalSize = filesize($finalPath);
error_log("Final file size: $finalSize bytes");
error_log("SUCCESS: File merged successfully");
http_response_code(200);
echo "OK";
error_log("=== MERGE CHUNKS END ===");
} catch (Exception $e) {
error_log("EXCEPTION in merge_chunks.php: " . $e->getMessage());
error_log("Stack trace: " . $e->getTraceAsString());
http_response_code(500);
echo "Server error: " . $e->getMessage();
} catch (Error $e) {
error_log("FATAL ERROR in merge_chunks.php: " . $e->getMessage());
error_log("Stack trace: " . $e->getTraceAsString());
http_response_code(500);
echo "Fatal error: " . $e->getMessage();
}