Skip to content

파일 공유

원본 다운로드: Markdown · PDF

정적 Astro 홈페이지에 비밀번호로 보호되는 파일 업로드/다운로드 드롭을 추가한 기능입니다. 링크와 공유 비밀번호를 아는 사람끼리 파일을 주고받을 수 있습니다.

두 개의 페이지 / 두 개의 접근 등급으로 나뉩니다.

페이지 주소 접근 기능
업로드(관리) https://dev.tictechtoeai.com/share 비밀번호 필요 (나만) 업로드·목록·다운로드·삭제·링크 복사
다운로드(공개) https://dev.tictechtoeai.com/download 비밀번호 없음 (누구나) 파일 목록 표시 → 클릭 시 다운로드

정책: 업로드는 나만, 목록·다운로드는 누구나. 공개 페이지 /download 에 올려진 파일이 전부 목록으로 보이고, 행을 클릭하면 바로 내려받습니다. 올리기·삭제만 비밀번호가 필요합니다.

항목
API (프록시) https://dev.tictechtoeai.com/share/api/*127.0.0.1:8090
헤더 네비 Files 링크(→ /download) 노출. 업로드 페이지 /share 는 네비 미노출(관리자 북마크용)
접근 모델 쓰기(업로드·삭제)는 토큰 필요, 읽기(목록·다운로드)는 공개
  • 그냥 /download 주소를 알려주면 됩니다 — 상대가 목록에서 골라 받습니다.
  • 특정 파일 하나만 콕 집어 주려면, /share 에서 그 파일의 링크 복사 버튼으로 개별 링크(/download?f=<파일명>)를 떠서 전달할 수도 있습니다.

/share 는 처음 들어가면 비밀번호 입력창이 뜹니다. 한 번 입력하면 브라우저 localStorage 에 저장되어 다음에 자동 잠금 해제됩니다. 잠금 버튼으로 지울 수 있습니다.

brower ──HTTPS──> Caddy (dev.tictechtoeai.com)
├─ /share/api/* ──reverse_proxy──> Node FileShare :8090 ─┐
└─ /share (그 외) ──file_server──> homepage/dist │
fileshare/storage/ (실제 파일)
  • 프런트: homepage/src/pages/share.astro — 정적 페이지 + 인라인 바닐라 JS(드래그앤드롭 업로드, 진행률, 목록, 다운로드, 삭제). 사이트 디자인 토큰 재사용.
  • 백엔드: fileshare/server.mjs — 의존성 0개 Node HTTP 서버. 127.0.0.1:8090 만 바인딩(외부 직접 노출 안 함, Caddy 통해서만).
  • 엣지: 루트 Caddyfiledev.tictechtoeai.com 블록에 handle /share/api/* 리버스 프록시 추가.
  • 서비스: LivekitDevFileShare (NSSM, 자동 시작 + 장애 복구).

모든 경로 접두사는 /share/api. 인증은 다음 중 하나:

  • 헤더 x-share-token: <토큰>
  • 헤더 Authorization: Bearer <토큰>
  • 쿼리 ?token=<토큰> (다운로드 전용 — <a> 링크로 스트리밍 받기 위함)
메서드 경로 인증 설명
GET /share/api/health 불필요 {"ok":true} (헬스체크)
GET /share/api/list 필요 {files:[{name,size,mtime}], maxMb} (최신순) — 관리 페이지용
POST /share/api/upload?name=<파일명> 필요 요청 본문 = 파일 원본 바이트. 스트리밍 저장
GET/HEAD /share/api/download?name=<파일명> 필요 파일 스트리밍 (attachment; &inline=1 이면 미리보기)
POST/DELETE /share/api/delete?name=<파일명> 필요 파일 삭제
GET /share/api/public/list 불필요 공개 목록 — /download 페이지가 사용
GET/HEAD /share/api/public/download?name=<파일명> 불필요 공개 다운로드 (비밀번호 없이 스트리밍). HEAD = 존재·크기 확인

공개 등급에는 읽기 전용 엔드포인트(목록·다운로드)만 있습니다. 업로드/삭제 공개 경로는 없으므로(/share/api/public/upload 는 404), 남들은 파일을 올리거나 지울 수 없습니다.

  • 파일명 정규화: 경로 구분자·제어문자·Windows 금지문자 제거, 디렉터리 탈출(..) 차단, basename 만 사용, 180자 제한.
  • 충돌 회피: 같은 이름 업로드 시 이름 (1).ext, 이름 (2).ext … 로 자동 분기 (덮어쓰지 않음).
  • 부분 파일: .part-xxxx 임시 파일로 받은 뒤 완료 시 rename (중단된 업로드가 목록에 남지 않음).
  • 크기 제한: 기본 512 MB/파일. Content-Length 사전 검사 + 스트림 초과 시 중단(413).
  • 상수시간 토큰 비교: 타이밍 공격 완화(crypto.timingSafeEqual).
{
"token": "N0Il2HIWJYBywt1ncE4c",
"port": 8090,
"dir": "storage",
"maxMb": 512
}
  • 이 파일은 .gitignore 대상입니다(토큰·저장 파일 비공개). 예시는 config.example.json.
  • 환경변수 SHARE_TOKEN / SHARE_PORT / SHARE_DIR / SHARE_MAX_MB 로 덮어쓸 수 있습니다.
  • 토큰이 어디에도 없으면 첫 실행 시 랜덤 토큰을 만들어 config.json 에 기록합니다.
Terminal window
# 1) 새 토큰 생성 예시
node -e "console.log(require('crypto').randomBytes(15).toString('base64url'))"
# 2) fileshare/config.json 의 "token" 값을 교체
# 3) 서비스 재시작
Restart-Service LivekitDevFileShare
Terminal window
# 상태
Get-Service LivekitDevFileShare
curl.exe http://127.0.0.1:8090/share/api/health
# 재시작 / 로그
Restart-Service LivekitDevFileShare
Get-Content C:\Developments\LivekitDev\logs\LivekitDevFileShare-stdout.log -Tail 20
# 저장된 파일 위치
# C:\Developments\LivekitDev\fileshare\storage\
  • 서비스는 ensure_stack.ps1(5분 주기 + 부팅 시 헬스 태스크)에 포함되어 죽으면 자동 복구됩니다.
  • 최초 서비스 등록(관리자 PowerShell 1회): scripts\install_fileshare_service.ps1.

현재 정책 = 업로드·삭제는 토큰(나만), 목록·다운로드는 공개. 조정 방향:

  • 다운로드도 비밀번호로 막기: /download 페이지와 /share/api/public/* 라우트를 제거하고 /share 만 쓰면 전면 보호 모델로 돌아갑니다.
  • 목록은 숨기고 링크로만 받게: server.mjs 에서 public/list 라우트를 빼고 /download?f=<파일명> 단일 파일 방식으로 바꾸면 됩니다.
  • IP 제한: Caddy handle /share/api/* 블록에 @allowed remote_ip ... 매처 추가.
fileshare/server.mjs # 백엔드 (신규)
fileshare/package.json # (신규)
fileshare/config.json # 토큰/포트 (신규, gitignore)
fileshare/config.example.json # (신규)
fileshare/.gitignore # (신규)
fileshare/storage/ # 업로드 저장소 (신규)
homepage/src/pages/share.astro # 업로드(관리) 페이지 — 비밀번호 (신규)
homepage/src/pages/download.astro # 다운로드(공개) 페이지 — 목록 표시 + 클릭 다운로드 (신규)
homepage/src/config/site.ts # 네비에 Files(다운로드) 링크 (수정)
Caddyfile # /share/api/* 프록시 (수정)
scripts/install_fileshare_service.ps1 # 서비스 등록 (신규)
scripts/ensure_stack.ps1 # 헬스 대상에 추가 (수정)