I have some engineering users who wish to attach some data files with uncommon file extensions to their posts. They are essentially plain text files but include extended ASCII characters.
I tried to update Discourse’s NGINX config to specify MIME media types for these files but it didn’t work. I posted a topic (How to customize MIME media type emitted for certain attachments?) about this two weeks ago but have not received any answers so far. Even if NGINX is not updated, it will still serve up unknown file types using the fallback MIME type of “application/octet-stream”. I can live with that for now.
However, when users try to upload these data files into a post (either using the “Upload” button or drag-and-drop), they get an error popup from Discourse like this one:
It appears that when users upload files, Discourse is trying to be smart and detect whether its an image or some other file type. Furthermore, it appears to be making this determination by looking at the file contents (much like the standard Unix command “file” does). I assume this is so Discourse can decide whether to inline it with the post’s content or put it off to the side as an attachment.
In the case of these data files, this check is incorrectly identifying the files as images. Just for yucks, I put some of these data files on an Ubuntu box and checked them with the “file” command, and sure enough, they were identified as “JPEG image data”.
Is there a way for users to upload files without Discourse trying to detect if they are images? IE, “Please upload this as an attachment, no matter what, don’t inline it”?
Alternatively, I could configure Discourse to allow zip files and tell the users to zip up their files before uploading them, but I’d rather not open up the site to random zip file uploads. That seems like a security issue.
In short, your file is being detected as JPEG because it starts with the same signature as this type of file.
Fixing this behavior in Discourse is possible, but it requires a modification. (see at the end)
Here some technical stuff.
This issue starts here:
FastImage library opens the file and determines the type and size.
As you expect, it returns a type of JPEG.
So with these changes, the file won’t be detected as an image and will be uploaded like a non-image and displayed to the right of the post?
If I understand correctly, you’re suggesting I make these tweaks in my local Discourse instance to try this out and/or use this until it is included in a future Discourse release. But how do I do this? (I am an experienced software developer but have limited experience with Docker and none with Ruby.)
The FastImage call that would need to be tweaked is in models/upload.rb, right?
I’m not suggesting you do the modification. However, if you can’t wait, you could certainly test that change.
For a temporary change (gone after rebuild):
./launcher enter app
sed -i "s/FastImage.new(@file)/FastImage.new(@file, :raise_on_failure=>true)/" lib/upload_creator.rb
sed -i "s/FastImage.new(original_path)/FastImage.new(original_path, :raise_on_failure=>true)/" app/models/upload.rb
For a persistent change (stay after rebuild):
nano containers/app.yml (use your preferred editor)
Add the following custom commands at the end (run section):
to: "FastImage.new(@file, :raise_on_failure=>true)"
to: "FastImage.new(original_path, :raise_on_failure=>true)"
./launcher rebuild app
I guess so if you plan to upload files without extensions. I did not check if other occurrences required the same change.