multer icon indicating copy to clipboard operation
multer copied to clipboard

Storage Engines, fileFilter, mixed behavour in v1/v2 and Docs

Open sosnik opened this issue 2 years ago • 3 comments

Perhaps this should be 3 separate issues but I'm keeping as one issue for brevity.

fileFilter in v2.x

Has the fileFilter function been removed from the v2 release? It is no longer documented in the readme, but its removal hasn't been mentioned in the changelogs.

fileFilter in v1.4.2

The latest version of multer available through npm is 1.4.2. The documentation for the master branch and the 1.4.2 tag indicates that it should be possible to use the MemoryStorage engine. When using the engine, a buffer property is added to the file object.

However, the buffer is not available on the file object that is being passed as the second argument to fileFilter.

The options:

multerOpts: Multer.Options = {
	storage: Multer.memoryStorage(),
	fileFilter: this.imageFilter,
	/* ... */
}

The filter function:

async imageFilter(req: express.Request, file: any, ffcb: Multer.FileFilterCallback) {
	log(req.file)) // => file object, no buffer
	log(req.file.buffer)) // => undefined
	log(file.buffer)) // => undefined
	ffcb(null, true)
}

Has this been removed/disabled/broken, or am I doing something wrong? The fileFilter is obviously working up to the point where it logs the file or req.file object. If I use DiskStorage engine, the file object gets the appropriate additional fields like filename and path. When using MemoryStorage, these fields are missing as expected, but the buffer is nowhere to be seen. No Stream is available either.

What is the proper way to use fileFilter?

My intended approach was to take the file buffer and pass it onto file-type to check mime, and then reject things with the wrong mime. Without access to the buffer, I cannot do this. If I use DiskStorage, when does fileFilter get triggered? Before or after the file is written to disk? If the latter, what's the point of using that function stead of using a separate middleware?

What do you use to detect mimetypes in v2.x? The docs state that some form of mime detection is going on, but I don't see file-type in the v2 dependencies. I believe formidable is just inferring from extension (eeeesh).

In any event, is there a way to filter based on mimetype in v2?

In the alternative, what's the dead-simplest, most lightweight parser out there so I can include my own limits/validations/"to keep or not to keep" checks.

sosnik avatar Jul 21 '21 10:07 sosnik

The file filter function was intended to be used to not accept a specific file, thus it has to run before we read in the file, and thus the file filter function cannot have access to the file contents, only the file metadata.

In any event, is there a way to filter based on mimetype in v2?

The simplest way to do this is in your route handler, by looking at the detectedMimeType property. Then you can decide wether to delete the file and return an error, or wether to accept the file for further processing...

(sorry for the brief answer, I'm out and about at the moment)

LinusU avatar Jul 21 '21 12:07 LinusU

Thank you for your response.

In v2, does detectedMimeType get populated before or after the file is downloaded? Is there a way to disable mime detection, and what are the benefits if using the multerv2 native detection versus something like file-type?

sosnik avatar Jul 23 '21 04:07 sosnik

In v2, does detectedMimeType get populated before or after the file is downloaded? Is there a way to disable mime detection, and what are the benefits if using the multerv2 native detection versus something like file-type?

In v2 all files are downloaded to temporary storage before being exposed outside of the library. While that happens, it detects the mime type.

There is no way to disable it, but if you don't want to use it you can simply not look at the property. I cannot see that it brings any overhead, but if it is we could add an option to disable it.

The native detection uses file-type, so the detection should be the same. The benefit is that you don't have to read the stream yourself, since Multer automatically passes the first chunk to file-type for you.

LinusU avatar Jul 23 '21 16:07 LinusU