Skip to content

Commit

Permalink
Add support for completely disabling multipart request handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ThisIsMissEm committed Jan 23, 2025
1 parent ad7d4c1 commit 4221aed
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/bindings/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Request.macro(
Request.macro('allFiles', function allFiles(this: Request) {
if (!this.__raw_files) {
throw new RuntimeException(
'Cannot read files. Make sure the bodyparser middleware is registered'
'Cannot read files. Make sure the bodyparser middleware is registered and enabled'
)
}

Expand Down
7 changes: 7 additions & 0 deletions src/bodyparser_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ export class BodyParserMiddleware {
if (this.#isType(ctx.request, multipartConfig.types)) {
debug('detected multipart request "%s:%s"', requestMethod, requestUrl)

if (!multipartConfig.enabled) {
throw new Exception('request content-type not supported', {
status: 415,
code: 'E_REQUEST_UNSUPPORTED_MEDIA_TYPE',
})
}

ctx.request.multipart = new Multipart(ctx, {
maxFields: multipartConfig.maxFields,
limit: multipartConfig.limit,
Expand Down
1 change: 1 addition & 0 deletions src/define_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function defineConfig(config: BodyParserOptionalConfig): BodyParserConfig
},

multipart: {
enabled: true,
autoProcess: true,
processManually: [],
encoding: 'utf-8',
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export type BodyParserRawConfig = BodyParserBaseConfig
* Parser config for parsing multipart requests
*/
export type BodyParserMultipartConfig = BodyParserBaseConfig & {
enabled: boolean
autoProcess: boolean | string[]
maxFields: number
processManually: string[]
Expand Down
38 changes: 38 additions & 0 deletions tests/body_parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,44 @@ test.group('BodyParser Middleware | form data', () => {
})
})

test('abort when multipart is not enabled', async ({ assert, cleanup }) => {
const server = createServer(async (req, res) => {
const request = new RequestFactory().merge({ req, res }).create()
const response = new ResponseFactory().merge({ req, res }).create()
const ctx = new HttpContextFactory().merge({ request, response }).create()
const middleware = new BodyParserMiddlewareFactory()
.merge({
multipart: {
enabled: false,
},
})
.create()

try {
await middleware.handle(ctx, async () => {})
} catch (error) {
res.writeHead(error.status)
res.end(error.message)
}
})
cleanup(() => {
server.close()
})

await new Promise<void>((resolve) => server.listen(3333, 'localhost', () => resolve()))

const response = await fetch('http://localhost:3333', {
method: 'POST',
headers: {
'Content-type': `multipart/form-data; boundary=9d01a3fb93deedb4d0a81389271d097f28fd67e2fcbff2932befc0458ad7`,
},
body: '--9d01a3fb93deedb4d0a81389271d097f28fd67e2fcbff2932befc0458ad7\x0d\x0aContent-Disposition: form-data; name="test"; filename="csv_files/test.csv"\x0d\x0aContent-Type: application/octet-stream\x0d\x0a\x0d\x0atest123',
})

assert.equal(response.status, 415)
assert.equal(await response.text(), 'request content-type not supported')
})

test('abort when multipart body is invalid', async ({ assert, cleanup }) => {
const server = createServer(async (req, res) => {
const request = new RequestFactory().merge({ req, res }).create()
Expand Down

0 comments on commit 4221aed

Please sign in to comment.