avoid cache problems with favicon
Massimo Melina committed
Mar 3, 2024 at 12:36 UTC
ae7c7d90a61bda4a0414fbd2a42f0a533fcddaf5
3 files changed
+10
-4
src/adminApis.ts
+1
-1
@@ -10,7 +10,7 @@ import {
10
HFS_STARTED,
11
IS_WINDOWS,
12
VERSION,
13
- HTTP_UNAUTHORIZED, HTTP_NOT_FOUND, HTTP_BAD_REQUEST, HTTP_SERVER_ERROR, HTTP_FORBIDDEN
13
+ HTTP_UNAUTHORIZED, HTTP_BAD_REQUEST, HTTP_SERVER_ERROR, HTTP_FORBIDDEN
14
} from './const'
15
import vfsApis from './api.vfs'
16
import accountsApis from './api.accounts'
src/serveGuiAndSharedFiles.ts
+1
-1
@@ -52,7 +52,7 @@ export const serveGuiAndSharedFiles: Koa.Middleware = async (ctx, next) => {
52
}
53
return
54
}
55
- if (ctx.originalUrl === '/favicon.ico' && favicon.get()) // originalUrl to not be subject to changes (vhosting plugin)
55
+ if (/^\/favicon.ico(\??.*)/.test(ctx.originalUrl) && favicon.get()) // originalUrl to not be subject to changes (vhosting plugin)
56
return serveFile(ctx, favicon.get())
57
let node = await urlToNode(path, ctx)
58
if (!node)
src/serveGuiFiles.ts
+8
-2
@@ -9,7 +9,7 @@ import { getPluginConfigFields, getPluginInfo, mapPlugins, pluginsConfig } from
9
import { refresh_session } from './api.auth'
10
import { ApiError } from './apiMiddleware'
11
import { join, extname } from 'path'
12
-import { CFG, FRONTEND_OPTIONS, getOrSet, newObj, onlyTruthy } from './misc'
12
+import { CFG, debounceAsync, FRONTEND_OPTIONS, getOrSet, newObj, onlyTruthy, repeat } from './misc'
13
import { favicon, title } from './adminApis'
14
import { subscribe } from 'valtio/vanilla'
15
import { customHtmlState, getSection } from './customHtml'
@@ -64,6 +64,11 @@ function adjustBundlerLinks(ctx: Koa.Context, uri: string, data: string | Buffer
64
: String(data).replace(/((?:import[ (]| from )['"])\//g, `$1${ctx.state.revProxyPath}${uri}`)
65
}
66
67
+const getFaviconTimestamp = debounceAsync(async () => {
68
+ const f = favicon.get()
69
+ return !f ? 0 : fs.stat(f).then(x => x?.mtimeMs || 0, () => 0)
70
+}, 0, { retain: 5_000 })
71
+
72
async function treatIndex(ctx: Koa.Context, filesUri: string, body: string) {
73
const session = await refresh_session({}, ctx)
74
ctx.set('etag', '')
@@ -83,13 +88,14 @@ async function treatIndex(ctx: Koa.Context, filesUri: string, body: string) {
88
configs = getPluginInfo(name).onFrontendConfig?.(configs) || configs
89
return !_.isEmpty(configs) && [name, configs]
90
})))
91
+ const timestamp = await getFaviconTimestamp()
92
const lang = await getLangData(ctx)
93
let ret = body
94
.replace(/((?:src|href) *= *['"])\/?(?!([a-z]+:\/)?\/)/g, '$1' + ctx.state.revProxyPath + filesUri)
95
.replace('<head>', () => `<head>
96
${!isFrontend ? '' : `
97
<title>${title.get()}</title>
92
- <link rel="shortcut icon" href="${favicon.get() ? '/favicon.ico' : '#'}" />
98
+ <link rel="shortcut icon" href="/favicon.ico?${timestamp}" />
99
`}
100
<script>
101
HFS = ${JSON.stringify({