189 lines
5.7 KiB
PHP
189 lines
5.7 KiB
PHP
<?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();
|
||
}
|