From 394345bf5d73468542dab73b19c3bb38afe00503 Mon Sep 17 00:00:00 2001 From: William Ferreira da Silva Date: Fri, 30 May 2025 12:28:47 -0300 Subject: [PATCH 1/4] fix: add 'limit' event to BusboyFileStream typings --- lib/main.d.ts | 11 ++++++++++ test/file-stream-limit.test.js | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 test/file-stream-limit.test.js diff --git a/lib/main.d.ts b/lib/main.d.ts index 1948334..4551863 100644 --- a/lib/main.d.ts +++ b/lib/main.d.ts @@ -3,6 +3,17 @@ // Igor Savin /// +declare module 'stream' { + interface Readable { + /** + * Emitted when the configured file size limit is reached. + */ + on(event: 'limit', listener: () => void): this; + once(event: 'limit', listener: () => void): this; + addListener(event: 'limit', listener: () => void): this; + removeListener(event: 'limit', listener: () => void): this; + } +} import * as http from 'node:http'; import { Readable, Writable } from 'node:stream'; diff --git a/test/file-stream-limit.test.js b/test/file-stream-limit.test.js new file mode 100644 index 0000000..d1cc700 --- /dev/null +++ b/test/file-stream-limit.test.js @@ -0,0 +1,37 @@ +'use strict' + +const { PassThrough } = require('stream') +const Busboy = require('../').default +const { test } = require('tap') + +test('BusboyFileStream emits limit', t => { + t.plan(1) + + const bigPayload = Buffer.alloc(20, 'a') + const boundary = 'foo' + const req = new PassThrough() + req.headers = { + 'content-type': `multipart/form-data; boundary=${boundary}` + } + + const bb = new Busboy({ + headers: req.headers, + limits: { fileSize: 10 } + }) + + bb.on('file', (_fieldname, stream) => { + stream.on('limit', () => { + t.pass('limit event emitted') + }) + stream.resume() + }) + + req.pipe(bb) + + const delimiter = `--${boundary}` + req.write(`${delimiter}\r\n`) + req.write('Content-Disposition: form-data; name="file"; filename="a.txt"\r\n\r\n') + req.write(bigPayload) + req.write(`\r\n${delimiter}--\r\n`) + req.end() +}) From ef1385b44741e890efb3dedb9273c668fd5c19d9 Mon Sep 17 00:00:00 2001 From: William Ferreira da Silva Date: Fri, 30 May 2025 12:34:36 -0300 Subject: [PATCH 2/4] docs: document 'limit' event in README and add tap to devDependencies --- README.md | 10 ++++++++++ package.json | 2 ++ 2 files changed, 12 insertions(+) diff --git a/README.md b/README.md index 7334f6f..746bc80 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,16 @@ Busboy (special) events * If a configured file size limit was reached, `stream` will both have a boolean property `truncated` (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens. * The property `bytesRead` informs about the number of bytes that have been read so far. +* **limit**() - Emitted when a file exceeds the configured `fileSize` limit. You can listen on the file stream to handle it: + +```js +busboy.on('file', (fieldname, stream) => { + stream.on('limit', () => { + console.log('File size exceeded') + }) +}) +``` + * **field**(< _string_ >fieldname, < _string_ >value, < _boolean_ >fieldnameTruncated, < _boolean_ >valueTruncated, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new non-file field found. * **partsLimit**() - Emitted when specified `parts` limit has been reached. No more 'file' or 'field' events will be emitted. diff --git a/package.json b/package.json index 3215fb9..f5b5f28 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,13 @@ }, "devDependencies": { "@types/node": "^22.0.0", + "@types/tap": "^15.0.12", "busboy": "^1.6.0", "c8": "^10.1.2", "photofinish": "^1.8.0", "snazzy": "^9.0.0", "standard": "^17.1.0", + "tap": "^21.1.0", "tinybench": "^4.0.1", "tsd": "^0.32.0", "typescript": "~5.8.2" From 1aa3a6123213c0da4ef0a78d8e47d6e912b271e8 Mon Sep 17 00:00:00 2001 From: William Ferreira da Silva Date: Mon, 2 Jun 2025 08:09:52 -0300 Subject: [PATCH 3/4] test: migrate BusboyFileStream emits limit from tap to node:test --- package.json | 2 -- test/file-stream-limit.test.js | 54 ++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index f5b5f28..3215fb9 100644 --- a/package.json +++ b/package.json @@ -32,13 +32,11 @@ }, "devDependencies": { "@types/node": "^22.0.0", - "@types/tap": "^15.0.12", "busboy": "^1.6.0", "c8": "^10.1.2", "photofinish": "^1.8.0", "snazzy": "^9.0.0", "standard": "^17.1.0", - "tap": "^21.1.0", "tinybench": "^4.0.1", "tsd": "^0.32.0", "typescript": "~5.8.2" diff --git a/test/file-stream-limit.test.js b/test/file-stream-limit.test.js index d1cc700..94db68e 100644 --- a/test/file-stream-limit.test.js +++ b/test/file-stream-limit.test.js @@ -2,36 +2,38 @@ const { PassThrough } = require('stream') const Busboy = require('../').default -const { test } = require('tap') +const { test } = require('node:test') +const assert = require('node:assert') -test('BusboyFileStream emits limit', t => { - t.plan(1) +test('BusboyFileStream emits limit', async (t) => { + await new Promise((resolve, reject) => { + const bigPayload = Buffer.alloc(20, 'a') + const boundary = 'foo' + const req = new PassThrough() + req.headers = { + 'content-type': `multipart/form-data; boundary=${boundary}` + } - const bigPayload = Buffer.alloc(20, 'a') - const boundary = 'foo' - const req = new PassThrough() - req.headers = { - 'content-type': `multipart/form-data; boundary=${boundary}` - } - - const bb = new Busboy({ - headers: req.headers, - limits: { fileSize: 10 } - }) + const bb = new Busboy({ + headers: req.headers, + limits: { fileSize: 10 } + }) - bb.on('file', (_fieldname, stream) => { - stream.on('limit', () => { - t.pass('limit event emitted') + bb.on('file', (_fieldname, stream) => { + stream.on('limit', () => { + assert.ok(true, 'limit event emitted') + resolve() + }) + stream.resume() }) - stream.resume() - }) - req.pipe(bb) + req.pipe(bb) - const delimiter = `--${boundary}` - req.write(`${delimiter}\r\n`) - req.write('Content-Disposition: form-data; name="file"; filename="a.txt"\r\n\r\n') - req.write(bigPayload) - req.write(`\r\n${delimiter}--\r\n`) - req.end() + const delimiter = `--${boundary}` + req.write(`${delimiter}\r\n`) + req.write('Content-Disposition: form-data; name="file"; filename="a.txt"\r\n\r\n') + req.write(bigPayload) + req.write(`\r\n${delimiter}--\r\n`) + req.end() + }) }) From e14c4c449eefb2365aa8b5109c1317bdcb62d148 Mon Sep 17 00:00:00 2001 From: Manuel Spigolon Date: Mon, 10 Nov 2025 12:00:37 +0100 Subject: [PATCH 4/4] chore Signed-off-by: Manuel Spigolon --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 746bc80..c648568 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ Requirements Install ======= - npm i @fastify/busboy +```sh +npm i @fastify/busboy +``` Examples