mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-02-21 20:59:04 +00:00
Better cache control when not using CDN
This commit is contained in:
parent
c0fc463595
commit
edce59243b
@ -101,7 +101,8 @@ module.exports = {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Trust proxy.
|
Trust proxy.
|
||||||
Only enable if you are running this behind a proxy like Cloudflare, Incapsula, etc.
|
Enable this if you are using proxy such as Cloudflare or Incapsula,
|
||||||
|
and/or also when you are using reverse proxy such as nginx or Apache.
|
||||||
*/
|
*/
|
||||||
trustProxy: true,
|
trustProxy: true,
|
||||||
|
|
||||||
@ -141,13 +142,13 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 4 requests in 30 seconds
|
// 6 requests in 30 seconds
|
||||||
routes: [
|
routes: [
|
||||||
'/api/album/zip'
|
'/api/album/zip'
|
||||||
],
|
],
|
||||||
config: {
|
config: {
|
||||||
windowMs: 30 * 1000,
|
windowMs: 30 * 1000,
|
||||||
max: 4
|
max: 6
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -449,6 +450,8 @@ module.exports = {
|
|||||||
ADVANCED: Use safe.fiery.me-exclusive cache control.
|
ADVANCED: Use safe.fiery.me-exclusive cache control.
|
||||||
This will only work properly with certain settings in nginx reverse proxy and Cloudflare.
|
This will only work properly with certain settings in nginx reverse proxy and Cloudflare.
|
||||||
Do NOT enable unless you know what you are doing.
|
Do NOT enable unless you know what you are doing.
|
||||||
|
true: With CDN (Cloudflare)
|
||||||
|
2: When NOT using Cloudflare
|
||||||
*/
|
*/
|
||||||
cacheControl: false,
|
cacheControl: false,
|
||||||
|
|
||||||
|
@ -352,14 +352,6 @@ self.get = async (req, res, next) => {
|
|||||||
|
|
||||||
self.generateZip = async (req, res, next) => {
|
self.generateZip = async (req, res, next) => {
|
||||||
const versionString = parseInt(req.query.v)
|
const versionString = parseInt(req.query.v)
|
||||||
const download = (filePath, fileName) => {
|
|
||||||
const headers = {}
|
|
||||||
if (config.cacheControl && versionString > 0) {
|
|
||||||
headers['Access-Control-Allow-Origin'] = '*'
|
|
||||||
headers['Cache-Control'] = 'public, max-age=2592000, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800'
|
|
||||||
}
|
|
||||||
return res.download(filePath, fileName, { headers })
|
|
||||||
}
|
|
||||||
|
|
||||||
const identifier = req.params.identifier
|
const identifier = req.params.identifier
|
||||||
if (identifier === undefined)
|
if (identifier === undefined)
|
||||||
@ -398,7 +390,7 @@ self.generateZip = async (req, res, next) => {
|
|||||||
try {
|
try {
|
||||||
const filePath = path.join(paths.zips, `${identifier}.zip`)
|
const filePath = path.join(paths.zips, `${identifier}.zip`)
|
||||||
await paths.access(filePath)
|
await paths.access(filePath)
|
||||||
return download(filePath, `${album.name}.zip`)
|
return res.download(filePath, `${album.name}.zip`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Re-throw error
|
// Re-throw error
|
||||||
if (error.code !== 'ENOENT')
|
if (error.code !== 'ENOENT')
|
||||||
@ -409,7 +401,7 @@ self.generateZip = async (req, res, next) => {
|
|||||||
logger.log(`Waiting previous zip task for album: ${identifier}.`)
|
logger.log(`Waiting previous zip task for album: ${identifier}.`)
|
||||||
return self.zipEmitters.get(identifier).once('done', (filePath, fileName, json) => {
|
return self.zipEmitters.get(identifier).once('done', (filePath, fileName, json) => {
|
||||||
if (filePath && fileName)
|
if (filePath && fileName)
|
||||||
download(filePath, fileName)
|
res.download(filePath, fileName)
|
||||||
else if (json)
|
else if (json)
|
||||||
res.json(json)
|
res.json(json)
|
||||||
})
|
})
|
||||||
@ -481,7 +473,7 @@ self.generateZip = async (req, res, next) => {
|
|||||||
const fileName = `${album.name}.zip`
|
const fileName = `${album.name}.zip`
|
||||||
|
|
||||||
self.zipEmitters.get(identifier).emit('done', filePath, fileName)
|
self.zipEmitters.get(identifier).emit('done', filePath, fileName)
|
||||||
return download(filePath, fileName)
|
return res.download(filePath, fileName)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
logger.error(error)
|
||||||
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
|
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
|
||||||
|
91
lolisafe.js
91
lolisafe.js
@ -50,52 +50,76 @@ if (Array.isArray(config.rateLimits) && config.rateLimits.length)
|
|||||||
safe.use(bodyParser.urlencoded({ extended: true }))
|
safe.use(bodyParser.urlencoded({ extended: true }))
|
||||||
safe.use(bodyParser.json())
|
safe.use(bodyParser.json())
|
||||||
|
|
||||||
let setHeaders
|
let cdnPages
|
||||||
|
let setHeaders = res => {
|
||||||
|
res.set('Access-Control-Allow-Origin', '*')
|
||||||
|
}
|
||||||
|
|
||||||
// Cache control (safe.fiery.me)
|
// Cache control (safe.fiery.me)
|
||||||
if (config.cacheControl) {
|
if (config.cacheControl) {
|
||||||
const cacheControls = {
|
const cacheControls = {
|
||||||
// max-age: 30 days
|
// max-age: 6 months
|
||||||
default: 'public, max-age=2592000, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800',
|
static: 'public, max-age=15778800, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800',
|
||||||
// s-max-age: 30 days (only cache in proxy server)
|
// s-max-age: 6 months (only cache in CDN)
|
||||||
// Obviously we have to purge proxy cache on every update
|
cdn: 's-max-age=15778800, proxy-revalidate, stale-while-revalidate=86400, stale-if-error=604800',
|
||||||
proxyOnly: 's-max-age=2592000, proxy-revalidate, stale-while-revalidate=86400, stale-if-error=604800',
|
// validate cache's validity before using them (soft cache)
|
||||||
|
validate: 'no-cache',
|
||||||
|
// do not use cache at all
|
||||||
disable: 'no-store'
|
disable: 'no-store'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// By default soft cache everything
|
||||||
safe.use('/', (req, res, next) => {
|
safe.use('/', (req, res, next) => {
|
||||||
res.set('Cache-Control', cacheControls.proxyOnly)
|
res.set('Cache-Control', cacheControls.validate)
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Do NOT cache these dynamic routes
|
// If using CDN, cache public pages in CDN
|
||||||
safe.use(['/a', '/api', '/nojs'], (req, res, next) => {
|
if (config.cacheControl !== 2) {
|
||||||
res.set('Cache-Control', cacheControls.disable)
|
cdnPages = config.pages.concat(['api/check'])
|
||||||
next()
|
for (const page of cdnPages)
|
||||||
})
|
safe.use(`/${page === 'home' ? '' : page}`, (req, res, next) => {
|
||||||
|
res.set('Cache-Control', cacheControls.cdn)
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Cache these in proxy server though
|
// If serving uploads with node
|
||||||
safe.use(['/api/check'], (req, res, next) => {
|
if (config.serveFilesWithNode)
|
||||||
res.set('Cache-Control', cacheControls.proxyOnly)
|
safe.use('/', express.static(paths.uploads, {
|
||||||
next()
|
setHeaders: res => {
|
||||||
})
|
res.set('Access-Control-Allow-Origin', '*')
|
||||||
|
// If using CDN, cache uploads in CDN as well
|
||||||
|
// Use with cloudflare.purgeCache enabled in config file
|
||||||
|
if (config.cacheControl !== 2)
|
||||||
|
res.set('Cache-Control', cacheControls.cdn)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
// Cache album ZIPs
|
// Function for static assets.
|
||||||
safe.use(['/api/album/zip'], (req, res, next) => {
|
// This requires the assets to use version in their query string,
|
||||||
setHeaders(res)
|
// as they will be cached by clients for a very long time.
|
||||||
next()
|
|
||||||
})
|
|
||||||
|
|
||||||
// For static assets (and uploads if serving with node)
|
|
||||||
setHeaders = res => {
|
setHeaders = res => {
|
||||||
res.set('Access-Control-Allow-Origin', '*')
|
res.set('Access-Control-Allow-Origin', '*')
|
||||||
res.set('Cache-Control', cacheControls.default)
|
res.set('Cache-Control', cacheControls.static)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consider album ZIPs static as well, since they use version in their query string
|
||||||
|
safe.use(['/api/album/zip'], (req, res, next) => {
|
||||||
|
res.set('Access-Control-Allow-Origin', '*')
|
||||||
|
const versionString = parseInt(req.query.v)
|
||||||
|
if (versionString > 0)
|
||||||
|
res.set('Cache-Control', cacheControls.static)
|
||||||
|
else
|
||||||
|
res.set('Cache-Control', cacheControls.disable)
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
} else if (config.serveFilesWithNode) {
|
||||||
|
// If serving uploads with node
|
||||||
|
safe.use('/', express.static(paths.uploads))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.serveFilesWithNode)
|
// Static assets
|
||||||
safe.use('/', express.static(paths.uploads, { setHeaders }))
|
|
||||||
|
|
||||||
safe.use('/', express.static(paths.public, { setHeaders }))
|
safe.use('/', express.static(paths.public, { setHeaders }))
|
||||||
safe.use('/', express.static(paths.dist, { setHeaders }))
|
safe.use('/', express.static(paths.dist, { setHeaders }))
|
||||||
|
|
||||||
@ -142,13 +166,13 @@ safe.use('/api', api)
|
|||||||
|
|
||||||
// Error pages
|
// Error pages
|
||||||
safe.use((req, res, next) => {
|
safe.use((req, res, next) => {
|
||||||
if (config.cacheControl) res.removeHeader('Cache-Control')
|
res.setHeader('Cache-Control', 'no-store')
|
||||||
res.status(404).sendFile(path.join(paths.errorRoot, config.errorPages[404]))
|
res.status(404).sendFile(path.join(paths.errorRoot, config.errorPages[404]))
|
||||||
})
|
})
|
||||||
|
|
||||||
safe.use((error, req, res, next) => {
|
safe.use((error, req, res, next) => {
|
||||||
logger.error(error)
|
logger.error(error)
|
||||||
if (config.cacheControl) res.removeHeader('Cache-Control')
|
res.setHeader('Cache-Control', 'no-store')
|
||||||
res.status(500).sendFile(path.join(paths.errorRoot, config.errorPages[500]))
|
res.status(500).sendFile(path.join(paths.errorRoot, config.errorPages[500]))
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -196,12 +220,11 @@ safe.use('/api', api)
|
|||||||
logger.log(`lolisafe started on port ${config.port}`)
|
logger.log(`lolisafe started on port ${config.port}`)
|
||||||
|
|
||||||
// Cache control (safe.fiery.me)
|
// Cache control (safe.fiery.me)
|
||||||
// Also only if explicitly using Cloudflare
|
// Purge Cloudflare cache
|
||||||
if (config.cacheControl)
|
if (config.cacheControl === 1)
|
||||||
if (config.cloudflare.purgeCache) {
|
if (config.cloudflare.purgeCache) {
|
||||||
logger.log('Cache control enabled, purging Cloudflare\'s cache...')
|
logger.log('Cache control enabled, purging Cloudflare\'s cache...')
|
||||||
const routes = config.pages.concat(['api/check'])
|
const results = await utils.purgeCloudflareCache(cdnPages)
|
||||||
const results = await utils.purgeCloudflareCache(routes)
|
|
||||||
let errored = false
|
let errored = false
|
||||||
let succeeded = 0
|
let succeeded = 0
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
|
Loading…
Reference in New Issue
Block a user