payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
23.58k stars 1.5k forks source link

Wrong mimeType set when saving upload field w/ glb #7408

Open jameskane05 opened 2 months ago

jameskane05 commented 2 months ago

Link to reproduction

No response

Describe the Bug

Similar to this issue, which referred to fonts: https://github.com/payloadcms/payload/issues/6717

You can specify an upload field's mimeTypes array to accept model/gltf-binary or model/gltf+json and this lets you select the .glb file for upload. But when trying to save a new instance of the collection, I get a 400 from the server, and inspecting the Network tab, I can see that the mimeType is being submitted as application/octet-stream - this will break the file when it is requested again for rendering.

The mimeType for glb should be model/gltf-binary and for .gltf it should be model/gltf+json according to mimeType index here: https://www.iana.org/assignments/media-types/media-types.xhtml#model

To Reproduce

Create a collection with upload options, and set the mimeTypes array to accept 'model/gltf-binary' or 'model/*'.

import { CollectionConfig } from 'payload/types'

const Models: CollectionConfig = {
    slug: 'models',
    upload: {
        staticURL: '/media/models',
        staticDir: 'media/models',
        mimeTypes: [
            'model/*'
        ]
    }
}

export default Models;

Then try to save a model in the Admin menu. The upload field will let you select the .glb file, but when you hit save, I get a 400 error. In the Dev Tools Network tab, I can see Payload is incorrectly labeling it as application/octet-stream thinking it's typical binary data. Once it gets stored like that on the server, my front-end three.js renderer won't be able to interpret it as a glb again. I think this is a bug in Payload and it should be setting the mimeType of the POST request to the correct model/gltf-binary field.

Payload Version

2.0.0

Adapters and Plugins

No response

JarrodMFlesch commented 2 months ago

@jameskane05 can you upload a file that I can use to test with?

jameskane05 commented 2 months ago

ZooPath.glb.zip

Sure, @JarrodMFlesch, here's a zipped .glb (GitHub won't let me upload a plain .glb).

I did a little more research and found this issue: https://github.com/payloadcms/payload/issues/1914

The author states: "unfortunately there's nothing that we can do about this with Payload itself. I just tested a few files with this site: https://www.htmlstrip.com/mime-file-type-checker "

I ran my .glb above through this checker and it also reads as application/octet-stream.

I could try to roll w/ this - but if I set the mimeTypes array of the upload field to application/octet-stream, the file picker no longer lets me select .glb files like the one I'm including here. Even if I set application/octet-stream AND model/gltf-binary, it still won't let me select the .glb. Vice versa, if I set it to just model/gltf-binary, I get a server error on save because the field type and what the type checker observes are different. So still seems like there's a bug here.