From 3bc6e3d77707207c8fc09671ed31d6049dd50bf9 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Fri, 18 Oct 2019 19:03:04 -0700 Subject: [PATCH] fix: only do range request override in Safari (#1594) should fix #1590 --- package.json | 1 + src/service-worker.js | 51 +++++++++++++++++++++---------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 5904a3fc..4dbebc38 100644 --- a/package.json +++ b/package.json @@ -143,6 +143,7 @@ "NotificationEvent", "OffscreenCanvas", "PointerEvent", + "Response", "URL", "WebSocket", "__assets__", diff --git a/src/service-worker.js b/src/service-worker.js index b6f8078d..701cad52 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -13,6 +13,8 @@ const timestamp = process.env.SAPPER_TIMESTAMP const ASSETS = `assets_${timestamp}` const WEBPACK_ASSETS = `webpack_assets_${timestamp}` +const isSafari = /Safari/.test(navigator.userAgent) && !/Chrom/.test(navigator.userAgent) + // `static` is an array of everything in the `static` directory const assets = __assets__ .map(file => file.startsWith('/') ? file : `/${file}`) @@ -78,33 +80,29 @@ 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 +async function returnRangeRequest (request) { + const response = await fetch(request, { headers: {}, mode: 'cors', credentials: 'omit' }) + const arrayBuffer = await response.arrayBuffer() + const bytes = /^bytes=(\d+)-(\d+)?$/g.exec(request.headers.get('range')) + if (bytes) { + const start = parseInt(bytes[1], 10) + const end = parseInt(bytes[2], 10) || 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}`]] - }) - } + return new Response(arrayBuffer.slice(start, end + 1), { + status: 206, + statusText: 'Partial Content', + headers: [ + ['Content-Range', `bytes ${start}-${end}/${arrayBuffer.byteLength}`] + ] }) + } else { + return new Response(null, { + status: 416, + statusText: 'Range Not Satisfiable', + headers: [['Content-Range', `*/${arrayBuffer.byteLength}`]] + }) + } +} self.addEventListener('fetch', event => { const req = event.request @@ -150,7 +148,8 @@ self.addEventListener('fetch', event => { // 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')) { + // Once this bug is fixed in WebKit we can remove this https://bugs.webkit.org/show_bug.cgi?id=186050 + if (isSafari && event.request.headers.get('range')) { return returnRangeRequest(req) }