1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
'use strict';
const assert = require('assert');
const { randomFillSync } = require('crypto');
const { inspect } = require('util');
const busboy = require('..');
const { mustCall } = require('./common.js');
const BOUNDARY = 'u2KxIV5yF1y+xUspOQCCZopaVgeV6Jxihv35XQJmuTx8X3sh';
function formDataSection(key, value) {
return Buffer.from(
`\r\n--${BOUNDARY}`
+ `\r\nContent-Disposition: form-data; name="${key}"`
+ `\r\n\r\n${value}`
);
}
function formDataFile(key, filename, contentType) {
const buf = Buffer.allocUnsafe(100000);
return Buffer.concat([
Buffer.from(`\r\n--${BOUNDARY}\r\n`),
Buffer.from(`Content-Disposition: form-data; name="${key}"`
+ `; filename="${filename}"\r\n`),
Buffer.from(`Content-Type: ${contentType}\r\n\r\n`),
randomFillSync(buf)
]);
}
const reqChunks = [
Buffer.concat([
formDataFile('file', 'file.bin', 'application/octet-stream'),
formDataSection('foo', 'foo value'),
]),
formDataSection('bar', 'bar value'),
Buffer.from(`\r\n--${BOUNDARY}--\r\n`)
];
const bb = busboy({
headers: {
'content-type': `multipart/form-data; boundary=${BOUNDARY}`
}
});
const expected = [
{ type: 'file',
name: 'file',
info: {
filename: 'file.bin',
encoding: '7bit',
mimeType: 'application/octet-stream',
},
},
{ type: 'field',
name: 'foo',
val: 'foo value',
info: {
nameTruncated: false,
valueTruncated: false,
encoding: '7bit',
mimeType: 'text/plain',
},
},
{ type: 'field',
name: 'bar',
val: 'bar value',
info: {
nameTruncated: false,
valueTruncated: false,
encoding: '7bit',
mimeType: 'text/plain',
},
},
];
const results = [];
bb.on('field', (name, val, info) => {
results.push({ type: 'field', name, val, info });
});
bb.on('file', (name, stream, info) => {
results.push({ type: 'file', name, info });
// Simulate a pipe where the destination is pausing (perhaps due to waiting
// for file system write to finish)
setTimeout(() => {
stream.resume();
}, 10);
});
bb.on('close', mustCall(() => {
assert.deepStrictEqual(
results,
expected,
'Results mismatch.\n'
+ `Parsed: ${inspect(results)}\n`
+ `Expected: ${inspect(expected)}`
);
}));
for (const chunk of reqChunks)
bb.write(chunk);
bb.end();
|