const originalSwOption = new URL(location.href).searchParams.get('sw'); let swOption = originalSwOption; if (swOption === 'fetch-handler-navigation-preload') { self.addEventListener('activate', event => { if (self.registration.navigationPreload) { event.waitUntil(self.registration.navigationPreload.enable()); } }); } if (swOption === 'race-fetch-handler' || swOption === 'race-fetch-handler-to-fallback' || swOption === 'race-fetch-handler-modify-url') { swOption = swOption.substring('race-'.length); self.addEventListener('install', event => { event.addRoutes([{ condition: { urlPattern: { pathname: '/**/counting-executor.py' } }, source: 'race-network-and-fetch-handler' }]); }); } const interceptedRequests = []; self.addEventListener('message', event => { if (event.data === 'getInterceptedRequests') { event.source.postMessage(interceptedRequests); } }); if (swOption !== 'no-fetch-handler') { self.addEventListener('fetch', event => { // Intercept the prefetched and navigated URLs only (e.g. do not intercept // subresource requests related to `/common/dispatcher/dispatcher.js`). if (!event.request.url.includes('counting-executor.py')) { return; } const headers = {}; event.request.headers.forEach((value, key) => { headers[key] = value; }); const interceptedRequest = { request: { url: event.request.url, headers: headers, }, clientId: event.clientId, resultingClientId: event.resultingClientId }; interceptedRequests.push(interceptedRequest); if (swOption === 'fetch-handler') { event.respondWith(fetch(event.request)); } else if (swOption === 'fetch-handler-synthetic') { const finalUrl = new URL(event.request.url).searchParams.get('location'); if (finalUrl) { event.respondWith(Response.redirect(finalUrl)); } else { // Fallback to the network. } } else if (swOption === 'fetch-handler-modify-url') { // The "Sec-Purpose: prefetch" header is dropped in fetch-handler-modify-* // cases in Step 33 of // https://fetch.spec.whatwg.org/#dom-request // because it's a https://fetch.spec.whatwg.org/#forbidden-request-header const url = new URL(event.request.url); url.searchParams.set('intercepted', 'true'); if (originalSwOption === 'race-fetch-handler-modify-url') { // See the comment in `basic.sub.https.html` for delay value. url.searchParams.set('delay', '500'); } event.respondWith(fetch(url, {headers: event.request.headers})); } else if (swOption === 'fetch-handler-modify-referrer') { event.respondWith(fetch(event.request, {referrer: new URL('/intercepted', location.href).href})); } else if (swOption === 'fetch-handler-navigation-preload') { event.respondWith((async () => { try { if (event.preloadResponse === 'undefined') { interceptedRequest.preloadResponse = 'undefined'; return fetch(event.request); } const response = await event.preloadResponse; if (response) { interceptedRequest.preloadResponse = 'resolved'; return response; } else { interceptedRequest.preloadResponse = 'resolved to undefined'; return fetch(event.request); } } catch(e) { interceptedRequest.preloadResponse = 'rejected'; throw e; } })()); } else { // Do nothing to fallback to the network. } }); }