better code: comments
Massimo Melina committed
May 22, 2024 at 16:57 UTC
0f2a5afceebd742526238642b081303a9b4a978e
1 file changed
+11
-2
src/upload.ts
+11
-2
@@ -47,6 +47,7 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
47
}
48
return fail()
49
}
50
+ // enforce minAvailableMb
51
const fullPath = join(base.source!, path)
52
const dir = dirname(fullPath)
53
const min = minAvailableMb.get() * (1 << 20)
@@ -66,21 +67,26 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
67
catch(e: any) { // warn, but let it through
68
console.warn("can't check disk size:", e.message || String(e))
69
}
70
+ // optionally 'skip'
71
if (ctx.query.existing === 'skip' && fs.existsSync(fullPath))
72
return fail(HTTP_CONFLICT)
73
+ // if upload creates a folder, then add meta to it too
74
if (fs.mkdirSync(dir, { recursive: true }))
75
setUploadMeta(dir, ctx)
76
+ // use temporary name while uploading
77
const keepName = basename(fullPath).slice(-200)
78
let tempName = join(dir, 'hfs$upload-' + keepName)
79
const resumable = fs.existsSync(tempName) && tempName
80
if (resumable)
81
tempName = join(dir, 'hfs$upload2-' + keepName)
82
+ // checks for resume feature
83
let resume = Number(ctx.query.resume)
84
const size = resumable && try_(() => fs.statSync(resumable).size)
85
if (size === undefined) // stat failed
86
return fail(HTTP_SERVER_ERROR)
87
if (resume > size)
88
return fail(HTTP_RANGE_NOT_SATISFIABLE)
89
+ // warn frontend about resume possibility
90
if (!resume && resumable) {
91
const timeout = 30
92
notifyClient(ctx, 'upload.resumable', { [path]: size, expires: Date.now() + timeout * 1000 })
@@ -90,6 +96,7 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
96
tempName = resumable
97
}) )
98
}
99
+ // append if resuming
100
const resuming = resume && resumable
101
if (!resuming)
102
resume = 0
@@ -102,9 +109,11 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
109
cancelDeletion(tempName)
110
ctx.state.uploadDestinationPath = tempName
111
trackProgress()
112
+ // allow plugins to mess with the write-stream, because the read-stream can be complicated in case of multipart
113
const obj = { ctx, writeStream }
114
events.emit('uploadStart', obj)
107
- const lockMiddleware = pendingPromise()
115
+
116
+ const lockMiddleware = pendingPromise() // outside we need to know when all operations stopped
117
writeStream.once('close', async () => {
118
try {
119
if (ctx.req.aborted) {
@@ -126,7 +135,7 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
135
ctx.state.uploadDestinationPath = dest
136
setUploadMeta(dest, ctx)
137
if (ctx.query.comment)
129
- setCommentFor(dest, escapeHTML(String(ctx.query.comment)))
138
+ void setCommentFor(dest, escapeHTML(String(ctx.query.comment)))
139
if (resumable)
140
delayedDelete(resumable, 0)
141
events.emit('uploadFinished', obj)