Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ Major changes since the last busboy release (0.31):
* Tests were converted to Mocha (#11, #12, #22, #23)
* Add isPartAFile-option, to make the file-detection configurable (#53)
* Empty Parts will not hang the process (#55)
* FileStreams also provide the property `bytesRead`
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ Busboy (special) events
* **file**(< _string_ >fieldname, < _ReadableStream_ >stream, < _string_ >filename, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new file form field found. `transferEncoding` contains the 'Content-Transfer-Encoding' value for the file stream. `mimeType` contains the 'Content-Type' value for the file stream.
* Note: if you listen for this event, you should always handle the `stream` no matter if you care about the file contents or not (e.g. you can simply just do `stream.resume();` if you want to discard the contents), otherwise the 'finish' event will never fire on the Busboy instance. However, if you don't care about **any** incoming files, you can simply not listen for the 'file' event at all and any/all files will be automatically and safely discarded (these discarded files do still count towards `files` and `parts` limits).
* 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.

* **field**(< _string_ >fieldname, < _string_ >value, < _boolean_ >fieldnameTruncated, < _boolean_ >valueTruncated, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new non-file field found.

Expand Down
4 changes: 2 additions & 2 deletions benchmarks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
},
"scripts": {
"install-node": "nvm install 17.2.0 && nvm install 16.13.1 && nvm install 14.18.2 && nvm install 12.22.7",
"benchmark-busboy": "node busboy/executioner.js -c 0",
"benchmark-fastify": "node busboy/executioner.js -c 1",
"benchmark-busboy": "node busboy/executioner.js -c 0 -p medium",
"benchmark-fastify": "node busboy/executioner.js -c 1 -p medium",
"benchmark-all": "npm run benchmark-busboy -- -p high && npm run benchmark-fastify -- -p high",
"benchmark-all-medium": "npm run benchmark-busboy -- -p medium && npm run benchmark-fastify -- -p medium",
"benchmark-all-low": "npm run benchmark-busboy -- -p low && npm run benchmark-fastify -- -p low",
Expand Down
19 changes: 15 additions & 4 deletions lib/main.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/// <reference types="node" />

import * as http from 'http';
import {Readable, Writable} from 'stream';
import { Readable, Writable } from 'stream';

declare const busboy: BusboyConstructor;
export default busboy
Expand Down Expand Up @@ -49,7 +49,7 @@ export interface BusboyConfig {
* Various limits on incoming data.
*/
limits?:
| {
| {
/**
* Max field name size (in bytes)
* @default 100 bytes
Expand Down Expand Up @@ -86,11 +86,22 @@ export interface BusboyConfig {
*/
headerPairs?: number | undefined;
}
| undefined;
| undefined;
}

export type BusboyHeaders = { 'content-type': string } & http.IncomingHttpHeaders;

export interface BusboyFileStream extends
Readable {

truncated: boolean;

/**
* The number of bytes that have been read so far.
*/
bytesRead: number;
}

export interface Busboy extends Writable {
addListener<Event extends keyof BusboyEvents>(event: Event, listener: BusboyEvents[Event]): this;

Expand Down Expand Up @@ -138,7 +149,7 @@ export interface BusboyEvents {
*/
file: (
fieldname: string,
stream: Readable,
stream: BusboyFileStream,
filename: string,
transferEncoding: string,
mimeType: string,
Expand Down
10 changes: 8 additions & 2 deletions lib/types/multipart.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,16 @@ function Multipart (boy, cfg) {

onData = function (data) {
if ((nsize += data.length) > fileSizeLimit) {
const extralen = (fileSizeLimit - (nsize - data.length))
const extralen = fileSizeLimit - nsize + data.length
if (extralen > 0) { file.push(data.slice(0, extralen)) }
file.emit('limit')
file.truncated = true
file.bytesRead = fileSizeLimit
part.removeAllListeners('data')
file.emit('limit')
return
} else if (!file.push(data)) { self._pause = true }

file.bytesRead = nsize
}

onEnd = function () {
Expand Down Expand Up @@ -287,6 +291,8 @@ function FileStream (opts) {
if (!(this instanceof FileStream)) { return new FileStream(opts) }
ReadableStream.call(this, opts)

this.bytesRead = 0

this.truncated = false
}
inherits(FileStream, ReadableStream)
Expand Down
2 changes: 2 additions & 0 deletions test/types-multipart.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ describe('types-multipart', () => {
++info[3]
}).on('end', function () {
info[2] = nb
assert(typeof (stream.bytesRead) === 'number', 'file.bytesRead is missing')
assert(stream.bytesRead === nb, 'file.bytesRead is not equal to filesize')
if (stream.truncated) { ++info[3] }
})
})
Expand Down
17 changes: 8 additions & 9 deletions test/types/main.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import BusboyDefault, { BusboyConstructor, BusboyConfig, BusboyHeaders, Busboy, BusboyEvents } from '../..';
import BusboyDefault, { BusboyConstructor, BusboyConfig, BusboyHeaders, Busboy, BusboyEvents, BusboyFileStream } from '../..';
import {expectError, expectType} from "tsd";
import {Readable} from "stream";

// test type exports
type Constructor = BusboyConstructor;
Expand Down Expand Up @@ -28,7 +27,7 @@ new BusboyDefault({ headers: { 'content-type': 'foo' }, isPartAFile: (fieldName,

busboy.addListener('file', (fieldname, file, filename, encoding, mimetype) => {
expectType<string> (fieldname)
expectType<Readable>(file);
expectType<BusboyFileStream>(file);
expectType<string>(filename);
expectType<string>(encoding);
expectType<string>(mimetype);
Expand Down Expand Up @@ -58,7 +57,7 @@ busboy.on(Symbol('foo'), foo => {

busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
expectType<string> (fieldname);
expectType<Readable> (file);
expectType<BusboyFileStream> (file);
expectType<string> (filename);
expectType<string> (encoding);
expectType<string> (mimetype);
Expand Down Expand Up @@ -88,7 +87,7 @@ busboy.on(Symbol('foo'), foo => {

busboy.once('file', (fieldname, file, filename, encoding, mimetype) => {
expectType<string> (fieldname);
expectType<Readable> (file);
expectType<BusboyFileStream> (file);
expectType<string> (filename);
expectType<string> (encoding);
expectType<string> (mimetype);
Expand Down Expand Up @@ -118,7 +117,7 @@ busboy.once(Symbol('foo'), foo => {

busboy.removeListener('file', (fieldname, file, filename, encoding, mimetype) => {
expectType<string> (fieldname);
expectType<Readable> (file);
expectType<BusboyFileStream> (file);
expectType<string> (filename);
expectType<string> (encoding);
expectType<string> (mimetype);
Expand Down Expand Up @@ -148,7 +147,7 @@ busboy.removeListener(Symbol('foo'), foo => {

busboy.off('file', (fieldname, file, filename, encoding, mimetype) => {
expectType<string> (fieldname);
expectType<Readable> (file);
expectType<BusboyFileStream> (file);
expectType<string> (filename);
expectType<string> (encoding);
expectType<string> (mimetype);
Expand Down Expand Up @@ -178,7 +177,7 @@ busboy.off(Symbol('foo'), foo => {

busboy.prependListener('file', (fieldname, file, filename, encoding, mimetype) => {
expectType<string> (fieldname);
expectType<Readable> (file);
expectType<BusboyFileStream> (file);
expectType<string> (filename);
expectType<string> (encoding);
expectType<string> (mimetype);
Expand Down Expand Up @@ -208,7 +207,7 @@ busboy.prependListener(Symbol('foo'), foo => {

busboy.prependOnceListener('file', (fieldname, file, filename, encoding, mimetype) => {
expectType<string> (fieldname);
expectType<Readable> (file);
expectType<BusboyFileStream> (file);
expectType<string> (filename);
expectType<string> (encoding);
expectType<string> (mimetype);
Expand Down