Use raw file uploads
This commit is contained in:
@@ -7,6 +7,31 @@ if (!is_dir($target['path'])) {
|
||||
unav_error(400, 'Upload target must be a directory');
|
||||
}
|
||||
|
||||
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);
|
||||
$input = fopen('php://input', 'rb');
|
||||
$output = fopen($destination['path'], 'xb');
|
||||
if (!$input || !$output) {
|
||||
if ($input) {
|
||||
fclose($input);
|
||||
}
|
||||
if ($output) {
|
||||
fclose($output);
|
||||
}
|
||||
unav_error(500, 'Could not open upload stream');
|
||||
}
|
||||
stream_copy_to_stream($input, $output);
|
||||
fclose($input);
|
||||
fclose($output);
|
||||
unav_json([
|
||||
'uploaded' => [[
|
||||
'name' => $destination['relative'],
|
||||
'size' => filesize($destination['path']) ?: 0,
|
||||
]],
|
||||
], 201);
|
||||
}
|
||||
|
||||
$uploaded = [];
|
||||
$names = unav_upload_array($_FILES['files']['name'] ?? []);
|
||||
$errors = unav_upload_array($_FILES['files']['error'] ?? []);
|
||||
@@ -17,33 +42,38 @@ foreach ($names as $index => $name) {
|
||||
unav_error(400, 'Upload failed');
|
||||
}
|
||||
$relativeName = $relativePaths[$index] ?? $name;
|
||||
$safeName = unav_upload_safe_relative_path((string)$relativeName);
|
||||
$destination = unav_prepare_upload_destination($target['path'], (string)$relativeName);
|
||||
if (!move_uploaded_file($tmpNames[$index] ?? '', $destination['path'])) {
|
||||
unav_error(500, 'Could not store uploaded file');
|
||||
}
|
||||
$uploaded[] = [
|
||||
'name' => $destination['relative'],
|
||||
'size' => filesize($destination['path']) ?: 0,
|
||||
];
|
||||
}
|
||||
|
||||
unav_json(['uploaded' => $uploaded], 201);
|
||||
|
||||
function unav_prepare_upload_destination(string $targetPath, string $relativeName): array {
|
||||
$safeName = unav_upload_safe_relative_path($relativeName);
|
||||
$relativeParent = dirname($safeName);
|
||||
if ($relativeParent !== '.') {
|
||||
$parentCandidate = $target['path'] . '/' . $relativeParent;
|
||||
unav_root_for_real($target['path']);
|
||||
$parentCandidate = $targetPath . '/' . $relativeParent;
|
||||
unav_root_for_real($targetPath);
|
||||
if (!is_dir($parentCandidate) && !mkdir($parentCandidate, 0777, true) && !is_dir($parentCandidate)) {
|
||||
unav_error(500, 'Could not create upload directory');
|
||||
}
|
||||
}
|
||||
$destination = unav_destination_path($target['path'] . '/' . $safeName);
|
||||
$destination = unav_destination_path($targetPath . '/' . $safeName);
|
||||
if (file_exists($destination['path'])) {
|
||||
unav_error(409, 'Destination already exists');
|
||||
}
|
||||
if (!is_dir(dirname($destination['path']))) {
|
||||
unav_error(500, 'Could not create upload directory');
|
||||
}
|
||||
if (!move_uploaded_file($tmpNames[$index] ?? '', $destination['path'])) {
|
||||
unav_error(500, 'Could not store uploaded file');
|
||||
}
|
||||
$uploaded[] = [
|
||||
'name' => $safeName,
|
||||
'size' => filesize($destination['path']) ?: 0,
|
||||
];
|
||||
return ['path' => $destination['path'], 'relative' => $safeName];
|
||||
}
|
||||
|
||||
unav_json(['uploaded' => $uploaded], 201);
|
||||
|
||||
function unav_upload_array($value): array {
|
||||
if (is_array($value)) {
|
||||
return array_values($value);
|
||||
|
||||
Reference in New Issue
Block a user