### Configure Character Encoding with Busboy (Node.js)
Source: https://context7.com/mscdex/busboy/llms.txt
This example shows how to configure character encoding for field names and values when using Busboy. This is essential for correctly handling international text. The `defCharset` and `defParamCharset` options are used for this purpose. Dependencies include 'http' and 'busboy'.
```javascript
const http = require('http');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({
headers: req.headers,
defCharset: 'utf8', // Default charset for field values
defParamCharset: 'latin1' // Default charset for header parameters
});
bb.on('field', (name, val, info) => {
console.log(`Field: ${name}`);
console.log(`Value: ${val}`);
console.log(`Encoding: ${info.encoding}`);
console.log(`MIME Type: ${info.mimeType}`);
console.log(`Name Truncated: ${info.nameTruncated}`);
console.log(`Value Truncated: ${info.valueTruncated}`);
});
bb.on('close', () => {
res.writeHead(200);
res.end('OK');
});
req.pipe(bb);
}
}).listen(8000);
```
--------------------------------
### Parse Multipart Form Data with Default Options in Node.js
Source: https://github.com/mscdex/busboy/blob/master/README.md
This example demonstrates how to parse multipart form data using busboy with default options in a Node.js HTTP server. It logs file and field information as they are processed and handles the completion of form parsing. The server also provides a basic HTML form for testing.
```javascript
const http = require('http');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
console.log('POST request');
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const { filename, encoding, mimeType } = info;
console.log(
`File [${name}]: filename: %j, encoding: %j, mimeType: %j`,
filename,
encoding,
mimeType
);
file.on('data', (data) => {
console.log(`File [${name}] got ${data.length} bytes`);
}).on('close', () => {
console.log(`File [${name}] done`);
});
});
bb.on('field', (name, val, info) => {
console.log(`Field [${name}]: value: %j`, val);
});
bb.on('close', () => {
console.log('Done parsing form!');
res.writeHead(303, { Connection: 'close', Location: '/' });
res.end();
});
req.pipe(bb);
} else if (req.method === 'GET') {
res.writeHead(200, { Connection: 'close' });
res.end(
`
`);
}
}).listen(8000, () => {
console.log('Listening for requests');
});
// Example output:
//
// Listening for requests
// < ... form submitted ... >
// POST request
// File [filefield]: filename: "logo.jpg", encoding: "binary", mime: "image/jpeg"
// File [filefield] got 11912 bytes
// Field [textfield]: value: "testing! :-")
// File [filefield] done
// Done parsing form!
```
--------------------------------
### Complete File Upload Server with Busboy and HTML Form
Source: https://context7.com/mscdex/busboy/llms.txt
This example provides a full Node.js server using busboy to handle file uploads. It configures limits for file size, number of files, and fields. The server supports multiple file uploads and text fields, and includes an HTML form for testing. It logs file information, tracks file sizes, and handles potential errors.
```javascript
const http = require('http');
const fs = require('fs');
const path = require('path');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
console.log('POST request received');
const bb = busboy({
headers: req.headers,
limits: {
fileSize: 50 * 1024 * 1024, // 50MB max file size
files: 10,
fields: 20
}
});
const uploads = [];
const fields = {};
bb.on('file', (name, file, info) => {
const { filename, encoding, mimeType } = info;
console.log(`File [${name}]: filename: ${filename}, encoding: ${encoding}, mimeType: ${mimeType}`);
const savePath = path.join(__dirname, 'uploads', `${Date.now()}-${filename}`);
const writeStream = fs.createWriteStream(savePath);
let fileSize = 0;
file.on('data', (data) => {
fileSize += data.length;
console.log(`File [${name}] got ${data.length} bytes (total: ${fileSize})`);
});
file.on('limit', () => {
console.log(`File [${name}] reached size limit`);
});
file.on('close', () => {
console.log(`File [${name}] done`);
uploads.push({
fieldName: name,
filename: filename,
path: savePath,
size: fileSize,
mimeType: mimeType,
truncated: file.truncated
});
});
file.pipe(writeStream);
});
bb.on('field', (name, val, info) => {
console.log(`Field [${name}]: value: ${val}`);
fields[name] = val;
});
bb.on('close', () => {
console.log('Done parsing form!');
res.writeHead(303, { Connection: 'close', Location: '/' });
res.end();
});
bb.on('error', (err) => {
console.error('Busboy error:', err);
res.writeHead(500);
res.end('Server error');
});
req.pipe(bb);
} else if (req.method === 'GET') {
res.writeHead(200, {
Connection: 'close',
'Content-Type': 'text/html'
});
res.end(`
File Upload Test
Upload Files
`);
} else {
res.writeHead(405);
res.end();
}
}).listen(8000, () => {
console.log('Server listening on http://localhost:8000');
console.log('Create uploads directory: mkdir -p uploads');
});
```
--------------------------------
### Configure Busboy Parser Limits for Resource Protection
Source: https://context7.com/mscdex/busboy/llms.txt
This example shows how to configure limits for a Busboy parser instance to prevent resource exhaustion. It sets limits on field name size, field value size, number of fields, file size, number of files, and total parts. It also includes event listeners for limit breaches like 'filesLimit', 'fieldsLimit', and 'partsLimit'.
```javascript
const http = require('http');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({
headers: req.headers,
limits: {
fieldNameSize: 100, // Max field name size in bytes
fieldSize: 1048576, // Max field value size (1MB)
fields: 10, // Max number of non-file fields
fileSize: 10485760, // Max file size (10MB)
files: 5, // Max number of files
parts: 15, // Max number of parts (fields + files)
headerPairs: 2000 // Max number of header key-value pairs
}
});
bb.on('file', (name, file, info) => {
file.on('limit', () => {
console.log(`File size limit reached for ${info.filename}`);
});
file.on('data', (data) => {
// Process file data
});
file.on('close', () => {
if (file.truncated) {
console.log(`File ${info.filename} was truncated`);
}
});
});
bb.on('filesLimit', () => {
console.log('Maximum number of files reached');
});
bb.on('fieldsLimit', () => {
console.log('Maximum number of fields reached');
});
bb.on('partsLimit', () => {
console.log('Maximum number of parts reached');
});
bb.on('close', () => {
res.writeHead(200);
res.end('Parsing complete');
});
req.pipe(bb);
}
}).listen(8000);
```
--------------------------------
### Save Incoming Files to Disk using Node.js and Busboy
Source: https://github.com/mscdex/busboy/blob/master/README.md
This Node.js example utilizes busboy to process incoming multipart form data and save each uploaded file to the system's temporary directory. It generates a unique filename for each saved file using crypto.randomFillSync and pipes the file stream directly to a writable stream on disk. The server responds with a success message upon completion.
```javascript
const { randomFillSync } = require('crypto');
const fs = require('fs');
const http = require('http');
const os = require('os');
const path = require('path');
const busboy = require('busboy');
const random = (() => {
const buf = Buffer.alloc(16);
return () => randomFillSync(buf).toString('hex');
})();
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const saveTo = path.join(os.tmpdir(), `busboy-upload-${random()}`);
file.pipe(fs.createWriteStream(saveTo));
});
bb.on('close', () => {
res.writeHead(200, { 'Connection': 'close' });
res.end(`That's all folks!`);
});
req.pipe(bb);
return;
}
res.writeHead(404);
res.end();
}).listen(8000, () => {
console.log('Listening for requests');
});
```
--------------------------------
### Control File Path Preservation in Busboy (Node.js)
Source: https://context7.com/mscdex/busboy/llms.txt
This example shows how to configure Busboy's `preservePath` option to control whether full client-provided file paths are preserved or if only the basename is used. Setting `preservePath` to `false` is recommended for security to prevent path traversal vulnerabilities. Dependencies include 'http', 'busboy', and 'path'.
```javascript
const http = require('http');
const busboy = require('busboy');
const path = require('path');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({
headers: req.headers,
preservePath: false // Strip directory paths from filenames (recommended for security)
});
bb.on('file', (name, file, info) => {
// With preservePath: false, "C:\\Users\\test\\file.txt" becomes "file.txt"
// With preservePath: true, full path is preserved (SECURITY RISK!)
console.log(`Original filename from client: ${info.filename}`);
// Always sanitize filenames in production
const safeFilename = path.basename(info.filename)
.replace(/[^a-zA-Z0-9.-]/g, '_')
.substring(0, 255);
console.log(`Sanitized filename: ${safeFilename}`);
file.on('data', (data) => {
// Process file data
});
file.resume(); // Consume stream even if not processing
});
bb.on('close', () => {
res.writeHead(200);
res.end('OK');
});
req.pipe(bb);
}
}).listen(8000);
```
--------------------------------
### Busboy Parser Instance and Event Handling
Source: https://context7.com/mscdex/busboy/llms.txt
Demonstrates how to create a Busboy parser instance and handle 'file' and 'field' events for processing form data and file uploads.
```APIDOC
## POST / (HTTP Server)
### Description
Processes incoming HTTP POST requests with multipart/form-data or application/x-www-form-urlencoded content types using the Busboy parser. It emits events for each file and field encountered during parsing.
### Method
POST
### Endpoint
/
### Parameters
#### Request Body
- **Request Stream**: The incoming HTTP request stream to be piped into the Busboy parser.
### Request Example
```javascript
const http = require('http');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const { filename, encoding, mimeType } = info;
console.log(`File [${name}]: filename: ${filename}, encoding: ${encoding}, mimeType: ${mimeType}`);
file.on('data', (data) => {
console.log(`File [${name}] got ${data.length} bytes`);
}).on('close', () => {
console.log(`File [${name}] done`);
});
});
bb.on('field', (name, val, info) => {
console.log(`Field [${name}]: value: ${val}`);
});
bb.on('close', () => {
console.log('Done parsing form!');
res.writeHead(200, { Connection: 'close' });
res.end('Upload complete');
});
req.pipe(bb);
}
}).listen(8000);
```
### Response
#### Success Response (200)
- **Connection**: 'close' - Indicates that the connection will be closed after the response is sent.
- **Body**: 'Upload complete' message.
#### Response Example
(No specific response body example, but the connection will close and 'Upload complete' will be sent.)
```
--------------------------------
### Busboy Parser Configuration with Limits
Source: https://context7.com/mscdex/busboy/llms.txt
Shows how to configure Busboy with specific limits for fields, files, and other parameters to prevent resource exhaustion and potential attacks.
```APIDOC
## POST / (HTTP Server with Limits)
### Description
Processes incoming HTTP POST requests while enforcing configurable limits on various aspects of the form data, such as field name size, field value size, number of files, and file size.
### Method
POST
### Endpoint
/
### Parameters
#### Request Body
- **Request Stream**: The incoming HTTP request stream to be piped into the Busboy parser.
#### Request Body Configuration (Options Object)
- **headers** (object) - Required - The request headers object.
- **limits** (object) - Optional - An object containing various parsing limits:
- **fieldNameSize** (number) - Max field name size in bytes.
- **fieldSize** (number) - Max field value size in bytes.
- **fields** (number) - Max number of non-file fields.
- **fileSize** (number) - Max file size in bytes.
- **files** (number) - Max number of files.
- **parts** (number) - Max number of parts (fields + files).
- **headerPairs** (number) - Max number of header key-value pairs.
### Request Example
```javascript
const http = require('http');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({
headers: req.headers,
limits: {
fieldNameSize: 100,
fieldSize: 1048576,
fields: 10,
fileSize: 10485760,
files: 5,
parts: 15,
headerPairs: 2000
}
});
bb.on('file', (name, file, info) => {
file.on('limit', () => {
console.log(`File size limit reached for ${info.filename}`);
});
file.on('data', (data) => {
// Process file data
});
file.on('close', () => {
if (file.truncated) {
console.log(`File ${info.filename} was truncated`);
}
});
});
bb.on('filesLimit', () => {
console.log('Maximum number of files reached');
});
bb.on('fieldsLimit', () => {
console.log('Maximum number of fields reached');
});
bb.on('partsLimit', () => {
console.log('Maximum number of parts reached');
});
bb.on('close', () => {
res.writeHead(200);
res.end('Parsing complete');
});
req.pipe(bb);
}
}).listen(8000);
```
### Response
#### Success Response (200)
- **Body**: 'Parsing complete' message.
#### Response Example
(No specific response body example, but 'Parsing complete' will be sent.)
#### Error Responses
- **filesLimit**: Emitted when the maximum number of files is reached.
- **fieldsLimit**: Emitted when the maximum number of fields is reached.
- **partsLimit**: Emitted when the maximum number of parts is reached.
- **file.limit**: Emitted when a single file exceeds its size limit.
```
--------------------------------
### Save Uploaded Files to Disk with Busboy (Node.js)
Source: https://context7.com/mscdex/busboy/llms.txt
This snippet demonstrates how to handle file uploads using Busboy and save them to the filesystem. It includes error handling for file writes and logs information about uploaded files. Dependencies include 'crypto', 'fs', 'http', 'os', 'path', and 'busboy'.
```javascript
const { randomFillSync } = require('crypto');
const fs = require('fs');
const http = require('http');
const os = require('os');
const path = require('path');
const busboy = require('busboy');
const random = (() => {
const buf = Buffer.alloc(16);
return () => randomFillSync(buf).toString('hex');
})();
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({ headers: req.headers });
const uploads = [];
bb.on('file', (name, file, info) => {
const { filename, encoding, mimeType } = info;
const saveTo = path.join(os.tmpdir(), `busboy-upload-${random()}`);
uploads.push({
field: name,
filename: filename,
path: saveTo,
encoding: encoding,
mimeType: mimeType
});
const writeStream = fs.createWriteStream(saveTo);
file.pipe(writeStream);
writeStream.on('error', (err) => {
console.error(`Error writing file ${filename}:`, err);
});
});
bb.on('field', (name, val, info) => {
console.log(`Received field ${name}: ${val}`);
});
bb.on('close', () => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ uploads: uploads }));
});
bb.on('error', (err) => {
console.error('Parsing error:', err);
res.writeHead(500);
res.end('Error processing upload');
});
req.pipe(bb);
return;
}
res.writeHead(404);
res.end();
}).listen(8000);
```
--------------------------------
### Busboy Parser Initialization
Source: https://github.com/mscdex/busboy/blob/master/README.md
Initializes a new Writable form parser stream using the busboy function with configurable options.
```APIDOC
## POST /upload
### Description
Creates and returns a new Writable form parser stream. This function can throw exceptions if the configuration is invalid or if the Content-Type header is missing or unsupported.
### Method
POST
### Endpoint
/upload
### Parameters
#### Request Body
- **config** (object) - Required - Configuration object for the parser stream.
- **headers** (object) - Required - The HTTP headers of the incoming request.
- **highWaterMark** (integer) - Optional - highWaterMark to use for the parser stream. Defaults to node's stream.Writable default.
- **fileHwm** (integer) - Optional - highWaterMark to use for individual file streams. Defaults to node's stream.Readable default.
- **defCharset** (string) - Optional - Default character set to use when one isn't defined. Defaults to 'utf8'.
- **defParamCharset** (string) - Optional - Default character set to use for part header parameter values. Defaults to 'latin1'.
- **preservePath** (boolean) - Optional - If paths in filenames from file parts should be preserved. Defaults to false.
- **limits** (object) - Optional - Various limits on incoming data.
- **fieldNameSize** (integer) - Optional - Max field name size (in bytes). Defaults to 100.
- **fieldSize** (integer) - Optional - Max field value size (in bytes). Defaults to 1048576 (1MB).
- **fields** (integer) - Optional - Max number of non-file fields. Defaults to Infinity.
- **fileSize** (integer) - Optional - Max file size (in bytes) for multipart forms. Defaults to Infinity.
- **files** (integer) - Optional - Max number of file fields for multipart forms. Defaults to Infinity.
- **parts** (integer) - Optional - Max number of parts (fields + files) for multipart forms. Defaults to Infinity.
- **headerPairs** (integer) - Optional - Max number of header key-value pairs to parse. Defaults to 2000.
### Request Example
```json
{
"headers": {
"content-type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
},
"highWaterMark": 16384,
"fileHwm": 16384,
"defCharset": "utf8",
"defParamCharset": "latin1",
"preservePath": false,
"limits": {
"fieldNameSize": 100,
"fieldSize": 1048576,
"fields": Infinity,
"fileSize": Infinity,
"files": Infinity,
"parts": Infinity,
"headerPairs": 2000
}
}
```
### Response
#### Success Response (200)
- **parserStream** (Writable stream) - The initialized form parser stream.
#### Response Example
(Returns a stream, not a JSON object)
```
--------------------------------
### Configure Busboy Stream Backpressure and High Water Mark
Source: https://context7.com/mscdex/busboy/llms.txt
This snippet demonstrates how to configure the 'highWaterMark' and 'fileHwm' options in busboy to manage buffer sizes for parser and file streams, optimizing memory usage and handling backpressure effectively. It includes basic logging for received data chunks and error handling for write streams.
```javascript
const http = require('http');
const busboy = require('busboy');
const fs = require('fs');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({
headers: req.headers,
highWaterMark: 32 * 1024, // Parser stream buffer size (32KB)
fileHwm: 64 * 1024 // Individual file stream buffer size (64KB)
});
bb.on('file', (name, file, info) => {
const writeStream = fs.createWriteStream(`/tmp/${Date.now()}.dat`);
// Proper backpressure handling
file.pipe(writeStream);
file.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes`);
});
writeStream.on('error', (err) => {
console.error('Write error:', err);
file.resume(); // Continue consuming to finish parsing
});
});
bb.on('close', () => {
res.writeHead(200);
res.end('Upload complete');
});
req.pipe(bb);
}
}).listen(8000);
```
--------------------------------
### Create Busboy Parser Instance for POST Requests
Source: https://context7.com/mscdex/busboy/llms.txt
This snippet demonstrates how to create a Busboy parser instance within a Node.js HTTP server to handle POST requests. It sets up event listeners for 'file' and 'field' to process incoming form data and pipes the request stream to the busboy parser. It also handles the 'close' event to send a response after parsing is complete.
```javascript
const http = require('http');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const { filename, encoding, mimeType } = info;
console.log(`File [${name}]: filename: ${filename}, encoding: ${encoding}, mimeType: ${mimeType}`);
file.on('data', (data) => {
console.log(`File [${name}] got ${data.length} bytes`);
}).on('close', () => {
console.log(`File [${name}] done`);
});
});
bb.on('field', (name, val, info) => {
console.log(`Field [${name}]: value: ${val}`);
});
bb.on('close', () => {
console.log('Done parsing form!');
res.writeHead(200, { Connection: 'close' });
res.end('Upload complete');
});
req.pipe(bb);
}
}).listen(8000);
```
--------------------------------
### Handle URL-Encoded Form Data with Busboy (Node.js)
Source: https://context7.com/mscdex/busboy/llms.txt
This snippet illustrates how to use Busboy to parse URL-encoded form submissions, mimicking the behavior of multipart/form-data. It demonstrates setting limits for form fields and handling potential `fieldsLimit` events. Dependencies include 'http' and 'busboy'.
```javascript
const http = require('http');
const busboy = require('busboy');
http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = busboy({
headers: req.headers,
limits: {
fieldNameSize: 100,
fieldSize: 1024,
fields: 20
}
});
const fields = {};
bb.on('field', (name, val, info) => {
fields[name] = {
value: val,
truncated: info.valueTruncated,
encoding: info.encoding
};
});
bb.on('fieldsLimit', () => {
console.log('Too many fields in submission');
});
bb.on('close', () => {
console.log('Parsed fields:', fields);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(fields));
});
bb.on('error', (err) => {
console.error('Error:', err);
res.writeHead(400);
res.end('Bad Request');
});
req.pipe(bb);
}
}).listen(8000);
```
--------------------------------
### Busboy Parser Stream Events
Source: https://github.com/mscdex/busboy/blob/master/README.md
Details the events emitted by the busboy parser stream, including file uploads, field data, and limit notifications.
```APIDOC
## Busboy Parser Stream Events
### Description
These events are emitted by the busboy parser stream as it processes the incoming form data.
### Events
#### `file` Event
Emitted for each new file found.
- **name** (string) - The form field name for the file.
- **stream** (Readable stream) - A Readable stream containing the file's data. Note: This stream may have a `truncated` property set to `true` if `limits.fileSize` was reached.
- **info** (object) - An object containing additional file information:
- **filename** (string) - The file's filename. **Warning:** Use with caution due to potential security risks.
- **encoding** (string) - The file's `'Content-Transfer-Encoding'` value.
- **mimeType** (string) - The file's `'Content-Type'` value.
**Note:** Always consume the `stream` (e.g., `stream.resume();`) to ensure the parser stream finishes correctly.
#### `field` Event
Emitted for each new non-file field found.
- **name** (string) - The form field name.
- **value** (string) - The string value of the field.
- **info** (object) - An object containing additional field information:
- **nameTruncated** (boolean) - Whether the field name was truncated due to `limits.fieldNameSize`.
- **valueTruncated** (boolean) - Whether the field value was truncated due to `limits.fieldSize`.
- **encoding** (string) - The field's `'Content-Transfer-Encoding'` value.
- **mimeType** (string) - The field's `'Content-Type'` value.
#### `partsLimit` Event
Emitted when the configured `limits.parts` limit has been reached. No more `'file'` or `'field'` events will be emitted.
#### `filesLimit` Event
Emitted when the configured `limits.files` limit has been reached. No more `'file'` events will be emitted.
#### `fieldsLimit` Event
Emitted when the configured `limits.fields` limit has been reached. No more `'field'` events will be emitted.
### Example Usage (Node.js)
```javascript
const http = require('http');
const Busboy = require('busboy');
const server = http.createServer((req, res) => {
if (req.method === 'POST') {
const bb = Busboy({ headers: req.headers });
bb.on('file', (name, fileStream, info) => {
console.log(`File [${name}]: filename: ${info.filename}, encoding: ${info.encoding}, mimeType: ${info.mimeType}`);
fileStream.pipe(process.stdout);
});
bb.on('field', (name, value, info) => {
console.log(`Field [${name}]: value: ${value}`);
});
bb.on('partsLimit', () => {
console.log('Parts limit reached');
});
bb.on('filesLimit', () => {
console.log('Files limit reached');
});
bb.on('fieldsLimit', () => {
console.log('Fields limit reached');
});
bb.on('finish', () => {
console.log('Upload finished');
res.writeHead(200, { Connection: 'close' });
res.end('Processing complete.');
});
req.pipe(bb);
} else {
res.writeHead(405, { 'Content-Type': 'text/plain' });
res.end('Method Not Allowed');
}
});
server.listen(3000, () => {
console.log('Listening on port 3000');
});
```
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.