nodejs with express server, leapmotion for movement control, and threejs for 3d render

This commit is contained in:
idoctnef
2016-05-30 18:14:08 +02:00
parent e2aeac1bae
commit 52b63ee33a
893 changed files with 127726 additions and 0 deletions

18
node_modules/formidable/test/common.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
var path = require('path');
var root = path.join(__dirname, '../');
exports.dir = {
root : root,
lib : root + '/lib',
fixture : root + '/test/fixture',
tmp : root + '/test/tmp',
};
exports.port = 13532;
exports.formidable = require('..');
exports.assert = require('assert');
exports.require = function(lib) {
return require(exports.dir.lib + '/' + lib);
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

BIN
node_modules/formidable/test/fixture/file/blank.gif generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B

View File

@@ -0,0 +1 @@
I am a text file with a funky name!

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 B

1
node_modules/formidable/test/fixture/file/plain.txt generated vendored Normal file
View File

@@ -0,0 +1 @@
I am a plain text file

View File

@@ -0,0 +1,3 @@
* Opera does not allow submitting this file, it shows a warning to the
user that the file could not be found instead. Tested in 9.8, 11.51 on OSX.
Reported to Opera on 08.09.2011 (tracking email DSK-346009@bugs.opera.com).

24
node_modules/formidable/test/fixture/js/encoding.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
module.exports['menu_seperator.png.http'] = [
{type: 'file', name: 'image', filename: 'menu_separator.png', fixture: 'menu_separator.png',
sha1: 'c845ca3ea794be298f2a1b79769b71939eaf4e54'}
];
module.exports['beta-sticker-1.png.http'] = [
{type: 'file', name: 'sticker', filename: 'beta-sticker-1.png', fixture: 'beta-sticker-1.png',
sha1: '6abbcffd12b4ada5a6a084fe9e4584f846331bc4'}
];
module.exports['blank.gif.http'] = [
{type: 'file', name: 'file', filename: 'blank.gif', fixture: 'blank.gif',
sha1: 'a1fdee122b95748d81cee426d717c05b5174fe96'}
];
module.exports['binaryfile.tar.gz.http'] = [
{type: 'file', name: 'file', filename: 'binaryfile.tar.gz', fixture: 'binaryfile.tar.gz',
sha1: 'cfabe13b348e5e69287d677860880c52a69d2155'}
];
module.exports['plain.txt.http'] = [
{type: 'file', name: 'file', filename: 'plain.txt', fixture: 'plain.txt',
sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'}
];

6
node_modules/formidable/test/fixture/js/misc.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
'empty.http': [],
'empty-urlencoded.http': [],
'empty-multipart.http': [],
'minimal.http': [],
};

View File

@@ -0,0 +1,9 @@
module.exports['generic.http'] = [
{type: 'file', name: 'upload', filename: '', fixture: 'plain.txt',
sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'},
];
module.exports['filename-name.http'] = [
{type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt',
sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'},
];

9
node_modules/formidable/test/fixture/js/preamble.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
module.exports['crlf.http'] = [
{type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt',
sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'},
];
module.exports['preamble.http'] = [
{type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt',
sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'},
];

View File

@@ -0,0 +1,21 @@
var properFilename = 'funkyfilename.txt';
function expect(filename) {
return [
{type: 'field', name: 'title', value: 'Weird filename'},
{type: 'file', name: 'upload', filename: filename, fixture: properFilename},
];
};
var webkit = " ? % * | \" < > . ? ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt";
var ffOrIe = " ? % * | \" < > . ☃ ; ' @ # $ ^ & ( ) - _ = + { } [ ] ` ~.txt";
module.exports = {
'osx-chrome-13.http' : expect(webkit),
'osx-firefox-3.6.http' : expect(ffOrIe),
'osx-safari-5.http' : expect(webkit),
'xp-chrome-12.http' : expect(webkit),
'xp-ie-7.http' : expect(ffOrIe),
'xp-ie-8.http' : expect(ffOrIe),
'xp-safari-5.http' : expect(webkit),
};

View File

@@ -0,0 +1,8 @@
module.exports['missing-hyphens1.http'] = [
{type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt',
sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'},
];
module.exports['missing-hyphens2.http'] = [
{type: 'file', name: 'upload', filename: 'plain.txt', fixture: 'plain.txt',
sha1: 'b31d07bac24ac32734de88b3687dddb10e976872'},
];

72
node_modules/formidable/test/fixture/multipart.js generated vendored Normal file
View File

@@ -0,0 +1,72 @@
exports['rfc1867'] =
{ boundary: 'AaB03x',
raw:
'--AaB03x\r\n'+
'content-disposition: form-data; name="field1"\r\n'+
'\r\n'+
'Joe Blow\r\nalmost tricked you!\r\n'+
'--AaB03x\r\n'+
'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+
'Content-Type: text/plain\r\n'+
'\r\n'+
'... contents of file1.txt ...\r\r\n'+
'--AaB03x--\r\n',
parts:
[ { headers: {
'content-disposition': 'form-data; name="field1"',
},
data: 'Joe Blow\r\nalmost tricked you!',
},
{ headers: {
'content-disposition': 'form-data; name="pics"; filename="file1.txt"',
'Content-Type': 'text/plain',
},
data: '... contents of file1.txt ...\r',
}
]
};
exports['noTrailing\r\n'] =
{ boundary: 'AaB03x',
raw:
'--AaB03x\r\n'+
'content-disposition: form-data; name="field1"\r\n'+
'\r\n'+
'Joe Blow\r\nalmost tricked you!\r\n'+
'--AaB03x\r\n'+
'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+
'Content-Type: text/plain\r\n'+
'\r\n'+
'... contents of file1.txt ...\r\r\n'+
'--AaB03x--',
parts:
[ { headers: {
'content-disposition': 'form-data; name="field1"',
},
data: 'Joe Blow\r\nalmost tricked you!',
},
{ headers: {
'content-disposition': 'form-data; name="pics"; filename="file1.txt"',
'Content-Type': 'text/plain',
},
data: '... contents of file1.txt ...\r',
}
]
};
exports['emptyHeader'] =
{ boundary: 'AaB03x',
raw:
'--AaB03x\r\n'+
'content-disposition: form-data; name="field1"\r\n'+
': foo\r\n'+
'\r\n'+
'Joe Blow\r\nalmost tricked you!\r\n'+
'--AaB03x\r\n'+
'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n'+
'Content-Type: text/plain\r\n'+
'\r\n'+
'... contents of file1.txt ...\r\r\n'+
'--AaB03x--\r\n',
expectError: true,
};

View File

@@ -0,0 +1,96 @@
var hashish = require('hashish');
var fs = require('fs');
var findit = require('findit');
var path = require('path');
var http = require('http');
var net = require('net');
var assert = require('assert');
var common = require('../common');
var formidable = common.formidable;
var server = http.createServer();
server.listen(common.port, findFixtures);
function findFixtures() {
var fixtures = [];
findit
.sync(common.dir.fixture + '/js')
.forEach(function(jsPath) {
if (!/\.js$/.test(jsPath)) return;
var group = path.basename(jsPath, '.js');
hashish.forEach(require(jsPath), function(fixture, name) {
fixtures.push({
name : group + '/' + name,
fixture : fixture,
});
});
});
testNext(fixtures);
}
function testNext(fixtures) {
var fixture = fixtures.shift();
if (!fixture) return server.close();
var name = fixture.name;
var fixture = fixture.fixture;
uploadFixture(name, function(err, parts) {
if (err) throw err;
fixture.forEach(function(expectedPart, i) {
var parsedPart = parts[i];
assert.equal(parsedPart.type, expectedPart.type);
assert.equal(parsedPart.name, expectedPart.name);
if (parsedPart.type === 'file') {
var file = parsedPart.value;
assert.equal(file.name, expectedPart.filename);
if(expectedPart.sha1) assert.equal(file.hash, expectedPart.sha1);
}
});
testNext(fixtures);
});
};
function uploadFixture(name, cb) {
server.once('request', function(req, res) {
var form = new formidable.IncomingForm();
form.uploadDir = common.dir.tmp;
form.hash = "sha1";
form.parse(req);
function callback() {
var realCallback = cb;
cb = function() {};
realCallback.apply(null, arguments);
}
var parts = [];
form
.on('error', callback)
.on('fileBegin', function(name, value) {
parts.push({type: 'file', name: name, value: value});
})
.on('field', function(name, value) {
parts.push({type: 'field', name: name, value: value});
})
.on('end', function() {
res.end('OK');
callback(null, parts);
});
});
var socket = net.createConnection(common.port);
var file = fs.createReadStream(common.dir.fixture + '/http/' + name);
file.pipe(socket, {end: false});
socket.on('data', function () {
socket.end();
});
}

38
node_modules/formidable/test/integration/test-json.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
var common = require('../common');
var formidable = common.formidable;
var http = require('http');
var assert = require('assert');
var testData = {
numbers: [1, 2, 3, 4, 5],
nested: { key: 'value' }
};
var server = http.createServer(function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
assert.deepEqual(fields, testData);
res.end();
server.close();
});
});
var port = common.port;
server.listen(port, function(err){
assert.equal(err, null);
var request = http.request({
port: port,
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
request.write(JSON.stringify(testData));
request.end();
});

View File

@@ -0,0 +1,45 @@
var common = require('../common');
var formidable = common.formidable;
var http = require('http');
var fs = require('fs');
var path = require('path');
var hashish = require('hashish');
var assert = require('assert');
var testFilePath = path.join(__dirname, '../fixture/file/binaryfile.tar.gz');
var server = http.createServer(function(req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
assert.equal(hashish(files).length, 1);
var file = files.file;
assert.equal(file.size, 301);
var uploaded = fs.readFileSync(file.path);
var original = fs.readFileSync(testFilePath);
assert.deepEqual(uploaded, original);
res.end();
server.close();
});
});
var port = common.port;
server.listen(port, function(err){
assert.equal(err, null);
var request = http.request({
port: port,
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream'
}
});
fs.createReadStream(testFilePath).pipe(request);
});

24
node_modules/formidable/test/legacy/common.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
var path = require('path'),
fs = require('fs');
try {
global.Gently = require('gently');
} catch (e) {
throw new Error('this test suite requires node-gently');
}
exports.lib = path.join(__dirname, '../../lib');
global.GENTLY = new Gently();
global.assert = require('assert');
global.TEST_PORT = 13532;
global.TEST_FIXTURES = path.join(__dirname, '../fixture');
global.TEST_TMP = path.join(__dirname, '../tmp');
// Stupid new feature in node that complains about gently attaching too many
// listeners to process 'exit'. This is a workaround until I can think of a
// better way to deal with this.
if (process.setMaxListeners) {
process.setMaxListeners(10000);
}

View File

@@ -0,0 +1,80 @@
var common = require('../common');
var CHUNK_LENGTH = 10,
multipartParser = require(common.lib + '/multipart_parser'),
MultipartParser = multipartParser.MultipartParser,
parser = new MultipartParser(),
fixtures = require(TEST_FIXTURES + '/multipart'),
Buffer = require('buffer').Buffer;
Object.keys(fixtures).forEach(function(name) {
var fixture = fixtures[name],
buffer = new Buffer(Buffer.byteLength(fixture.raw, 'binary')),
offset = 0,
chunk,
nparsed,
parts = [],
part = null,
headerField,
headerValue,
endCalled = '';
parser.initWithBoundary(fixture.boundary);
parser.onPartBegin = function() {
part = {headers: {}, data: ''};
parts.push(part);
headerField = '';
headerValue = '';
};
parser.onHeaderField = function(b, start, end) {
headerField += b.toString('ascii', start, end);
};
parser.onHeaderValue = function(b, start, end) {
headerValue += b.toString('ascii', start, end);
}
parser.onHeaderEnd = function() {
part.headers[headerField] = headerValue;
headerField = '';
headerValue = '';
};
parser.onPartData = function(b, start, end) {
var str = b.toString('ascii', start, end);
part.data += b.slice(start, end);
}
parser.onEnd = function() {
endCalled = true;
}
buffer.write(fixture.raw, 'binary', 0);
while (offset < buffer.length) {
if (offset + CHUNK_LENGTH < buffer.length) {
chunk = buffer.slice(offset, offset+CHUNK_LENGTH);
} else {
chunk = buffer.slice(offset, buffer.length);
}
offset = offset + CHUNK_LENGTH;
nparsed = parser.write(chunk);
if (nparsed != chunk.length) {
if (fixture.expectError) {
return;
}
puts('-- ERROR --');
p(chunk.toString('ascii'));
throw new Error(chunk.length+' bytes written, but only '+nparsed+' bytes parsed!');
}
}
if (fixture.expectError) {
throw new Error('expected parse error did not happen');
}
assert.ok(endCalled);
assert.deepEqual(parts, fixture.parts);
});

104
node_modules/formidable/test/legacy/simple/test-file.js generated vendored Normal file
View File

@@ -0,0 +1,104 @@
var common = require('../common');
var WriteStreamStub = GENTLY.stub('fs', 'WriteStream');
var File = require(common.lib + '/file'),
EventEmitter = require('events').EventEmitter,
file,
gently;
function test(test) {
gently = new Gently();
file = new File();
test();
gently.verify(test.name);
}
test(function constructor() {
assert.ok(file instanceof EventEmitter);
assert.strictEqual(file.size, 0);
assert.strictEqual(file.path, null);
assert.strictEqual(file.name, null);
assert.strictEqual(file.type, null);
assert.strictEqual(file.lastModifiedDate, null);
assert.strictEqual(file._writeStream, null);
(function testSetProperties() {
var file2 = new File({foo: 'bar'});
assert.equal(file2.foo, 'bar');
})();
});
test(function open() {
var WRITE_STREAM;
file.path = '/foo';
gently.expect(WriteStreamStub, 'new', function (path) {
WRITE_STREAM = this;
assert.strictEqual(path, file.path);
});
file.open();
assert.strictEqual(file._writeStream, WRITE_STREAM);
});
test(function write() {
var BUFFER = {length: 10},
CB_STUB,
CB = function() {
CB_STUB.apply(this, arguments);
};
file._writeStream = {};
gently.expect(file._writeStream, 'write', function (buffer, cb) {
assert.strictEqual(buffer, BUFFER);
gently.expect(file, 'emit', function (event, bytesWritten) {
assert.ok(file.lastModifiedDate instanceof Date);
assert.equal(event, 'progress');
assert.equal(bytesWritten, file.size);
});
CB_STUB = gently.expect(function writeCb() {
assert.equal(file.size, 10);
});
cb();
gently.expect(file, 'emit', function (event, bytesWritten) {
assert.equal(event, 'progress');
assert.equal(bytesWritten, file.size);
});
CB_STUB = gently.expect(function writeCb() {
assert.equal(file.size, 20);
});
cb();
});
file.write(BUFFER, CB);
});
test(function end() {
var CB_STUB,
CB = function() {
CB_STUB.apply(this, arguments);
};
file._writeStream = {};
gently.expect(file._writeStream, 'end', function (cb) {
gently.expect(file, 'emit', function (event) {
assert.equal(event, 'end');
});
CB_STUB = gently.expect(function endCb() {
});
cb();
});
file.end(CB);
});

View File

@@ -0,0 +1,756 @@
var common = require('../common');
var MultipartParserStub = GENTLY.stub('./multipart_parser', 'MultipartParser'),
QuerystringParserStub = GENTLY.stub('./querystring_parser', 'QuerystringParser'),
EventEmitterStub = GENTLY.stub('events', 'EventEmitter'),
StreamStub = GENTLY.stub('stream', 'Stream'),
FileStub = GENTLY.stub('./file');
var formidable = require(common.lib + '/index'),
IncomingForm = formidable.IncomingForm,
events = require('events'),
fs = require('fs'),
path = require('path'),
Buffer = require('buffer').Buffer,
fixtures = require(TEST_FIXTURES + '/multipart'),
form,
gently;
function test(test) {
gently = new Gently();
gently.expect(EventEmitterStub, 'call');
form = new IncomingForm();
test();
gently.verify(test.name);
}
test(function constructor() {
assert.strictEqual(form.error, null);
assert.strictEqual(form.ended, false);
assert.strictEqual(form.type, null);
assert.strictEqual(form.headers, null);
assert.strictEqual(form.keepExtensions, false);
// Can't assume dir === '/tmp' for portability
// assert.strictEqual(form.uploadDir, '/tmp');
// Make sure it is a directory instead
assert.doesNotThrow(function () {
assert(fs.statSync(form.uploadDir).isDirectory());
});
assert.strictEqual(form.encoding, 'utf-8');
assert.strictEqual(form.bytesReceived, null);
assert.strictEqual(form.bytesExpected, null);
assert.strictEqual(form.maxFieldsSize, 2 * 1024 * 1024);
assert.strictEqual(form._parser, null);
assert.strictEqual(form._flushing, 0);
assert.strictEqual(form._fieldsSize, 0);
assert.ok(form instanceof EventEmitterStub);
assert.equal(form.constructor.name, 'IncomingForm');
(function testSimpleConstructor() {
gently.expect(EventEmitterStub, 'call');
var form = IncomingForm();
assert.ok(form instanceof IncomingForm);
})();
(function testSimpleConstructorShortcut() {
gently.expect(EventEmitterStub, 'call');
var form = formidable();
assert.ok(form instanceof IncomingForm);
})();
});
test(function parse() {
var REQ = {headers: {}}
, emit = {};
gently.expect(form, 'writeHeaders', function(headers) {
assert.strictEqual(headers, REQ.headers);
});
var EVENTS = ['error', 'aborted', 'data', 'end'];
gently.expect(REQ, 'on', EVENTS.length, function(event, fn) {
assert.equal(event, EVENTS.shift());
emit[event] = fn;
return this;
});
form.parse(REQ);
(function testPause() {
gently.expect(REQ, 'pause');
assert.strictEqual(form.pause(), true);
})();
(function testPauseCriticalException() {
form.ended = false;
var ERR = new Error('dasdsa');
gently.expect(REQ, 'pause', function() {
throw ERR;
});
gently.expect(form, '_error', function(err) {
assert.strictEqual(err, ERR);
});
assert.strictEqual(form.pause(), false);
})();
(function testPauseHarmlessException() {
form.ended = true;
var ERR = new Error('dasdsa');
gently.expect(REQ, 'pause', function() {
throw ERR;
});
assert.strictEqual(form.pause(), false);
})();
(function testResume() {
gently.expect(REQ, 'resume');
assert.strictEqual(form.resume(), true);
})();
(function testResumeCriticalException() {
form.ended = false;
var ERR = new Error('dasdsa');
gently.expect(REQ, 'resume', function() {
throw ERR;
});
gently.expect(form, '_error', function(err) {
assert.strictEqual(err, ERR);
});
assert.strictEqual(form.resume(), false);
})();
(function testResumeHarmlessException() {
form.ended = true;
var ERR = new Error('dasdsa');
gently.expect(REQ, 'resume', function() {
throw ERR;
});
assert.strictEqual(form.resume(), false);
})();
(function testEmitError() {
var ERR = new Error('something bad happened');
gently.expect(form, '_error',function(err) {
assert.strictEqual(err, ERR);
});
emit.error(ERR);
})();
(function testEmitAborted() {
gently.expect(form, 'emit',function(event) {
assert.equal(event, 'aborted');
});
gently.expect(form, '_error');
emit.aborted();
})();
(function testEmitData() {
var BUFFER = [1, 2, 3];
gently.expect(form, 'write', function(buffer) {
assert.strictEqual(buffer, BUFFER);
});
emit.data(BUFFER);
})();
(function testEmitEnd() {
form._parser = {};
(function testWithError() {
var ERR = new Error('haha');
gently.expect(form._parser, 'end', function() {
return ERR;
});
gently.expect(form, '_error', function(err) {
assert.strictEqual(err, ERR);
});
emit.end();
})();
(function testWithoutError() {
gently.expect(form._parser, 'end');
emit.end();
})();
(function testAfterError() {
form.error = true;
emit.end();
})();
})();
(function testWithCallback() {
gently.expect(EventEmitterStub, 'call');
var form = new IncomingForm(),
REQ = {headers: {}},
parseCalled = 0;
gently.expect(form, 'on', 4, function(event, fn) {
if (event == 'field') {
fn('field1', 'foo');
fn('field1', 'bar');
fn('field2', 'nice');
}
if (event == 'file') {
fn('file1', '1');
fn('file1', '2');
fn('file2', '3');
}
if (event == 'end') {
fn();
}
return this;
});
gently.expect(form, 'writeHeaders');
gently.expect(REQ, 'on', 4, function() {
return this;
});
var parseCbOk = function (err, fields, files) {
assert.deepEqual(fields, {field1: 'bar', field2: 'nice'});
assert.deepEqual(files, {file1: '2', file2: '3'});
};
form.parse(REQ, parseCbOk);
var ERR = new Error('test');
gently.expect(form, 'on', 3, function(event, fn) {
if (event == 'field') {
fn('foo', 'bar');
}
if (event == 'error') {
fn(ERR);
gently.expect(form, 'on');
gently.expect(form, 'writeHeaders');
gently.expect(REQ, 'on', 4, function() {
return this;
});
}
return this;
});
form.parse(REQ, function parseCbErr(err, fields, files) {
assert.strictEqual(err, ERR);
assert.deepEqual(fields, {foo: 'bar'});
});
})();
(function testWriteOrder() {
gently.expect(EventEmitterStub, 'call');
var form = new IncomingForm();
var REQ = new events.EventEmitter();
var BUF = {};
var DATACB = null;
REQ.on('newListener', function(event, fn) {
if ('data' === event) fn(BUF);
});
gently.expect(form, 'writeHeaders');
gently.expect(form, 'write', function(buf) {
assert.strictEqual(buf, BUF);
});
form.parse(REQ);
})();
});
test(function pause() {
assert.strictEqual(form.pause(), false);
});
test(function resume() {
assert.strictEqual(form.resume(), false);
});
test(function writeHeaders() {
var HEADERS = {};
gently.expect(form, '_parseContentLength');
gently.expect(form, '_parseContentType');
form.writeHeaders(HEADERS);
assert.strictEqual(form.headers, HEADERS);
});
test(function write() {
var parser = {},
BUFFER = [1, 2, 3];
form._parser = parser;
form.bytesExpected = 523423;
(function testBasic() {
gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
assert.equal(event, 'progress');
assert.equal(bytesReceived, BUFFER.length);
assert.equal(bytesExpected, form.bytesExpected);
});
gently.expect(parser, 'write', function(buffer) {
assert.strictEqual(buffer, BUFFER);
return buffer.length;
});
assert.equal(form.write(BUFFER), BUFFER.length);
assert.equal(form.bytesReceived, BUFFER.length);
})();
(function testParserError() {
gently.expect(form, 'emit');
gently.expect(parser, 'write', function(buffer) {
assert.strictEqual(buffer, BUFFER);
return buffer.length - 1;
});
gently.expect(form, '_error', function(err) {
assert.ok(err.message.match(/parser error/i));
});
assert.equal(form.write(BUFFER), BUFFER.length - 1);
assert.equal(form.bytesReceived, BUFFER.length + BUFFER.length);
})();
(function testUninitialized() {
delete form._parser;
gently.expect(form, '_error', function(err) {
assert.ok(err.message.match(/unintialized parser/i));
});
form.write(BUFFER);
})();
});
test(function parseContentType() {
var HEADERS = {};
form.headers = {'content-type': 'application/x-www-form-urlencoded'};
gently.expect(form, '_initUrlencoded');
form._parseContentType();
// accept anything that has 'urlencoded' in it
form.headers = {'content-type': 'broken-client/urlencoded-stupid'};
gently.expect(form, '_initUrlencoded');
form._parseContentType();
var BOUNDARY = '---------------------------57814261102167618332366269';
form.headers = {'content-type': 'multipart/form-data; boundary='+BOUNDARY};
gently.expect(form, '_initMultipart', function(boundary) {
assert.equal(boundary, BOUNDARY);
});
form._parseContentType();
(function testQuotedBoundary() {
form.headers = {'content-type': 'multipart/form-data; boundary="' + BOUNDARY + '"'};
gently.expect(form, '_initMultipart', function(boundary) {
assert.equal(boundary, BOUNDARY);
});
form._parseContentType();
})();
(function testNoBoundary() {
form.headers = {'content-type': 'multipart/form-data'};
gently.expect(form, '_error', function(err) {
assert.ok(err.message.match(/no multipart boundary/i));
});
form._parseContentType();
})();
(function testNoContentType() {
form.headers = {};
gently.expect(form, '_error', function(err) {
assert.ok(err.message.match(/no content-type/i));
});
form._parseContentType();
})();
(function testUnknownContentType() {
form.headers = {'content-type': 'invalid'};
gently.expect(form, '_error', function(err) {
assert.ok(err.message.match(/unknown content-type/i));
});
form._parseContentType();
})();
});
test(function parseContentLength() {
var HEADERS = {};
form.headers = {};
gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
assert.equal(event, 'progress');
assert.equal(bytesReceived, 0);
assert.equal(bytesExpected, 0);
});
form._parseContentLength();
form.headers['content-length'] = '8';
gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
assert.equal(event, 'progress');
assert.equal(bytesReceived, 0);
assert.equal(bytesExpected, 8);
});
form._parseContentLength();
assert.strictEqual(form.bytesReceived, 0);
assert.strictEqual(form.bytesExpected, 8);
// JS can be evil, lets make sure we are not
form.headers['content-length'] = '08';
gently.expect(form, 'emit', function(event, bytesReceived, bytesExpected) {
assert.equal(event, 'progress');
assert.equal(bytesReceived, 0);
assert.equal(bytesExpected, 8);
});
form._parseContentLength();
assert.strictEqual(form.bytesExpected, 8);
});
test(function _initMultipart() {
var BOUNDARY = '123',
PARSER;
gently.expect(MultipartParserStub, 'new', function() {
PARSER = this;
});
gently.expect(MultipartParserStub.prototype, 'initWithBoundary', function(boundary) {
assert.equal(boundary, BOUNDARY);
});
form._initMultipart(BOUNDARY);
assert.equal(form.type, 'multipart');
assert.strictEqual(form._parser, PARSER);
(function testRegularField() {
var PART;
gently.expect(StreamStub, 'new', function() {
PART = this;
});
gently.expect(form, 'onPart', function(part) {
assert.strictEqual(part, PART);
assert.deepEqual
( part.headers
, { 'content-disposition': 'form-data; name="field1"'
, 'foo': 'bar'
}
);
assert.equal(part.name, 'field1');
var strings = ['hello', ' world'];
gently.expect(part, 'emit', 2, function(event, b) {
assert.equal(event, 'data');
assert.equal(b.toString(), strings.shift());
});
gently.expect(part, 'emit', function(event, b) {
assert.equal(event, 'end');
});
});
PARSER.onPartBegin();
PARSER.onHeaderField(new Buffer('content-disposition'), 0, 10);
PARSER.onHeaderField(new Buffer('content-disposition'), 10, 19);
PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 0, 14);
PARSER.onHeaderValue(new Buffer('form-data; name="field1"'), 14, 24);
PARSER.onHeaderEnd();
PARSER.onHeaderField(new Buffer('foo'), 0, 3);
PARSER.onHeaderValue(new Buffer('bar'), 0, 3);
PARSER.onHeaderEnd();
PARSER.onHeadersEnd();
PARSER.onPartData(new Buffer('hello world'), 0, 5);
PARSER.onPartData(new Buffer('hello world'), 5, 11);
PARSER.onPartEnd();
})();
(function testFileField() {
var PART;
gently.expect(StreamStub, 'new', function() {
PART = this;
});
gently.expect(form, 'onPart', function(part) {
assert.deepEqual
( part.headers
, { 'content-disposition': 'form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"'
, 'content-type': 'text/plain'
}
);
assert.equal(part.name, 'field2');
assert.equal(part.filename, 'Sun"et.jpg');
assert.equal(part.mime, 'text/plain');
gently.expect(part, 'emit', function(event, b) {
assert.equal(event, 'data');
assert.equal(b.toString(), '... contents of file1.txt ...');
});
gently.expect(part, 'emit', function(event, b) {
assert.equal(event, 'end');
});
});
PARSER.onPartBegin();
PARSER.onHeaderField(new Buffer('content-disposition'), 0, 19);
PARSER.onHeaderValue(new Buffer('form-data; name="field2"; filename="C:\\Documents and Settings\\IE\\Must\\Die\\Sun"et.jpg"'), 0, 85);
PARSER.onHeaderEnd();
PARSER.onHeaderField(new Buffer('Content-Type'), 0, 12);
PARSER.onHeaderValue(new Buffer('text/plain'), 0, 10);
PARSER.onHeaderEnd();
PARSER.onHeadersEnd();
PARSER.onPartData(new Buffer('... contents of file1.txt ...'), 0, 29);
PARSER.onPartEnd();
})();
(function testEnd() {
gently.expect(form, '_maybeEnd');
PARSER.onEnd();
assert.ok(form.ended);
})();
});
test(function _fileName() {
// TODO
return;
});
test(function _initUrlencoded() {
var PARSER;
gently.expect(QuerystringParserStub, 'new', function() {
PARSER = this;
});
form._initUrlencoded();
assert.equal(form.type, 'urlencoded');
assert.strictEqual(form._parser, PARSER);
(function testOnField() {
var KEY = 'KEY', VAL = 'VAL';
gently.expect(form, 'emit', function(field, key, val) {
assert.equal(field, 'field');
assert.equal(key, KEY);
assert.equal(val, VAL);
});
PARSER.onField(KEY, VAL);
})();
(function testOnEnd() {
gently.expect(form, '_maybeEnd');
PARSER.onEnd();
assert.equal(form.ended, true);
})();
});
test(function _error() {
var ERR = new Error('bla');
gently.expect(form, 'pause');
gently.expect(form, 'emit', function(event, err) {
assert.equal(event, 'error');
assert.strictEqual(err, ERR);
});
form._error(ERR);
assert.strictEqual(form.error, ERR);
// make sure _error only does its thing once
form._error(ERR);
});
test(function onPart() {
var PART = {};
gently.expect(form, 'handlePart', function(part) {
assert.strictEqual(part, PART);
});
form.onPart(PART);
});
test(function handlePart() {
(function testUtf8Field() {
var PART = new events.EventEmitter();
PART.name = 'my_field';
gently.expect(form, 'emit', function(event, field, value) {
assert.equal(event, 'field');
assert.equal(field, 'my_field');
assert.equal(value, 'hello world: €');
});
form.handlePart(PART);
PART.emit('data', new Buffer('hello'));
PART.emit('data', new Buffer(' world: '));
PART.emit('data', new Buffer([0xE2]));
PART.emit('data', new Buffer([0x82, 0xAC]));
PART.emit('end');
})();
(function testBinaryField() {
var PART = new events.EventEmitter();
PART.name = 'my_field2';
gently.expect(form, 'emit', function(event, field, value) {
assert.equal(event, 'field');
assert.equal(field, 'my_field2');
assert.equal(value, 'hello world: '+new Buffer([0xE2, 0x82, 0xAC]).toString('binary'));
});
form.encoding = 'binary';
form.handlePart(PART);
PART.emit('data', new Buffer('hello'));
PART.emit('data', new Buffer(' world: '));
PART.emit('data', new Buffer([0xE2]));
PART.emit('data', new Buffer([0x82, 0xAC]));
PART.emit('end');
})();
(function testFieldSize() {
form.maxFieldsSize = 8;
var PART = new events.EventEmitter();
PART.name = 'my_field';
gently.expect(form, '_error', function(err) {
assert.equal(err.message, 'maxFieldsSize exceeded, received 9 bytes of field data');
});
form.handlePart(PART);
form._fieldsSize = 1;
PART.emit('data', new Buffer(7));
PART.emit('data', new Buffer(1));
})();
(function testFilePart() {
var PART = new events.EventEmitter(),
FILE = new events.EventEmitter(),
PATH = '/foo/bar';
PART.name = 'my_file';
PART.filename = 'sweet.txt';
PART.mime = 'sweet.txt';
gently.expect(form, '_uploadPath', function(filename) {
assert.equal(filename, PART.filename);
return PATH;
});
gently.expect(FileStub, 'new', function(properties) {
assert.equal(properties.path, PATH);
assert.equal(properties.name, PART.filename);
assert.equal(properties.type, PART.mime);
FILE = this;
gently.expect(form, 'emit', function (event, field, file) {
assert.equal(event, 'fileBegin');
assert.strictEqual(field, PART.name);
assert.strictEqual(file, FILE);
});
gently.expect(FILE, 'open');
});
form.handlePart(PART);
assert.equal(form._flushing, 1);
var BUFFER;
gently.expect(form, 'pause');
gently.expect(FILE, 'write', function(buffer, cb) {
assert.strictEqual(buffer, BUFFER);
gently.expect(form, 'resume');
// @todo handle cb(new Err)
cb();
});
PART.emit('data', BUFFER = new Buffer('test'));
gently.expect(FILE, 'end', function(cb) {
gently.expect(form, 'emit', function(event, field, file) {
assert.equal(event, 'file');
assert.strictEqual(file, FILE);
});
gently.expect(form, '_maybeEnd');
cb();
assert.equal(form._flushing, 0);
});
PART.emit('end');
})();
});
test(function _uploadPath() {
(function testUniqueId() {
var UUID_A, UUID_B;
gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) {
assert.equal(uploadDir, form.uploadDir);
UUID_A = uuid;
});
form._uploadPath();
gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) {
UUID_B = uuid;
});
form._uploadPath();
assert.notEqual(UUID_A, UUID_B);
})();
(function testFileExtension() {
form.keepExtensions = true;
var FILENAME = 'foo.jpg',
EXT = '.bar';
gently.expect(GENTLY.hijacked.path, 'extname', function(filename) {
assert.equal(filename, FILENAME);
gently.restore(path, 'extname');
return EXT;
});
gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, name) {
assert.equal(path.extname(name), EXT);
});
form._uploadPath(FILENAME);
})();
});
test(function _maybeEnd() {
gently.expect(form, 'emit', 0);
form._maybeEnd();
form.ended = true;
form._flushing = 1;
form._maybeEnd();
gently.expect(form, 'emit', function(event) {
assert.equal(event, 'end');
});
form.ended = true;
form._flushing = 0;
form._maybeEnd();
});

View File

@@ -0,0 +1,50 @@
var common = require('../common');
var multipartParser = require(common.lib + '/multipart_parser'),
MultipartParser = multipartParser.MultipartParser,
events = require('events'),
Buffer = require('buffer').Buffer,
parser;
function test(test) {
parser = new MultipartParser();
test();
}
test(function constructor() {
assert.equal(parser.boundary, null);
assert.equal(parser.state, 0);
assert.equal(parser.flags, 0);
assert.equal(parser.boundaryChars, null);
assert.equal(parser.index, null);
assert.equal(parser.lookbehind, null);
assert.equal(parser.constructor.name, 'MultipartParser');
});
test(function initWithBoundary() {
var boundary = 'abc';
parser.initWithBoundary(boundary);
assert.deepEqual(Array.prototype.slice.call(parser.boundary), [13, 10, 45, 45, 97, 98, 99]);
assert.equal(parser.state, multipartParser.START);
assert.deepEqual(parser.boundaryChars, {10: true, 13: true, 45: true, 97: true, 98: true, 99: true});
});
test(function parserError() {
var boundary = 'abc',
buffer = new Buffer(5);
parser.initWithBoundary(boundary);
buffer.write('--ad', 'ascii', 0);
assert.equal(parser.write(buffer), 5);
});
test(function end() {
(function testError() {
assert.equal(parser.end().message, 'MultipartParser.end(): stream ended unexpectedly: ' + parser.explain());
})();
(function testRegular() {
parser.state = multipartParser.END;
assert.strictEqual(parser.end(), undefined);
})();
});

View File

@@ -0,0 +1,45 @@
var common = require('../common');
var QuerystringParser = require(common.lib + '/querystring_parser').QuerystringParser,
Buffer = require('buffer').Buffer,
gently,
parser;
function test(test) {
gently = new Gently();
parser = new QuerystringParser();
test();
gently.verify(test.name);
}
test(function constructor() {
assert.equal(parser.buffer, '');
assert.equal(parser.constructor.name, 'QuerystringParser');
});
test(function write() {
var a = new Buffer('a=1');
assert.equal(parser.write(a), a.length);
var b = new Buffer('&b=2');
parser.write(b);
assert.equal(parser.buffer, a + b);
});
test(function end() {
var FIELDS = {a: ['b', {c: 'd'}], e: 'f'};
gently.expect(GENTLY.hijacked.querystring, 'parse', function(str) {
assert.equal(str, parser.buffer);
return FIELDS;
});
gently.expect(parser, 'onField', Object.keys(FIELDS).length, function(key, val) {
assert.deepEqual(FIELDS[key], val);
});
gently.expect(parser, 'onEnd');
parser.buffer = 'my buffer';
parser.end();
assert.equal(parser.buffer, '');
});

View File

@@ -0,0 +1,71 @@
var common = require('../common');
var BOUNDARY = '---------------------------10102754414578508781458777923',
FIXTURE = TEST_FIXTURES+'/multi_video.upload',
fs = require('fs'),
http = require('http'),
formidable = require(common.lib + '/index'),
server = http.createServer();
server.on('request', function(req, res) {
var form = new formidable.IncomingForm(),
uploads = {};
form.uploadDir = TEST_TMP;
form.hash = 'sha1';
form.parse(req);
form
.on('fileBegin', function(field, file) {
assert.equal(field, 'upload');
var tracker = {file: file, progress: [], ended: false};
uploads[file.name] = tracker;
file
.on('progress', function(bytesReceived) {
tracker.progress.push(bytesReceived);
assert.equal(bytesReceived, file.size);
})
.on('end', function() {
tracker.ended = true;
});
})
.on('field', function(field, value) {
assert.equal(field, 'title');
assert.equal(value, '');
})
.on('file', function(field, file) {
assert.equal(field, 'upload');
assert.strictEqual(uploads[file.name].file, file);
})
.on('end', function() {
assert.ok(uploads['shortest_video.flv']);
assert.ok(uploads['shortest_video.flv'].ended);
assert.ok(uploads['shortest_video.flv'].progress.length > 3);
assert.equal(uploads['shortest_video.flv'].file.hash, 'd6a17616c7143d1b1438ceeef6836d1a09186b3a');
assert.equal(uploads['shortest_video.flv'].progress.slice(-1), uploads['shortest_video.flv'].file.size);
assert.ok(uploads['shortest_video.mp4']);
assert.ok(uploads['shortest_video.mp4'].ended);
assert.ok(uploads['shortest_video.mp4'].progress.length > 3);
assert.equal(uploads['shortest_video.mp4'].file.hash, '937dfd4db263f4887ceae19341dcc8d63bcd557f');
server.close();
res.writeHead(200);
res.end('good');
});
});
server.listen(TEST_PORT, function() {
var stat, headers, request, fixture;
stat = fs.statSync(FIXTURE);
request = http.request({
port: TEST_PORT,
path: '/',
method: 'POST',
headers: {
'content-type': 'multipart/form-data; boundary='+BOUNDARY,
'content-length': stat.size,
},
});
fs.createReadStream(FIXTURE).pipe(request);
});

1
node_modules/formidable/test/run.js generated vendored Normal file
View File

@@ -0,0 +1 @@
require('urun')(__dirname)

View File

@@ -0,0 +1,27 @@
var assert = require('assert');
var http = require('http');
var net = require('net');
var formidable = require('../../lib/index');
var server = http.createServer(function (req, res) {
var form = new formidable.IncomingForm();
var aborted_received = false;
form.on('aborted', function () {
aborted_received = true;
});
form.on('error', function () {
assert(aborted_received, 'Error event should follow aborted');
server.close();
});
form.on('end', function () {
throw new Error('Unexpected "end" event');
});
form.parse(req);
}).listen(0, 'localhost', function () {
var client = net.connect(server.address().port);
client.write(
"POST / HTTP/1.1\r\n" +
"Content-Length: 70\r\n" +
"Content-Type: multipart/form-data; boundary=foo\r\n\r\n");
client.end();
});

View File

@@ -0,0 +1,48 @@
var assert = require('assert');
var common = require('../common');
var formidable = require('../../lib/index');
var http = require('http');
var server = http.createServer(function(req, res) {
var form = new formidable.IncomingForm();
form.uploadDir = common.dir.tmp;
form.on('end', function () {
throw new Error('Unexpected "end" event');
});
form.on('error', function (e) {
res.writeHead(500);
res.end(e.message);
});
form.parse(req);
});
server.listen(0, function() {
var body =
'--foo\r\n' +
'Content-Disposition: form-data; name="file1"; filename="file1"\r\n' +
'Content-Type: application/octet-stream\r\n' +
'\r\nThis is the first file\r\n' +
'--foo\r\n' +
'Content-Type: application/octet-stream\r\n' +
'Content-Disposition: form-data; name="file2"; filename="file2"\r\n' +
'Content-Transfer-Encoding: unknown\r\n' +
'\r\nThis is the second file\r\n' +
'--foo--\r\n';
var req = http.request({
method: 'POST',
port: server.address().port,
headers: {
'Content-Length': body.length,
'Content-Type': 'multipart/form-data; boundary=foo'
}
});
req.on('response', function (res) {
assert.equal(res.statusCode, 500);
res.on('data', function () {});
res.on('end', function () {
server.close();
});
});
req.end(body);
});

View File

@@ -0,0 +1,49 @@
var http = require('http'),
formidable = require('../../lib/index'),
request = require('request'),
assert = require('assert');
var host = 'localhost';
var index = [
'<form action="/" method="post" enctype="multipart/form-data">',
' <input type="text" name="foo" />',
' <input type="submit" />',
'</form>'
].join("\n");
var server = http.createServer(function(req, res) {
// Show a form for testing purposes.
if (req.method == 'GET') {
res.writeHead(200, {'content-type': 'text/html'});
res.end(index);
return;
}
// Parse form and write results to response.
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
res.write(JSON.stringify({err: err, fields: fields, files: files}));
res.end();
});
}).listen(0, host, function() {
console.log("Server up and running...");
var server = this,
url = 'http://' + host + ':' + server.address().port;
var parts = [
{'Content-Disposition': 'form-data; name="foo"', 'body': 'bar'}
]
var req = request({method: 'POST', url: url, multipart: parts}, function(e, res, body) {
var obj = JSON.parse(body);
assert.equal("bar", obj.fields.foo);
server.close();
});
});

67
node_modules/formidable/test/tools/base64.html generated vendored Normal file
View File

@@ -0,0 +1,67 @@
<html>
<head>
<title>Convert a file to a base64 request</title>
<script type="text/javascript">
function form_submit(e){
console.log(e)
var resultOutput = document.getElementById('resultOutput');
var fileInput = document.getElementById('fileInput');
var fieldInput = document.getElementById('fieldInput');
makeRequestBase64(fileInput.files[0], fieldInput.value, function(err, result){
resultOutput.value = result;
});
return false;
}
function makeRequestBase64(file, fieldName, cb){
var boundary = '\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/';
var crlf = "\r\n";
var reader = new FileReader();
reader.onload = function(e){
var body = '';
body += '--' + boundary + crlf;
body += 'Content-Disposition: form-data; name="' + fieldName + '"; filename="' + escape(file.name)+ '"' + crlf;
body += 'Content-Type: ' + file.type + '' + crlf;
body += 'Content-Transfer-Encoding: base64' + crlf
body += crlf;
body += e.target.result.substring(e.target.result.indexOf(',') + 1) + crlf;
body += '--' + boundary + '--';
var head = '';
head += 'POST /upload HTTP/1.1' + crlf;
head += 'Host: localhost:8080' + crlf;
head += 'Content-Type: multipart/form-data; boundary=' + boundary + '' + crlf;
head += 'Content-Length: ' + body.length + '' + crlf;
cb(null, head + crlf + body);
};
reader.readAsDataURL(file);
}
</script>
</head>
<body>
<form action="" onsubmit="return form_submit();">
<label>File: <input id="fileInput" type="file" /></label><br />
<label>Field: <input id="fieldInput" type="text" value="file" /></label><br />
<button type="submit">Ok!</button><br />
<label>Request: <textarea id="resultOutput" readonly="readonly" rows="20" cols="80"></textarea></label><br />
</form>
<p>
Don't forget to save the output with windows (CRLF) line endings!
</p>
</body>
</html>

33
node_modules/formidable/test/unit/test-file.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
var common = require('../common');
var test = require('utest');
var assert = common.assert;
var File = common.require('file');
var file;
var now = new Date;
test('IncomingForm', {
before: function() {
file = new File({
size: 1024,
path: '/tmp/cat.png',
name: 'cat.png',
type: 'image/png',
lastModifiedDate: now,
filename: 'cat.png',
mime: 'image/png'
})
},
'#toJSON()': function() {
var obj = file.toJSON();
var len = Object.keys(obj).length;
assert.equal(1024, obj.size);
assert.equal('/tmp/cat.png', obj.path);
assert.equal('cat.png', obj.name);
assert.equal('image/png', obj.type);
assert.equal('image/png', obj.mime);
assert.equal('cat.png', obj.filename);
assert.equal(now, obj.mtime);
assert.equal(len, 8);
}
});

View File

@@ -0,0 +1,63 @@
var common = require('../common');
var test = require('utest');
var assert = common.assert;
var IncomingForm = common.require('incoming_form').IncomingForm;
var path = require('path');
var form;
test('IncomingForm', {
before: function() {
form = new IncomingForm();
},
'#_fileName with regular characters': function() {
var filename = 'foo.txt';
assert.equal(form._fileName(makeHeader(filename)), 'foo.txt');
},
'#_fileName with unescaped quote': function() {
var filename = 'my".txt';
assert.equal(form._fileName(makeHeader(filename)), 'my".txt');
},
'#_fileName with escaped quote': function() {
var filename = 'my%22.txt';
assert.equal(form._fileName(makeHeader(filename)), 'my".txt');
},
'#_fileName with bad quote and additional sub-header': function() {
var filename = 'my".txt';
var header = makeHeader(filename) + '; foo="bar"';
assert.equal(form._fileName(header), filename);
},
'#_fileName with semicolon': function() {
var filename = 'my;.txt';
assert.equal(form._fileName(makeHeader(filename)), 'my;.txt');
},
'#_fileName with utf8 character': function() {
var filename = 'my&#9731;.txt';
assert.equal(form._fileName(makeHeader(filename)), 'my☃.txt');
},
'#_uploadPath strips harmful characters from extension when keepExtensions': function() {
form.keepExtensions = true;
var ext = path.extname(form._uploadPath('fine.jpg?foo=bar'));
assert.equal(ext, '.jpg');
var ext = path.extname(form._uploadPath('fine?foo=bar'));
assert.equal(ext, '');
var ext = path.extname(form._uploadPath('super.cr2+dsad'));
assert.equal(ext, '.cr2');
var ext = path.extname(form._uploadPath('super.bar'));
assert.equal(ext, '.bar');
},
});
function makeHeader(filename) {
return 'Content-Disposition: form-data; name="upload"; filename="' + filename + '"';
}