TUS Protocol
TUS란
TUS는 파일을 업로드하기 위해 만들어진 오픈 프로토콜이다. HTTP를 기반으로 구축되어 모든 언어, 플랫폼 및 네트워크를 지원한다.
TUS.io에서는 TUS를 Open Protocol for Resumable File Uploads라는 한 문장으로 표현하고 있다. 이 문장에서 볼 수 있듯이 TUS는 재개 가능한 파일 업로드를 위한 오픈 프로토콜이다.
특징
여기서 작성하는 특징은 TUS.io의 내용을 참고하여 살을 조금 붙인 내용이다.
HTTP 기반
현재 HTTP는 여기저기 다양한 곳에서 활용하고 있다. 개발자라면 대부분이 알고있고 사용하며 일반 사용자 또한 알게 모르게 많이 사용하는 프로토콜이다. 그만큼 일상생활에서 많이 활용되고있고 그렇기에 활용하기 편한 환경이 조성되어있다. 이러한 특성을 사용하여 기존 라이브러리와 연동하여 사용하거나 프록시, 방화벽 등 여러 기능을 융합하여 사용하기 편리하다. 그리고 모든 웹사이트에서는 HTTP 기반으로 이루어져있기에 사용자가 별도로 환경을 설정할 필요도 없다.
즉시 활용 가능
TUS는 공식적으로 여러 언어로 되어있는 클라이언트, 서버 코드를 제공하고있다. 여러 차례 개선을 했으며 Vimeo, Google 등 유명 회사들로부터 피드백을 받아 업데이트를 진행했다. 이는 어느정도 검증이 되어있음을 의미하고 있다. 2024년 6월 현재까지도 업데이트는 계속되고 있다.
오픈소스
위에서 말한 프로젝트와 프로토콜 자체까지 모두 MIT 라이선스에 따라 누구나 접근하여 사용할 수 있다. 오픈소스로 공유되어있는 코드는 누구나 확인이 가능하며 다같이 개선할 수 있기에 좋은 코드로 남을 수 있다.
미니멀한 디자인
TUS에서 제공하는 코드는 최소한으로 필요한 기능만을 제공한다. 그렇기에 개발자의 입장에서는 이 코드를 이해하고 사용하는 데에 드는 시간과 비용도 적게 든다.
기능 확장 가능성
병렬 업로드나 체크섬 및 만료 등과 같은 추가 기능을 제공한다. 따라서 개발자는 필요성에 따라 기능을 쉽게 확장하여 사용할 수 있다.
커뮤니티 소유
TUS에서는 커뮤니티를 소유하여 소스코드와 프로토콜을 계속 발전해 나간다. 커뮤니티가 얼마나 크게 형성되어있는가 단순히 존재하는가에 따라서 이 라이브러리나 오픈 소스를 사용할 지 결정할 만큼 커뮤니티의 유무는 정말 영향이 크다고 생각한다.
필요성
이 프로토콜이 왜 필요한지 이해한 상태로 문서를 읽는 것을 추천한다. 여기서 “재개 가능한”이라는 단어는 파일 업로드를 하다가 중간에 일시정지 후 다시 재개할 수 있는 기능을 의미한다.
평소 대용량 파일을 업로드하는 일이 많지않아 크게 와닿지않을 수 있지만 반대로 다운로드를 생각한다면 업로더의 입장 또한 쉽게 이해할 수 있다.
우리가 용량이 큰 파일을 다운로드하다가 네트워크가 끊기거나 그 외 다른 문제로 인해서 다시 처음부터 다운로드를 받아야하는 상황이 온다면 이 보다 화나고 시간을 낭비하는 일은 없을 것이다. 우리가 다운로드 받다가 끊긴 지점부터 다운로드를 계속할 수 있다면 시간도 아끼고 우리의 감정도 낭비할 필요가 없다.
마찬가지로 특정 직업이나 작업을 할 때 대용량 업로드가 필요한 경우가 있다. 이 때 업로드가 끊긴 지점에서 나머지를 업로드할 수 있는 기능이 있다면 사용자 경험은 매우 좋음으로 평가될 것이다.
활용
회사에서 대용량 영상을 업로드하고 트랜스코딩할 수 있는 플랫폼을 개발하는 프로젝트를 담당하게되었다. 이 프로젝트에서 TUS를 활용하여 업로드 시스템을 개발했다. 아래의 이유들로 TUS를 사용하기로 결정했다.
- 완성된 프로젝트 형태
- 재개 가능한 업로드
동작
TUS의 동작은 POST, HEAD, PATCH로 크게 3가지이다. 메서드와 기능을 기준으로 나누었다.
아래의 예시는 tus.io/demo를 기준으로 설명한다.
POST
METHOD : POST
URL : https://tusd.tusdemo.net/files/
POST 메서드를 사용하며 업로드를 위한 작업을 생성한다.
여기서 작업은 하나의 파일을 업로드 완료할 때까지의 프로세스를 의미하며 각 작업마다 고유의 ID를 가진다.
응답으로는 작업의 ID가 담긴 URL을 제공한다.
사용자는 로컬스토리지에 업로드에 대한 정보를 저장한다.
{
"size": 397285,
"metadata": {
"filename": "KakaoTalk_Photo_2023-11-29-20-24-00 005jpeg.jpeg",
"filetype": "image/jpeg"
},
"creationTime": "Mon Jul 01 2024 00:03:22 GMT+0900 (한국 표준시)",
"uploadUrl": "https://tusd.tusdemo.net/files/602f70d85837a29d78408ebfc1969265+3z43LS_xkriSP5AZQUgeii5sTNGUmAnK08CqIUbrda6tc9tIIrUIsCJtL31iecJUfXx3GIn6R6mLP2CcEBvdeo7RIbcB6gOTY3gqzDMhEjizagzuel2u9EzUmT95eoKl"
}
HEAD
METHOD : HEAD
URL : https://tusd.tusdemo.net/files/{{작업 ID}}
HEAD 메서드를 사용하며 현재 업로드하려는 파일이 새로운 파일인지 업로드 중이던 파일인지 확인한다.
여기서 uploadUrl을 HEAD 메서드로 전송하여 어디까지 전송이 되었는지 확인한다.
응답으로는 TUS 버전과 함께 몇퍼센트 진행되었는지 등 작업에 대한 정보를 제공한다.
Tus-Resumable: 1.0.0
Upload-Offset: 0
Upload-Length: 373150
Upload-Metadata: filename {{file name}}
PATCH
METHOD : PATCH
URL : https://tusd.tusdemo.net/files/{{작업 ID}}
PATCH 메서드를 사용하며 서버의 설정에 따라 파일을 분할하여 보낸다.
서버에서는 한번의 PATCH에서 보낼 수 있는 용량을 설정하고 이에 따라 사용자가 설정한 용량에 맞게 파일을 업로드한다.
파일을 모두 전송했다면 더 이상 호출하지않고 요청은 종료된다.
정리
프로세스를 정리하면 다음과 같다.
- 로컬 스토리지를 확인하여 업로드하려는 파일에 대한 작업이 존재하는 지 확인한다.
- 존재하는 작업이라면 HEAD 메서드를 통해서 얼마나 전송되었는지 확인하고 4번 프로세스를 실행한다.
- 존재하지않는 작업이라면 POST 메서드를 통해 새로운 업로드 작업을 생성하고 이에 대한 내용을 로컬스토리지에 저장한다.
- PATCH 메서드를 통해 파일을 분할하여 업로드한다.
- 모두 업로드했다면 요청을 멈추어 업로드를 완료한다.
서버 구조
나는 TUSD라는 Golang으로 된 프로젝트를 활용하여 서버를 구성했다.
따라서 아래는 Golang의 기준으로 작성되어있으며 다른 언어로된 서버 코드와는 구조가 다를 수 있다.
서버를 실행할 때 upload 폴더를 지정할 수 있다.
업로드 폴더로 지정된 폴더에는 업로드가 완료되었을 때 해당 파일이 생성된다. 파일은 총 2개가 생성되며 아래와 같다.
- ./uploads/test
- ./uploads/test.info