From 3daf4170e74e607729430b1659ce5f4352fb51be Mon Sep 17 00:00:00 2001 From: dexter21767-dev Date: Wed, 10 Apr 2024 10:30:33 +0100 Subject: [PATCH 1/2] add manifestHandler to change the manifest according to the user config --- src/builder.js | 7 ++++ src/getRouter.js | 96 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 75 insertions(+), 28 deletions(-) diff --git a/src/builder.js b/src/builder.js index 55f32d1..4ff9d8a 100755 --- a/src/builder.js +++ b/src/builder.js @@ -29,6 +29,12 @@ function AddonBuilder(manifest) { const handlersInManifest = [] if (manifest.catalogs.length > 0) handlersInManifest.push('catalog') manifest.resources.forEach((r) => handlersInManifest.push(r.name || r)) + // add manifestHandler using behaviorHints or manifest.resources + /* + if(manifest.behaviorHints && (manifest.behaviorHints.configurationRequired || manifest.behaviorHints.configurable)){ + handlersInManifest.push('manifest'); + } + */ const handlersDefined = Object.keys(handlers) handlersDefined.forEach(defined => { if (!handlersInManifest.includes(defined)) { @@ -63,6 +69,7 @@ function AddonBuilder(manifest) { handlers[resource] = handler return this } + this.defineManifestHandler = this.defineResourceHandler.bind(this, 'manifest') this.defineStreamHandler = this.defineResourceHandler.bind(this, 'stream') this.defineMetaHandler = this.defineResourceHandler.bind(this, 'meta') this.defineCatalogHandler = this.defineResourceHandler.bind(this, 'catalog') diff --git a/src/getRouter.js b/src/getRouter.js index bde8f1e..b2f8efb 100644 --- a/src/getRouter.js +++ b/src/getRouter.js @@ -12,8 +12,8 @@ function getRouter({ manifest , get }) { // Serve the manifest const manifestBuf = JSON.stringify(manifest) - function manifestHandler(req, res) { - const { config } = req.params + + function manifestHandler(config) { let manifestRespBuf = manifestBuf if (config && manifest.behaviorHints && (manifest.behaviorHints.configurationRequired || manifest.behaviorHints.configurable)) { const manifestClone = JSON.parse(manifestBuf) @@ -23,10 +23,37 @@ function getRouter({ manifest , get }) { delete manifestClone.behaviorHints.configurable manifestRespBuf = JSON.stringify(manifestClone) } - res.setHeader('Content-Type', 'application/json; charset=utf-8') - res.end(manifestRespBuf) + return manifestRespBuf + } + + function parseConfig(params) { + let { config } = params + if ((config || '').length) { + try { + config = JSON.parse(config) + } catch(e) { + config = false + } + } + return config; } + function getCacheControl(resp){ + let cacheHeaders = { + cacheMaxAge: 'max-age', + staleRevalidate: 'stale-while-revalidate', + staleError: 'stale-if-error' + } + return Object.keys(cacheHeaders).map(prop => { + const cacheProp = cacheHeaders[prop] + const cacheValue = resp[prop] + if (!Number.isInteger(cacheValue)) return false + if (cacheValue > 365 * 24 * 60 * 60) + console.warn(`${prop} set to more then 1 year, be advised that cache times are in seconds, not milliseconds.`) + return cacheProp + '=' + cacheValue + }).filter(val => !!val).join(', ') + } + const hasConfig = (manifest.config || []).length if (hasConfig && !(manifest.behaviorHints || {}).configurable) { @@ -37,7 +64,40 @@ function getRouter({ manifest , get }) { // having config prifix always set to '/:config?' won't resault in a problem for non configurable addons, // since now the order is restricted by resources. - router.get(`${configPrefix}/manifest.json`, manifestHandler) + // Handles manifest + router.get(`${configPrefix}/manifest.json`, function(req, res, next) { + let config = parseConfig(req.params) + let manifestRespBuf = manifestHandler(config) + res.setHeader('Content-Type', 'application/json; charset=utf-8') + if(!config) res.end(manifestRespBuf); + + // setting type and id to null since this route doesn't support them + get('manifest',null,null, extra={manifest:JSON.parse(manifestRespBuf)}, config) + .then(resp => { + const cacheControl = getCacheControl(resp); + if (cacheControl) + res.setHeader('Cache-Control', `${cacheControl}, public`) + + if (resp.redirect) { + res.redirect(307, resp.redirect) + return + } + res.end(JSON.stringify(resp.manifest)) + }) + .catch(err => { + if (err.noHandler) { + if (next) next() + else { + res.status(404) + res.end(JSON.stringify({ err: 'not found' })) + } + } else { + console.error(err) + res.status(500) + res.end(JSON.stringify({ err: 'handler error' })) + } + }) + }) // using the same methode used in builder.js to extract resources from manifest const handlersInManifest = [] @@ -50,37 +110,17 @@ function getRouter({ manifest , get }) { // Handle all resources router.get(`${configPrefix}/:resource${ResourcesRegex}/:type/:id/:extra?.json`, function(req, res, next) { const { resource, type, id } = req.params - let { config } = req.params + let config = parseConfig(req.params) // we get `extra` from `req.url` because `req.params.extra` decodes the characters // and breaks dividing querystring parameters with `&`, in case `&` is one of the // encoded characters of a parameter value const extra = req.params.extra ? qs.parse(req.url.split('/').pop().slice(0, -5)) : {} - if ((config || '').length) { - try { - config = JSON.parse(config) - } catch(e) { - config = false - } - } + res.setHeader('Content-Type', 'application/json; charset=utf-8') get(resource, type, id, extra, config) .then(resp => { - let cacheHeaders = { - cacheMaxAge: 'max-age', - staleRevalidate: 'stale-while-revalidate', - staleError: 'stale-if-error' - } - - const cacheControl = Object.keys(cacheHeaders).map(prop => { - const cacheProp = cacheHeaders[prop] - const cacheValue = resp[prop] - if (!Number.isInteger(cacheValue)) return false - if (cacheValue > 365 * 24 * 60 * 60) - console.warn(`${prop} set to more then 1 year, be advised that cache times are in seconds, not milliseconds.`) - return cacheProp + '=' + cacheValue - }).filter(val => !!val).join(', ') - + const cacheControl = getCacheControl(resp); if (cacheControl) res.setHeader('Cache-Control', `${cacheControl}, public`) From 9780c372033f771df8b767f1a5dd267986c665d0 Mon Sep 17 00:00:00 2001 From: dexter21767-dev Date: Wed, 10 Apr 2024 11:59:30 +0100 Subject: [PATCH 2/2] fix eslint issues --- src/getRouter.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/getRouter.js b/src/getRouter.js index b2f8efb..c5a75bf 100644 --- a/src/getRouter.js +++ b/src/getRouter.js @@ -35,7 +35,7 @@ function getRouter({ manifest , get }) { config = false } } - return config; + return config } function getCacheControl(resp){ @@ -69,12 +69,13 @@ function getRouter({ manifest , get }) { let config = parseConfig(req.params) let manifestRespBuf = manifestHandler(config) res.setHeader('Content-Type', 'application/json; charset=utf-8') - if(!config) res.end(manifestRespBuf); + if(!config) res.end(manifestRespBuf) + const extra = { manifest: JSON.parse(manifestRespBuf) } // setting type and id to null since this route doesn't support them - get('manifest',null,null, extra={manifest:JSON.parse(manifestRespBuf)}, config) + get('manifest',null,null, extra, config) .then(resp => { - const cacheControl = getCacheControl(resp); + const cacheControl = getCacheControl(resp) if (cacheControl) res.setHeader('Cache-Control', `${cacheControl}, public`) @@ -120,7 +121,7 @@ function getRouter({ manifest , get }) { get(resource, type, id, extra, config) .then(resp => { - const cacheControl = getCacheControl(resp); + const cacheControl = getCacheControl(resp) if (cacheControl) res.setHeader('Cache-Control', `${cacheControl}, public`) @@ -129,8 +130,6 @@ function getRouter({ manifest , get }) { return } - res.setHeader('Content-Type', 'application/json; charset=utf-8') - if (!warned.filename && resource === 'stream' && ((resp || {}).streams || []).length) if (resp.streams.find(stream => stream && stream.url && !(stream.behaviorHints || {}).filename)) { warned.filename = true