Skip to content

Latest commit

 

History

History
82 lines (68 loc) · 4.38 KB

File metadata and controls

82 lines (68 loc) · 4.38 KB

Proxy (lớp byte nặng) — deep dive

VI: Vì sao & cách proxy video. Spec máy-đọc: spec/proxy.yaml. Code: proxy/. EN: Why & how the video proxy works. Machine-readable: spec/proxy.yaml. Code: proxy/.

Nguyên tắc một dòng

Data đọc THẲNG R2. Chỉ byte nặng ở host cần CORS/Range (gd/src) mới qua proxy. r2/b2 custom domain phát thẳng — đừng tốn CPU proxy.

client <video src=resolveBlob(token)>
   │
   ├── r2:key / b2:key ──────────────► cdn.example/key        (THẲNG: Range+CORS+egress$0)
   │
   └── gd:id / src:url ──► px.example/p/<token> ──► upstream   (PROXY: Range/CORS/confirm/hide)

Vì sao phải proxy gd/src

Vấn đề Không proxy Có proxy
Range seek (<video> tua) Drive trả 200 nguyên file / không Accept-Ranges → không seek forward Range, giữ 206 Partial Content
CORS (<video crossorigin>, <track> sub) thiếu Access-Control-Allow-Origin → trình duyệt chặn proxy gắn CORS + expose Content-Range
Confirm token (Drive file lớn) trả HTML "virus scan" thay vì byte proxy bóc confirm= và gọi lại
Giấu origin lộ URL Drive/B2, dễ bị khoá/hotlink client chỉ thấy domain proxy
Cache mỗi host khác header → cache loạn 1 domain → Cloudflare cache từng byte-range

Hợp đồng endpoint

GET|HEAD|OPTIONS  /p/<host>:<ref>
  /p/gd:1A2b3C4d5E
  /p/src:https%3A%2F%2Fhost.example%2Fmovie%2F1.mp4   (ref percent-encoded)
  • r2/b2400 (phải phát thẳng).
  • method khác GET/HEAD/OPTIONS → 405.
  • src vi phạm SSRF/allowlist → 403.

Range passthrough (trái tim của seek)

  1. Client gửi Range: bytes=N- khi tua.
  2. Proxy forward Range (+ If-Range/If-None-Match) lên upstream.
  3. Upstream trả 206 + Content-Range: bytes N-M/Total + Accept-Ranges: bytes.
  4. Proxy giữ nguyên status + các header range, thêm CORS, strip hop-by-hop, set Cache-Control: immutable.

<video> chỉ seek mượt khi thấy Accept-Ranges: bytes và server tôn trọng 206. Worker mẫu đảm bảo cả hai.

Google Drive: confirm token

File lớn → Drive trả HTML "Google Drive can't scan this file for viruses". Proxy:

GET uc?export=download&id=ID
  └─ Content-Type: text/html  → match /confirm=([\w-]+)/ → GET ...&confirm=TOKEN[&uuid=UUID]
  └─ Content-Type: video/*    → stream thẳng

PROD nên dùng GD_API_KEY → resolver googleapis.com/drive/v3/files/{id}?alt=media (Range ổn định, không trang confirm). Drive vẫn dính quota/ban theo IP+ngày → bám cache CF cứng; nghiêm túc thì đẩy phim lên R2/B2.

HLS (video-hls)

  • .m3u8 + segment .ts/.m4s đều immutable → đặt trên R2/B2 custom domain, phát thẳng là rẻ + nhanh nhất, không cần proxy.
  • Nếu buộc proxy (host gd): dùng URI tuyệt đối /p/gd:<segment> ngay lúc ingest (ghi vào playlist), không rewrite lúc đọc. Set CORS cho .m3u8.vtt.

Cache (rẻ = cache cứng byte immutable)

  • Byte phim/segment/sub không đổiCache-Control: public, max-age=31536000, immutable.
  • Bật range object caching ở Cloudflare → cache từng byte-range (206→200) → tua lại không tốn egress upstream.
  • Worker dùng cf: { cacheEverything: true, cacheTtl: 31536000 }.

Bảo mật

  • Chỉ GET/HEAD/OPTIONS; không forward cookie/Server upstream.
  • src: — chặn IP nội bộ (10./127./169.254./192.168./172.16-31.) + allowlist host (SRC_ALLOWLIST) chống open-proxy/SSRF.
  • (tuỳ chọn) chặn Content-Length quá ngưỡng cho src lạ.

Triển khai nhanh

# Worker
cd proxy && npm i
npx wrangler secret put GD_API_KEY      # (tuỳ chọn)
npx wrangler deploy                      # route: px.example/*

# Pages Function: bỏ proxy/functions/ vào repo Astro -> /p/* tự nhận khi deploy Pages

Kiểm thử

curl -I -H 'Range: bytes=0-1023' https://px.example/p/gd:FILEID   # 206 + Content-Range
curl -I -X OPTIONS                https://px.example/p/gd:FILEID   # 204 + Access-Control-Allow-Origin
curl -I                           https://px.example/p/r2:key      # 400 (phải phát thẳng)