diff --git a/frontend/components/usage.js b/frontend/components/usage.js index 923ce7eced4fdda0ece130e98d1eb95e6077bdeb..a94cc4560c7943657225f1ccd4548426bd2b8f40 100644 --- a/frontend/components/usage.js +++ b/frontend/components/usage.js @@ -269,8 +269,9 @@ export default class Usage extends React.PureComponent { <code>?maxAge=3600</code> </td> <td> - Set the HTTP cache lifetime in secs (values below the default - (currently 120 seconds) will be ignored) + Set the HTTP cache lifetime in secs (rules are applied to infer + a default value on a per-badge basis, any values specified below + the default will be ignored) </td> </tr> </tbody> diff --git a/lib/request-handler.js b/lib/request-handler.js index 48d99ed5c95c63d435b148aca349f4be820de8f9..aa93684ecd9ea3cc846344d786e2f599a19f3c2e 100644 --- a/lib/request-handler.js +++ b/lib/request-handler.js @@ -56,10 +56,29 @@ function flattenQueryParams(queryParams) { return Array.from(union).sort() } +function getBadgeMaxAge(handlerOptions, queryParams) { + let maxAge = isInt(process.env.BADGE_MAX_AGE_SECONDS) + ? parseInt(process.env.BADGE_MAX_AGE_SECONDS) + : 120 + if (handlerOptions.cacheLength) { + // if we've set a more specific cache length for this badge (or category), + // use that instead of env.BADGE_MAX_AGE_SECONDS + maxAge = parseInt(handlerOptions.cacheLength) + } + if (isInt(queryParams.maxAge) && parseInt(queryParams.maxAge) > maxAge) { + // only allow queryParams.maxAge to override the default + // if it is greater than the default + maxAge = parseInt(queryParams.maxAge) + } + return maxAge +} + // handlerOptions can contain: // - handler: The service's request handler function // - queryParams: An array of the field names of any custom query parameters // the service uses +// - cacheLength: An optional badge or category-specific cache length +// (in number of seconds) to be used in preference to the default // // For safety, the service must declare the query parameters it wants to use. // Only the declared parameters (and the global parameters) are provided to @@ -81,14 +100,7 @@ function handleRequest(makeBadge, handlerOptions) { return (queryParams, match, end, ask) => { const reqTime = new Date() - let maxAge = isInt(process.env.BADGE_MAX_AGE_SECONDS) - ? parseInt(process.env.BADGE_MAX_AGE_SECONDS) - : 120 - if (isInt(queryParams.maxAge) && parseInt(queryParams.maxAge) > maxAge) { - // only queryParams.maxAge to override the default - // if it is greater than env.BADGE_MAX_AGE_SECONDS - maxAge = parseInt(queryParams.maxAge) - } + const maxAge = getBadgeMaxAge(handlerOptions, queryParams) // send both Cache-Control max-age and Expires // in case the client implements HTTP/1.0 but not HTTP/1.1 if (maxAge === 0) { @@ -269,4 +281,5 @@ module.exports = { clearRequestCache, // Expose for testing. _requestCache: requestCache, + getBadgeMaxAge, } diff --git a/lib/request-handler.spec.js b/lib/request-handler.spec.js index d3fc1b4f12b8b7e272f889b701fb450e859f1598..1adba41078891100486606b6624194bdd6956e70 100644 --- a/lib/request-handler.spec.js +++ b/lib/request-handler.spec.js @@ -1,6 +1,7 @@ 'use strict' const { expect } = require('chai') +const { test, given } = require('sazerac') const fetch = require('node-fetch') const config = require('./test-config') const Camp = require('camp') @@ -10,6 +11,7 @@ const { makeHandleRequestFn, clearRequestCache, _requestCache, + getBadgeMaxAge, } = require('./request-handler') const testHelpers = require('./make-badge-test-helpers') @@ -206,4 +208,14 @@ describe('The request handler', function() { }) }) }) + + describe('getBadgeMaxAge function', function() { + process.env.BADGE_MAX_AGE_SECONDS = 120 + test(getBadgeMaxAge, () => { + given({}, {}).expect(120) + given({ cacheLength: 900 }, {}).expect(900) + given({ cacheLength: 900 }, { maxAge: 1000 }).expect(1000) + given({ cacheLength: 900 }, { maxAge: 400 }).expect(900) + }) + }) }) diff --git a/services/base.js b/services/base.js index ce9a684ff4a01b7451c37f081c80d05545baf9dc..2cf802dd3a78651faa1415792ff5d078914cd9e2 100644 --- a/services/base.js +++ b/services/base.js @@ -165,6 +165,15 @@ class BaseService { return new RegExp(fullRegex) } + static get _cacheLength() { + const cacheLengths = { + build: 30, + license: 3600, + version: 300, + } + return cacheLengths[this.category] + } + static _namedParamsForMatch(match) { const names = this.url.capture || [] @@ -315,6 +324,7 @@ class BaseService { const format = match.slice(-1)[0] sendBadge(format, badgeData) }, + cacheLength: this._cacheLength, }) ) } diff --git a/services/discord/discord.service.js b/services/discord/discord.service.js index 414820d86f23b0915a123bef9f8cabb6413ed55f..6b2bae01d851539a250cc63448ccbcf6e5c04de7 100644 --- a/services/discord/discord.service.js +++ b/services/discord/discord.service.js @@ -22,6 +22,10 @@ module.exports = class Discord extends BaseJsonService { }) } + static get _cacheLength() { + return 30 + } + static render({ members }) { return { message: `${members} online`,