9.2 이미지/파일 업로드 서버 처리 및 검증 o

This commit is contained in:
koreacomp5
2025-10-09 17:51:05 +09:00
parent 0c66bf6fa7
commit b4d2a08de7
2 changed files with 19 additions and 2 deletions

View File

@@ -9,9 +9,26 @@ export async function POST(req: Request) {
const file = form.get("file") as File | null;
if (!file) return NextResponse.json({ error: "file required" }, { status: 400 });
// 검증: 이미지 MIME 및 용량 제한(5MB)
const ALLOWED = new Set(["image/jpeg", "image/png", "image/webp", "image/gif"]);
const MAX_SIZE = 5 * 1024 * 1024;
const contentType = (file as any).type || "";
if (!ALLOWED.has(contentType)) return NextResponse.json({ error: "invalid file type" }, { status: 400 });
const bytes = await file.arrayBuffer();
if (bytes.byteLength > MAX_SIZE) return NextResponse.json({ error: "file too large" }, { status: 400 });
const buffer = Buffer.from(bytes);
const ext = path.extname(file.name || "") || ".bin";
// 확장자 결정
const mimeToExt: Record<string, string> = {
"image/jpeg": ".jpg",
"image/png": ".png",
"image/webp": ".webp",
"image/gif": ".gif",
};
const inferredExt = mimeToExt[contentType] ?? ".bin";
const nameExt = path.extname(file.name || "");
const ext = nameExt && Object.values(mimeToExt).includes(nameExt.toLowerCase()) ? nameExt.toLowerCase() : inferredExt;
const uploadsDir = path.join(process.cwd(), "public", "uploads");
await fs.mkdir(uploadsDir, { recursive: true });
const filename = `${Date.now()}-${Math.random().toString(36).slice(2)}${ext}`;