--- app/(protected)/(basic)/contents/_components/content-video-field.tsx
+++ app/(protected)/(basic)/contents/_components/content-video-field.tsx
... | ... | @@ -5,7 +5,6 @@ |
| 5 | 5 |
import { FoxHelperText } from '@fox/core/components/fox-helper-text';
|
| 6 | 6 |
import {
|
| 7 | 7 |
FILE_MODULE, |
| 8 |
- MAX_STREAM_UPLOAD_BYTES, |
|
| 9 | 8 |
allowedExtensions, |
| 10 | 9 |
fileModuleAccept, |
| 11 | 10 |
isAllowedFileExtension, |
... | ... | @@ -43,13 +42,6 @@ |
| 43 | 42 |
); |
| 44 | 43 |
return; |
| 45 | 44 |
} |
| 46 |
- if (file.size > MAX_STREAM_UPLOAD_BYTES) {
|
|
| 47 |
- setError( |
|
| 48 |
- `${Math.floor(MAX_STREAM_UPLOAD_BYTES / 1_000_000)}MB 이하만 올릴 수 있습니다.`
|
|
| 49 |
- ); |
|
| 50 |
- return; |
|
| 51 |
- } |
|
| 52 |
- |
|
| 53 | 45 |
const body = new FormData(); |
| 54 | 46 |
body.set('file', file);
|
| 55 | 47 |
|
--- app/(protected)/(basic)/contents/upload/route.ts
+++ app/(protected)/(basic)/contents/upload/route.ts
... | ... | @@ -1,9 +1,6 @@ |
| 1 | 1 |
import { getSessionAccessToken, verifySession } from '@/lib/auth/dal';
|
| 2 | 2 |
import { backendFetchUpload } from '@/lib/http/backend-fetch';
|
| 3 |
-import {
|
|
| 4 |
- MAX_STREAM_UPLOAD_BYTES, |
|
| 5 |
- findFileModule, |
|
| 6 |
-} from '@/lib/domain/file-module'; |
|
| 3 |
+import { findFileModule } from '@/lib/domain/file-module';
|
|
| 7 | 4 |
|
| 8 | 5 |
/** |
| 9 | 6 |
* 큰 파일 업로드 중계 — 브라우저 → 이 라우트 → 백엔드로 본문을 그대로 흘려보낸다. |
... | ... | @@ -11,6 +8,10 @@ |
| 11 | 8 |
* Server Action을 쓰지 않는 이유는 그 경로의 multipart가 10MB 부근에서 잘리기 때문이다 |
| 12 | 9 |
* (`MAX_ATTACHMENT_BYTES` 주석). 브라우저가 백엔드를 직접 부를 수는 없다 — 토큰이 httpOnly |
| 13 | 10 |
* 세션 안에만 있어서 여기서 붙여 준다. |
| 11 |
+ * |
|
| 12 |
+ * 크기를 여기서 막지 않는다(사용자 확정). 본문을 버퍼에 담지 않고 그대로 흘려보내므로 이 |
|
| 13 |
+ * 라우트에는 상한이 필요 없고, 실제 한도는 앞단 프록시와 백엔드가 정한다 — 넘으면 413이 |
|
| 14 |
+ * 사유와 함께 화면까지 올라간다. |
|
| 14 | 15 |
*/ |
| 15 | 16 |
|
| 16 | 17 |
const UPLOAD_PATH = '/api/v1/common/file/upload'; |
... | ... | @@ -31,14 +32,6 @@ |
| 31 | 32 |
const contentType = request.headers.get('content-type') ?? '';
|
| 32 | 33 |
if (!contentType.startsWith('multipart/form-data')) {
|
| 33 | 34 |
return fail(400, '요청 형식이 올바르지 않습니다.'); |
| 34 |
- } |
|
| 35 |
- |
|
| 36 |
- const declaredLength = Number(request.headers.get('content-length') ?? '');
|
|
| 37 |
- if (Number.isFinite(declaredLength) && declaredLength > MAX_STREAM_UPLOAD_BYTES) {
|
|
| 38 |
- return fail( |
|
| 39 |
- 413, |
|
| 40 |
- `${Math.floor(MAX_STREAM_UPLOAD_BYTES / 1_000_000)}MB 이하만 올릴 수 있습니다.`
|
|
| 41 |
- ); |
|
| 42 | 35 |
} |
| 43 | 36 |
|
| 44 | 37 |
if (!request.body) {
|
--- lib/domain/file-module.ts
+++ lib/domain/file-module.ts
... | ... | @@ -126,6 +126,3 @@ |
| 126 | 126 |
* 없다. 더 큰 파일은 미들웨어에서 제외한 스트리밍 라우트(`/contents/upload`)로 보낸다. |
| 127 | 127 |
*/ |
| 128 | 128 |
export const MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024; |
| 129 |
- |
|
| 130 |
-/** 스트리밍 업로드 상한 — 백엔드 `multipartResolver`의 `maxUploadSize`(100,000,000)와 같은 값. */ |
|
| 131 |
-export const MAX_STREAM_UPLOAD_BYTES = 100_000_000; |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?