Skip to content

Commit 6133a1d

Browse files
authored
perf: optimize file access promises (#12275)
Improves performance in local strategy uploads by reading the file and metadata info synchronously. This change uses `promise.all` for three separately awaited calls. This improves the perf by making all calls in a non-blocking way.
1 parent 710fe09 commit 6133a1d

File tree

2 files changed

+21
-17
lines changed

2 files changed

+21
-17
lines changed

packages/payload/src/uploads/generateFileData.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { SanitizedConfig } from '../config/types.js'
1010
import type { PayloadRequest } from '../types/index.js'
1111
import type { FileData, FileToSave, ProbedImageSize, UploadEdits } from './types.js'
1212

13-
import { FileRetrievalError, FileUploadError, MissingFile } from '../errors/index.js'
13+
import { FileRetrievalError, FileUploadError, Forbidden, MissingFile } from '../errors/index.js'
1414
import { canResizeImage } from './canResizeImage.js'
1515
import { cropImage } from './cropImage.js'
1616
import { getExternalFile } from './getExternalFile.js'
@@ -85,6 +85,10 @@ export const generateFileData = async <T>({
8585
if (!file && uploadEdits && incomingFileData) {
8686
const { filename, url } = incomingFileData as FileData
8787

88+
if (filename && (filename.includes('../') || filename.includes('..\\'))) {
89+
throw new Forbidden(req.t)
90+
}
91+
8892
try {
8993
if (url && url.startsWith('/') && !disableLocalStorage) {
9094
const filePath = `${staticPath}/${filename}`

packages/payload/src/uploads/getFileByPath.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,28 @@ import path from 'path'
55

66
import type { PayloadRequest } from '../types/index.js'
77

8-
const mimeTypeEstimate = {
8+
const mimeTypeEstimate: Record<string, string> = {
99
svg: 'image/svg+xml',
1010
}
1111

1212
export const getFileByPath = async (filePath: string): Promise<PayloadRequest['file']> => {
13-
if (typeof filePath === 'string') {
14-
const data = await fs.readFile(filePath)
15-
const mimetype = fileTypeFromFile(filePath)
16-
const { size } = await fs.stat(filePath)
13+
if (typeof filePath !== 'string') {
14+
return undefined
15+
}
1716

18-
const name = path.basename(filePath)
19-
const ext = path.extname(filePath).slice(1)
17+
const name = path.basename(filePath)
18+
const ext = path.extname(filePath).slice(1)
2019

21-
const mime = (await mimetype)?.mime || mimeTypeEstimate[ext]
20+
const [data, stat, type] = await Promise.all([
21+
fs.readFile(filePath),
22+
fs.stat(filePath),
23+
fileTypeFromFile(filePath),
24+
])
2225

23-
return {
24-
name,
25-
data,
26-
mimetype: mime,
27-
size,
28-
}
26+
return {
27+
name,
28+
data,
29+
mimetype: type?.mime || mimeTypeEstimate[ext],
30+
size: stat.size,
2931
}
30-
31-
return undefined
3232
}

0 commit comments

Comments
 (0)