verifyConfigData() initial implementation; getResourceThroughLibResilient() now accepts url and init instead of Request (ref. #31)

merge-requests/11/head
Michał 'rysiek' Woźniak 2022-01-24 13:55:40 +00:00
rodzic 5a7abc344b
commit 3ae6f422ed
2 zmienionych plików z 48 dodań i 27 usunięć

Wyświetl plik

@ -1,16 +1,13 @@
{ {
"plugins": [{ "plugins": [{
"name": "fetch"
},{
"name": "cache"
},{
"name": "basic-integrity", "name": "basic-integrity",
"integrity": [{ "requireIntegrity": false,
"/test.json": "sha384-kn5dhxz4RpBmx7xC7Dmq2N43PclV9U/niyh+4Km7oz5W0FaWdz3Op+3K0Qxz8y3z" "integrity": {
}], "http://localhost:8000/__tests__/test.json": "sha256-FCNALvZ0mSxEs0+SjOgx/sDFFVuh0MwkhhYnI0UJWDg="
},
"uses": [{ "uses": [{
"name": "fetch" "name": "fetch"
}] }]
}], }],
"loggedComponents": ["service-worker", "fetch", "cache"] "loggedComponents": ["service-worker", "fetch", "cache", "basic-integrity"]
} }

Wyświetl plik

@ -83,12 +83,35 @@ if (typeof self.LibResilientConfig !== 'object' || self.LibResilientConfig === n
* items - the rest of arguments will be passed to console.debug() * items - the rest of arguments will be passed to console.debug()
*/ */
self.log = function(component, ...items) { self.log = function(component, ...items) {
if (self.LibResilientConfig.loggedComponents.indexOf(component) >= 0) { if ( ('LibResilientConfig' in self) && ('loggedComponents' in self.LibResilientConfig) && (self.LibResilientConfig.loggedComponents != undefined)) {
console.debug(`LibResilient [COMMIT_UNKNOWN, ${component}] ::`, ...items) if (self.LibResilientConfig.loggedComponents.indexOf(component) >= 0) {
console.debug(`LibResilient [COMMIT_UNKNOWN, ${component}] ::`, ...items)
}
} }
} }
/**
* verifying a config JSON
*
* cdata - config data to verify
*/
let verifyConfigData = (cdata) => {
// basic check for the plugins field
if ( !("plugins" in cdata) || ! Array.isArray(cdata.plugins) ) {
self.log('service-worker', 'fetched config does not contain a valid "plugins" field')
return false;
}
// basic check for the loggedComponents
if ( !("loggedComponents" in cdata) || !Array.isArray(cdata.loggedComponents) ) {
self.log('service-worker', 'fetched config does not contain a valid "loggedComponents" field')
return false;
}
// we're good
return true;
}
// load the plugins // load the plugins
// //
// everything in a try-catch block // everything in a try-catch block
@ -103,14 +126,17 @@ let initServiceWorker = async () => {
// //
// TODO: providing config directly from browser-side control script via postMessage? // TODO: providing config directly from browser-side control script via postMessage?
// TODO: `updateViaCache=imports` allows at least config.json to be updated using the cache plugin? // TODO: `updateViaCache=imports` allows at least config.json to be updated using the cache plugin?
console.debug('* * * LOADING CONFIG * * *')
try { try {
//self.importScripts(self.registration.scope + "config.json") //self.importScripts(self.registration.scope + "config.json")
var cdata = await fetch(self.registration.scope + "config.json") var cdata = await fetch(self.registration.scope + "config.json")
cdata = await cdata.json() cdata = await cdata.json()
self.LibResilientConfig.plugins = cdata.plugins if (verifyConfigData(cdata)) {
self.LibResilientConfig.loggedComponents = cdata.loggedComponents self.LibResilientConfig.plugins = cdata.plugins
self.log('service-worker', 'config loaded.') self.LibResilientConfig.loggedComponents = cdata.loggedComponents
self.log('service-worker', 'config loaded.')
} else {
self.log('service-worker', 'ignoring invalid config, using defaults.')
}
} catch (e) { } catch (e) {
self.log('service-worker', 'config loading failed, using defaults') self.log('service-worker', 'config loading failed, using defaults')
} }
@ -446,7 +472,6 @@ let initFromRequest = (req) => {
* reqInfo - instance of LibResilientResourceInfo * reqInfo - instance of LibResilientResourceInfo
*/ */
let libresilientFetch = (plugin, url, init, reqInfo) => { let libresilientFetch = (plugin, url, init, reqInfo) => {
// status of the plugin // status of the plugin
reqInfo.update({ reqInfo.update({
method: plugin.name, method: plugin.name,
@ -494,19 +519,14 @@ let callOnLibResilientPlugin = (call, args) => {
* and returns a Promise resolving to a Response in case any of the plugins * and returns a Promise resolving to a Response in case any of the plugins
* was able to get the resource * was able to get the resource
* *
* request - string containing the URL we want to fetch * url - the url we want to fetch
* init - the init data for responses
* clientId - string containing the clientId of the requesting client * clientId - string containing the clientId of the requesting client
* useStashed - use stashed resources; if false, only pull resources from live sources * useStashed - use stashed resources; if false, only pull resources from live sources
* doStash - stash resources once fetched successfully; if false, do not stash pulled resources automagically * doStash - stash resources once fetched successfully; if false, do not stash pulled resources automagically
* stashedResponse - TBD * stashedResponse - TBD
*/ */
let getResourceThroughLibResilient = (request, clientId, useStashed=true, doStash=true, stashedResponse=null) => { let getResourceThroughLibResilient = (url, init, clientId, useStashed=true, doStash=true, stashedResponse=null) => {
// clean the URL, removing any fragment identifier
var url = request.url.replace(/#.+$/, '');
// get the init object from Request
var init = initFromRequest(request)
// set-up reqInfo for the fetch event // set-up reqInfo for the fetch event
var reqInfo = new LibResilientResourceInfo(url, clientId) var reqInfo = new LibResilientResourceInfo(url, clientId)
@ -576,8 +596,7 @@ let getResourceThroughLibResilient = (request, clientId, useStashed=true, doStas
self.log('service-worker', 'starting background no-stashed fetch for:', url); self.log('service-worker', 'starting background no-stashed fetch for:', url);
// event.waitUntil? // event.waitUntil?
// https://stackoverflow.com/questions/37902441/what-does-event-waituntil-do-in-service-worker-and-why-is-it-needed/37906330#37906330 // https://stackoverflow.com/questions/37902441/what-does-event-waituntil-do-in-service-worker-and-why-is-it-needed/37906330#37906330
// TODO: perhaps don't use the `request` again? some wrapper? getResourceThroughLibResilient(url, init, clientId, false, true, response.clone()).catch((e)=>{
getResourceThroughLibResilient(request, clientId, false, true, response.clone()).catch((e)=>{
self.log('service-worker', 'background no-stashed fetch failed for:', url); self.log('service-worker', 'background no-stashed fetch failed for:', url);
}) })
// return the response so that stuff can keep happening // return the response so that stuff can keep happening
@ -678,7 +697,6 @@ let getResourceThroughLibResilient = (request, clientId, useStashed=true, doStas
/* ========================================================================= *\ /* ========================================================================= *\
|* === Setting up the event handlers === *| |* === Setting up the event handlers === *|
\* ========================================================================= */ \* ========================================================================= */
self.addEventListener('install', async (event) => { self.addEventListener('install', async (event) => {
event.waitUntil(initServiceWorker()) event.waitUntil(initServiceWorker())
// TODO: Might we want to have a local cache? // TODO: Might we want to have a local cache?
@ -747,9 +765,15 @@ self.addEventListener('fetch', event => {
return void event.respondWith(fetch(event.request)); return void event.respondWith(fetch(event.request));
} }
// clean the URL, removing any fragment identifier
var url = event.request.url.replace(/#.+$/, '');
// get the init object from Request
var init = initFromRequest(event.request)
// GET requests to our own domain that are *not* #libresilient-info requests // GET requests to our own domain that are *not* #libresilient-info requests
// get handled by plugins in case of an error // get handled by plugins in case of an error
return void event.respondWith(getResourceThroughLibResilient(event.request, clientId)) return void event.respondWith(getResourceThroughLibResilient(url, init, clientId))
}); });