diff --git a/server.js b/server.js index c3b63cb..7a724e8 100644 --- a/server.js +++ b/server.js @@ -59,8 +59,12 @@ button:hover{background:#3a80c6}.err{color:#f0857d;font-size:12px;margin-top:12p
${err ? 'Incorrect passphrase.' : ''}
`; } +// Every response must be uncacheable — otherwise the CDN could cache a gated file +// under its URL and serve it to unauthenticated visitors (bypassing the gate), or +// cache a lock page and show it to authenticated ones. +const NOCACHE = { 'Cache-Control': 'no-store, no-cache, must-revalidate, private', 'Pragma': 'no-cache', 'Vary': 'Cookie' }; function send(res, code, type, body, extra) { - const h = { 'Content-Type': type, 'X-Robots-Tag': 'noindex, nofollow', ...(extra || {}) }; + const h = { 'Content-Type': type, 'X-Robots-Tag': 'noindex, nofollow', ...NOCACHE, ...(extra || {}) }; res.writeHead(code, h); res.end(body); } @@ -100,7 +104,7 @@ http.createServer((req, res) => { const base = path.basename(abs); if (BLOCK.has(base) || abs.includes('/node_modules/') || abs.includes('/.git/')) { send(res, 404, 'text/plain', 'not found'); return; } const type = MIME[path.extname(abs).toLowerCase()] || 'application/octet-stream'; - res.writeHead(200, { 'Content-Type': type, 'X-Robots-Tag': 'noindex, nofollow' }); + res.writeHead(200, { 'Content-Type': type, 'X-Robots-Tag': 'noindex, nofollow', ...NOCACHE }); fs.createReadStream(abs).pipe(res); } catch (_) { send(res, 404, 'text/html; charset=utf-8', '

404

'); } }).listen(PORT, () => console.log('gate proxy on ' + PORT));