blob: 89bef8272106139c096007c62b475dca9d0861fd [file] [log] [blame]
{"version":3,"file":"workbox-range-requests.prod.js","sources":["../_version.mjs","../createPartialResponse.mjs","../utils/parseRangeHeader.mjs","../utils/calculateEffectiveBoundaries.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:range-requests:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\n\nimport {calculateEffectiveBoundaries} from\n './utils/calculateEffectiveBoundaries.mjs';\nimport {parseRangeHeader} from './utils/parseRangeHeader.mjs';\n\nimport './_version.mjs';\n\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 workbox.rangeRequests\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\n assert.isInstance(originalResponse, Response, {\n moduleName: 'workbox-range-requests',\n funcName: 'createPartialResponse',\n paramName: 'originalResponse',\n });\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\n const rangeHeader = request.headers.get('range');\n if (!rangeHeader) {\n throw new WorkboxError('no-range-header');\n }\n\n const boundaries = parseRangeHeader(rangeHeader);\n const originalBlob = await originalResponse.blob();\n\n const effectiveBoundaries = calculateEffectiveBoundaries(\n originalBlob, boundaries.start, boundaries.end);\n\n const slicedBlob = originalBlob.slice(effectiveBoundaries.start,\n effectiveBoundaries.end);\n const slicedBlobSize = slicedBlob.size;\n\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\n slicedResponse.headers.set('Content-Length', slicedBlobSize);\n slicedResponse.headers.set('Content-Range',\n `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` +\n originalBlob.size);\n\n return slicedResponse;\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\n return new Response('', {\n status: 416,\n statusText: 'Range Not Satisfiable',\n });\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\n\nimport '../_version.mjs';\n\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\n const normalizedRangeHeader = rangeHeader.trim().toLowerCase();\n if (!normalizedRangeHeader.startsWith('bytes=')) {\n throw new WorkboxError('unit-must-be-bytes', {normalizedRangeHeader});\n }\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\n const rangeParts = /(\\d*)-(\\d*)/.exec(normalizedRangeHeader);\n // We need either at least one of the start or end values.\n if (rangeParts === null || !(rangeParts[1] || rangeParts[2])) {\n throw new WorkboxError('invalid-range-values', {normalizedRangeHeader});\n }\n\n return {\n start: rangeParts[1] === '' ? null : Number(rangeParts[1]),\n end: rangeParts[2] === '' ? null : Number(rangeParts[2]),\n };\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\n\nimport '../_version.mjs';\n\n/**\n * @param {Blob} blob A source blob.\n * @param {number|null} start The offset to use as the start of the\n * slice.\n * @param {number|null} 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\n const blobSize = blob.size;\n\n if (end > blobSize || start < 0) {\n throw new WorkboxError('range-not-satisfiable', {\n size: blobSize,\n end,\n start,\n });\n }\n\n let effectiveStart;\n let effectiveEnd;\n\n if (start === null) {\n effectiveStart = blobSize - end;\n effectiveEnd = blobSize;\n } else if (end === null) {\n effectiveStart = start;\n effectiveEnd = blobSize;\n } else {\n effectiveStart = start;\n // Range values are inclusive, so add 1 to the value.\n effectiveEnd = end + 1;\n }\n\n return {\n start: effectiveStart,\n end: effectiveEnd,\n };\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*/\n\nimport {createPartialResponse} from './createPartialResponse.mjs';\n\nimport './_version.mjs';\n\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 workbox.rangeRequests\n */\nclass Plugin {\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 async cachedResponseWillBeUsed({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\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 {Plugin};\n"],"names":["self","_","e","async","createPartialResponse","request","originalResponse","status","rangeHeader","headers","get","WorkboxError","boundaries","normalizedRangeHeader","trim","toLowerCase","startsWith","includes","rangeParts","exec","start","Number","end","parseRangeHeader","originalBlob","blob","effectiveBoundaries","blobSize","size","effectiveStart","effectiveEnd","calculateEffectiveBoundaries","slicedBlob","slice","slicedBlobSize","slicedResponse","Response","statusText","set","error","cachedResponse","has"],"mappings":"oFAAA,IAAIA,KAAK,iCAAiCC,IAAI,MAAMC,ICoCpDC,eAAeC,EAAsBC,EAASC,UAgBV,MAA5BA,EAAiBC,cAGZD,QAGHE,EAAcH,EAAQI,QAAQC,IAAI,aACnCF,QACG,IAAIG,eAAa,yBAGnBC,EC1CV,SAA0BJ,SASlBK,EAAwBL,EAAYM,OAAOC,kBAC5CF,EAAsBG,WAAW,gBAC9B,IAAIL,eAAa,qBAAsB,CAACE,sBAAAA,OAM5CA,EAAsBI,SAAS,WAC3B,IAAIN,eAAa,oBAAqB,CAACE,sBAAAA,UAGzCK,EAAa,cAAcC,KAAKN,MAEnB,OAAfK,IAAyBA,EAAW,KAAMA,EAAW,SACjD,IAAIP,eAAa,uBAAwB,CAACE,sBAAAA,UAG3C,CACLO,MAAyB,KAAlBF,EAAW,GAAY,KAAOG,OAAOH,EAAW,IACvDI,IAAuB,KAAlBJ,EAAW,GAAY,KAAOG,OAAOH,EAAW,KDalCK,CAAiBf,GAC9BgB,QAAqBlB,EAAiBmB,OAEtCC,EE3CV,SAAsCD,EAAML,EAAOE,SAS3CK,EAAWF,EAAKG,QAElBN,EAAMK,GAAYP,EAAQ,QACtB,IAAIT,eAAa,wBAAyB,CAC9CiB,KAAMD,EACNL,IAAAA,EACAF,MAAAA,QAIAS,EACAC,SAEU,OAAVV,GACFS,EAAiBF,EAAWL,EAC5BQ,EAAeH,GACE,OAARL,GACTO,EAAiBT,EACjBU,EAAeH,IAEfE,EAAiBT,EAEjBU,EAAeR,EAAM,GAGhB,CACLF,MAAOS,EACPP,IAAKQ,GFOuBC,CACxBP,EAAcZ,EAAWQ,MAAOR,EAAWU,KAEzCU,EAAaR,EAAaS,MAAMP,EAAoBN,MACtDM,EAAoBJ,KAClBY,EAAiBF,EAAWJ,KAE5BO,EAAiB,IAAIC,SAASJ,EAAY,CAG9CzB,OAAQ,IACR8B,WAAY,kBACZ5B,QAASH,EAAiBG,iBAG5B0B,EAAe1B,QAAQ6B,IAAI,iBAAkBJ,GAC7CC,EAAe1B,QAAQ6B,IAAI,yBACdZ,EAAoBN,SAASM,EAAoBJ,IAAM,KAClEE,EAAaI,MAERO,EACP,MAAOI,UAWA,IAAIH,SAAS,GAAI,CACtB7B,OAAQ,IACR8B,WAAY,qEG/ElB,sCAYiChC,QAACA,EAADmC,eAAUA,WAGnCA,GAAkBnC,EAAQI,QAAQgC,IAAI,eAC3BrC,EAAsBC,EAASmC,GAKvCA"}