From b0f648b71c6a961226417a32c5c3d33022fbe913 Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Wed, 13 May 2026 02:12:02 +0200 Subject: [PATCH] trying to fix tag cache --- src/inc/routes/tag_image.mjs | 53 +++++++++++++++++++++++------------- src/index.mjs | 4 +-- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/inc/routes/tag_image.mjs b/src/inc/routes/tag_image.mjs index 5c898ac..e5ae2f3 100644 --- a/src/inc/routes/tag_image.mjs +++ b/src/inc/routes/tag_image.mjs @@ -26,12 +26,17 @@ export async function regenerateTagImage(tag, mode) { } const items = await db` - SELECT i.id - FROM items i - JOIN tags_assign ta ON ta.item_id = i.id - JOIN tags t ON t.id = ta.tag_id - ${modeFilter} - WHERE (t.tag = ${tag} OR t.normalized = ${tag}) AND i.active = true + SELECT id FROM ( + SELECT i.id + FROM items i + JOIN tags_assign ta ON ta.item_id = i.id + JOIN tags t ON t.id = ta.tag_id + ${modeFilter} + WHERE (t.tag = ${tag} OR t.normalized = ${tag}) + AND i.active = true + AND i.is_deleted = false + LIMIT 100 + ) pool ORDER BY RANDOM() LIMIT 3 `; @@ -139,16 +144,20 @@ function generateFallbackSvg(tag) { } export default (router, tpl) => { - router.get(/^\/tag_image\/(?.+)$/, async (req, res) => { + router.get(/^\/tag_image\/(?[^?]+)$/, async (req, res) => { const tag = decodeURIComponent(req.params.tag); - // Parse query parameters + // Parse query parameters robustly let query = {}; - if (typeof req.url === 'string') { - const parsedUrl = url.parse(req.url, true); - query = parsedUrl.query; - } else { - query = req.url.qs || {}; + try { + if (typeof req.url === 'string') { + const parsedUrl = url.parse(req.url, true); + query = parsedUrl.query; + } else if (req.url && req.url.qs) { + query = req.url.qs; + } + } catch (e) { + console.error('[TAG_IMAGE] Query parse failed:', e); } const mode = query.m ? parseInt(query.m) : (req.mode ?? 0); @@ -163,7 +172,8 @@ export default (router, tpl) => { 'Content-Type': 'image/webp', 'Cache-Control': `public, max-age=${CACHE_MAX_AGE}` }); - return res.end(await fs.readFile(cachePath)); + const content = await fs.readFile(cachePath); + return res.end(content); } } catch (e) { // Cache miss, proceed to generation @@ -172,11 +182,16 @@ export default (router, tpl) => { // Generate on-demand const generated = await regenerateTagImage(tag, mode); if (generated) { - res.writeHead(200, { - 'Content-Type': 'image/webp', - 'Cache-Control': `public, max-age=${CACHE_MAX_AGE}` - }); - return res.end(await fs.readFile(generated)); + try { + const content = await fs.readFile(generated); + res.writeHead(200, { + 'Content-Type': 'image/webp', + 'Cache-Control': `public, max-age=${CACHE_MAX_AGE}` + }); + return res.end(content); + } catch (err) { + console.error(`[TAG_IMAGE] Failed to read generated file ${generated}:`, err); + } } // Fallback to deterministic SVG diff --git a/src/index.mjs b/src/index.mjs index 5c773e1..ac25f43 100644 --- a/src/index.mjs +++ b/src/index.mjs @@ -227,7 +227,7 @@ process.on('uncaughtException', err => { return; if (req.url.pathname === '/manifest.json' || req.url.pathname === '/sw.js') return; - if (req.url.pathname.match(/^\/(b|t|ca|a|memes)\//) || req.url.pathname.startsWith('/s/emojis/')) { + if (req.url.pathname.match(/^\/(b|t|ca|a|memes|tag_image)\//) || req.url.pathname.startsWith('/s/emojis/')) { if (cfg.websrv.private_society && !req.cookies?.session) { res.writeHead(502, { 'Content-Type': 'text/html' }).end(nginx502); req.url.pathname = '/private_society_media_bypass'; @@ -409,7 +409,7 @@ process.on('uncaughtException', err => { // Private Society gate — require login for all content when enabled if (cfg.websrv.private_society && !req.session) { - const publicPaths = /^\/(s|login|logout|register|activate|forgot-password|reset-password|banned|api\/v2\/auth|manifest\.json|sw\.js|robots\.txt|favicon\.(ico|png|gif)|s\/img\/duck-icon-(192|512)\.png)(\/.*)?$/; + const publicPaths = /^\/(s|tag_image|login|logout|register|activate|forgot-password|reset-password|banned|api\/v2\/auth|manifest\.json|sw\.js|robots\.txt|favicon\.(ico|png|gif)|s\/img\/duck-icon-(192|512)\.png)(\/.*)?$/; if (!publicPaths.test(req.url.pathname)) { // For AJAX requests, return 502 so it looks like the backend is down if (req.headers['x-requested-with'] === 'XMLHttpRequest') {