From 3de7a5ba9aa78bad2650cec794b0673a11aa0523 Mon Sep 17 00:00:00 2001 From: sgenoud Date: Mon, 7 Oct 2019 17:36:05 +0200 Subject: [PATCH] fix: Return a synthetic response for range requests (#1555) Fixes #1547 --- src/service-worker.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/service-worker.js b/src/service-worker.js index a4353814..537165e6 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -77,6 +77,34 @@ self.addEventListener('activate', event => { })()) }) +// from https://stackoverflow.com/questions/54138601/cant-access-arraybuffer-on-rangerequest/54207122 +const returnRangeRequest = request => + fetch(request, { headers: {}, mode: 'cors', credentials: 'omit' }) + .then(res => { + return res.arrayBuffer() + }) + .then(arrayBuffer => { + const bytes = /^bytes=(\d+)-(\d+)?$/g.exec(request.headers.get('range')) + if (bytes) { + const start = Number(bytes[1]) + const end = Number(bytes[2]) || arrayBuffer.byteLength - 1 + + return new self.Response(arrayBuffer.slice(start, end + 1), { + status: 206, + statusText: 'Partial Content', + headers: [ + ['Content-Range', `bytes ${start}-${end}/${arrayBuffer.byteLength}`] + ] + }) + } else { + return new self.Response(null, { + status: 416, + statusText: 'Range Not Satisfiable', + headers: [['Content-Range', `*/${arrayBuffer.byteLength}`]] + }) + } + }) + self.addEventListener('fetch', event => { const req = event.request const url = new URL(req.url) @@ -118,6 +146,13 @@ self.addEventListener('fetch', event => { } // for everything else, go network-only + + // range request need to be be patched with a 206 response to satisfy + // Safari (https://stackoverflow.com/questions/52087208) + if (event.request.headers.get('range')) { + return returnRangeRequest(req) + } + return fetch(req) })()) })