generated from ttipo/project-base
7c70862647
APK 받기가 일반 /api 로 가면 X-Accel-Buffering 이 외부 프록시로 넘어가지 않아 받는 사람마다 임시 파일이 쌓이고, 버퍼링을 끈 받기에 둘 동시 연결 상한도 없다(리뷰). 앱 안 대용량 받기와 같은 location(대소문자를 가리지 않는 정규식 · 같은 그릇)을 두고, CI 의 받기 경로 시험에 변형 · 정보 경로 · 그릇 공유를 더했다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
4.3 KiB
Plaintext
48 lines
4.3 KiB
Plaintext
# ==========================================
|
||
# 대용량 첨부의 공개 API — /api/public-links/ (11단계 — docs/mail/api-contract.md 4절 "공개 내려받기")
|
||
#
|
||
# 두 server 의 location ^~ /api/ 블록 **안에** 넣는다(nginx.conf) — 공개 내려받기 server 는 늘, 포털은 공개 호스트를 따로 두지 않을 때
|
||
# (nginx-env.envsh 의 NGINX_PORTAL_SHARE=open). 템플릿이 아니다 — /etc/nginx/snippets/share-api-open.conf 로 그대로 들어간다(Dockerfile).
|
||
# $backend_upstream 과 limit_conn 의 영역(download_public_*)은 nginx.conf 의 http 단계, @api_* 는 nginx-api-errors.conf.
|
||
# /api/ 블록의 add_header_inherit off 를 물려받는다 — 응답의 머리글(no-store · noindex · no-referrer · 파일의 CSP 등)은 백엔드가 정한다.
|
||
#
|
||
# 대소문자를 가리지 않는다(~*) — 백엔드(Express) 라우팅이 가리지 않아 /api/Public-Links/…/FILES/… 도 받기 처리기에 닿는다(nginx.conf 머리말).
|
||
# 정규식은 적은 차례로 처음 맞은 것을 쓴다 — 파일 받기를 링크 정보보다 먼저 둔다.
|
||
# ==========================================
|
||
|
||
# 파일 받기 GET·HEAD /api/public-links/{token}/files/{fileId} — 200 · 206(Range) · 416, 2GB 까지
|
||
# - 버퍼링을 끈다: 기본값이면 받는 쪽이 느릴 때 nginx 가 응답을 임시 파일(/tmp/proxy_temp)에 1GB 까지 받아 둔다 — 받는 사람마다.
|
||
# 백엔드가 보내는 X-Accel-Buffering: no 로도 꺼지지만 그 머리글에 기대지 않는다(실시간 알림과 같다)
|
||
# - X-Accel-Buffering 을 넘긴다: nginx 계열 외부 리버스 프록시(Nginx Proxy Manager 등)도 이 응답만 버퍼링을 끈다
|
||
# - proxy_buffer_size 16k — 머리글 버퍼. 한글 255자 파일 이름이면 응답 머리글이 3.5KB 쯤이다(Content-Disposition 하나가 2.5KB) — 기본 4k 로는 빠듯하다
|
||
# 버퍼링을 끈 응답은 본문도 이 크기로 받아 넘긴다(기본 4k 보다 시스템 호출이 적다). proxy_busy_buffers_size 는 nginx 가 함께 맞추라고 하는 값이다 —
|
||
# 안 적으면 2 × 16k = 32k 가 proxy_buffers(8 × 4k)의 "하나 뺀 합" 28k 를 넘어 설정 검사가 멈춘다. 버퍼링을 끈 location 이라 proxy_buffers 는 쓰이지 않는다
|
||
# - 압축하지 않는다(gzip_types 에 application/octet-stream 이 없지만 목록을 넓혀도 이 경로는 그대로) · Range · If-Range 는 손대지 않고 넘긴다
|
||
# (nginx 는 프록시한 응답을 스스로 자르지 않는다 — 백엔드의 206 · 416 이 그대로 간다)
|
||
# - 시간: proxy_read_timeout 은 백엔드에서 "두 번 읽는 사이", send_timeout(기본 60s)은 받는 쪽에 "두 번 쓰는 사이"다 — 느려도 조금씩
|
||
# 받아 가면 끊지 않고, 받는 쪽이 60초 동안 하나도 받지 않으면 끊는다(브라우저 · 내려받기 관리자는 Range 로 이어 받는다 — mail/README.md 의 시험)
|
||
# - 동시 연결: 클라이언트 주소마다 10 · 공개 받기 전체 400 — 넘으면 429 REQ_001 (nginx.conf 의 http 단계 "동시 연결 수")
|
||
# - 토큰 칸은 [^/]+ 가 아니라 .+ — nginx 는 %2F 를 / 로 풀어 location 을 고르고 백엔드는 한 칸으로 읽는다(지금은 백엔드의 토큰 검사가 그 꼴을 404 로 막지만 기대지 않는다)
|
||
# - 같은 줄들이 nginx.conf 의 앱 안 받기(/api/messages/{id}/large-files/…) · 휴대폰 앱 받기(/api/app-releases/…/file)에 있다 — 한쪽을 고치면 다른 쪽도
|
||
# error_page 를 하나라도 쓰면 위의 것을 물려받지 않아 셋을 다 적는다
|
||
location ~* ^/api/public-links/.+/files/ {
|
||
limit_conn download_public_ip 10;
|
||
limit_conn download_public_total 400;
|
||
error_page 413 @api_payload_too_large;
|
||
error_page 429 @api_too_many_requests;
|
||
error_page 500 502 503 504 @api_unavailable;
|
||
proxy_buffering off;
|
||
proxy_buffer_size 16k;
|
||
proxy_busy_buffers_size 16k;
|
||
gzip off;
|
||
proxy_pass_header X-Accel-Buffering;
|
||
proxy_pass $backend_upstream;
|
||
}
|
||
|
||
# 링크 정보 GET /api/public-links/{token}(JSON) 등 — 백엔드로 넘긴다. 공개 내려받기 server 의 /api/ 블록은 404 만 정하므로 여기서 다 적는다
|
||
location ~* ^/api/public-links(?:/|$) {
|
||
error_page 413 @api_payload_too_large;
|
||
error_page 500 502 503 504 @api_unavailable;
|
||
proxy_pass $backend_upstream;
|
||
}
|