Proxy stream từ google drive với cloudflare worker.

Mình đang trong quá trình phát triển hệ thống lưu trữ và streaming video thì cuộc đời đưa đẩy tới với cloudflare workers, mặc dù chính sách của cloudflare không cho sử dụng để streaming video nhưng mà kệ, cứ làm đại nào nó chặn thì thôi.

Cloudflare thì các bác không lạ gì đâu ha, hạ tầng của bọn nó cực kỳ xịn, mà code chạy trên worker để làm proxy streaming video từ google drive thì nhanh hơn gió nữa chứ, dại gì mà không tận dụng ngoại trừ cái phí cắt cổ 0.5$ cho 1 triệu request. Thôi tản mạn vậy đủ rồi, đi vào chi tiết về cái proxy mình code chỉ vài chục dòng sử dụng cloudflare worker nào.

Cloudflare worker là gì?

Từ cái này chị gồ ra cloud function, rồi Amazon thì có AWS Lambda, bla bla.... thì anh cloudflare cũng đâu thể không tham gia cuộc chơi này, có điều theo quan điểm cá nhân thì cloudflare làm tốt hơn, xịn hơn và rẻ hơn. Cloudflare worker cho phép bạn chạy 1 đoạn mã nguồn trên cloud, tự động scale mà chẳng cần phải lo tới hạ tầng bên dưới, cứ code là chạy, mà nó hay ở chỗ là thời gian deploy đến khi nó ready để mình sử dụng chỉ tính bằng giây, khái niệm này gọi là cold start, mấy dịch vụ khác như google hay amazon thì tính bằng phút lận. Đoạn code của bạn sẽ được đẩy lên hàng trăm datacenter của cloudflare, đồng thời bạn có toàn quyền đọc ghi cache nữa. Thử 1 đoạn hello world nha.

Tạo workers

  • Vào trang chủ và click vào chữ workers
    alt text

  • Tạo mới 1 worker
    alt text

  • Code thôi
    alt text

  • Deploy và 2 giây sau gọi api là có ngay kết quả
    alt text

Bạn thấy đó, rất đơn giản, bạn được sử dụng miễn phí 100.000 request tới toàn bộ workers trong tài khoản bạn trong một ngày!

Caching

Cái mà mình thấy hay nhất là bạn toàn quyền thao tác với cache của cloudflare, nếu các bạn đã từng dùng cloudflare thì sẽ thấy caching của cloudflare nó kinh khủng như thế nào, bình thường để gọi lên API server ở Mỹ từ VN tốn tầm 200ms - 500ms, nhưng nếu đã cached ở cloudflare thì chỉ tốn 30-50ms mà thôi. Một ví dụ đơn giản khi thao tác với cache ở workers:

async function handleRequest(event) {
  const request = event.request
  const cacheUrl = new URL('https://t4.ftcdn.net/jpg/02/25/46/33/240_F_225463322_MGgmerZgA9kcbpwfhD1MkS9xC05f9fVM.jpg')

  // Construct the cache key from the cache URL
  const cacheKey = new Request(cacheUrl.toString(), request)
  const cache = caches.default

  // Check whether the value is already available in the cache
  // if not, you will need to fetch it from origin, and store it in the cache
  // for future access
  let response = await cache.match(cacheKey)

  if (!response) {
    // If not in cache, get it from origin
    response = await fetch(request)

    // Must use Response constructor to inherit all of response's fields
    response = new Response(response.body, response)

    // Cache API respects Cache-Control headers. Setting s-max-age to 10
    // will limit the response to be in cache for 10 seconds max

    // Any changes made to the response here will be reflected in the cached value
    response.headers.append("Cache-Control", "s-maxage=10")

    // Store the fetched response as cacheKey
    // Use waitUntil so you can return the response without blocking on
    // writing to cache
    event.waitUntil(cache.put(cacheKey, response.clone()))
  }
  return response
}

addEventListener("fetch", event => {
  try {
    const request = event.request
    return event.respondWith(handleRequest(event))
  } catch (e) {
    return event.respondWith(new Response("Error thrown " + e.message))
  }
})

Với request đầu tiên sẽ có trạng thái là Miss
alt text

Request sau sẽ có trạng thái là Hit
alt text

Proxy streaming đơn giản

Giờ mình sẽ code 1 đoạn để biến cloudflare thành proxy streaming server, các bạn có thể mở rộng để nó làm proxy cho các dịch vụ lưu trữ như google drive, onedrive, box.com ..... tùy, miễn qua mặt được limitaion của bọn nó thì có ngay cái server proxy stream xịn xò chỉ tốn CÓ 0.5 USD cho 1 triệu request, tính ra tầm 3TB - 7TB băng thông ~ 10$ cho 100TB băng thông video, quá chi là rẻ luôn.

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event))
})

/**
 * Respond to the request
 * @param {Request} request
 */
async function handleRequest(event) {
  const headers = {
    'cache-control': 'max-age=0,s-maxage=21600',
    'content-type': 'video/mp4',
    'Access-Control-Allow-Origin': "*",
    'Access-Control-Allow-Methods': "GET,HEAD,POST,OPTIONS",
    'Access-Control-Allow-Headers': "Range,User-Agent"
  };

  const request = new Request('https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_1920_18MG.mp4', {
    method: 'GET',
    headers: event.request.headers
  })

  let { readable, writable } = new TransformStream()
  let response = await fetch(request)
  headers['content-range'] = `${response.headers.get('content-range')}`;
  headers['content-length'] = `${response.headers.get('content-length')}`;
  response.body.pipeTo(writable)
  response = new Response(readable, {
    status: response.status,
    headers: headers
  })

  return response;
}

Thử phát được ngay :v
alt text

Chỉ tốn tầm 3 request tới workers là có thể xem toàn bộ video, đó là lý do mình nói 1 triệu request phía trên quy đổi là băng thông thì quá hời rồi.
alt text

Google drive proxy demo

Còn đây là 1 demo worker làm proxy streaming từ google drive, kết hợp caching của cloudflare nữa là vô đối thủ luôn: DEMO

Trên đây là những gì mình tìm hiểu được trong quá trình làm Lậu CDN và Lậu Proxy, cloudflare workers còn rất nhiều cái hay, các bạn tìm hiểu thêm ở Cloudflare Document hoặc tham gia group discord của mình để trao đổi thêm về các giải pháp lưu trữ và streaming cho web phim tại Lậu Discord

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Lậu Chủ

3 bài viết.
61 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
76 8
Bài viết này sẽ hướng dẫn các bạn sử dụng Discord để làm ứng dụng theo dõi bất kỳ thứ gì các bạn muốn hay cần. Bối cảnh: Hôm bữa thấy người ta đăn...
Lậu Chủ viết hơn 2 năm trước
76 8
White
28 7
Vấn đề hiện tại Mặc dù hiện cũng khá lớn tuổi, nhưng mình đặc biệt thích xem animes, nhưng hầu như website xem phim hiện tại không đáp ứng được nh...
Lậu Chủ viết hơn 1 năm trước
28 7
Bài viết liên quan
White
21 1
Vưỡn như thường lệ, bài gốc đăng ở Êku :bow: (Link) (Ảnh) _Dragon Knight Minh họa bởi (Link)_ Nói về ES6 có lẽ chúng ta đã quá quen thuộc với ...
An viết gần 3 năm trước
21 1
White
4 4
Chú ý: bài viết khá dài, dự kiến đọc cần ít nhất 1015 phút. TL;DR: Dừng trả tiền cho VPN nếu bạn đang làm vậy, vì VPN không như lời quảng cáo tý n...
wello6143 viết hơn 1 năm trước
4 4
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
3 bài viết.
61 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!