fastify-multipart: Automatic decoding of JSON fields doesn't work well with browser requests
Prerequisites
- I have written a descriptive issue title
- I have searched existing issues to ensure the bug has not already been reported
Fastify version
3.22.1
Plugin version
5.1.0
Node.js version
16.3.0
Operating system
Windows
Operating system version (i.e. 20.04, 11.3, 10)
20H2
Description
fastify-multipart
uses busboy
for multipart parsing. busboy
has a logic to decide whether a part is a field or file by checking the filename:
https://github.com/mscdex/busboy/blob/master/lib/types/multipart.js#L174
However this doesn’t work well with browser generated requests as it doesn’t seem possible to leave out the filename when specifying a content type. The best I’ve achieved is passing an empty filename.
Steps to Reproduce
Setup the server:
await server.register(fastifyMultipart, {
attachFieldsToBody: true,
});
Define the route:
server.post('/test', async (req, rep) => {
console.log(req.body.json.value);
rep.send('ok');
});
Send a browser request:
const body = new FormData();
body.append('json', new Blob(['{"foo":"bar"}'], {type: 'application/json'}), '');
fetch('/test', {method: 'POST', body});
Expected Behavior
The expected behaviour is getting a console output of the json payload.
However because of busboy
’s behaviour onField
won’t be triggered and therefore json parsing not started:
https://github.com/fastify/fastify-multipart/blob/master/index.js#L358
A possible solution could be checking detected files whether they have an empty filename and then deciding whether to parse them as json.
Another (hacky) solution would be allowing to configure a naming schema for part names that would be used to decide whether to handle a part as file or json field. Part names could look like json.foo
.
However the best solution would be to adjust busboy
. However I’m not sure whether this is realistic as it hasn’t been updated in years.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 26 (18 by maintainers)
After https://github.com/fastify/fastify-multipart/pull/300 lands, we should revisit this issue and check if fastify-multipart exposes enough of busboy configuration to make use of new isPartFile config option, or if some extra changes would be needed.
An alternative idea is to remove the automatic decoding of JSON fields because we can’t support it.
I don’t think there is a brtter alternative than busboy.
@cyantree After looking into this issue once more, the conclusion is that the workaround that you posted earlier is great, if it solves your problem then I think we are good.
Despite the issue with
busboy
, I’ve tried to come up with a workaround solution - just to see if we could do an easy detection and handle the json form data like a field - but there is no easy solution here, unfortunately, without seriously changing some internal handling.This can be solved in two ways:
busboy
side - https://github.com/mscdex/busboy/issues/258 ORbusboy
Could @cyantree explain why you need to use the
Blob
object instead of the string?I don’t think busboy will accept the request because the
Blob
object maps files