Path: blob/master/views/scram/scramjet.sw-blacklist.js
5227 views
importScripts('{{route}}{{/scram/scramjet.all.js}}');1const { ScramjetServiceWorker } = $scramjetLoadWorker();2const scramjet = new ScramjetServiceWorker();34// Get list of blacklisted domains.5const blacklist = {},6nativeFunction = Function;7fetch('{{route}}{{/assets/json/blacklist.json}}').then((request) => {8request.json().then((jsonData) => {9// Organize each domain by their tld (top level domain) ending.10jsonData.forEach((domain) => {11const domainTld = domain.replace(/.+(?=\.\w)/, '');12if (!blacklist.hasOwnProperty(domainTld)) blacklist[domainTld] = [];1314// Store each entry in an array. Each tld has its own array, which will15// later be concatenated into a regular expression.16blacklist[domainTld].push(17encodeURIComponent(domain.slice(0, -domainTld.length))18.replace(/([()])/g, '\\$1')19.replace(/(\*\.)|\./g, (match, firstExpression) =>20firstExpression ? '(?:.+\\.)?' : '\\' + match21)22);23});2425// Turn each domain list into a regular expression and prevent this26// from being accidentally modified afterward.27for (let [domainTld, domainList] of Object.entries(blacklist))28blacklist[domainTld] = new RegExp(`^(?:${domainList.join('|')})$`);29Object.freeze(blacklist);30});31});3233async function handleRequest(event) {34await scramjet.loadConfig();35if (scramjet.route(event)) {36// The one and only ghetto domain blacklist.37try {38const domain = new URL(39nativeFunction(`return ${scramjet.config.codec.decode}`)()(40new URL(event.request.url).pathname.replace(41scramjet.config.prefix,42''43)44)45).hostname,46domainTld = domain.replace(/.+(?=\.\w)/, '');4748// If the domain is in the blacklist, return a 406 response code.49if (50blacklist.hasOwnProperty(domainTld) &&51blacklist[domainTld].test(domain.slice(0, -domainTld.length))52)53return new Response(new Blob(), { status: 406 });54} catch (e) {55// This is the case where it is an invalid fetch request, or the WASM file.56}5758return scramjet.fetch(event);59}60return fetch(event.request);61}6263self.addEventListener('fetch', (event) => {64event.respondWith(handleRequest(event));65});6667let playgroundData;68self.addEventListener('message', (event) => {69if (event.data.type === 'playgroundData') {70playgroundData = event.data;71} else if (event.data.type === 'requestAC') {72// Set up a message channel from common.js to process autocomplete search results.73const requestPort = event.ports[0];74requestPort.addEventListener('message', async (event) => {75const response = await scramjet.fetch(event.data);7677// This contains some duplicate code from common.js, since Response objects78// cannot be passed through service workers and must be preprocessed.79const responseType = response.headers.get('content-type');80let responseJSON = {};81if (responseType && responseType.indexOf('application/json') !== -1)82responseJSON = await response.json();83else84try {85responseJSON = await response.text();86try {87responseJSON = JSON.parse(responseJSON);88} catch (e) {89responseJSON = JSON.parse(90responseJSON.replace(/^[^[{]*|[^\]}]*$/g, '')91);92}93} catch (e) {94// responseJSON will be an empty object if everything was invalid.95}9697// Return the processed data.98requestPort.postMessage({99responseJSON: responseJSON,100searchType: event.data.type,101time: event.data.request.headers.get('Date'),102});103});104requestPort.start();105}106});107108109