Upload files via form chunks

This commit is contained in:
Mikei386
2026-06-23 21:53:49 +02:00
parent c661cbaf46
commit 76fc7e7251
6 changed files with 82 additions and 26 deletions
@@ -7,6 +7,44 @@ if (!is_dir($target['path'])) {
unav_error(400, 'Upload target must be a directory');
}
if (($_POST['uploadMode'] ?? '') === 'chunk') {
$relativeName = (string)($_POST['relativePath'] ?? '');
$chunkIndex = filter_var($_POST['chunkIndex'] ?? null, FILTER_VALIDATE_INT);
$totalChunks = filter_var($_POST['totalChunks'] ?? null, FILTER_VALIDATE_INT);
$encoded = (string)($_POST['data'] ?? '');
if ($relativeName === '' || $chunkIndex === false || $totalChunks === false || $chunkIndex < 0 || $totalChunks < 1 || $chunkIndex >= $totalChunks) {
unav_error(400, 'Invalid upload chunk');
}
$destination = unav_prepare_upload_destination($target['path'], $relativeName);
$temporary = $destination['path'] . '.u-nav-upload';
if ($chunkIndex === 0) {
@unlink($temporary);
} elseif (!is_file($temporary)) {
unav_error(400, 'Upload session not found');
}
$data = base64_decode($encoded, true);
if ($data === false) {
unav_error(400, 'Invalid upload data');
}
if (file_put_contents($temporary, $data, $chunkIndex === 0 ? LOCK_EX : FILE_APPEND | LOCK_EX) === false) {
unav_error(500, 'Could not write upload chunk');
}
$complete = $chunkIndex === $totalChunks - 1;
if ($complete && !rename($temporary, $destination['path'])) {
@unlink($temporary);
unav_error(500, 'Could not finalize upload');
}
unav_json([
'uploaded' => $complete ? [[
'name' => $destination['relative'],
'size' => filesize($destination['path']) ?: 0,
]] : [],
'chunk' => $chunkIndex + 1,
'totalChunks' => $totalChunks,
'complete' => $complete,
], $complete ? 201 : 202);
}
if (isset($_GET['relativePath']) || isset($_SERVER['HTTP_X_UNAV_RELATIVE_PATH'])) {
$relativeName = (string)($_GET['relativePath'] ?? $_SERVER['HTTP_X_UNAV_RELATIVE_PATH']);
$destination = unav_prepare_upload_destination($target['path'], $relativeName);