diff --git a/deploy/app.js b/deploy/app.js index 133eed8a44179ad6ca4686a47141f3556a8c775b..9192aa73ba7eeee36bdd5198dbf0eb0a2834f4a8 100644 --- a/deploy/app.js +++ b/deploy/app.js @@ -8,8 +8,7 @@ const cookieParser = require('cookie-parser') const bkwdMdl = require('./bkwdCompat')() const { router: regionalFeaturesRouter, regionalFeatureIsReady } = require('./regionalFeatures') -const { router: datasetRouter, ready: datasetRouteIsReady } = require('./datasets') -const { ready: saneUrlIsReady } = require('./saneUrl') +const { router: datasetRouter } = require('./datasets') const LOCAL_CDN_FLAG = !!process.env.PRECOMPUTED_SERVER @@ -109,7 +108,8 @@ const _ = (async () => { /** * saneUrl end points */ - app.use('/saneUrl', require('./saneUrl')) + const { router: saneUrlRouter } = require('./saneUrl') + app.use('/saneUrl', saneUrlRouter) })() const PUBLIC_PATH = process.env.NODE_ENV === 'production' @@ -204,13 +204,10 @@ app.use('/logo', require('./logo')) app.get('/ready', async (req, res) => { const authIsReady = authReady ? await authReady() : false const regionalFeatureReady = await regionalFeatureIsReady() - const datasetReady = await datasetRouteIsReady() - const saneUrlReady = await saneUrlIsReady() + const allReady = [ authIsReady, regionalFeatureReady, - datasetReady, - saneUrlReady, /** * add other ready endpoints here * call sig is await fn(): boolean diff --git a/deploy/saneUrl/index.js b/deploy/saneUrl/index.js index 7700ba4d76a16dfab1b793c0de9cf396772f0803..b0033f9acefeb56e79bb379cfc0accad09d7b4d6 100644 --- a/deploy/saneUrl/index.js +++ b/deploy/saneUrl/index.js @@ -2,9 +2,8 @@ const express = require('express') const router = express.Router() const RateLimit = require('express-rate-limit') const RedisStore = require('rate-limit-redis') -const { Store, NotFoundError } = require('./store') -const { redisURL } = require('../lruStore') -const { readUserData, saveUserData } = require('../user/store') +const { FallbackStore: Store, NotFoundError } = require('./store') +const lruStore = require('../lruStore') const { Store: DepcStore } = require('./depcObjStore') const { readUserData, saveUserData } = require('../user/store') @@ -12,11 +11,29 @@ const store = new Store() const depStore = new DepcStore() const { DISABLE_LIMITER, HOSTNAME, HOST_PATHNAME } = process.env -const limiter = new RateLimit({ - windowMs: 1e3 * 5, - max: 5, - ...( redisURL ? { store: new RedisStore({ redisURL }) } : {} ) -}) + + +let limiter +const getLimiter = async () => { + if (DISABLE_LIMITER) return passthrough + + if (!!limiter) return limiter + + await lruStore._initPr + if (lruStore.redisURL) { + limiter = new RateLimit({ + windowMs: 1e3 * 5, + max: 5, + store: new RedisStore({ redisURL }) + }) + } else { + limiter = new RateLimit({ + windowMs: 1e3 * 5, + max: 5, + }) + } + return limiter +} const passthrough = (_, __, next) => next() @@ -88,7 +105,7 @@ router.get('/:name', async (req, res) => { }) router.post('/:name', - DISABLE_LIMITER ? passthrough : limiter, + getLimiter, async (req, res, next) => { const { name } = req.params try { diff --git a/deploy/saneUrl/store.js b/deploy/saneUrl/store.js index c6dc3c6af43b8475d1b821e48f7333fead478661..656a070f4fcd5805d816c54390449546fa2885a1 100644 --- a/deploy/saneUrl/store.js +++ b/deploy/saneUrl/store.js @@ -17,36 +17,11 @@ const { HBP_V2_REFRESH_TOKEN, HBP_V2_ACCESS_TOKEN, - REDIS_PROTO, - REDIS_ADDR, - REDIS_PORT, - - REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_PROTO, - REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_ADDR, - REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_PORT, - - REDIS_USERNAME, - REDIS_PASSWORD, - DATA_PROXY_URL, DATA_PROXY_BUCKETNAME, } = process.env -const redisProto = REDIS_PROTO || REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_PROTO || 'redis' -const redisAddr = REDIS_ADDR || REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_ADDR || null -const redisPort = REDIS_PORT || REDIS_RATE_LIMITING_DB_EPHEMERAL_PORT_6379_TCP_PORT || 6379 - -const userPass = (() => { - let returnString = '' - if (REDIS_USERNAME) returnString += REDIS_USERNAME - if (REDIS_PASSWORD) returnString += `:${REDIS_PASSWORD}` - if (returnString.length > 0) returnString += `@` - return returnString -})() - -const redisURL = redisAddr && `${redisProto}://${userPass}${redisAddr}:${redisPort}` - class NotFoundError extends Error{} // not part of class, since class is exported, and prototype of class can be easily changed @@ -78,8 +53,21 @@ function _checkValid(urlString){ return (new Date() - new Date(expiry)) < 1e3 * 10 } +class FallbackStore { + async get(){ + throw new Error(`saneurl is currently offline for maintainence.`) + } + async set(){ + throw new Error(`saneurl is currently offline for maintainence.`) + } + async healthCheck() { + return false + } +} + class Store { constructor(){ + throw new Error(`Not implemented`) this.healthFlag = false this.seafileHandle = null @@ -427,6 +415,6 @@ class Store { } } - +exports.FallbackStore = FallbackStore exports.Store = Store exports.NotFoundError = NotFoundError