import fs from 'fs' import path from 'path' import { lookup } from 'mime-types' import { createError, setHeader, sendStream } from 'h3' const config = useRuntimeConfig() const FOLDER_PATH = config.public.folder_path; export default defineEventHandler(async (event) => { const rawName = event.context.params?.name as string | undefined if (!rawName) { throw createError({ statusCode: 400, statusMessage: 'Nama file tidak diberikan' }) } const name = decodeURIComponent(rawName) const safeName = path.basename(name) if (safeName !== name) { throw createError({ statusCode: 400, statusMessage: 'Nama file tidak valid' }) } const filePath = path.join(FOLDER_PATH, safeName) if (!fs.existsSync(filePath)) { throw createError({ statusCode: 404, statusMessage: 'File tidak ditemukan' }) } // Ambil ekstensi file (lowercase) const ext = path.extname(safeName).toLowerCase() let mimeType = (lookup(safeName) as string) || 'application/octet-stream' // Koreksi MIME type umum switch (ext) { case '.mp4': mimeType = 'video/mp4' break case '.mkv': mimeType = 'video/x-matroska' break case '.avi': mimeType = 'video/x-msvideo' break case '.mov': mimeType = 'video/quicktime' break case '.exe': case '.msi': mimeType = 'application/octet-stream' break case '.gif': mimeType = 'image/gif' break } setHeader(event, 'Content-Type', mimeType) setHeader(event, 'Cache-Control', 'no-cache') setHeader(event, 'Content-Disposition', `inline; filename="${safeName}"`) const stream = fs.createReadStream(filePath) return sendStream(event, stream) })