workbox-range-requests.prod.js.map 11.7 KB
{"version":3,"file":"workbox-range-requests.prod.js","sources":["../_version.js","../createPartialResponse.js","../utils/parseRangeHeader.js","../utils/calculateEffectiveBoundaries.js","../RangeRequestsPlugin.js"],"sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n    self['workbox:range-requests:5.1.4'] && _();\n}\ncatch (e) { }\n","/*\n  Copyright 2018 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { calculateEffectiveBoundaries } from './utils/calculateEffectiveBoundaries.js';\nimport { parseRangeHeader } from './utils/parseRangeHeader.js';\nimport './_version.js';\n/**\n * Given a `Request` and `Response` objects as input, this will return a\n * promise for a new `Response`.\n *\n * If the original `Response` already contains partial content (i.e. it has\n * a status of 206), then this assumes it already fulfills the `Range:`\n * requirements, and will return it as-is.\n *\n * @param {Request} request A request, which should contain a Range:\n * header.\n * @param {Response} originalResponse A response.\n * @return {Promise<Response>} Either a `206 Partial Content` response, with\n * the response body set to the slice of content specified by the request's\n * `Range:` header, or a `416 Range Not Satisfiable` response if the\n * conditions of the `Range:` header can't be met.\n *\n * @memberof module:workbox-range-requests\n */\nasync function createPartialResponse(request, originalResponse) {\n    try {\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isInstance(request, Request, {\n                moduleName: 'workbox-range-requests',\n                funcName: 'createPartialResponse',\n                paramName: 'request',\n            });\n            assert.isInstance(originalResponse, Response, {\n                moduleName: 'workbox-range-requests',\n                funcName: 'createPartialResponse',\n                paramName: 'originalResponse',\n            });\n        }\n        if (originalResponse.status === 206) {\n            // If we already have a 206, then just pass it through as-is;\n            // see https://github.com/GoogleChrome/workbox/issues/1720\n            return originalResponse;\n        }\n        const rangeHeader = request.headers.get('range');\n        if (!rangeHeader) {\n            throw new WorkboxError('no-range-header');\n        }\n        const boundaries = parseRangeHeader(rangeHeader);\n        const originalBlob = await originalResponse.blob();\n        const effectiveBoundaries = calculateEffectiveBoundaries(originalBlob, boundaries.start, boundaries.end);\n        const slicedBlob = originalBlob.slice(effectiveBoundaries.start, effectiveBoundaries.end);\n        const slicedBlobSize = slicedBlob.size;\n        const slicedResponse = new Response(slicedBlob, {\n            // Status code 206 is for a Partial Content response.\n            // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206\n            status: 206,\n            statusText: 'Partial Content',\n            headers: originalResponse.headers,\n        });\n        slicedResponse.headers.set('Content-Length', String(slicedBlobSize));\n        slicedResponse.headers.set('Content-Range', `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` +\n            originalBlob.size);\n        return slicedResponse;\n    }\n    catch (error) {\n        if (process.env.NODE_ENV !== 'production') {\n            logger.warn(`Unable to construct a partial response; returning a ` +\n                `416 Range Not Satisfiable response instead.`);\n            logger.groupCollapsed(`View details here.`);\n            logger.log(error);\n            logger.log(request);\n            logger.log(originalResponse);\n            logger.groupEnd();\n        }\n        return new Response('', {\n            status: 416,\n            statusText: 'Range Not Satisfiable',\n        });\n    }\n}\nexport { createPartialResponse };\n","/*\n  Copyright 2018 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {string} rangeHeader A Range: header value.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the parsed value of the Range: header. If either the `start` or `end` are\n * omitted, then `null` will be returned.\n *\n * @private\n */\nfunction parseRangeHeader(rangeHeader) {\n    if (process.env.NODE_ENV !== 'production') {\n        assert.isType(rangeHeader, 'string', {\n            moduleName: 'workbox-range-requests',\n            funcName: 'parseRangeHeader',\n            paramName: 'rangeHeader',\n        });\n    }\n    const normalizedRangeHeader = rangeHeader.trim().toLowerCase();\n    if (!normalizedRangeHeader.startsWith('bytes=')) {\n        throw new WorkboxError('unit-must-be-bytes', { normalizedRangeHeader });\n    }\n    // Specifying multiple ranges separate by commas is valid syntax, but this\n    // library only attempts to handle a single, contiguous sequence of bytes.\n    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#Syntax\n    if (normalizedRangeHeader.includes(',')) {\n        throw new WorkboxError('single-range-only', { normalizedRangeHeader });\n    }\n    const rangeParts = /(\\d*)-(\\d*)/.exec(normalizedRangeHeader);\n    // We need either at least one of the start or end values.\n    if (!rangeParts || !(rangeParts[1] || rangeParts[2])) {\n        throw new WorkboxError('invalid-range-values', { normalizedRangeHeader });\n    }\n    return {\n        start: rangeParts[1] === '' ? undefined : Number(rangeParts[1]),\n        end: rangeParts[2] === '' ? undefined : Number(rangeParts[2]),\n    };\n}\nexport { parseRangeHeader };\n","/*\n  Copyright 2018 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\n/**\n * @param {Blob} blob A source blob.\n * @param {number} [start] The offset to use as the start of the\n * slice.\n * @param {number} [end] The offset to use as the end of the slice.\n * @return {Object} An object with `start` and `end` properties, reflecting\n * the effective boundaries to use given the size of the blob.\n *\n * @private\n */\nfunction calculateEffectiveBoundaries(blob, start, end) {\n    if (process.env.NODE_ENV !== 'production') {\n        assert.isInstance(blob, Blob, {\n            moduleName: 'workbox-range-requests',\n            funcName: 'calculateEffectiveBoundaries',\n            paramName: 'blob',\n        });\n    }\n    const blobSize = blob.size;\n    if ((end && end > blobSize) || (start && start < 0)) {\n        throw new WorkboxError('range-not-satisfiable', {\n            size: blobSize,\n            end,\n            start,\n        });\n    }\n    let effectiveStart;\n    let effectiveEnd;\n    if (start !== undefined && end !== undefined) {\n        effectiveStart = start;\n        // Range values are inclusive, so add 1 to the value.\n        effectiveEnd = end + 1;\n    }\n    else if (start !== undefined && end === undefined) {\n        effectiveStart = start;\n        effectiveEnd = blobSize;\n    }\n    else if (end !== undefined && start === undefined) {\n        effectiveStart = blobSize - end;\n        effectiveEnd = blobSize;\n    }\n    return {\n        start: effectiveStart,\n        end: effectiveEnd,\n    };\n}\nexport { calculateEffectiveBoundaries };\n","/*\n  Copyright 2018 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { createPartialResponse } from './createPartialResponse.js';\nimport './_version.js';\n/**\n * The range request plugin makes it easy for a request with a 'Range' header to\n * be fulfilled by a cached response.\n *\n * It does this by intercepting the `cachedResponseWillBeUsed` plugin callback\n * and returning the appropriate subset of the cached response body.\n *\n * @memberof module:workbox-range-requests\n */\nclass RangeRequestsPlugin {\n    constructor() {\n        /**\n         * @param {Object} options\n         * @param {Request} options.request The original request, which may or may not\n         * contain a Range: header.\n         * @param {Response} options.cachedResponse The complete cached response.\n         * @return {Promise<Response>} If request contains a 'Range' header, then a\n         * new response with status 206 whose body is a subset of `cachedResponse` is\n         * returned. Otherwise, `cachedResponse` is returned as-is.\n         *\n         * @private\n         */\n        this.cachedResponseWillBeUsed = async ({ request, cachedResponse }) => {\n            // Only return a sliced response if there's something valid in the cache,\n            // and there's a Range: header in the request.\n            if (cachedResponse && request.headers.has('range')) {\n                return await createPartialResponse(request, cachedResponse);\n            }\n            // If there was no Range: header, or if cachedResponse wasn't valid, just\n            // pass it through as-is.\n            return cachedResponse;\n        };\n    }\n}\nexport { RangeRequestsPlugin };\n"],"names":["self","_","e","async","createPartialResponse","request","originalResponse","status","rangeHeader","headers","get","WorkboxError","boundaries","normalizedRangeHeader","trim","toLowerCase","startsWith","includes","rangeParts","exec","start","undefined","Number","end","parseRangeHeader","originalBlob","blob","effectiveBoundaries","blobSize","size","effectiveStart","effectiveEnd","calculateEffectiveBoundaries","slicedBlob","slice","slicedBlobSize","slicedResponse","Response","statusText","set","String","error","constructor","cachedResponseWillBeUsed","cachedResponse","has"],"mappings":"sFAEA,IACIA,KAAK,iCAAmCC,IAE5C,MAAOC,IC0BPC,eAAeC,EAAsBC,EAASC,UAcN,MAA5BA,EAAiBC,cAGVD,QAELE,EAAcH,EAAQI,QAAQC,IAAI,aACnCF,QACK,IAAIG,eAAa,yBAErBC,ECpCd,SAA0BJ,SAQhBK,EAAwBL,EAAYM,OAAOC,kBAC5CF,EAAsBG,WAAW,gBAC5B,IAAIL,eAAa,qBAAsB,CAAEE,sBAAAA,OAK/CA,EAAsBI,SAAS,WACzB,IAAIN,eAAa,oBAAqB,CAAEE,sBAAAA,UAE5CK,EAAa,cAAcC,KAAKN,OAEjCK,IAAgBA,EAAW,KAAMA,EAAW,SACvC,IAAIP,eAAa,uBAAwB,CAAEE,sBAAAA,UAE9C,CACHO,MAAyB,KAAlBF,EAAW,QAAYG,EAAYC,OAAOJ,EAAW,IAC5DK,IAAuB,KAAlBL,EAAW,QAAYG,EAAYC,OAAOJ,EAAW,KDWvCM,CAAiBhB,GAC9BiB,QAAqBnB,EAAiBoB,OACtCC,EEpCd,SAAsCD,EAAMN,EAAOG,SAQzCK,EAAWF,EAAKG,QACjBN,GAAOA,EAAMK,GAAcR,GAASA,EAAQ,QACvC,IAAIT,eAAa,wBAAyB,CAC5CkB,KAAMD,EACNL,IAAAA,EACAH,MAAAA,QAGJU,EACAC,cACUV,IAAVD,QAA+BC,IAARE,GACvBO,EAAiBV,EAEjBW,EAAeR,EAAM,QAENF,IAAVD,QAA+BC,IAARE,GAC5BO,EAAiBV,EACjBW,EAAeH,QAEFP,IAARE,QAA+BF,IAAVD,IAC1BU,EAAiBF,EAAWL,EAC5BQ,EAAeH,GAEZ,CACHR,MAAOU,EACPP,IAAKQ,GFGuBC,CAA6BP,EAAcb,EAAWQ,MAAOR,EAAWW,KAC9FU,EAAaR,EAAaS,MAAMP,EAAoBP,MAAOO,EAAoBJ,KAC/EY,EAAiBF,EAAWJ,KAC5BO,EAAiB,IAAIC,SAASJ,EAAY,CAG5C1B,OAAQ,IACR+B,WAAY,kBACZ7B,QAASH,EAAiBG,iBAE9B2B,EAAe3B,QAAQ8B,IAAI,iBAAkBC,OAAOL,IACpDC,EAAe3B,QAAQ8B,IAAI,gBAAkB,SAAQZ,EAAoBP,SAASO,EAAoBJ,IAAM,KACxGE,EAAaI,MACVO,EAEX,MAAOK,UAUI,IAAIJ,SAAS,GAAI,CACpB9B,OAAQ,IACR+B,WAAY,wDGjExB,MACII,mBAYSC,yBAA2BxC,OAASE,QAAAA,EAASuC,eAAAA,KAG1CA,GAAkBvC,EAAQI,QAAQoC,IAAI,eACzBzC,EAAsBC,EAASuC,GAIzCA"}