qwen_agent/upload.php
2026-06-14 16:46:27 +08:00

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