busboy icon indicating copy to clipboard operation
busboy copied to clipboard

Wrong mime type

Open alssdllc opened this issue 1 year ago • 3 comments

I'm still trying to understand how all of this works. The issue is I record a video with MediaRecorder in the browser and submit it to my node server which uses multer (which uses busboy).

In chrome the content-type is: video/mp4;codecs=avc1,opus even when I specify video/mp4. In safari the content-type is video/mp4.

busboy returns the proper mimetype for safari but returns text/plain for chrome. The safari made video is saved properly and plays. The chrome made video does not play properly. I'm assuming it's corrupt or something.

alssdllc avatar Jul 28 '24 00:07 alssdllc

I think that's an issue you'll have to dive into yourself because busboy can only give you what was given to it. It doesn't modify content types or anything like that. The most important thing to ensure is that you're giving busboy multipart/form-data data and not video data directly.

mscdex avatar Jul 28 '24 02:07 mscdex

You are correct that the content-type is not modified. But isn't the content-type used to determine the mime type?

When I look through some of the code. I am comparing the safari run and the chrome run.

They both hit this code (in multipart.js):

if (header['content-type']) {
    const conType = parseContentType(header['content-type'][0]);
    if (conType) {
        partType = `${conType.type}/${conType.subtype}`;
        if (conType.params && typeof conType.params.charset === 'string')
            partCharset = conType.params.charset.toLowerCase();
    }
}

For safari header['content-type'][0] is equal to video/mp4 For chrome header['content-type'][0] is equal to video/mp4;codecs=avc1,opus

For safari conType is a proper object:

params = {}
subtype = 'mp4'
type = 'video'

For chrome conType is undefined.

I would imagine that is part of the problem.

alssdllc avatar Jul 30 '24 19:07 alssdllc

Well, how nice, Chrome gives more, it is not missing or wrong.

aydincandan avatar Aug 02 '24 21:08 aydincandan

This is a bug. It happens, because of the comma in the codecs parameter value. Having dived way too deep into RFCs and standards, it seems that comma-separated values for parameters are allowed. They are certainly for video/mp4 according to RFC6381.

For an easy repro head over to https://codepen.io/ChristianUlbrich/pen/zxvgKLz?editors=1111 (directly taken from source)

The problem is presumably in parseContentTypeParams, AI says:

It’s because the parser only allows unquoted “token” chars in parameter values. A comma , (ASCII 44) is not a token (TOKEN[44] === 0). The unquoted value stops at the comma (avc1), and the next char is not a semicolon ;, so the function treats it as malformed and returns undefined.

This looks plausible™ and hints at an incorrect, not rfc-compliant implementation of parameter values for media types. As the various "parsers" are hand-crafted loops, fixing this w/o affecting other stuff is not so trivial, well at least not for me. :)

I'd go either with a real (A)BNF parser and supplying the BNF rules for The Content-Type Header Field OR use a way more trivial, "direct" parser, that is much easier to read, than the current loop and magic token trickery.

ChristianUlbrich avatar Sep 15 '25 13:09 ChristianUlbrich

They are certainly for video/mp4 according to RFC6381.

Notice how in the examples you linked to the values containing commas are only ever enclosed within quotes.

the BNF rules for The Content-Type Header Field

If you look at these rules more closely you'll notice that commas are only allowed inside a quoted value.

mscdex avatar Sep 15 '25 14:09 mscdex