fix: possible EXDEV error moving a file
Massimo Melina committed
Feb 6, 2024 at 22:16 UTC
3713c56e0b93b2abfa9c110d6a7c97db2c4f6d16
1 file changed
+8
-3
src/frontEndApis.ts
+8
-3
@@ -9,7 +9,7 @@ import { dirTraversal, isValidFileName } from './util-files'
9
import { HTTP_BAD_REQUEST, HTTP_CONFLICT, HTTP_FAILED_DEPENDENCY, HTTP_FORBIDDEN,
10
HTTP_NOT_FOUND, HTTP_SERVER_ERROR, HTTP_UNAUTHORIZED } from './const'
11
import { hasPermission, statusCodeForMissingPerm, urlToNode } from './vfs'
12
-import { mkdir, rename, rm } from 'fs/promises'
12
+import { mkdir, rename, rm, copyFile, unlink } from 'fs/promises'
13
import { basename, dirname, join } from 'path'
14
import { getUploadMeta } from './upload'
15
import { apiAssertTypes } from './misc'
@@ -125,9 +125,14 @@ export const frontEndApis: ApiHandlers = {
125
if (typeof src !== 'string') return HTTP_BAD_REQUEST
126
const srcNode = await urlToNode(src, ctx)
127
if (!srcNode) return HTTP_NOT_FOUND
128
+ const s = srcNode.source!
129
+ const d = join(destNode!.source!, basename(srcNode.source!))
130
return statusCodeForMissingPerm(srcNode, 'can_delete', ctx)
129
- || rename(srcNode.source!, join(destNode!.source!, basename(srcNode.source!)))
130
- .catch(e => e.code || String(e))
131
+ || rename(s, d).catch(async e => {
132
+ if (e.code !== 'EXDEV') throw e // exdev = different drive
133
+ await copyFile(s, d)
134
+ await unlink(s)
135
+ }).catch(e => e.code || String(e))
136
}))
137
}
138
},