Skip to content

Commit 6f6b1e9

Browse files
committed
Make getLength work with file streams
1 parent 1707ebb commit 6f6b1e9

3 files changed

Lines changed: 81 additions & 4 deletions

File tree

lib/form_data.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
var CombinedStream = require('combined-stream');
22
var util = require('util');
33
var path = require('path');
4+
var fs = require('fs');
45
var mime = require('mime');
6+
var async = require('async');
57

68
module.exports = FormData;
79
function FormData() {
810
this._overheadLength = 0;
911
this._valueLength = 0;
12+
this._lengthRetrievers = [];
1013

1114
CombinedStream.call(this);
1215
}
@@ -39,6 +42,21 @@ FormData.prototype._trackLength = function(header, value) {
3942
this._overheadLength +=
4043
Buffer.byteLength(header) +
4144
+ FormData.LINE_BREAK.length;
45+
46+
if (!value || !value.path) {
47+
return;
48+
}
49+
50+
this._lengthRetrievers.push(function(next) {
51+
fs.stat(value.path, function(err, stat) {
52+
if (err) {
53+
next(err);
54+
return;
55+
}
56+
57+
next(null, stat.size);
58+
});
59+
});
4260
};
4361

4462
FormData.prototype._multiPartHeader = function(field, value) {
@@ -112,5 +130,21 @@ FormData.prototype.getLength = function(cb) {
112130
knownLength += this._lastBoundary().length;
113131
}
114132

115-
process.nextTick(cb.bind(this, null, knownLength));
133+
if (!this._lengthRetrievers.length) {
134+
process.nextTick(cb.bind(this, null, knownLength));
135+
return;
136+
}
137+
138+
async.parallel(this._lengthRetrievers, function(err, values) {
139+
if (err) {
140+
cb(err);
141+
return;
142+
}
143+
144+
values.forEach(function(length) {
145+
knownLength += length;
146+
});
147+
148+
cb(null, knownLength);
149+
});
116150
};

test/fixture/bacon.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Bacon is delicious.

test/integration/test-form-get-length.js

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ var common = require('../common');
22
var assert = common.assert;
33
var FormData = require(common.dir.lib + '/form_data');
44
var fake = require('fake').create();
5+
var fs = require('fs');
56

67
(function testEmptyForm() {
78
var form = new FormData();
89
var callback = fake.callback(arguments.callee.name + '-getLength');
9-
var calls = fake.expect(callback, [null, 0]).calls;
10+
var calls = fake.expectAnytime(callback, [null, 0]).calls;
1011

1112
form.getLength(callback);
1213

@@ -27,7 +28,7 @@ var fake = require('fake').create();
2728
Buffer.byteLength(VALUE) +
2829
form._lastBoundary().length;
2930

30-
fake.expect(callback, [null, expectedLength]);
31+
fake.expectAnytime(callback, [null, expectedLength]);
3132
form.getLength(callback);
3233
})();
3334

@@ -44,7 +45,48 @@ var fake = require('fake').create();
4445
VALUE.length +
4546
form._lastBoundary().length;
4647

47-
fake.expect(callback, [null, expectedLength]);
48+
fake.expectAnytime(callback, [null, expectedLength]);
49+
form.getLength(callback);
50+
})();
51+
52+
53+
(function testStringFileBufferFile() {
54+
var fields = [
55+
{
56+
name: 'my_field',
57+
value: 'Test 123',
58+
},
59+
{
60+
name: 'my_image',
61+
value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg'),
62+
},
63+
{
64+
name: 'my_buffer',
65+
value: new Buffer('123'),
66+
},
67+
{
68+
name: 'my_txt',
69+
value: fs.createReadStream(common.dir.fixture + '/bacon.txt'),
70+
},
71+
];
72+
73+
var form = new FormData();
74+
var expectedLength = 0;
75+
76+
fields.forEach(function(field) {
77+
form.append(field.name, field.value);
78+
if (field.value.path) {
79+
var stat = fs.statSync(field.value.path);
80+
expectedLength += stat.size;
81+
} else {
82+
expectedLength += field.value.length;
83+
}
84+
});
85+
86+
expectedLength += form._overheadLength + form._lastBoundary().length;
87+
88+
var callback = fake.callback(arguments.callee.name + '-getLength');
89+
fake.expectAnytime(callback, [null, expectedLength]);
4890
form.getLength(callback);
4991
})();
5092

0 commit comments

Comments
 (0)