Add proper filename to the content-disposition header
By default we take the slug given in the request, if this is not set we try to give a filename from known types. If we still have no filename we fallback to the previous method of setting no filename. If the filename is non ascii we will only create the encoded "filename*" and not the ascii only "filename". This is to prevent other applications to save a file like "?????.png" if the filename contains non ascii chars. For the browsers nothing will really change comapred to the behaviour before this change as good fallbacks if no content-disposition filename is set. But that is not the case for all application, thus it makes sense to include the proper way to set the filename.
This commit is contained in:
parent
8dd9bc0e98
commit
14d76f8023
@ -45,6 +45,7 @@
|
||||
"chalk": "4.1.0",
|
||||
"cheerio": "1.0.0-rc.5",
|
||||
"commander": "7.2.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"express": "4.17.1",
|
||||
"file-type": "16.2.0",
|
||||
"filenamify": "4.2.0",
|
||||
|
@ -10,26 +10,27 @@ const readChunk = require("read-chunk");
|
||||
const crypto = require("crypto");
|
||||
const isUtf8 = require("is-utf8");
|
||||
const log = require("../log");
|
||||
const contentDisposition = require("content-disposition");
|
||||
|
||||
// List of allowed mime types that can be rendered in browser
|
||||
// without forcing it to be downloaded
|
||||
const inlineContentDispositionTypes = [
|
||||
"application/ogg",
|
||||
"audio/midi",
|
||||
"audio/mpeg",
|
||||
"audio/ogg",
|
||||
"audio/vnd.wave",
|
||||
"image/bmp",
|
||||
"image/gif",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
"image/avif",
|
||||
"text/plain",
|
||||
"video/mp4",
|
||||
"video/ogg",
|
||||
"video/webm",
|
||||
];
|
||||
// Map of allowed mime types to their respecive default filenames
|
||||
// that will be rendered in browser without forcing them to be downloaded
|
||||
const inlineContentDispositionTypes = {
|
||||
"application/ogg": "media.ogx",
|
||||
"audio/midi": "audio.midi",
|
||||
"audio/mpeg": "audio.mp3",
|
||||
"audio/ogg": "audio.ogg",
|
||||
"audio/vnd.wave": "audio.wav",
|
||||
"image/bmp": "image.bmp",
|
||||
"image/gif": "image.gif",
|
||||
"image/jpeg": "image.jpg",
|
||||
"image/png": "image.png",
|
||||
"image/webp": "image.webp",
|
||||
"image/avif": "image.avif",
|
||||
"text/plain": "text.txt",
|
||||
"video/mp4": "video.mp4",
|
||||
"video/ogg": "video.ogv",
|
||||
"video/webm": "video.webm",
|
||||
};
|
||||
|
||||
const uploadTokens = new Map();
|
||||
|
||||
@ -92,9 +93,20 @@ class Uploader {
|
||||
}
|
||||
|
||||
// Force a download in the browser if it's not an allowed type (binary or otherwise unknown)
|
||||
const contentDisposition = inlineContentDispositionTypes.includes(detectedMimeType)
|
||||
? "inline"
|
||||
: "attachment";
|
||||
let slug = req.params.slug;
|
||||
const isInline = detectedMimeType in inlineContentDispositionTypes;
|
||||
let disposition = isInline ? "inline" : "attachment";
|
||||
|
||||
if (!slug && isInline) {
|
||||
slug = inlineContentDispositionTypes[detectedMimeType];
|
||||
}
|
||||
|
||||
if (slug) {
|
||||
disposition = contentDisposition(slug.trim(), {
|
||||
fallback: false,
|
||||
type: disposition,
|
||||
});
|
||||
}
|
||||
|
||||
if (detectedMimeType === "audio/vnd.wave") {
|
||||
// Send a more common mime type for wave audio files
|
||||
@ -102,7 +114,7 @@ class Uploader {
|
||||
detectedMimeType = "audio/wav";
|
||||
}
|
||||
|
||||
res.setHeader("Content-Disposition", contentDisposition);
|
||||
res.setHeader("Content-Disposition", disposition);
|
||||
res.setHeader("Cache-Control", "max-age=86400");
|
||||
res.contentType(detectedMimeType);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user