summaryrefslogtreecommitdiff
path: root/app/api/files
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/files')
-rw-r--r--app/api/files/[...path]/route.ts38
1 files changed, 29 insertions, 9 deletions
diff --git a/app/api/files/[...path]/route.ts b/app/api/files/[...path]/route.ts
index 3fb60347..88211f5b 100644
--- a/app/api/files/[...path]/route.ts
+++ b/app/api/files/[...path]/route.ts
@@ -31,6 +31,7 @@ const getMimeType = (filePath: string): string => {
const isAllowedPath = (requestedPath: string): boolean => {
const allowedPaths = [
'basicContract',
+ 'contracts',
'basicContract/template',
'basicContract/signed',
'vendorFormReportSample',
@@ -64,7 +65,12 @@ export async function GET(
) {
try {
// 요청된 파일 경로 구성
- const requestedPath = params.path.join('/');
+ const decodedPath = params.path.map(segment =>
+ decodeURIComponent(segment)
+ );
+
+ // 디코딩된 경로로 조합
+ const requestedPath = decodedPath.join('/');
console.log(`📂 파일 요청: ${requestedPath}`);
@@ -124,10 +130,14 @@ export async function GET(
console.log(`✅ 파일 서빙 성공: ${fileName} (${stats.size} bytes)`);
- // ✅ Content-Disposition 헤더 결정
+ const encodedFileName = encodeURIComponent(fileName)
+ .replace(/'/g, "%27")
+ .replace(/"/g, "%22");
+
const contentDisposition = forceDownload
- ? `attachment; filename="${fileName}"` // 강제 다운로드
- : `inline; filename="${fileName}"`; // 브라우저에서 열기
+ ? `attachment; filename="${encodedFileName}"; filename*=UTF-8''${encodedFileName}`
+ : `inline; filename="${encodedFileName}"; filename*=UTF-8''${encodedFileName}`;
+
// Range 요청 처리 (큰 파일의 부분 다운로드 지원)
const range = request.headers.get('range');
@@ -176,7 +186,12 @@ export async function HEAD(
{ params }: { params: { path: string[] } }
) {
try {
- const requestedPath = params.path.join('/');
+ const decodedPath = params.path.map(segment =>
+ decodeURIComponent(segment)
+ );
+
+ // 디코딩된 경로로 조합
+ const requestedPath = decodedPath.join('/');
// ✅ HEAD 요청에서도 다운로드 강제 여부 확인
const url = new URL(request.url);
@@ -207,11 +222,16 @@ export async function HEAD(
const mimeType = getMimeType(filePath);
const fileName = path.basename(filePath);
- // ✅ HEAD 요청에서도 Content-Disposition 헤더 적용
- const contentDisposition = forceDownload
- ? `attachment; filename="${fileName}"` // 강제 다운로드
- : `inline; filename="${fileName}"`; // 브라우저에서 열기
+ const encodedFileName = encodeURIComponent(fileName)
+ .replace(/'/g, "%27")
+ .replace(/"/g, "%22");
+
+ const contentDisposition = forceDownload
+ ? `attachment; filename="${encodedFileName}"; filename*=UTF-8''${encodedFileName}`
+ : `inline; filename="${encodedFileName}"; filename*=UTF-8''${encodedFileName}`;
+
+
return new NextResponse(null, {
headers: {
'Content-Type': mimeType,