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(); }