diff --git a/README.md b/README.md index 7334f6f..c648568 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ Requirements Install ======= - npm i @fastify/busboy +```sh +npm i @fastify/busboy +``` Examples @@ -201,6 +203,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/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..94db68e --- /dev/null +++ b/test/file-stream-limit.test.js @@ -0,0 +1,39 @@ +'use strict' + +const { PassThrough } = require('stream') +const Busboy = require('../').default +const { test } = require('node:test') +const assert = require('node:assert') + +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 bb = new Busboy({ + headers: req.headers, + limits: { fileSize: 10 } + }) + + bb.on('file', (_fieldname, stream) => { + stream.on('limit', () => { + assert.ok(true, 'limit event emitted') + resolve() + }) + 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() + }) +})