Support `multipart/form-data` uploads
helje5 opened this issue · comments
We need a body parser for multipart/form-data
uploads, as per apple/swift-nio#1724 (comment)
I.e. to handle things like
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" id="filename" name="file" onchange="onchanged()" multiple="multiple" />
<input type="submit" value="Upload">
</form>
Need to check whether there is a more official Node API for that. Generally I'd think this should stream the files to a temporary location, keep the file handles open, but unlink them - or just regular tmpfiles. The body
structure would then have a reference to the file handles.
RFC: https://tools.ietf.org/html/rfc7578
Multer seems to be the default Node thing: https://www.npmjs.com/package/multer
var upload = multer({ dest: 'uploads/' })
app.post('/profile', upload.single('avatar'), function (req, res, next) {})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {})
app.post('/profile', upload.none(), function (req, res, next) {})
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
File info: filename, originalname, encoding, mimetype, size, destination (DiskStorage), filename, path, buffer
Options:
- dest (path) or storage (xyzStorage)
- fileFilter
- limits
- preservePath
DiskStorage or MemoryStorage:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload = multer({ storage: storage })
var storage = multer.memoryStorage()
var upload = multer({ storage: storage })
There is also Formidable: https://github.com/node-formidable/formidable
The feature/multipart-formdata-1
now has an apparently working multipart/form-data parser, with quite a few tests. Only the MemoryStorage is supported so far, DiskStorage would require more async hops.
Performance doesn't seem to be too great yet, uploading a 3MB image (locally) takes 255ms in release (4s in debug), which seems a little slow for an M1 Mini. Need to check where the time gets lost.
Uploading my 3MB test image on M1 now takes 2ms in release (12ms in Debug), which seems quite reasonable. 100 MB take about 50ms, which also sounds OK.
What we don't have yet is DiskStorage (though it's prepared), I put that into a separate Issue #8.
The multer module is available in 0.8.0.