Highlights
multer finally supports Google Cloud Functions and Firebase 🎉
These platforms read the request body before your code runs, so multer's classic req.pipe(busboy) received nothing: empty req.body, empty req.files, and nearly a decade of duplicated issues.
The new streamHandler option closes that gap: you decide how the body reaches the parser, so the pre-read rawBody just works (see image).
const multer = require('multer')
const upload = multer({
storage: multer.memoryStorage(),
streamHandler: (req, busboy) => {
// Cloud Functions / Firebase expose the pre-read body here
if (req.rawBody) busboy.end(req.rawBody)
else req.pipe(busboy)
}
})
app.post('/upload', upload.single('file'), (req, res) => {
res.json({ name: req.file.originalname, size: req.file.size })
})This landed thanks to community PRs going back to 2017; their authors are credited as co-authors in the release.
Important: Security
What's Changed
- docs: remove README translations by @UlisesGascon in #1463
- ci: add macOS to the test matrix by @kilisamemarisaaa in #1464
- feat. improve wording for LIMIT_UNEXPECTED_FILE error code by @flashbag in #426
- feat: add filename to file errors by @UjjwalKumar239 in #1416
- refactor: remove concat-stream dependency by @Phillip9587 in #1356
- fix: reject non-integer fileSize limits by @abhu85 in #1395
- fix: allow exactly limits.parts parts by @deepakganesh78 in #1446
- fix: do not consume maxCount for files skipped by fileFilter by @Sagargupta16 in #1426
- fix: validate all limits at construction time by @ShubhamOulkar in #1335
- test: cover storage engine _removeFile invocation semantics by @kilisamemarisaaa in #1460
- feat: accept a function for limits by @hossein-zare in #1133
- fix: add flush option to disk storage to fsync files before completion by @kilisamemarisaaa in #1458
- feat: expose busboy defCharset, highWaterMark and fileHwm options by @UlisesGascon in #1465
- docs: describe the file stream contract for storage engines by @UlisesGascon in #1468
- fix: wait for the flush descriptor before unlinking on aborted uploads by @UlisesGascon in #1479
- fix: reserve the maxCount slot before yielding to an async fileFilter by @UlisesGascon in #1480
- docs: add FormData upload examples by @davidmashe in #896
- feat: add streamHandler option to feed busboy from pre-consumed bodies by @UlisesGascon in #1466
- docs: add JSDoc to the public API by @UlisesGascon in #1467
- fix: decode escaped field names, not just filenames by @MohammedAlkindi in #1473
- fix: report the decoded filename on LIMIT_FILE_SIZE by @MaxFreedomPollard in #1478
- feat: allow diskStorage without options by @vaibhavmashal in #1471
- chore(deps): bump github/codeql-action/init from 4.37.4 to 4.37.9 by @dependabot[bot] in #1476
- chore(deps): bump github/codeql-action/analyze from 4.37.4 to 4.37.9 by @dependabot[bot] in #1475
- chore(deps): bump github/codeql-action/upload-sarif to 4.37.9 by @dependabot[bot] in #1474
- 2.4.0 by @UlisesGascon in #1469
New Contributors
- @flashbag made their first contribution in #426
- @UjjwalKumar239 made their first contribution in #1416
- @Phillip9587 made their first contribution in #1356
- @deepakganesh78 made their first contribution in #1446
- @Sagargupta16 made their first contribution in #1426
- @hossein-zare made their first contribution in #1133
- @davidmashe made their first contribution in #896
- @MaxFreedomPollard made their first contribution in #1478
- @vaibhavmashal made their first contribution in #1471
Full Changelog: v2.3.0...v2.4.0