interrupt directory walking if request was aborted
Massimo Melina committed
Dec 28, 2021 at 21:06 UTC
e4850d3529b06acfae463ceeb04da8dec693e4d0
2 files changed
+9
-7
src/apis.ts
+3
-4
@@ -2,7 +2,7 @@ import Koa from 'koa'
2
import { vfs, VfsNode, walkNode } from './vfs'
3
import { stat } from 'fs/promises'
4
import _ from 'lodash'
5
-import { getCurrentUsername, getCurrentUsernameExpanded, updateAccount, verifyLogin } from './perm'
5
+import { getCurrentUsername, updateAccount, verifyLogin } from './perm'
6
import createSSE from './sse'
7
import { basename } from 'path'
8
@@ -48,8 +48,7 @@ export const frontEndApis: ApiHandlers = {
48
limit = Number(limit)
49
const re = new RegExp(_.escapeRegExp(search),'i')
50
const match = (s?:string) => !s || !search || re.test(s)
51
- const who = await getCurrentUsernameExpanded(ctx) // cache value
52
- const walker = walkNode(node, who, search ? Infinity : 0)
51
+ const walker = walkNode(node, ctx, search ? Infinity : 0)
52
const sseSrv = sse ? createSSE(ctx) : null
53
const res = produceEntries()
54
return !sseSrv && { list: await res }
@@ -58,7 +57,7 @@ export const frontEndApis: ApiHandlers = {
57
const list = []
58
const h = sseSrv && setInterval(()=> console.log('WALKING'), 500)
59
for await (const sub of walker) {
61
- if (sseSrv?.stopped) break
60
+ if (sseSrv?.stopped || ctx.aborted) break
61
const filename = basename(sub.name||'')
62
if (!match(filename))
63
continue
src/vfs.ts
+6
-3
@@ -99,15 +99,16 @@ export function forbidden(node:VfsNode, users:string[]) {
99
}
100
101
102
-export async function* walkNode(parent:VfsNode, who:string[], depth:number=0, prefixPath:string=''): AsyncIterableIterator<VfsNode> {
102
+export async function* walkNode(parent:VfsNode, ctx: Koa.Context, depth:number=0, prefixPath:string=''): AsyncIterableIterator<VfsNode> {
103
const { children, source } = parent
104
+ ctx._who = ctx._who || await getCurrentUsernameExpanded(ctx) // cache value
105
if (children)
106
for (const c of children) {
106
- if (c.hidden || forbidden(c, who))
107
+ if (c.hidden || forbidden(c, ctx._who))
108
continue
109
yield prefixPath ? { ...c, name: prefixPath+c.name } : c
110
if (depth > 0 && c)
110
- yield* walkNode(c, who, depth - 1, prefixPath+c.name+'/')
111
+ yield* walkNode(c, ctx, depth - 1, prefixPath+c.name+'/')
112
}
113
if (!source)
114
return
@@ -122,6 +123,8 @@ export async function* walkNode(parent:VfsNode, who:string[], depth:number=0, pr
123
ignore,
124
})
125
for await (let path of dirStream) {
126
+ if (ctx.req.aborted)
127
+ return
128
if (path instanceof Buffer)
129
path = path.toString('utf8')
130
const name = path.slice(base.length)