1 | this.workbox = this.workbox || {};
|
2 | this.workbox.rangeRequests = (function (exports,WorkboxError_mjs,assert_mjs,logger_mjs) {
|
3 | ;
|
4 |
|
5 | try {
|
6 | self.workbox.v['workbox:range-requests:3.6.2'] = 1;
|
7 | } catch (e) {} // eslint-disable-line
|
8 |
|
9 | /*
|
10 | Copyright 2017 Google Inc.
|
11 |
|
12 | Licensed under the Apache License, Version 2.0 (the "License");
|
13 | you may not use this file except in compliance with the License.
|
14 | You may obtain a copy of the License at
|
15 |
|
16 | https://www.apache.org/licenses/LICENSE-2.0
|
17 |
|
18 | Unless required by applicable law or agreed to in writing, software
|
19 | distributed under the License is distributed on an "AS IS" BASIS,
|
20 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
21 | See the License for the specific language governing permissions and
|
22 | limitations under the License.
|
23 | */
|
24 |
|
25 | /**
|
26 | * @param {Blob} blob A source blob.
|
27 | * @param {number|null} start The offset to use as the start of the
|
28 | * slice.
|
29 | * @param {number|null} end The offset to use as the end of the slice.
|
30 | * @return {Object} An object with `start` and `end` properties, reflecting
|
31 | * the effective boundaries to use given the size of the blob.
|
32 | *
|
33 | * @private
|
34 | */
|
35 | function calculateEffectiveBoundaries(blob, start, end) {
|
36 | {
|
37 | assert_mjs.assert.isInstance(blob, Blob, {
|
38 | moduleName: 'workbox-range-requests',
|
39 | funcName: 'calculateEffectiveBoundaries',
|
40 | paramName: 'blob'
|
41 | });
|
42 | }
|
43 |
|
44 | const blobSize = blob.size;
|
45 |
|
46 | if (end > blobSize || start < 0) {
|
47 | throw new WorkboxError_mjs.WorkboxError('range-not-satisfiable', {
|
48 | size: blobSize,
|
49 | end,
|
50 | start
|
51 | });
|
52 | }
|
53 |
|
54 | let effectiveStart;
|
55 | let effectiveEnd;
|
56 |
|
57 | if (start === null) {
|
58 | effectiveStart = blobSize - end;
|
59 | effectiveEnd = blobSize;
|
60 | } else if (end === null) {
|
61 | effectiveStart = start;
|
62 | effectiveEnd = blobSize;
|
63 | } else {
|
64 | effectiveStart = start;
|
65 | // Range values are inclusive, so add 1 to the value.
|
66 | effectiveEnd = end + 1;
|
67 | }
|
68 |
|
69 | return {
|
70 | start: effectiveStart,
|
71 | end: effectiveEnd
|
72 | };
|
73 | }
|
74 |
|
75 | /*
|
76 | Copyright 2017 Google Inc.
|
77 |
|
78 | Licensed under the Apache License, Version 2.0 (the "License");
|
79 | you may not use this file except in compliance with the License.
|
80 | You may obtain a copy of the License at
|
81 |
|
82 | https://www.apache.org/licenses/LICENSE-2.0
|
83 |
|
84 | Unless required by applicable law or agreed to in writing, software
|
85 | distributed under the License is distributed on an "AS IS" BASIS,
|
86 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
87 | See the License for the specific language governing permissions and
|
88 | limitations under the License.
|
89 | */
|
90 |
|
91 | /**
|
92 | * @param {string} rangeHeader A Range: header value.
|
93 | * @return {Object} An object with `start` and `end` properties, reflecting
|
94 | * the parsed value of the Range: header. If either the `start` or `end` are
|
95 | * omitted, then `null` will be returned.
|
96 | *
|
97 | * @private
|
98 | */
|
99 | function parseRangeHeader(rangeHeader) {
|
100 | {
|
101 | assert_mjs.assert.isType(rangeHeader, 'string', {
|
102 | moduleName: 'workbox-range-requests',
|
103 | funcName: 'parseRangeHeader',
|
104 | paramName: 'rangeHeader'
|
105 | });
|
106 | }
|
107 |
|
108 | const normalizedRangeHeader = rangeHeader.trim().toLowerCase();
|
109 | if (!normalizedRangeHeader.startsWith('bytes=')) {
|
110 | throw new WorkboxError_mjs.WorkboxError('unit-must-be-bytes', { normalizedRangeHeader });
|
111 | }
|
112 |
|
113 | // Specifying multiple ranges separate by commas is valid syntax, but this
|
114 | // library only attempts to handle a single, contiguous sequence of bytes.
|
115 | // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#Syntax
|
116 | if (normalizedRangeHeader.includes(',')) {
|
117 | throw new WorkboxError_mjs.WorkboxError('single-range-only', { normalizedRangeHeader });
|
118 | }
|
119 |
|
120 | const rangeParts = /(\d*)-(\d*)/.exec(normalizedRangeHeader);
|
121 | // We need either at least one of the start or end values.
|
122 | if (rangeParts === null || !(rangeParts[1] || rangeParts[2])) {
|
123 | throw new WorkboxError_mjs.WorkboxError('invalid-range-values', { normalizedRangeHeader });
|
124 | }
|
125 |
|
126 | return {
|
127 | start: rangeParts[1] === '' ? null : Number(rangeParts[1]),
|
128 | end: rangeParts[2] === '' ? null : Number(rangeParts[2])
|
129 | };
|
130 | }
|
131 |
|
132 | /**
|
133 | * Given a `Request` and `Response` objects as input, this will return a
|
134 | * promise for a new `Response`.
|
135 | *
|
136 | * @param {Request} request A request, which should contain a Range:
|
137 | * header.
|
138 | * @param {Response} originalResponse An original response containing the full
|
139 | * content.
|
140 | * @return {Promise<Response>} Either a `206 Partial Content` response, with
|
141 | * the response body set to the slice of content specified by the request's
|
142 | * `Range:` header, or a `416 Range Not Satisfiable` response if the
|
143 | * conditions of the `Range:` header can't be met.
|
144 | *
|
145 | * @memberof workbox.rangeRequests
|
146 | */
|
147 | let createPartialResponse = (() => {
|
148 | var _ref = babelHelpers.asyncToGenerator(function* (request, originalResponse) {
|
149 | try {
|
150 | {
|
151 | assert_mjs.assert.isInstance(request, Request, {
|
152 | moduleName: 'workbox-range-requests',
|
153 | funcName: 'createPartialResponse',
|
154 | paramName: 'request'
|
155 | });
|
156 |
|
157 | assert_mjs.assert.isInstance(originalResponse, Response, {
|
158 | moduleName: 'workbox-range-requests',
|
159 | funcName: 'createPartialResponse',
|
160 | paramName: 'originalResponse'
|
161 | });
|
162 | }
|
163 |
|
164 | const rangeHeader = request.headers.get('range');
|
165 | if (!rangeHeader) {
|
166 | throw new WorkboxError_mjs.WorkboxError('no-range-header');
|
167 | }
|
168 |
|
169 | const boundaries = parseRangeHeader(rangeHeader);
|
170 | const originalBlob = yield originalResponse.blob();
|
171 |
|
172 | const effectiveBoundaries = calculateEffectiveBoundaries(originalBlob, boundaries.start, boundaries.end);
|
173 |
|
174 | const slicedBlob = originalBlob.slice(effectiveBoundaries.start, effectiveBoundaries.end);
|
175 | const slicedBlobSize = slicedBlob.size;
|
176 |
|
177 | const slicedResponse = new Response(slicedBlob, {
|
178 | // Status code 206 is for a Partial Content response.
|
179 | // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206
|
180 | status: 206,
|
181 | statusText: 'Partial Content',
|
182 | headers: originalResponse.headers
|
183 | });
|
184 |
|
185 | slicedResponse.headers.set('Content-Length', slicedBlobSize);
|
186 | slicedResponse.headers.set('Content-Range', `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` + originalBlob.size);
|
187 |
|
188 | return slicedResponse;
|
189 | } catch (error) {
|
190 | {
|
191 | logger_mjs.logger.warn(`Unable to construct a partial response; returning a ` + `416 Range Not Satisfiable response instead.`);
|
192 | logger_mjs.logger.groupCollapsed(`View details here.`);
|
193 | logger_mjs.logger.unprefixed.log(error);
|
194 | logger_mjs.logger.unprefixed.log(request);
|
195 | logger_mjs.logger.unprefixed.log(originalResponse);
|
196 | logger_mjs.logger.groupEnd();
|
197 | }
|
198 |
|
199 | return new Response('', {
|
200 | status: 416,
|
201 | statusText: 'Range Not Satisfiable'
|
202 | });
|
203 | }
|
204 | });
|
205 |
|
206 | return function createPartialResponse(_x, _x2) {
|
207 | return _ref.apply(this, arguments);
|
208 | };
|
209 | })();
|
210 |
|
211 | /*
|
212 | Copyright 2016 Google Inc. All Rights Reserved.
|
213 | Licensed under the Apache License, Version 2.0 (the "License");
|
214 | you may not use this file except in compliance with the License.
|
215 | You may obtain a copy of the License at
|
216 | http://www.apache.org/licenses/LICENSE-2.0
|
217 | Unless required by applicable law or agreed to in writing, software
|
218 | distributed under the License is distributed on an "AS IS" BASIS,
|
219 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
220 | See the License for the specific language governing permissions and
|
221 | limitations under the License.
|
222 | */
|
223 |
|
224 | /**
|
225 | * The range request plugin makes it easy for a request with a 'Range' header to
|
226 | * be fulfilled by a cached response.
|
227 | *
|
228 | * It does this by intercepting the `cachedResponseWillBeUsed` plugin callback
|
229 | * and returning the appropriate subset of the cached response body.
|
230 | *
|
231 | * @memberof workbox.rangeRequests
|
232 | */
|
233 | class Plugin {
|
234 | /**
|
235 | * @param {Object} options
|
236 | * @param {Request} options.request The original request, which may or may not
|
237 | * contain a Range: header.
|
238 | * @param {Response} options.cachedResponse The complete cached response.
|
239 | * @return {Promise<Response>} If request contains a 'Range' header, then a
|
240 | * new response with status 206 whose body is a subset of `cachedResponse` is
|
241 | * returned. Otherwise, `cachedResponse` is returned as-is.
|
242 | *
|
243 | * @private
|
244 | */
|
245 | cachedResponseWillBeUsed({ request, cachedResponse }) {
|
246 | return babelHelpers.asyncToGenerator(function* () {
|
247 | // Only return a sliced response if there's something valid in the cache,
|
248 | // and there's a Range: header in the request.
|
249 | if (cachedResponse && request.headers.has('range')) {
|
250 | return yield createPartialResponse(request, cachedResponse);
|
251 | }
|
252 |
|
253 | // If there was no Range: header, or if cachedResponse wasn't valid, just
|
254 | // pass it through as-is.
|
255 | return cachedResponse;
|
256 | })();
|
257 | }
|
258 | }
|
259 |
|
260 | /*
|
261 | Copyright 2017 Google Inc.
|
262 |
|
263 | Licensed under the Apache License, Version 2.0 (the "License");
|
264 | you may not use this file except in compliance with the License.
|
265 | You may obtain a copy of the License at
|
266 |
|
267 | https://www.apache.org/licenses/LICENSE-2.0
|
268 |
|
269 | Unless required by applicable law or agreed to in writing, software
|
270 | distributed under the License is distributed on an "AS IS" BASIS,
|
271 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
272 | See the License for the specific language governing permissions and
|
273 | limitations under the License.
|
274 | */
|
275 |
|
276 | /*
|
277 | Copyright 2017 Google Inc.
|
278 |
|
279 | Licensed under the Apache License, Version 2.0 (the "License");
|
280 | you may not use this file except in compliance with the License.
|
281 | You may obtain a copy of the License at
|
282 |
|
283 | https://www.apache.org/licenses/LICENSE-2.0
|
284 |
|
285 | Unless required by applicable law or agreed to in writing, software
|
286 | distributed under the License is distributed on an "AS IS" BASIS,
|
287 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
288 | See the License for the specific language governing permissions and
|
289 | limitations under the License.
|
290 | */
|
291 |
|
292 | exports.createPartialResponse = createPartialResponse;
|
293 | exports.Plugin = Plugin;
|
294 |
|
295 | return exports;
|
296 |
|
297 | }({},workbox.core._private,workbox.core._private,workbox.core._private));
|
298 |
|
299 | //# sourceMappingURL=workbox-range-requests.dev.js.map
|