- 备份恢复的 multipart 分支改用 Web FormData,移除旧解析器约 128 MB 的限制 - 初始化恢复新增 application/octet-stream 流式写盘,前端改为直接上传文件流,避免整包进入内存 - 站点同步改用 Web FormData,并在读取请求体前拒绝超过 500 MB 的文件 - 新增 multipart 字段、重复字段和文件读取回归测试 验证: - 2 GB 测试备份包流式恢复预览成功,服务内存保持低位 - 130 MB 站点同步上传成功 - 原有备份预览及图片、视频、文件上传正常 - npm test 234 项通过;npm run typecheck 与 eslint 通过
49 lines
1.5 KiB
TypeScript
49 lines
1.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { readFormData, type H3Event } from 'h3'
|
|
import {
|
|
readFormDataFieldValues,
|
|
readFormDataFiles
|
|
} from './multipart-form'
|
|
|
|
async function parseFormData(form: FormData): Promise<FormData> {
|
|
const request = new Request('http://localhost/upload', {
|
|
method: 'POST',
|
|
body: form
|
|
})
|
|
return readFormData({ web: { request } } as unknown as H3Event)
|
|
}
|
|
|
|
describe('web FormData helpers', () => {
|
|
it('reads text fields and files from a multipart request', async () => {
|
|
const form = new FormData()
|
|
form.append('key', ' videos/2026/10/test.mov ')
|
|
form.append('tagNames', '["a","b"]')
|
|
form.append(
|
|
'file',
|
|
new File([new Uint8Array(1024)], 'test.mov', { type: 'video/quicktime' })
|
|
)
|
|
|
|
const parsed = await parseFormData(form)
|
|
|
|
expect(parsed.get('key')).toBe(' videos/2026/10/test.mov ')
|
|
expect(readFormDataFieldValues(parsed, 'tagNames')).toEqual(['a', 'b'])
|
|
expect(readFormDataFiles(parsed, ['file'])[0]).toMatchObject({
|
|
name: 'test.mov',
|
|
size: 1024,
|
|
type: 'video/quicktime'
|
|
})
|
|
})
|
|
|
|
it('keeps repeated field values and ignores empty files', async () => {
|
|
const form = new FormData()
|
|
form.append('tagNames', 'a,b')
|
|
form.append('tagNames', 'c')
|
|
form.append('files', new File([], 'empty.txt'))
|
|
|
|
const parsed = await parseFormData(form)
|
|
|
|
expect(readFormDataFieldValues(parsed, 'tagNames')).toEqual(['a,b', 'c'])
|
|
expect(readFormDataFiles(parsed, ['files'])).toEqual([])
|
|
})
|
|
})
|