diff --git a/src/validator/validator.test.ts b/src/validator/validator.test.ts index 62a8711a4..12028b935 100644 --- a/src/validator/validator.test.ts +++ b/src/validator/validator.test.ts @@ -910,6 +910,24 @@ describe('Clone Request object', () => { } ) + app.post( + '/cached', + async (c, next) => { + await c.req.parseBody() + await next() + }, + validator('form', (value) => { + if (value instanceof FormData) { + throw new Error('The value should not be a FormData') + } + return value + }), + (c) => { + const v = c.req.valid('form') + return c.json(v) + } + ) + it('Should not throw the error with c.req.parseBody()', async () => { const body = new FormData() body.append('foo', 'bar') @@ -920,6 +938,18 @@ describe('Clone Request object', () => { const res = await app.request(req) expect(res.status).toBe(200) }) + + it('Should not be an instance of FormData if the formData is cached', async () => { + const body = new FormData() + body.append('foo', 'bar') + const req = new Request('http://localhost/cached', { + method: 'POST', + body: body, + }) + const res = await app.request(req) + expect(res.status).toBe(200) + expect(await res.json()).toEqual({ foo: 'bar' }) + }) }) }) diff --git a/src/validator/validator.ts b/src/validator/validator.ts index 1cc0547f0..bf83a4ab1 100644 --- a/src/validator/validator.ts +++ b/src/validator/validator.ts @@ -83,33 +83,35 @@ export const validator = < break } + let formData: FormData + if (c.req.bodyCache.formData) { - value = await c.req.bodyCache.formData - break + formData = await c.req.bodyCache.formData + } else { + try { + const arrayBuffer = await c.req.arrayBuffer() + formData = await bufferToFormData(arrayBuffer, contentType) + c.req.bodyCache.formData = formData + } catch (e) { + let message = 'Malformed FormData request.' + message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}` + throw new HTTPException(400, { message }) + } } - try { - const arrayBuffer = await c.req.arrayBuffer() - const formData = await bufferToFormData(arrayBuffer, contentType) - const form: BodyData<{ all: true }> = {} - formData.forEach((value, key) => { - if (key.endsWith('[]')) { - if (form[key] === undefined) { - form[key] = [value] - } else if (Array.isArray(form[key])) { - ;(form[key] as unknown[]).push(value) - } - } else { - form[key] = value + const form: BodyData<{ all: true }> = {} + formData.forEach((value, key) => { + if (key.endsWith('[]')) { + if (form[key] === undefined) { + form[key] = [value] + } else if (Array.isArray(form[key])) { + ;(form[key] as unknown[]).push(value) } - }) - value = form - c.req.bodyCache.formData = formData - } catch (e) { - let message = 'Malformed FormData request.' - message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}` - throw new HTTPException(400, { message }) - } + } else { + form[key] = value + } + }) + value = form break } case 'query':