Skip to content

Commit de3502f

Browse files
committed
Added custom request params to form.submit(). Made tests more stable.
1 parent 7e98fb9 commit de3502f

4 files changed

Lines changed: 189 additions & 21 deletions

File tree

lib/form_data.js

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ FormData.prototype.append = function(field, value, options) {
4141

4242
FormData.prototype._trackLength = function(header, value, options) {
4343
var valueLength = 0;
44-
44+
4545
// used w/ trackLengthSync(), when length is known.
4646
// e.g. for streaming directly from a remote server,
4747
// w/ a known file a size, and not wanting to wait for
@@ -232,21 +232,37 @@ FormData.prototype.getLength = function(cb) {
232232
});
233233
};
234234

235-
FormData.prototype.submit = function(url, cb) {
235+
FormData.prototype.submit = function(params, cb) {
236236
this.getLength(function(err, length) {
237+
237238
var request
238-
, parsedUrl = parseUrl(url)
239-
, options = {
240-
method: 'post',
241-
port: parsedUrl.port || 80,
242-
path: parsedUrl.pathname,
243-
headers: this.getHeaders({'Content-Length': length}),
244-
host: parsedUrl.hostname
245-
};
246-
247-
if (parsedUrl.protocol == 'https:') {
239+
, options
240+
, defaults = {
241+
method : 'post',
242+
port : 80,
243+
headers: this.getHeaders({'Content-Length': length})
244+
};
245+
246+
// parse provided url if it's string
247+
// or treat it as options object
248+
if (typeof params == 'string') {
249+
params = parseUrl(params);
250+
251+
options = populate({
252+
port: params.port,
253+
path: params.pathname,
254+
host: params.hostname
255+
}, defaults);
256+
}
257+
else // use custom params
258+
{
259+
options = populate(params, defaults);
260+
}
261+
262+
// https if specified, fallback to http in any other case
263+
if (params.protocol == 'https:') {
248264
// override default port
249-
if (!parsedUrl.port) options.port = 443;
265+
if (!params.port) options.port = 443;
250266
request = https.request(options);
251267
} else {
252268
request = http.request(options);
@@ -261,3 +277,15 @@ FormData.prototype.submit = function(url, cb) {
261277
return request;
262278
}.bind(this));
263279
};
280+
281+
/*
282+
* Santa's little helpers
283+
*/
284+
285+
// populates missing values
286+
function populate(dst, src) {
287+
for (var prop in src) {
288+
if (!dst[prop]) dst[prop] = src[prop];
289+
}
290+
return dst;
291+
}

test/integration/test-pipe.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@ var IncomingForm = require('formidable').IncomingForm;
1010

1111
var remoteFile = 'http://nodejs.org/images/logo.png';
1212

13+
// wrap non simple values into function
14+
// just to deal with ReadStream "autostart"
15+
// Can't wait for 0.10
1316
var FIELDS = [
1417
{name: 'my_field', value: 'my_value'},
15-
{name: 'my_buffer', value: new Buffer([1, 2, 3])},
16-
{name: 'my_file', value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg')},
17-
{name: 'remote_file', value: request(remoteFile) }
18+
{name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} },
19+
{name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} },
20+
{name: 'remote_file', value: function(){ return request(remoteFile)} }
1821
];
1922

2023
var server = http.createServer(function(req, res) {
2124

22-
// formidable is broken so let's do it manual way
25+
// formidable is fixed on github
26+
// but still 7 month old in npm
2327
//
2428
// var form = new IncomingForm();
2529
// form.uploadDir = common.dir.tmp;
@@ -66,6 +70,7 @@ var server = http.createServer(function(req, res) {
6670
var field = FIELDS.shift();
6771
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
6872
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
73+
6974
// check for unicycle.jpg traces
7075
assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 );
7176
assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 );
@@ -89,6 +94,10 @@ var server = http.createServer(function(req, res) {
8994
server.listen(common.port, function() {
9095
var form = new FormData();
9196
FIELDS.forEach(function(field) {
97+
// important to append ReadStreams within the same tick
98+
if ((typeof field.value == 'function')) {
99+
field.value = field.value();
100+
}
92101
form.append(field.name, field.value);
93102
});
94103

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
var common = require('../common');
2+
var assert = common.assert;
3+
var http = require('http');
4+
var path = require('path');
5+
var mime = require('mime');
6+
var request = require('request');
7+
var fs = require('fs');
8+
var FormData = require(common.dir.lib + '/form_data');
9+
var IncomingForm = require('formidable').IncomingForm;
10+
11+
var remoteFile = 'http://nodejs.org/images/logo.png';
12+
13+
// wrap non simple values into function
14+
// just to deal with ReadStream "autostart"
15+
// Can't wait for 0.10
16+
var FIELDS = [
17+
{name: 'my_field', value: 'my_value'},
18+
{name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} },
19+
{name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} },
20+
{name: 'remote_file', value: function(){ return request(remoteFile)} }
21+
];
22+
23+
var server = http.createServer(function(req, res) {
24+
25+
// formidable is fixed on github
26+
// but still 7 month old in npm
27+
//
28+
// var form = new IncomingForm();
29+
// form.uploadDir = common.dir.tmp;
30+
// form.parse(req);
31+
// form
32+
// .on('field', function(name, value) {
33+
// var field = FIELDS.shift();
34+
// assert.strictEqual(name, field.name);
35+
// assert.strictEqual(value, field.value+'');
36+
// })
37+
// .on('file', function(name, file) {
38+
// var field = FIELDS.shift();
39+
// assert.strictEqual(name, field.name);
40+
// assert.strictEqual(file.name, path.basename(field.value.path));
41+
// // mime.lookup file.NAME == 'my_file' ?
42+
// assert.strictEqual(file.type, mime.lookup(file.name));
43+
// })
44+
// .on('end', function() {
45+
// res.writeHead(200);
46+
// res.end('done');
47+
// });
48+
49+
// temp workaround
50+
var data = '';
51+
req.setEncoding('utf8');
52+
req.on('data', function(d) {
53+
data += d;
54+
});
55+
req.on('end', function() {
56+
// check for the fields' traces
57+
58+
// 1st field : my_field
59+
var field = FIELDS.shift();
60+
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
61+
assert.ok( data.indexOf(field.value) != -1 );
62+
63+
// 2nd field : my_buffer
64+
var field = FIELDS.shift();
65+
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
66+
assert.ok( data.indexOf(field.value) != -1 );
67+
68+
// 3rd field : my_file
69+
var field = FIELDS.shift();
70+
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
71+
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
72+
// check for unicycle.jpg traces
73+
assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 );
74+
assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 );
75+
76+
// 4th field : remote_file
77+
var field = FIELDS.shift();
78+
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
79+
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
80+
// check for http://nodejs.org/images/logo.png traces
81+
assert.ok( data.indexOf('ImageReady') != -1 );
82+
assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
83+
84+
res.writeHead(200);
85+
res.end('done');
86+
87+
});
88+
89+
});
90+
91+
server.listen(common.port, function() {
92+
93+
var form = new FormData();
94+
95+
FIELDS.forEach(function(field) {
96+
// important to append ReadStreams within the same tick
97+
if ((typeof field.value == 'function')) {
98+
field.value = field.value();
99+
}
100+
form.append(field.name, field.value);
101+
});
102+
103+
// custom params object passed to submit
104+
form.submit({
105+
port: common.port,
106+
path: '/'
107+
}, function(err, res) {
108+
109+
if (err) {
110+
throw err;
111+
}
112+
113+
assert.strictEqual(res.statusCode, 200);
114+
server.close();
115+
});
116+
117+
});
118+
119+
process.on('exit', function() {
120+
assert.strictEqual(FIELDS.length, 0);
121+
});

test/integration/test-submit.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@ var IncomingForm = require('formidable').IncomingForm;
1010

1111
var remoteFile = 'http://nodejs.org/images/logo.png';
1212

13+
// wrap non simple values into function
14+
// just to deal with ReadStream "autostart"
15+
// Can't wait for 0.10
1316
var FIELDS = [
1417
{name: 'my_field', value: 'my_value'},
15-
{name: 'my_buffer', value: new Buffer([1, 2, 3])},
16-
{name: 'my_file', value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg') },
17-
{name: 'remote_file', value: request(remoteFile) }
18+
{name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} },
19+
{name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} },
20+
{name: 'remote_file', value: function(){ return request(remoteFile)} }
1821
];
1922

2023
var server = http.createServer(function(req, res) {
2124

22-
// formidable is broken so let's do it manual way
25+
// formidable is fixed on github
26+
// but still 7 month old in npm
2327
//
2428
// var form = new IncomingForm();
2529
// form.uploadDir = common.dir.tmp;
@@ -85,8 +89,14 @@ var server = http.createServer(function(req, res) {
8589
});
8690

8791
server.listen(common.port, function() {
92+
8893
var form = new FormData();
94+
8995
FIELDS.forEach(function(field) {
96+
// important to append ReadStreams within the same tick
97+
if ((typeof field.value == 'function')) {
98+
field.value = field.value();
99+
}
90100
form.append(field.name, field.value);
91101
});
92102

0 commit comments

Comments
 (0)