TUS resumable upload

TUS chia file thành các chunk và theo dõi Upload-Offset. Khi kết nối bị gián đoạn, client kiểm tra offset bằng HEAD rồi tiếp tục thay vì gửi lại toàn bộ file.

Luồng upload TUS có thể tiếp tục

Khi nên sử dụng

  • File lớn hoặc đường truyền có thể bị gián đoạn.
  • Backend/worker cần retry tự động và theo dõi tiến độ.
  • Ứng dụng cần pause/resume hoặc tiếp tục sau khi process khởi động lại.

MPS hỗ trợ upload tối đa 20 GiB và phiên upload 24 giờ. Các TUS extension được hỗ trợ gồm creation, creation-with-upload, termination, expiration, deferred length và checksum.

Vòng đời request

Request Mục đích Response quan trọng
POST /v1/namespaces/{namespace}/tus Tạo upload 201, Location, Upload-Key, Tus-Upload-Expires
HEAD {Location} Đọc trạng thái Upload-Offset, Upload-Length
PATCH {Location} Gửi chunk tại offset hiện tại 204, Upload-Offset mới
DELETE {Location} Hủy phiên upload 204

Ví dụ Node.js đầy đủ

Cài client:

npm install tus-js-client

Ví dụ này bao gồm toàn bộ metadata được dùng trong demo MPS:

const fs = require('fs');
const tus = require('tus-js-client');

const localPath = '/path/to/video.mp4';
const file = fs.createReadStream(localPath);
const upload = new tus.Upload(file, {
  endpoint: 'https://mps.mediacdn.vn/v1/namespaces/<namespace>/tus',
  uploadSize: fs.statSync(localPath).size,
  chunkSize: 50 * 1024 * 1024,
  retryDelays: [0, 3000, 5000, 10000, 20000],
  headers: {
    'X-Auth-Type': 'application_credential',
    'X-App-Credential-Id': '<credential-id>',
    'X-App-Credential-Secret': '<credential-secret>'
  },
  metadata: {
    file_path: '2026/09/22/video.mp4',
    display_name: 'Product introduction',
    video_profile_ids: '360,480,720,1080',
    client_reference: 'customer-record-42',
    video_encryption: false,
    default_thumb_timepct: 0.25
  },
  onError(error) {
    console.error('Upload failed:', error);
  },
  onProgress(bytesUploaded, bytesTotal) {
    const percent = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
    console.log(`${percent}%`);
  },
  onSuccess() {
    console.log('Upload completed:', upload.url);
  }
});

upload.start();

Giải thích cấu hình

  • endpoint là collection endpoint dùng để tạo phiên upload.
  • uploadSize giúp MPS kiểm tra giới hạn và biết thời điểm hoàn tất.
  • chunkSize đặt kích thước mỗi request PATCH; 50 MiB là điểm bắt đầu phù hợp, nhưng nên điều chỉnh theo mạng và giới hạn proxy của bạn.
  • retryDelays retry các lỗi có thể phục hồi theo khoảng thời gian millisecond đã cho.
  • headers chứa Application Credential và chỉ được đặt trong backend/worker đáng tin cậy.
  • metadata được tus-js-client Base64-encode vào Upload-Metadata. Ý nghĩa từng field được mô tả tại tổng quan upload .
  • upload.url là URL tài nguyên TUS được trả trong Location.

Pause và tiếp tục

Trong cùng process:

await upload.abort(); // pause, không hủy dữ liệu trên MPS
upload.start();       // tiếp tục từ offset đã biết

Để tiếp tục sau khi ứng dụng khởi động lại, lưu upload.url trong storage an toàn và khôi phục URL theo API của tus-js-client. Client sẽ gọi HEAD để đọc offset trước khi gửi chunk tiếp theo. Nếu phiên đã quá 24 giờ, tạo upload mới.

Gọi DELETE vào URL upload với header Tus-Resumable và credential khi muốn hủy phiên và giải phóng tài nguyên upload trên server.

Bảo mật

TUS resumable là phương thức được khuyến nghị cho upload production từ backend hoặc worker. Lưu cả X-App-Credential-Id và X-App-Credential-Secret ở nơi bảo mật; không nhúng một trong hai giá trị vào JavaScript gửi cho browser. Với file từ end user, dùng Direct TUS upload .