diff --git a/src/core/tileserver.js b/src/core/tileserver.js index f8eeed5..5d92119 100644 --- a/src/core/tileserver.js +++ b/src/core/tileserver.js @@ -161,9 +161,9 @@ class CanvasUpdater { } for (let c = 0; c < this.maxTiledZoom; c += 1) { this.TileLoadingQueues.push([]); - const invZoom = this.maxTiledZoom - c - 1; + const invZoom = this.maxTiledZoom - c; // eslint-disable-next-line max-len - const timeout = TILE_ZOOM_LEVEL ** (2 * invZoom + 2) * (6 / TILE_ZOOM_LEVEL ** 2) * 1000; + const timeout = TILE_ZOOM_LEVEL ** (2 * invZoom) * (6 / TILE_ZOOM_LEVEL ** 2) * 1000; logger.info( `Tiling: Set interval for zoomlevel ${c} update to ${timeout / 1000}`, ); diff --git a/src/routes/tiles.js b/src/routes/tiles.js index 8e1cf53..8a22cfa 100644 --- a/src/routes/tiles.js +++ b/src/routes/tiles.js @@ -6,44 +6,82 @@ import fs from 'fs'; import express from 'express'; + +// eslint-disable-next-line import/no-unresolved +import canvases from './canvases.json'; +import { getMaxTiledZoom } from '../core/utils'; import { TILE_FOLDER } from '../core/config'; -import { HOUR } from '../core/constants'; const router = express.Router(); +/* + * decide on cache length + */ +router.use('/:c([0-9]+)/:z([0-9]+)/:x([0-9]+)/:y([0-9]+).webp', + (req, res, next) => { + const { c: id } = req.params; + const canvas = canvases[id]; + if (!canvas) { + next(new Error('Canvas not found.')); + return; + } + req.canvasId = id; + + const maxTiledZoom = getMaxTiledZoom(canvas.size); + const { z: paramZ } = req.params; + const z = parseInt(paramZ, 10); + if (z < 0 || z >= maxTiledZoom) { + next(new Error('Invalid zoom level')); + return; + } + const invZoom = maxTiledZoom - z - 1; + const cacheTime = (15 + 180 * invZoom) * 60; + const pubCacheTime = Math.floor(cacheTime * 0.75); + res.set({ + 'Cache-Control': `public, s-maxage=${pubCacheTime}, max-age=${cacheTime}`, + }); + next(); + }, +); + /* * get other tiles from directory */ -router.use('/', express.static(TILE_FOLDER, { - maxAge: 2 * HOUR, -})); +router.use(express.static(TILE_FOLDER)); /* * catch File Not Found: Send empty tile */ -router.use('/:c([0-9]+)/:z([0-9]+)/:x([0-9]+)/:y([0-9]+).webp', - async (req, res) => { - const { c: paramC } = req.params; - const c = parseInt(paramC, 10); - - const filename = `${TILE_FOLDER}/${c}/emptytile.webp`; - if (!fs.existsSync(filename)) { - res.set({ - 'Cache-Control': `public, s-maxage=${24 * 3600}, max-age=${24 * 3600}`, - }); - res.status(404).end(); - return; - } +router.use(async (req, res) => { + const { canvasId } = req; + const filename = `${TILE_FOLDER}/${canvasId}/emptytile.webp`; + if (!fs.existsSync(filename)) { res.set({ - 'Cache-Control': `public, s-maxage=${2 * 3600}, max-age=${1 * 3600}`, - 'Content-Type': 'image/webp', + 'Cache-Control': `public, s-maxage=${24 * 3600}, max-age=${24 * 3600}`, }); - res.status(200); - res.sendFile(filename); + res.status(404).end(); + return; + } + + res.set({ + 'Cache-Control': `public, s-maxage=${2 * 3600}, max-age=${1 * 3600}`, + 'Content-Type': 'image/webp', }); + res.status(200); + res.sendFile(filename); +}, +); + +/* + * error handler + */ +// eslint-disable-next-line no-unused-vars +router.use((err, req, res, next) => { + res.status(400).end(); +}); export default router;