Files
llm-wiki/raw/official-docs/file-tus-resumable-upload-protocol.md
T

111 lines
8.3 KiB
Markdown

---
title: tus.io — Resumable upload protocol (v1.0.0)
source_type: official-doc
url: https://tus.io/protocols/resumable-upload
archive_url:
status: raw
confidence: high
tags: [file, tus, resumable-upload, multipart, ca-skeleton, official-doc]
related_projects: [ca-skeleton-operational-contract]
related_branches: [feature-file-resource-handling-contract]
created: 2026-05-22
last_reviewed: 2026-05-27
---
# tus.io — Open protocol for resumable file uploads
> Layer: `raw/official-docs/` — tus.io 공식 protocol v1.0.0 발췌. 대용량/이어올리기 시나리오에서 ca-tmpl Spring 10MB multipart enforcement 의 한계 비교 근거.
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-file-resource-handling-contract]] | tus 가 resumable 표준이라는 사실 → ca-tmpl 의 Spring multipart 단일 stream 가정과 충돌하는 영역 식별 (Tus-Max-Size 헤더 enforcement, session vs orphan threshold 분리 필요성) |
## 컨텍스트
ca-tmpl의 multipart 10MB limit은 short file 기준. 대용량(영상, 백업) upload는 connection drop → 처음부터 재시도라는 운영 문제 발생. tus는 byte offset 기반 resume 표준. ca-tmpl이 현재 채택하지 않은 이유와 채택 시 size limit 결정에 어떤 영향이 있는지 비교용.
## 출처 / Source
- 원본 URL: https://tus.io/protocols/resumable-upload
- 보조 1: tus-java-server (reference Java implementation) — https://github.com/tomdesair/tus-java-server
- 보조 2: Vimeo "How we built a resumable upload service" — https://medium.com/vimeo-engineering-blog/from-zero-to-100mbs-how-we-massively-improved-vimeos-upload-speed-71f72ca1ca5e
- 아카이브 URL: (미수집)
- 저자/조직: transloadit / tus.io community (Marius Kleidl 외)
- 발행일: v1.0.0 — 2018-02 (지속 업데이트)
- 마지막 확인일: 2026-05-27
## 핵심 인용 / Key quotes (verbatim)
> [§Abstract] "The protocol provides a mechanism for resumable file uploads via HTTP (RFC 9110)."
> [§HEAD] "The Server MUST always include the `Upload-Offset` header in the response for a `HEAD` request, even if the offset is `0`."
> [§PATCH] "All `PATCH` requests MUST use `Content-Type: application/offset+octet-stream`, otherwise the server SHOULD return a `415 Unsupported Media Type` status."
> [§PATCH] "If the offsets do not match, the Server MUST respond with the `409 Conflict` status without modifying the upload resource."
> [§Tus-Max-Size] "The `Tus-Max-Size` response header MUST be a non-negative integer indicating the maximum allowed size of an entire upload in bytes."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| TUS-RUP-C1 | tus 는 HTTP (RFC 9110) 위에서 동작하는 resumable file upload 프로토콜이다 | [§Abstract] "The protocol provides a mechanism for resumable file uploads via HTTP (RFC 9110)." | `official-standard` | resumable upload 표준 채택 평가 | RFC 9110 자체가 tus 를 정의/승인한다는 뜻은 아님 — tus 는 HTTP **위에** 정의된 프로토콜 |
| TUS-RUP-C2 | Server 는 HEAD 응답에 `Upload-Offset` 헤더를 항상 포함해야 한다 (offset 이 0 이어도 포함 — MUST) | [§HEAD] "The Server MUST always include the `Upload-Offset` header in the response for a `HEAD` request, even if the offset is `0`." | `official-standard` | tus core protocol 구현 시 HEAD 핸들러 | client 측 retry 로직의 정확한 형태나 idempotency 보장은 본 조항 범위 밖 |
| TUS-RUP-C3 | PATCH 요청은 `Content-Type: application/offset+octet-stream` 을 반드시 사용해야 하며 (MUST), 그렇지 않으면 server 는 `415 Unsupported Media Type` 응답을 권장 (SHOULD) | [§PATCH] "All `PATCH` requests MUST use `Content-Type: application/offset+octet-stream`, otherwise the server SHOULD return a `415 Unsupported Media Type` status." | `official-standard` | tus PATCH 요청/응답 처리 | Spring 의 default multipart parser 가 이 content-type 을 처리한다는 뜻이 아님 — 별도 controller 필요 |
| TUS-RUP-C4 | 클라이언트 offset 과 서버 offset 이 일치하지 않으면 server 는 `409 Conflict` 로 응답하고 upload 리소스를 수정하지 않아야 한다 (MUST) | [§PATCH] "If the offsets do not match, the Server MUST respond with the `409 Conflict` status without modifying the upload resource." | `official-standard` | concurrent / out-of-order PATCH 처리 | conflict 후 클라이언트의 정확한 복구 절차 (재 HEAD 후 재 PATCH) 형태는 본 인용에 명시 없음 |
| TUS-RUP-C5 | `Tus-Max-Size` 응답 헤더는 전체 upload 의 허용 최대 byte 수를 나타내는 non-negative integer 여야 한다 (MUST) | [§Tus-Max-Size] "The `Tus-Max-Size` response header MUST be a non-negative integer indicating the maximum allowed size of an entire upload in bytes." | `official-standard` | tus server 의 size limit 알림 | per-PATCH chunk size limit 이 동일 메커니즘으로 표현된다는 뜻은 아님 — chunk-level limit 은 별도 확장 |
### Strength 허용값 사용
- `official-standard` — tus.io v1.0.0 protocol specification (open standard)
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것**:
- `TUS-RUP-C1`: tus 의 HTTP 기반 정의
- `TUS-RUP-C2`, `TUS-RUP-C3`, `TUS-RUP-C4`: HEAD/PATCH 의 핵심 의무사항 (Upload-Offset / Content-Type / 409 Conflict)
- `TUS-RUP-C5`: `Tus-Max-Size` 헤더의 단위와 의미
- **이 자료가 증명하지 않는 것**:
- tus 가 모든 production 환경에서 multipart 대비 더 안정적이라는 일반화 (Vimeo case study 는 별도 company-tech-blog 영역)
- tus-java-server reference impl 의 Spring Boot 통합 정확한 절차
- tus session 의 server-side storage backend 선택 (memory / disk / object store) 의 trade-off
- chunk-level retry 와 session-level resume 의 정확한 경계 (Tus-Max-Size 외 chunk extension)
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl 의 "1h orphan cleanup" 정책과 tus unfinished upload session 의 충돌 가능성
- Spring 환경에서 PATCH + `application/offset+octet-stream` 처리 controller 의 직접 구현 패턴
- `Tus-Max-Size` 와 nginx/gateway level body size limit 의 상호작용
## 메모 / Notes (내 프로젝트 해석)
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
- ca-tmpl과의 trade-off:
- **tus 채택 시 장점**: 100MB 영상 업로드도 disconnect 무관, mobile 사용자 friendly, 서버 메모리 부담 분산 (chunk 단위).
- **tus 채택 시 비용**: PATCH 기반 protocol → Spring multipart는 동작 안 함, 별도 controller + storage layer 필요. ca-tmpl의 Spring 10MB enforcement가 직접 적용 안 됨 (`Tus-Max-Size` 헤더로 대체).
- temp file cleanup 정책 변경 필요: tus는 unfinished upload가 hours 동안 잔존 가능 → ca-tmpl의 "1h orphan cleanup"이 tus upload session을 잘못 삭제할 수 있음. session timeout과 orphan threshold 분리 필요.
- 대안 비교:
- **multipart only (ca-tmpl 현재)**: 단순, 작은 파일에 최적, resume 불가.
- **tus**: resumable, 큰 파일 적합, 서버 stateful (session storage 필요).
- **direct S3 multipart upload (S3 SDK)**: S3 자체의 multipart API. 5MB 미만 last part 외엔 chunk 단위 retry 가능. tus와 유사한 효과지만 vendor-specific.
- ca-tmpl 결정 영향: 현재 "streaming 100MB max + 60s timeout"이 단일 stream 가정. tus 채택 시 session-level limit과 chunk-level limit 분리 필요.
## 관련 ca-tmpl branch / contract
- 적용 branch-note:
- [[raw/branch-notes/feature-file-resource-handling-contract]]
- canonical contract 섹션:
- [[raw/project-notes/ca-skeleton-operational-contract#18. Control Plane Contract]]
- 대안 그룹: **Group G-J — Privacy / File / Domain Modeling** (file resource handling)
- 본 source의 위치: 대안 2 — tus.io resumable protocol (100MB+ video upload, session vs orphan threshold)
## Related / 관련
- 같은 주제 다른 official-doc:
- [[raw/official-docs/file-s3-presigned-url-upload]] (direct S3 presigned URL — 다른 대안)
- 인용하는 branch:
- [[raw/branch-notes/feature-file-resource-handling-contract]]
- 인용하는 wiki: (미작성)