plugins: serveFileNode will now always set the filename, in case the url is "anonymous"

Massimo Melina committed May 14, 2025 at 15:03 UTC cd47fab2a200912196c82d055ac8437148adcd53
1 file changed +10 -6
src/serveFile.ts
+10 -6
@@ -27,10 +27,14 @@ function toAsciiEquivalent(s: string) {
27 return iconv.encode(iconv.decode(Buffer.from(s), 'utf-8'), 'ascii').toString().replaceAll('?', '')
28 }
29
30 -export function forceDownload(ctx: Koa.Context, name='') {
30 +export function forceDownload(ctx: Koa.Context, name: string) {
31 + disposition(ctx, name, true)
32 +}
33 +
34 +export function disposition(ctx: Koa.Context, name: string, forceDownload=false) {
35 // ctx.attachment is not working well on Windows. Eg: for file "èÖ.txt" it is producing `Content-Disposition: attachment; filename="??.txt"`. Koa uses module content-disposition, that actually produces a better result anyway: ``
32 - ctx.set('Content-Disposition', 'attachment'
33 - + (name && `; filename="${toAsciiEquivalent(name)}"; filename*=UTF-8''${encodeURI(name).replace(/#/g, '%23')}`))
36 + ctx.set('Content-Disposition', (forceDownload ? 'attachment; ' : '')
37 + + `filename="${toAsciiEquivalent(name)}"; filename*=UTF-8''${encodeURI(name).replace(/#/g, '%23')}`)
38 }
39
40 export async function serveFileNode(ctx: Koa.Context, node: VfsNode) {
@@ -47,9 +51,9 @@ export async function serveFileNode(ctx: Koa.Context, node: VfsNode) {
51
52 ctx.vfsNode = // legacy pre-0.51 (download-quota)
53 ctx.state.vfsNode = node // useful to tell service files from files shared by the user
50 - if ('dl' in ctx.query) // please, download
51 - forceDownload(ctx, name)
52 - else if (ctx.get('referer')?.endsWith('/') && with_(ctx.get('accept'), x => x && !x.includes('text')))
54 + const download = 'dl' in ctx.query
55 + disposition(ctx, name, download)
56 + if (!download && ctx.get('referer')?.endsWith('/') && with_(ctx.get('accept'), x => x && !x.includes('text')))
57 ctx.state.considerAsGui = true
58 await serveFile(ctx, source||'', mimeString)
59