blob: b9dd14d11a9246582d44eb476fde0840c75152f9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
import { NextRequest } from "next/server"
import { join } from "path"
import { readFile } from "fs/promises"
export async function GET(request: NextRequest) {
try {
const searchParams = request.nextUrl.searchParams
const filePath = searchParams.get("path")
if (!filePath) {
return new Response("File path is required", { status: 400 })
}
// 보안: 경로 조작 방지
if (filePath.includes("..") || !filePath.startsWith("/techsales-rfq/")) {
return new Response("Invalid file path", { status: 400 })
}
// 파일 경로 구성 (public 폴더 기준)
const fullPath = join(process.cwd(), "public", filePath)
try {
// 파일 읽기
const fileBuffer = await readFile(fullPath)
// 파일명 추출
const fileName = filePath.split("/").pop() || "download"
// MIME 타입 결정
const ext = fileName.split(".").pop()?.toLowerCase()
let contentType = "application/octet-stream"
switch (ext) {
case "pdf":
contentType = "application/pdf"
break
case "doc":
contentType = "application/msword"
break
case "docx":
contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
break
case "xls":
contentType = "application/vnd.ms-excel"
break
case "xlsx":
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
break
case "jpg":
case "jpeg":
contentType = "image/jpeg"
break
case "png":
contentType = "image/png"
break
case "gif":
contentType = "image/gif"
break
case "txt":
contentType = "text/plain"
break
case "zip":
contentType = "application/zip"
break
default:
contentType = "application/octet-stream"
}
// 응답 헤더 설정
const headers = new Headers({
"Content-Type": contentType,
"Content-Disposition": `attachment; filename="${encodeURIComponent(fileName)}"`,
"Content-Length": fileBuffer.length.toString(),
})
return new Response(fileBuffer, { headers })
} catch (fileError) {
console.error("File read error:", fileError)
return new Response("File not found", { status: 404 })
}
} catch (error) {
console.error("Download error:", error)
return new Response("Internal server error", { status: 500 })
}
}
|