ipfs/service-worker-gateway

bug: loading video in browser native video player doesn't send response quick enough

SgtPooki opened this issue · 2 comments

see #122 (comment)

Basically:

  1. when fetching content for a large video, bafybeidsp6fva53dexzjycntiucts57ftecajcn5omzfgjx57pqfy3kwbq, the browser doesn't seem to get the response until the full stream is resolved
  2. In order to effectively return video files, we need to make sure the response headers are written immediately and that the stream resolution is non-blocking.

You can see some examples of how browsers will cancel the first request when it knows it's video content, and then send a byte request immediately after, in this gist: https://gist.github.com/SgtPooki/9efc039d1d349d112d0f505b2ed275c8

For future triage purposes: the scenario impacted by this bug is when https://example.com/ipfs/cid/video.mp4 is opened directly. It does not impact <video> tags and players which operate on range requests from the start.

To reproduce:

  1. Browsers sends HTTP GET for URL and expects HTTP 200
  2. Browser receives headers for HTTP 200, and realizes the response if for content-type that is a supported video stream
  3. Browser cancels HTTP GET, and sends HTTP Range Request only for the beginning of the file, avoiding download of the entire thing.

The bug described here makes (1) take forever because SW does not return headers with status code and content type fast enough.

Ok.. after debugging this for the last 3 hours in #138.. I can confirm that caching large responses before it has all been fetched causes the service worker to block on that request until it's all consumed.

explicitly disabling this for 'video/webm' responses in http://bafybeidsp6fva53dexzjycntiucts57ftecajcn5omzfgjx57pqfy3kwbq.ipfs.helia-sw-gateway.localhost/ result in a 4984ms-12s DOMContentLoaded and TTFB response from the service worker when ran against a completely fresh kubo node: export IPFS_PATH=$(mktemp -d); npx kubo init; npx kubo config Addresses.Gateway /ip4/127.0.0.1/tcp/8081; npx kubo daemon

I'm simply blocking the caching with the below check to get these results.

function shouldCache ({ event, response }: { event: FetchEvent, response: Response }): boolean {
  if (event.request.headers.get('pragma') === 'no-cache' || event.request.headers.get('cache-control') === 'no-cache') {
    log('helia-sw-cache-debug: request indicated no-cache, not caching')
    return false
  }
  const contentType = response.headers.get('content-type')
  if (contentType != null && response.status === 200 && ['video/webm'].includes(contentType)) {
    log('helia-sw-cache-debug: not caching video/webm')
    return false
  }

  return true
}

investigating further.