Files
arasystem/frontend/nginx-api-errors.conf
ttipo 7c70862647 feat(docker): 휴대폰 앱 받기 경로에 앱 안 받기와 같은 상한 · 흘려보내기를 둔다
APK 받기가 일반 /api 로 가면 X-Accel-Buffering 이 외부 프록시로 넘어가지 않아 받는 사람마다 임시 파일이 쌓이고,
버퍼링을 끈 받기에 둘 동시 연결 상한도 없다(리뷰). 앱 안 대용량 받기와 같은 location(대소문자를 가리지 않는 정규식 ·
같은 그릇)을 두고, CI 의 받기 경로 시험에 변형 · 정보 경로 · 그릇 공유를 더했다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 23:29:05 +09:00

64 lines
3.7 KiB
Plaintext

# ==========================================
# /api 의 nginx 오류 응답 — 두 server(포털 · 공개 내려받기)가 넣는다 (nginx.conf). 템플릿이 아니다(/etc/nginx/snippets/api-errors.conf)
# (잘못된 원문 요청 대상의 400 은 화면 경로에도 같은 JSON 이다 — 아래 /__request-target-rejected)
#
# message 는 비운다 (문구는 클라이언트가 code 로 사전에서 찾는다, 레지스트리와 겹치지 않게).
# traceId 는 이 nginx 의 요청 ID(로그의 rid=)다. 이름 있는 location 은 server 단계라 화면용 헤더 상속을 끈다
# (접근 로그는 server 단계의 쿼리 없는 main_rid 를 그대로 물려받는다).
# return 200 은 본문만 정한다 — error_page 를 = 없이 썼으므로 상태 코드는 원래 값(404·413·429·502·504 등)이 그대로 나간다 (2026-10-27 확인)
# ==========================================
# nginx 가 닫은 경로 404 — 공개 내려받기 server 의 /api/(공개 API 밖) · 포털의 공개 API(공개 호스트를 따로 둘 때) ·
# 두 server 의 /api/internal/(엔진만 부르는 경로 — 12단계, internal-api-closed.conf). 없는 경로와 같은 RES_001
location @api_not_found {
add_header_inherit off;
default_type application/json;
add_header Cache-Control "no-store" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Request-Id $request_id always;
return 200 '{"success":false,"error":{"code":"RES_001","message":"","traceId":"$request_id"}}';
}
# 본문 한도 초과 413 — 첨부 · 업로드 · 대용량 조각 · 공개 내려받기 server 의 /api/(1m)
location @api_payload_too_large {
add_header_inherit off;
default_type application/json;
add_header Cache-Control "no-store" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Request-Id $request_id always;
return 200 '{"success":false,"error":{"code":"FILE_002","message":"","traceId":"$request_id"}}';
}
# 동시 연결 수 초과 429 — 대용량 받기 · 휴대폰 앱 받기의 limit_conn (11단계 — nginx.conf 의 http 단계 "동시 연결 수"). 백엔드의 요청 수 한도와 같은 REQ_001
location @api_too_many_requests {
add_header_inherit off;
default_type application/json;
add_header Cache-Control "no-store" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Request-Id $request_id always;
return 200 '{"success":false,"error":{"code":"REQ_001","message":"","traceId":"$request_id"}}';
}
# 원문 요청 대상이 잘못된 400 — 경로의 날 역슬래시 · 날 # · 0x80 이상 바이트 (nginx.conf 의 $request_target_rejected — 두 server 의 server 단계 if 가
# 이리로 넘긴다). 화면 경로든 /api 든 같은 JSON 이다 — 브라우저는 이런 요청을 보내지 않는다. 입력 형식 오류의 VAL_001.
# internal 이라 바깥에서 이 경로를 바로 부르면 404 다
location = /__request-target-rejected {
internal;
add_header_inherit off;
default_type application/json;
add_header Cache-Control "no-store" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Request-Id $request_id always;
return 400 '{"success":false,"error":{"code":"VAL_001","message":"","traceId":"$request_id"}}';
}
# 백엔드 응답 없음 · 시간 초과 등 5xx
location @api_unavailable {
add_header_inherit off;
default_type application/json;
add_header Cache-Control "no-store" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Request-Id $request_id always;
return 200 '{"success":false,"error":{"code":"SYS_001","message":"","traceId":"$request_id"}}';
}