92 lines
2.7 KiB
PHP
92 lines
2.7 KiB
PHP
<?php
|
|
// Simple file upload API. Saves uploaded files into the avatar directory.
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
// Only allow POST requests
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['code' => 405, 'message' => 'Method Not Allowed, use POST']);
|
|
exit;
|
|
}
|
|
|
|
// Form field name for the uploaded file
|
|
$field = 'file';
|
|
|
|
// Validate that a file was actually uploaded
|
|
if (!isset($_FILES[$field]) || $_FILES[$field]['error'] === UPLOAD_ERR_NO_FILE) {
|
|
http_response_code(400);
|
|
echo json_encode(['code' => 400, 'message' => 'No file uploaded, field name should be "file"']);
|
|
exit;
|
|
}
|
|
|
|
$file = $_FILES[$field];
|
|
|
|
// Check upload errors reported by PHP
|
|
if ($file['error'] !== UPLOAD_ERR_OK) {
|
|
http_response_code(400);
|
|
echo json_encode(['code' => 400, 'message' => 'Upload failed, error code: ' . $file['error']]);
|
|
exit;
|
|
}
|
|
|
|
// Limit file size to 5MB
|
|
$maxSize = 5 * 1024 * 1024;
|
|
if ($file['size'] > $maxSize) {
|
|
http_response_code(400);
|
|
echo json_encode(['code' => 400, 'message' => 'File too large, max 5MB']);
|
|
exit;
|
|
}
|
|
|
|
// Allow only common image types (detected by actual content, not the client-provided type)
|
|
$allowed = [
|
|
'image/jpeg' => 'jpg',
|
|
'image/png' => 'png',
|
|
'image/gif' => 'gif',
|
|
'image/webp' => 'webp',
|
|
];
|
|
|
|
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
|
$mime = $finfo->file($file['tmp_name']);
|
|
|
|
if (!isset($allowed[$mime])) {
|
|
http_response_code(400);
|
|
echo json_encode(['code' => 400, 'message' => 'Unsupported file type: ' . $mime]);
|
|
exit;
|
|
}
|
|
|
|
// Ensure the avatar directory exists
|
|
$uploadDir = __DIR__ . '/avatar';
|
|
if (!is_dir($uploadDir)) {
|
|
if (!mkdir($uploadDir, 0755, true) && !is_dir($uploadDir)) {
|
|
http_response_code(500);
|
|
echo json_encode(['code' => 500, 'message' => 'Failed to create avatar directory']);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Generate a safe, unique filename to avoid collisions and path traversal
|
|
$ext = $allowed[$mime];
|
|
$filename = bin2hex(random_bytes(16)) . '.' . $ext;
|
|
$target = $uploadDir . '/' . $filename;
|
|
|
|
// Move the uploaded file into place
|
|
if (!move_uploaded_file($file['tmp_name'], $target)) {
|
|
http_response_code(500);
|
|
echo json_encode(['code' => 500, 'message' => 'Failed to save file']);
|
|
exit;
|
|
}
|
|
|
|
// Build a public URL relative to the current script location
|
|
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
|
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
|
$basePath = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/\\');
|
|
$url = $scheme . '://' . $host . $basePath . '/avatar/' . $filename;
|
|
|
|
http_response_code(200);
|
|
echo json_encode([
|
|
'code' => 0,
|
|
'message' => 'success',
|
|
'filename' => $filename,
|
|
'url' => $url,
|
|
], JSON_UNESCAPED_SLASHES);
|