diff --git a/app.js b/app.js
new file mode 100644
index 0000000..cd9d6ad
--- /dev/null
+++ b/app.js
@@ -0,0 +1,265 @@
+
+/**
+ * Module dependencies.
+ */
+var fs = require('fs');
+var path = require('path');
+var mongo = require('mongodb');
+var BSON = mongo.BSONPure;
+var db = require('mongoskin').db('localhost:27017/test');
+var testcollection = db.collection('testcollection');
+var exercisecollection = db.collection('exercisecollection');
+var expressocollection = db.collection('expressocollection');
+var hrdatacollection = db.collection('hrdatacollection');
+var util = require('util');
+var formidable = require('formidable');
+var xml2js = require('xml2js');
+var parser = new xml2js.Parser();
+var dateFormat = require('dateformat');
+
+var app = require('http').createServer(function handler(request, response) {
+
+ console.log('request starting...;' + request.url);
+
+ switch(request.url) {
+ case '/upload':
+ var form = new formidable.IncomingForm(),
+ files = [],
+ fields = [];
+
+ var tempdirectory = "/tmp/";
+
+ // //tempdirectory changes if the operating system is windows
+ if(process.platform == "windows")
+ {
+ tempdirectory = "c:\\temp\\";
+ }
+ form.uploaddir = tempdirectory;
+
+ //tempDirectory = "c:\\Temp\\";
+ //form.uploadDir = tempDirectory;
+
+ form.on('error', function(err) {
+ response.writeHead(200, {'content-type': 'text/plain'});
+ response.end('error:\n\n'+util.inspect(err));
+ });
+ form.on('field', function(field, value) {
+ console.log(field, value);
+ fields.push([field, value]);
+ });
+ form.on('file', function(field, file) {
+ console.log(field, file);
+ files.push([field, file]);
+ });
+ form.on('end', function() {
+ console.log('-> upload done');
+ response.writeHead(200, {'content-type': 'text/plain'});
+ response.write('received fields:\n\n '+util.inspect(fields));
+ response.write('\n\n');
+ response.write('received files:\n\n '+util.inspect(files));
+ });
+
+ form.parse(request, function(err, fields, files) {
+ console.log('-> uploaded -' + files.upload.path);
+ fs.readFile(files.upload.path, function(err, data) {
+ parser.parseString(data, function (err, result) {
+ response.write('received file contents:\n\n ');
+ response.end(JSON.stringify(result));
+ console.log('Done');
+
+ //hrdatacollectionJSON.stringify(result)
+ var data = JSON.stringify(result)
+ var buf1 = new Buffer(12);
+ var dataid = JSON.parse(data).Activities.Activity.Id;
+ var datadate = Date.parse(dataid);
+ //console.log('TCX ID' + JSON.parse(data).Activities.Activity.Id);
+ console.log('TCX ID ' + datadate);
+ var document_id = new BSON.ObjectID(datadate);
+ console.log('inserted BSONID ' + document_id);
+ hrdatacollection.update({_id:document_id}, data,{upsert:true} , function(err, result) {
+ if (err) throw err;
+ });
+
+ });
+ });
+ });
+ break;
+ default:
+ var filePath = '.' + request.url;
+ if (filePath == './')
+ filePath = './index.html';
+
+ var extname = path.extname(filePath);
+ var contentType = 'text/html';
+ switch (extname) {
+ case '.js':
+ contentType = 'text/javascript';
+ break;
+ case '.css':
+ contentType = 'text/css';
+ break;
+ }
+ path.exists(filePath, function(exists) {
+
+ if (exists) {
+ fs.readFile(filePath, function(error, content) {
+ if (error) {
+ response.writeHead(500);
+ response.end();
+ }
+ else {
+ response.writeHead(200, { 'Content-Type': contentType });
+ response.end(content, 'utf-8');
+ }
+ });
+ }
+ else {
+ response.writeHead(404);
+ response.end();
+ }
+ });
+ };
+}).listen(3000);
+
+
+var io = require('socket.io');
+io = io.listen(app);
+io.configure('development', function(){
+io.set("transports", ["websocket"]);
+});
+
+io.sockets.on('connection', function(socket) {
+ console.log('Client connected');
+
+ socket.on('getactivites', function(data) {
+ console.log('getactivites')
+ testcollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ socket.emit('populateactivities', result);
+ });
+ });
+///////////////////////////////////////
+ socket.on('getactivitybyid', function(id) {
+ console.log('getactivitybyid')
+ testcollection.findById(id, function(err, result) {
+ if (err) throw err;
+ socket.emit('populateactivitybyid', result);
+ });
+ });
+
+
+////////////////////////
+ socket.on('addactivity', function(data, docid) {
+ console.log('addactivity' + docid)
+ if (docid === null) {
+ var document_id = new BSON.ObjectID();
+ }
+ else {
+ var document_id = new BSON.ObjectID(docid);
+ };
+ //var document_id = new BSON.ObjectID(docid);
+ console.log('inserted BSONID' + document_id);
+ testcollection.update({_id:document_id}, data,{upsert:true} , function(err, result) {
+ if (err) throw err;
+ exercisecollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ socket.emit('populateexercises', result);
+ });
+ });
+
+
+ });
+
+/////////////////////
+ socket.on('delactivity', function(id) {
+ testcollection.removeById(id,function(err, reply){
+ if (err) throw err;
+ testcollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ socket.emit('populateactivities', result);
+ });
+ });
+ });
+ ///////////////////
+ socket.on('getexercises', function(data) {
+ console.log('emit exercises')
+ exercisecollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ socket.emit('populateexercises', result);
+ });
+ });
+ socket.on('updateexercises', function(data, docid) {
+ console.log('updateexecises' + JSON.stringify(data))
+ if (docid == 'undefined') {
+ console.log('edited updateexecises' + JSON.stringify(data))
+ exercisecollection.insert(data, function(err, result) {
+ if (err) throw err;
+ exercisecollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ socket.emit('populateexercises', result);
+ });
+ });
+ }
+ else {
+ var document_id = new BSON.ObjectID(docid);
+ exercisecollection.update({_id:document_id}, data,{upsert:true} , function(err, result) {
+ if (err) throw err;
+ exercisecollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ console.log('populateexercises');
+ socket.emit('populateexercises', result);
+ });
+ });
+
+ };
+ });
+////////////////
+ socket.on('getexpresso', function(data) {
+ console.log('emit expresso')
+ expressocollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ socket.emit('populateexpresso', result);
+ });
+ });
+ socket.on('updateexpresso', function(data, docid) {
+
+ if (docid == 'undefined') {
+ console.log('addedexpresso ' + JSON.stringify(data))
+ console.log('edited updateexpresso' + JSON.stringify(data))
+ expressocollection.insert(data, function(err, result) {
+ if (err) throw err;
+ expressocollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ socket.emit('populateexpresso', result);
+ });
+ });
+ }
+ else {
+ console.log('updateexpresso ' + JSON.stringify(data))
+ var document_id = new BSON.ObjectID(docid);
+ expressocollection.update({_id:document_id}, data,{upsert:true} , function(err, result) {
+ if (err) throw err;
+ expressocollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ console.log('populateexpresoo');
+ socket.emit('populateexpresso', result);
+ });
+ });
+
+ };
+ });
+////////////////
+ socket.on('gethrdata', function(data) {
+ console.log('emit hrdata')
+ hrdatacollection.find().toArray(function(err, result) {
+ if (err) throw err;
+ socket.emit('populatehrdata', result);
+ });
+ });
+
+
+////////////////
+});
+
+
+
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..3627972
--- /dev/null
+++ b/index.html
@@ -0,0 +1,146 @@
+
+
+
+
+ Ninja Store - Items
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Workout Tracker
+
+
+-
+
+
+ delete
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/index.html.backup b/index.html.backup
new file mode 100644
index 0000000..94691f5
--- /dev/null
+++ b/index.html.backup
@@ -0,0 +1,439 @@
+
+
+
+
+ Ninja Store - Items
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Workout Tracker
+
+
+-
+
+
+ delete
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/index_backup.html b/index_backup.html
new file mode 100644
index 0000000..e2636ea
--- /dev/null
+++ b/index_backup.html
@@ -0,0 +1,216 @@
+
+
+
+
+ Ninja Store - Items
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/node_modules/formidable/.npmignore b/node_modules/formidable/.npmignore
new file mode 100644
index 0000000..4fbabb3
--- /dev/null
+++ b/node_modules/formidable/.npmignore
@@ -0,0 +1,4 @@
+/test/tmp/
+*.upload
+*.un~
+*.http
diff --git a/node_modules/formidable/.travis.yml b/node_modules/formidable/.travis.yml
new file mode 100644
index 0000000..f1d0f13
--- /dev/null
+++ b/node_modules/formidable/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
diff --git a/node_modules/formidable/Makefile b/node_modules/formidable/Makefile
new file mode 100644
index 0000000..8945872
--- /dev/null
+++ b/node_modules/formidable/Makefile
@@ -0,0 +1,14 @@
+SHELL := /bin/bash
+
+test:
+ @./test/run.js
+
+build: npm test
+
+npm:
+ npm install .
+
+clean:
+ rm test/tmp/*
+
+.PHONY: test clean build
diff --git a/node_modules/formidable/Readme.md b/node_modules/formidable/Readme.md
new file mode 100644
index 0000000..a5ca104
--- /dev/null
+++ b/node_modules/formidable/Readme.md
@@ -0,0 +1,311 @@
+# Formidable
+
+[](http://travis-ci.org/felixge/node-formidable)
+
+## Purpose
+
+A node.js module for parsing form data, especially file uploads.
+
+## Current status
+
+This module was developed for [Transloadit](http://transloadit.com/), a service focused on uploading
+and encoding images and videos. It has been battle-tested against hundreds of GB of file uploads from
+a large variety of clients and is considered production-ready.
+
+## Features
+
+* Fast (~500mb/sec), non-buffering multipart parser
+* Automatically writing file uploads to disk
+* Low memory footprint
+* Graceful error handling
+* Very high test coverage
+
+## Changelog
+
+### v1.0.9
+
+* Emit progress when content length header parsed (Tim Koschützki)
+* Fix Readme syntax due to GitHub changes (goob)
+* Replace references to old 'sys' module in Readme with 'util' (Peter Sugihara)
+
+### v1.0.8
+
+* Strip potentially unsafe characters when using `keepExtensions: true`.
+* Switch to utest / urun for testing
+* Add travis build
+
+### v1.0.7
+
+* Remove file from package that was causing problems when installing on windows. (#102)
+* Fix typos in Readme (Jason Davies).
+
+### v1.0.6
+
+* Do not default to the default to the field name for file uploads where
+ filename="".
+
+### v1.0.5
+
+* Support filename="" in multipart parts
+* Explain unexpected end() errors in parser better
+
+**Note:** Starting with this version, formidable emits 'file' events for empty
+file input fields. Previously those were incorrectly emitted as regular file
+input fields with value = "".
+
+### v1.0.4
+
+* Detect a good default tmp directory regardless of platform. (#88)
+
+### v1.0.3
+
+* Fix problems with utf8 characters (#84) / semicolons in filenames (#58)
+* Small performance improvements
+* New test suite and fixture system
+
+### v1.0.2
+
+* Exclude node\_modules folder from git
+* Implement new `'aborted'` event
+* Fix files in example folder to work with recent node versions
+* Make gently a devDependency
+
+[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.1...v1.0.2)
+
+### v1.0.1
+
+* Fix package.json to refer to proper main directory. (#68, Dean Landolt)
+
+[See Commits](https://github.com/felixge/node-formidable/compare/v1.0.0...v1.0.1)
+
+### v1.0.0
+
+* Add support for multipart boundaries that are quoted strings. (Jeff Craig)
+
+This marks the beginning of development on version 2.0 which will include
+several architectural improvements.
+
+[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.11...v1.0.0)
+
+### v0.9.11
+
+* Emit `'progress'` event when receiving data, regardless of parsing it. (Tim Koschützki)
+* Use [W3C FileAPI Draft](http://dev.w3.org/2006/webapi/FileAPI/) properties for File class
+
+**Important:** The old property names of the File class will be removed in a
+future release.
+
+[See Commits](https://github.com/felixge/node-formidable/compare/v0.9.10...v0.9.11)
+
+### Older releases
+
+These releases were done before starting to maintain the above Changelog:
+
+* [v0.9.10](https://github.com/felixge/node-formidable/compare/v0.9.9...v0.9.10)
+* [v0.9.9](https://github.com/felixge/node-formidable/compare/v0.9.8...v0.9.9)
+* [v0.9.8](https://github.com/felixge/node-formidable/compare/v0.9.7...v0.9.8)
+* [v0.9.7](https://github.com/felixge/node-formidable/compare/v0.9.6...v0.9.7)
+* [v0.9.6](https://github.com/felixge/node-formidable/compare/v0.9.5...v0.9.6)
+* [v0.9.5](https://github.com/felixge/node-formidable/compare/v0.9.4...v0.9.5)
+* [v0.9.4](https://github.com/felixge/node-formidable/compare/v0.9.3...v0.9.4)
+* [v0.9.3](https://github.com/felixge/node-formidable/compare/v0.9.2...v0.9.3)
+* [v0.9.2](https://github.com/felixge/node-formidable/compare/v0.9.1...v0.9.2)
+* [v0.9.1](https://github.com/felixge/node-formidable/compare/v0.9.0...v0.9.1)
+* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
+* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
+* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
+* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
+* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
+* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
+* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
+* [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
+* [v0.1.0](https://github.com/felixge/node-formidable/commits/v0.1.0)
+
+## Installation
+
+Via [npm](http://github.com/isaacs/npm):
+
+ npm install formidable@latest
+
+Manually:
+
+ git clone git://github.com/felixge/node-formidable.git formidable
+ vim my.js
+ # var formidable = require('./formidable');
+
+Note: Formidable requires [gently](http://github.com/felixge/node-gently) to run the unit tests, but you won't need it for just using the library.
+
+## Example
+
+Parse an incoming file upload.
+
+ var formidable = require('formidable'),
+ http = require('http'),
+
+ util = require('util');
+
+ http.createServer(function(req, res) {
+ if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
+ // parse a file upload
+ var form = new formidable.IncomingForm();
+ form.parse(req, function(err, fields, files) {
+ res.writeHead(200, {'content-type': 'text/plain'});
+ res.write('received upload:\n\n');
+ res.end(util.inspect({fields: fields, files: files}));
+ });
+ return;
+ }
+
+ // show a file upload form
+ res.writeHead(200, {'content-type': 'text/html'});
+ res.end(
+ ''
+ );
+ }).listen(80);
+
+## API
+
+### formidable.IncomingForm
+
+__new formidable.IncomingForm()__
+
+Creates a new incoming form.
+
+__incomingForm.encoding = 'utf-8'__
+
+The encoding to use for incoming form fields.
+
+__incomingForm.uploadDir = process.env.TMP || '/tmp' || process.cwd()__
+
+The directory for placing file uploads in. You can move them later on using
+`fs.rename()`. The default directory is picked at module load time depending on
+the first existing directory from those listed above.
+
+__incomingForm.keepExtensions = false__
+
+If you want the files written to `incomingForm.uploadDir` to include the extensions of the original files, set this property to `true`.
+
+__incomingForm.type__
+
+Either 'multipart' or 'urlencoded' depending on the incoming request.
+
+__incomingForm.maxFieldsSize = 2 * 1024 * 1024__
+
+Limits the amount of memory a field (not file) can allocate in bytes.
+If this value is exceeded, an `'error'` event is emitted. The default
+size is 2MB.
+
+__incomingForm.hash = false__
+
+If you want checksums calculated for incoming files, set this to either `'sha1'` or `'md5'`.
+
+__incomingForm.bytesReceived__
+
+The amount of bytes received for this form so far.
+
+__incomingForm.bytesExpected__
+
+The expected number of bytes in this form.
+
+__incomingForm.parse(request, [cb])__
+
+Parses an incoming node.js `request` containing form data. If `cb` is provided, all fields an files are collected and passed to the callback:
+
+ incomingForm.parse(req, function(err, fields, files) {
+ // ...
+ });
+
+__incomingForm.onPart(part)__
+
+You may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any `'field'` / `'file'` events processing which would occur otherwise, making you fully responsible for handling the processing.
+
+ incomingForm.onPart = function(part) {
+ part.addListener('data', function() {
+ // ...
+ });
+ }
+
+If you want to use formidable to only handle certain parts for you, you can do so:
+
+ incomingForm.onPart = function(part) {
+ if (!part.filename) {
+ // let formidable handle all non-file parts
+ incomingForm.handlePart(part);
+ }
+ }
+
+Check the code in this method for further inspiration.
+
+__Event: 'progress' (bytesReceived, bytesExpected)__
+
+Emitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar.
+
+__Event: 'field' (name, value)__
+
+Emitted whenever a field / value pair has been received.
+
+__Event: 'fileBegin' (name, file)__
+
+Emitted whenever a new file is detected in the upload stream. Use this even if
+you want to stream the file to somewhere else while buffering the upload on
+the file system.
+
+__Event: 'file' (name, file)__
+
+Emitted whenever a field / file pair has been received. `file` is an instance of `File`.
+
+__Event: 'error' (err)__
+
+Emitted when there is an error processing the incoming form. A request that experiences an error is automatically paused, you will have to manually call `request.resume()` if you want the request to continue firing `'data'` events.
+
+__Event: 'aborted'__
+
+Emitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. In the future there will be a separate 'timeout' event (needs a change in the node core).
+
+__Event: 'end' ()__
+
+Emitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response.
+
+### formidable.File
+
+__file.size = 0__
+
+The size of the uploaded file in bytes. If the file is still being uploaded (see `'fileBegin'` event), this property says how many bytes of the file have been written to disk yet.
+
+__file.path = null__
+
+The path this file is being written to. You can modify this in the `'fileBegin'` event in
+case you are unhappy with the way formidable generates a temporary path for your files.
+
+__file.name = null__
+
+The name this file had according to the uploading client.
+
+__file.type = null__
+
+The mime type of this file, according to the uploading client.
+
+__file.lastModifiedDate = null__
+
+A date object (or `null`) containing the time this file was last written to. Mostly
+here for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/).
+
+__file.hash = null__
+
+If hash calculation was set, you can read the hex digest out of this var.
+
+## License
+
+Formidable is licensed under the MIT license.
+
+## Ports
+
+* [multipart-parser](http://github.com/FooBarWidget/multipart-parser): a C++ parser based on formidable
+
+## Credits
+
+* [Ryan Dahl](http://twitter.com/ryah) for his work on [http-parser](http://github.com/ry/http-parser) which heavily inspired multipart_parser.js
diff --git a/node_modules/formidable/TODO b/node_modules/formidable/TODO
new file mode 100644
index 0000000..e1107f2
--- /dev/null
+++ b/node_modules/formidable/TODO
@@ -0,0 +1,3 @@
+- Better bufferMaxSize handling approach
+- Add tests for JSON parser pull request and merge it
+- Implement QuerystringParser the same way as MultipartParser
diff --git a/node_modules/formidable/benchmark/bench-multipart-parser.js b/node_modules/formidable/benchmark/bench-multipart-parser.js
new file mode 100644
index 0000000..bff41f1
--- /dev/null
+++ b/node_modules/formidable/benchmark/bench-multipart-parser.js
@@ -0,0 +1,70 @@
+require('../test/common');
+var multipartParser = require('../lib/multipart_parser'),
+ MultipartParser = multipartParser.MultipartParser,
+ parser = new MultipartParser(),
+ Buffer = require('buffer').Buffer,
+ boundary = '-----------------------------168072824752491622650073',
+ mb = 100,
+ buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
+ callbacks =
+ { partBegin: -1,
+ partEnd: -1,
+ headerField: -1,
+ headerValue: -1,
+ partData: -1,
+ end: -1,
+ };
+
+
+parser.initWithBoundary(boundary);
+parser.onHeaderField = function() {
+ callbacks.headerField++;
+};
+
+parser.onHeaderValue = function() {
+ callbacks.headerValue++;
+};
+
+parser.onPartBegin = function() {
+ callbacks.partBegin++;
+};
+
+parser.onPartData = function() {
+ callbacks.partData++;
+};
+
+parser.onPartEnd = function() {
+ callbacks.partEnd++;
+};
+
+parser.onEnd = function() {
+ callbacks.end++;
+};
+
+var start = +new Date(),
+ nparsed = parser.write(buffer),
+ duration = +new Date - start,
+ mbPerSec = (mb / (duration / 1000)).toFixed(2);
+
+console.log(mbPerSec+' mb/sec');
+
+assert.equal(nparsed, buffer.length);
+
+function createMultipartBuffer(boundary, size) {
+ var head =
+ '--'+boundary+'\r\n'
+ + 'content-disposition: form-data; name="field1"\r\n'
+ + '\r\n'
+ , tail = '\r\n--'+boundary+'--\r\n'
+ , buffer = new Buffer(size);
+
+ buffer.write(head, 'ascii', 0);
+ buffer.write(tail, 'ascii', buffer.length - tail.length);
+ return buffer;
+}
+
+process.on('exit', function() {
+ for (var k in callbacks) {
+ assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
+ }
+});
diff --git a/node_modules/formidable/example/post.js b/node_modules/formidable/example/post.js
new file mode 100644
index 0000000..f6c15a6
--- /dev/null
+++ b/node_modules/formidable/example/post.js
@@ -0,0 +1,43 @@
+require('../test/common');
+var http = require('http'),
+ util = require('util'),
+ formidable = require('formidable'),
+ server;
+
+server = http.createServer(function(req, res) {
+ if (req.url == '/') {
+ res.writeHead(200, {'content-type': 'text/html'});
+ res.end(
+ ''
+ );
+ } else if (req.url == '/post') {
+ var form = new formidable.IncomingForm(),
+ fields = [];
+
+ form
+ .on('error', function(err) {
+ res.writeHead(200, {'content-type': 'text/plain'});
+ res.end('error:\n\n'+util.inspect(err));
+ })
+ .on('field', function(field, value) {
+ console.log(field, value);
+ fields.push([field, value]);
+ })
+ .on('end', function() {
+ console.log('-> post done');
+ res.writeHead(200, {'content-type': 'text/plain'});
+ res.end('received fields:\n\n '+util.inspect(fields));
+ });
+ form.parse(req);
+ } else {
+ res.writeHead(404, {'content-type': 'text/plain'});
+ res.end('404');
+ }
+});
+server.listen(TEST_PORT);
+
+console.log('listening on http://localhost:'+TEST_PORT+'/');
diff --git a/node_modules/formidable/example/upload.js b/node_modules/formidable/example/upload.js
new file mode 100644
index 0000000..050cdd9
--- /dev/null
+++ b/node_modules/formidable/example/upload.js
@@ -0,0 +1,48 @@
+require('../test/common');
+var http = require('http'),
+ util = require('util'),
+ formidable = require('formidable'),
+ server;
+
+server = http.createServer(function(req, res) {
+ if (req.url == '/') {
+ res.writeHead(200, {'content-type': 'text/html'});
+ res.end(
+ ''
+ );
+ } else if (req.url == '/upload') {
+ var form = new formidable.IncomingForm(),
+ files = [],
+ fields = [];
+
+ form.uploadDir = TEST_TMP;
+
+ form
+ .on('field', function(field, value) {
+ console.log(field, value);
+ fields.push([field, value]);
+ })
+ .on('file', function(field, file) {
+ console.log(field, file);
+ files.push([field, file]);
+ })
+ .on('end', function() {
+ console.log('-> upload done');
+ res.writeHead(200, {'content-type': 'text/plain'});
+ res.write('received fields:\n\n '+util.inspect(fields));
+ res.write('\n\n');
+ res.end('received files:\n\n '+util.inspect(files));
+ });
+ form.parse(req);
+ } else {
+ res.writeHead(404, {'content-type': 'text/plain'});
+ res.end('404');
+ }
+});
+server.listen(TEST_PORT);
+
+console.log('listening on http://localhost:'+TEST_PORT+'/');
diff --git a/node_modules/formidable/index.js b/node_modules/formidable/index.js
new file mode 100644
index 0000000..be41032
--- /dev/null
+++ b/node_modules/formidable/index.js
@@ -0,0 +1 @@
+module.exports = require('./lib/formidable');
\ No newline at end of file
diff --git a/node_modules/formidable/lib/file.js b/node_modules/formidable/lib/file.js
new file mode 100644
index 0000000..dad8d5f
--- /dev/null
+++ b/node_modules/formidable/lib/file.js
@@ -0,0 +1,73 @@
+if (global.GENTLY) require = GENTLY.hijack(require);
+
+var util = require('./util'),
+ WriteStream = require('fs').WriteStream,
+ EventEmitter = require('events').EventEmitter,
+ crypto = require('crypto');
+
+function File(properties) {
+ EventEmitter.call(this);
+
+ this.size = 0;
+ this.path = null;
+ this.name = null;
+ this.type = null;
+ this.hash = null;
+ this.lastModifiedDate = null;
+
+ this._writeStream = null;
+
+ for (var key in properties) {
+ this[key] = properties[key];
+ }
+
+ if(typeof this.hash === 'string') {
+ this.hash = crypto.createHash(properties.hash);
+ }
+
+ this._backwardsCompatibility();
+}
+module.exports = File;
+util.inherits(File, EventEmitter);
+
+// @todo Next release: Show error messages when accessing these
+File.prototype._backwardsCompatibility = function() {
+ var self = this;
+ this.__defineGetter__('length', function() {
+ return self.size;
+ });
+ this.__defineGetter__('filename', function() {
+ return self.name;
+ });
+ this.__defineGetter__('mime', function() {
+ return self.type;
+ });
+};
+
+File.prototype.open = function() {
+ this._writeStream = new WriteStream(this.path);
+};
+
+File.prototype.write = function(buffer, cb) {
+ var self = this;
+ this._writeStream.write(buffer, function() {
+ if(self.hash) {
+ self.hash.update(buffer);
+ }
+ self.lastModifiedDate = new Date();
+ self.size += buffer.length;
+ self.emit('progress', self.size);
+ cb();
+ });
+};
+
+File.prototype.end = function(cb) {
+ var self = this;
+ this._writeStream.end(function() {
+ if(self.hash) {
+ self.hash = self.hash.digest('hex');
+ }
+ self.emit('end');
+ cb();
+ });
+};
diff --git a/node_modules/formidable/lib/incoming_form.js b/node_modules/formidable/lib/incoming_form.js
new file mode 100644
index 0000000..060eac2
--- /dev/null
+++ b/node_modules/formidable/lib/incoming_form.js
@@ -0,0 +1,384 @@
+if (global.GENTLY) require = GENTLY.hijack(require);
+
+var fs = require('fs');
+var util = require('./util'),
+ path = require('path'),
+ File = require('./file'),
+ MultipartParser = require('./multipart_parser').MultipartParser,
+ QuerystringParser = require('./querystring_parser').QuerystringParser,
+ StringDecoder = require('string_decoder').StringDecoder,
+ EventEmitter = require('events').EventEmitter,
+ Stream = require('stream').Stream;
+
+function IncomingForm(opts) {
+ if (!(this instanceof IncomingForm)) return new IncomingForm;
+ EventEmitter.call(this);
+
+ opts=opts||{};
+
+ this.error = null;
+ this.ended = false;
+
+ this.maxFieldsSize = opts.maxFieldsSize || 2 * 1024 * 1024;
+ this.keepExtensions = opts.keepExtensions || false;
+ this.uploadDir = opts.uploadDir || IncomingForm.UPLOAD_DIR;
+ this.encoding = opts.encoding || 'utf-8';
+ this.headers = null;
+ this.type = null;
+ this.hash = false;
+
+ this.bytesReceived = null;
+ this.bytesExpected = null;
+
+ this._parser = null;
+ this._flushing = 0;
+ this._fieldsSize = 0;
+};
+util.inherits(IncomingForm, EventEmitter);
+exports.IncomingForm = IncomingForm;
+
+IncomingForm.UPLOAD_DIR = (function() {
+ var dirs = [process.env.TMP, '/tmp', process.cwd()];
+ for (var i = 0; i < dirs.length; i++) {
+ var dir = dirs[i];
+ var isDirectory = false;
+
+ try {
+ isDirectory = fs.statSync(dir).isDirectory();
+ } catch (e) {}
+
+ if (isDirectory) return dir;
+ }
+})();
+
+IncomingForm.prototype.parse = function(req, cb) {
+ this.pause = function() {
+ try {
+ req.pause();
+ } catch (err) {
+ // the stream was destroyed
+ if (!this.ended) {
+ // before it was completed, crash & burn
+ this._error(err);
+ }
+ return false;
+ }
+ return true;
+ };
+
+ this.resume = function() {
+ try {
+ req.resume();
+ } catch (err) {
+ // the stream was destroyed
+ if (!this.ended) {
+ // before it was completed, crash & burn
+ this._error(err);
+ }
+ return false;
+ }
+
+ return true;
+ };
+
+ this.writeHeaders(req.headers);
+
+ var self = this;
+ req
+ .on('error', function(err) {
+ self._error(err);
+ })
+ .on('aborted', function() {
+ self.emit('aborted');
+ })
+ .on('data', function(buffer) {
+ self.write(buffer);
+ })
+ .on('end', function() {
+ if (self.error) {
+ return;
+ }
+
+ var err = self._parser.end();
+ if (err) {
+ self._error(err);
+ }
+ });
+
+ if (cb) {
+ var fields = {}, files = {};
+ this
+ .on('field', function(name, value) {
+ fields[name] = value;
+ })
+ .on('file', function(name, file) {
+ files[name] = file;
+ })
+ .on('error', function(err) {
+ cb(err, fields, files);
+ })
+ .on('end', function() {
+ cb(null, fields, files);
+ });
+ }
+
+ return this;
+};
+
+IncomingForm.prototype.writeHeaders = function(headers) {
+ this.headers = headers;
+ this._parseContentLength();
+ this._parseContentType();
+};
+
+IncomingForm.prototype.write = function(buffer) {
+ if (!this._parser) {
+ this._error(new Error('unintialized parser'));
+ return;
+ }
+
+ this.bytesReceived += buffer.length;
+ this.emit('progress', this.bytesReceived, this.bytesExpected);
+
+ var bytesParsed = this._parser.write(buffer);
+ if (bytesParsed !== buffer.length) {
+ this._error(new Error('parser error, '+bytesParsed+' of '+buffer.length+' bytes parsed'));
+ }
+
+ return bytesParsed;
+};
+
+IncomingForm.prototype.pause = function() {
+ // this does nothing, unless overwritten in IncomingForm.parse
+ return false;
+};
+
+IncomingForm.prototype.resume = function() {
+ // this does nothing, unless overwritten in IncomingForm.parse
+ return false;
+};
+
+IncomingForm.prototype.onPart = function(part) {
+ // this method can be overwritten by the user
+ this.handlePart(part);
+};
+
+IncomingForm.prototype.handlePart = function(part) {
+ var self = this;
+
+ if (part.filename === undefined) {
+ var value = ''
+ , decoder = new StringDecoder(this.encoding);
+
+ part.on('data', function(buffer) {
+ self._fieldsSize += buffer.length;
+ if (self._fieldsSize > self.maxFieldsSize) {
+ self._error(new Error('maxFieldsSize exceeded, received '+self._fieldsSize+' bytes of field data'));
+ return;
+ }
+ value += decoder.write(buffer);
+ });
+
+ part.on('end', function() {
+ self.emit('field', part.name, value);
+ });
+ return;
+ }
+
+ this._flushing++;
+
+ var file = new File({
+ path: this._uploadPath(part.filename),
+ name: part.filename,
+ type: part.mime,
+ hash: self.hash
+ });
+
+ this.emit('fileBegin', part.name, file);
+
+ file.open();
+
+ part.on('data', function(buffer) {
+ self.pause();
+ file.write(buffer, function() {
+ self.resume();
+ });
+ });
+
+ part.on('end', function() {
+ file.end(function() {
+ self._flushing--;
+ self.emit('file', part.name, file);
+ self._maybeEnd();
+ });
+ });
+};
+
+IncomingForm.prototype._parseContentType = function() {
+ if (!this.headers['content-type']) {
+ this._error(new Error('bad content-type header, no content-type'));
+ return;
+ }
+
+ if (this.headers['content-type'].match(/urlencoded/i)) {
+ this._initUrlencoded();
+ return;
+ }
+
+ if (this.headers['content-type'].match(/multipart/i)) {
+ var m;
+ if (m = this.headers['content-type'].match(/boundary=(?:"([^"]+)"|([^;]+))/i)) {
+ this._initMultipart(m[1] || m[2]);
+ } else {
+ this._error(new Error('bad content-type header, no multipart boundary'));
+ }
+ return;
+ }
+
+ this._error(new Error('bad content-type header, unknown content-type: '+this.headers['content-type']));
+};
+
+IncomingForm.prototype._error = function(err) {
+ if (this.error) {
+ return;
+ }
+
+ this.error = err;
+ this.pause();
+ this.emit('error', err);
+};
+
+IncomingForm.prototype._parseContentLength = function() {
+ if (this.headers['content-length']) {
+ this.bytesReceived = 0;
+ this.bytesExpected = parseInt(this.headers['content-length'], 10);
+ this.emit('progress', this.bytesReceived, this.bytesExpected);
+ }
+};
+
+IncomingForm.prototype._newParser = function() {
+ return new MultipartParser();
+};
+
+IncomingForm.prototype._initMultipart = function(boundary) {
+ this.type = 'multipart';
+
+ var parser = new MultipartParser(),
+ self = this,
+ headerField,
+ headerValue,
+ part;
+
+ parser.initWithBoundary(boundary);
+
+ parser.onPartBegin = function() {
+ part = new Stream();
+ part.readable = true;
+ part.headers = {};
+ part.name = null;
+ part.filename = null;
+ part.mime = null;
+ headerField = '';
+ headerValue = '';
+ };
+
+ parser.onHeaderField = function(b, start, end) {
+ headerField += b.toString(self.encoding, start, end);
+ };
+
+ parser.onHeaderValue = function(b, start, end) {
+ headerValue += b.toString(self.encoding, start, end);
+ };
+
+ parser.onHeaderEnd = function() {
+ headerField = headerField.toLowerCase();
+ part.headers[headerField] = headerValue;
+
+ var m;
+ if (headerField == 'content-disposition') {
+ if (m = headerValue.match(/name="([^"]+)"/i)) {
+ part.name = m[1];
+ }
+
+ part.filename = self._fileName(headerValue);
+ } else if (headerField == 'content-type') {
+ part.mime = headerValue;
+ }
+
+ headerField = '';
+ headerValue = '';
+ };
+
+ parser.onHeadersEnd = function() {
+ self.onPart(part);
+ };
+
+ parser.onPartData = function(b, start, end) {
+ part.emit('data', b.slice(start, end));
+ };
+
+ parser.onPartEnd = function() {
+ part.emit('end');
+ };
+
+ parser.onEnd = function() {
+ self.ended = true;
+ self._maybeEnd();
+ };
+
+ this._parser = parser;
+};
+
+IncomingForm.prototype._fileName = function(headerValue) {
+ var m = headerValue.match(/filename="(.*?)"($|; )/i)
+ if (!m) return;
+
+ var filename = m[1].substr(m[1].lastIndexOf('\\') + 1);
+ filename = filename.replace(/%22/g, '"');
+ filename = filename.replace(/([\d]{4});/g, function(m, code) {
+ return String.fromCharCode(code);
+ });
+ return filename;
+};
+
+IncomingForm.prototype._initUrlencoded = function() {
+ this.type = 'urlencoded';
+
+ var parser = new QuerystringParser()
+ , self = this;
+
+ parser.onField = function(key, val) {
+ self.emit('field', key, val);
+ };
+
+ parser.onEnd = function() {
+ self.ended = true;
+ self._maybeEnd();
+ };
+
+ this._parser = parser;
+};
+
+IncomingForm.prototype._uploadPath = function(filename) {
+ var name = '';
+ for (var i = 0; i < 32; i++) {
+ name += Math.floor(Math.random() * 16).toString(16);
+ }
+
+ if (this.keepExtensions) {
+ var ext = path.extname(filename);
+ ext = ext.replace(/(\.[a-z0-9]+).*/, '$1')
+
+ name += ext;
+ }
+
+ return path.join(this.uploadDir, name);
+};
+
+IncomingForm.prototype._maybeEnd = function() {
+ if (!this.ended || this._flushing) {
+ return;
+ }
+
+ this.emit('end');
+};
diff --git a/node_modules/formidable/lib/index.js b/node_modules/formidable/lib/index.js
new file mode 100644
index 0000000..7a6e3e1
--- /dev/null
+++ b/node_modules/formidable/lib/index.js
@@ -0,0 +1,3 @@
+var IncomingForm = require('./incoming_form').IncomingForm;
+IncomingForm.IncomingForm = IncomingForm;
+module.exports = IncomingForm;
diff --git a/node_modules/formidable/lib/multipart_parser.js b/node_modules/formidable/lib/multipart_parser.js
new file mode 100644
index 0000000..9ca567c
--- /dev/null
+++ b/node_modules/formidable/lib/multipart_parser.js
@@ -0,0 +1,312 @@
+var Buffer = require('buffer').Buffer,
+ s = 0,
+ S =
+ { PARSER_UNINITIALIZED: s++,
+ START: s++,
+ START_BOUNDARY: s++,
+ HEADER_FIELD_START: s++,
+ HEADER_FIELD: s++,
+ HEADER_VALUE_START: s++,
+ HEADER_VALUE: s++,
+ HEADER_VALUE_ALMOST_DONE: s++,
+ HEADERS_ALMOST_DONE: s++,
+ PART_DATA_START: s++,
+ PART_DATA: s++,
+ PART_END: s++,
+ END: s++,
+ },
+
+ f = 1,
+ F =
+ { PART_BOUNDARY: f,
+ LAST_BOUNDARY: f *= 2,
+ },
+
+ LF = 10,
+ CR = 13,
+ SPACE = 32,
+ HYPHEN = 45,
+ COLON = 58,
+ A = 97,
+ Z = 122,
+
+ lower = function(c) {
+ return c | 0x20;
+ };
+
+for (var s in S) {
+ exports[s] = S[s];
+}
+
+function MultipartParser() {
+ this.boundary = null;
+ this.boundaryChars = null;
+ this.lookbehind = null;
+ this.state = S.PARSER_UNINITIALIZED;
+
+ this.index = null;
+ this.flags = 0;
+};
+exports.MultipartParser = MultipartParser;
+
+MultipartParser.stateToString = function(stateNumber) {
+ for (var state in S) {
+ var number = S[state];
+ if (number === stateNumber) return state;
+ }
+};
+
+MultipartParser.prototype.initWithBoundary = function(str) {
+ this.boundary = new Buffer(str.length+4);
+ this.boundary.write('\r\n--', 'ascii', 0);
+ this.boundary.write(str, 'ascii', 4);
+ this.lookbehind = new Buffer(this.boundary.length+8);
+ this.state = S.START;
+
+ this.boundaryChars = {};
+ for (var i = 0; i < this.boundary.length; i++) {
+ this.boundaryChars[this.boundary[i]] = true;
+ }
+};
+
+MultipartParser.prototype.write = function(buffer) {
+ var self = this,
+ i = 0,
+ len = buffer.length,
+ prevIndex = this.index,
+ index = this.index,
+ state = this.state,
+ flags = this.flags,
+ lookbehind = this.lookbehind,
+ boundary = this.boundary,
+ boundaryChars = this.boundaryChars,
+ boundaryLength = this.boundary.length,
+ boundaryEnd = boundaryLength - 1,
+ bufferLength = buffer.length,
+ c,
+ cl,
+
+ mark = function(name) {
+ self[name+'Mark'] = i;
+ },
+ clear = function(name) {
+ delete self[name+'Mark'];
+ },
+ callback = function(name, buffer, start, end) {
+ if (start !== undefined && start === end) {
+ return;
+ }
+
+ var callbackSymbol = 'on'+name.substr(0, 1).toUpperCase()+name.substr(1);
+ if (callbackSymbol in self) {
+ self[callbackSymbol](buffer, start, end);
+ }
+ },
+ dataCallback = function(name, clear) {
+ var markSymbol = name+'Mark';
+ if (!(markSymbol in self)) {
+ return;
+ }
+
+ if (!clear) {
+ callback(name, buffer, self[markSymbol], buffer.length);
+ self[markSymbol] = 0;
+ } else {
+ callback(name, buffer, self[markSymbol], i);
+ delete self[markSymbol];
+ }
+ };
+
+ for (i = 0; i < len; i++) {
+ c = buffer[i];
+ switch (state) {
+ case S.PARSER_UNINITIALIZED:
+ return i;
+ case S.START:
+ index = 0;
+ state = S.START_BOUNDARY;
+ case S.START_BOUNDARY:
+ if (index == boundary.length - 2) {
+ if (c != CR) {
+ return i;
+ }
+ index++;
+ break;
+ } else if (index - 1 == boundary.length - 2) {
+ if (c != LF) {
+ return i;
+ }
+ index = 0;
+ callback('partBegin');
+ state = S.HEADER_FIELD_START;
+ break;
+ }
+
+ if (c != boundary[index+2]) {
+ return i;
+ }
+ index++;
+ break;
+ case S.HEADER_FIELD_START:
+ state = S.HEADER_FIELD;
+ mark('headerField');
+ index = 0;
+ case S.HEADER_FIELD:
+ if (c == CR) {
+ clear('headerField');
+ state = S.HEADERS_ALMOST_DONE;
+ break;
+ }
+
+ index++;
+ if (c == HYPHEN) {
+ break;
+ }
+
+ if (c == COLON) {
+ if (index == 1) {
+ // empty header field
+ return i;
+ }
+ dataCallback('headerField', true);
+ state = S.HEADER_VALUE_START;
+ break;
+ }
+
+ cl = lower(c);
+ if (cl < A || cl > Z) {
+ return i;
+ }
+ break;
+ case S.HEADER_VALUE_START:
+ if (c == SPACE) {
+ break;
+ }
+
+ mark('headerValue');
+ state = S.HEADER_VALUE;
+ case S.HEADER_VALUE:
+ if (c == CR) {
+ dataCallback('headerValue', true);
+ callback('headerEnd');
+ state = S.HEADER_VALUE_ALMOST_DONE;
+ }
+ break;
+ case S.HEADER_VALUE_ALMOST_DONE:
+ if (c != LF) {
+ return i;
+ }
+ state = S.HEADER_FIELD_START;
+ break;
+ case S.HEADERS_ALMOST_DONE:
+ if (c != LF) {
+ return i;
+ }
+
+ callback('headersEnd');
+ state = S.PART_DATA_START;
+ break;
+ case S.PART_DATA_START:
+ state = S.PART_DATA
+ mark('partData');
+ case S.PART_DATA:
+ prevIndex = index;
+
+ if (index == 0) {
+ // boyer-moore derrived algorithm to safely skip non-boundary data
+ i += boundaryEnd;
+ while (i < bufferLength && !(buffer[i] in boundaryChars)) {
+ i += boundaryLength;
+ }
+ i -= boundaryEnd;
+ c = buffer[i];
+ }
+
+ if (index < boundary.length) {
+ if (boundary[index] == c) {
+ if (index == 0) {
+ dataCallback('partData', true);
+ }
+ index++;
+ } else {
+ index = 0;
+ }
+ } else if (index == boundary.length) {
+ index++;
+ if (c == CR) {
+ // CR = part boundary
+ flags |= F.PART_BOUNDARY;
+ } else if (c == HYPHEN) {
+ // HYPHEN = end boundary
+ flags |= F.LAST_BOUNDARY;
+ } else {
+ index = 0;
+ }
+ } else if (index - 1 == boundary.length) {
+ if (flags & F.PART_BOUNDARY) {
+ index = 0;
+ if (c == LF) {
+ // unset the PART_BOUNDARY flag
+ flags &= ~F.PART_BOUNDARY;
+ callback('partEnd');
+ callback('partBegin');
+ state = S.HEADER_FIELD_START;
+ break;
+ }
+ } else if (flags & F.LAST_BOUNDARY) {
+ if (c == HYPHEN) {
+ callback('partEnd');
+ callback('end');
+ state = S.END;
+ } else {
+ index = 0;
+ }
+ } else {
+ index = 0;
+ }
+ }
+
+ if (index > 0) {
+ // when matching a possible boundary, keep a lookbehind reference
+ // in case it turns out to be a false lead
+ lookbehind[index-1] = c;
+ } else if (prevIndex > 0) {
+ // if our boundary turned out to be rubbish, the captured lookbehind
+ // belongs to partData
+ callback('partData', lookbehind, 0, prevIndex);
+ prevIndex = 0;
+ mark('partData');
+
+ // reconsider the current character even so it interrupted the sequence
+ // it could be the beginning of a new sequence
+ i--;
+ }
+
+ break;
+ case S.END:
+ break;
+ default:
+ return i;
+ }
+ }
+
+ dataCallback('headerField');
+ dataCallback('headerValue');
+ dataCallback('partData');
+
+ this.index = index;
+ this.state = state;
+ this.flags = flags;
+
+ return len;
+};
+
+MultipartParser.prototype.end = function() {
+ if (this.state != S.END) {
+ return new Error('MultipartParser.end(): stream ended unexpectedly: ' + this.explain());
+ }
+};
+
+MultipartParser.prototype.explain = function() {
+ return 'state = ' + MultipartParser.stateToString(this.state);
+};
diff --git a/node_modules/formidable/lib/querystring_parser.js b/node_modules/formidable/lib/querystring_parser.js
new file mode 100644
index 0000000..63f109e
--- /dev/null
+++ b/node_modules/formidable/lib/querystring_parser.js
@@ -0,0 +1,25 @@
+if (global.GENTLY) require = GENTLY.hijack(require);
+
+// This is a buffering parser, not quite as nice as the multipart one.
+// If I find time I'll rewrite this to be fully streaming as well
+var querystring = require('querystring');
+
+function QuerystringParser() {
+ this.buffer = '';
+};
+exports.QuerystringParser = QuerystringParser;
+
+QuerystringParser.prototype.write = function(buffer) {
+ this.buffer += buffer.toString('ascii');
+ return buffer.length;
+};
+
+QuerystringParser.prototype.end = function() {
+ var fields = querystring.parse(this.buffer);
+ for (var field in fields) {
+ this.onField(field, fields[field]);
+ }
+ this.buffer = '';
+
+ this.onEnd();
+};
\ No newline at end of file
diff --git a/node_modules/formidable/lib/util.js b/node_modules/formidable/lib/util.js
new file mode 100644
index 0000000..e9493e9
--- /dev/null
+++ b/node_modules/formidable/lib/util.js
@@ -0,0 +1,6 @@
+// Backwards compatibility ...
+try {
+ module.exports = require('util');
+} catch (e) {
+ module.exports = require('sys');
+}
diff --git a/node_modules/formidable/node-gently/Makefile b/node_modules/formidable/node-gently/Makefile
new file mode 100644
index 0000000..01f7140
--- /dev/null
+++ b/node_modules/formidable/node-gently/Makefile
@@ -0,0 +1,4 @@
+test:
+ @find test/simple/test-*.js | xargs -n 1 -t node
+
+.PHONY: test
\ No newline at end of file
diff --git a/node_modules/formidable/node-gently/Readme.md b/node_modules/formidable/node-gently/Readme.md
new file mode 100644
index 0000000..f8f0c66
--- /dev/null
+++ b/node_modules/formidable/node-gently/Readme.md
@@ -0,0 +1,167 @@
+# Gently
+
+## Purpose
+
+A node.js module that helps with stubbing and behavior verification. It allows you to test the most remote and nested corners of your code while keeping being fully unobtrusive.
+
+## Features
+
+* Overwrite and stub individual object functions
+* Verify that all expected calls have been made in the expected order
+* Restore stubbed functions to their original behavior
+* Detect object / class names from obj.constructor.name and obj.toString()
+* Hijack any required module function or class constructor
+
+## Installation
+
+Via [npm](http://github.com/isaacs/npm):
+
+ npm install gently@latest
+
+## Example
+
+Make sure your dog is working properly:
+
+ function Dog() {}
+
+ Dog.prototype.seeCat = function() {
+ this.bark('whuf, whuf');
+ this.run();
+ }
+
+ Dog.prototype.bark = function(bark) {
+ require('sys').puts(bark);
+ }
+
+ var gently = new (require('gently'))
+ , assert = require('assert')
+ , dog = new Dog();
+
+ gently.expect(dog, 'bark', function(bark) {
+ assert.equal(bark, 'whuf, whuf');
+ });
+ gently.expect(dog, 'run');
+
+ dog.seeCat();
+
+You can also easily test event emitters with this, for example a simple sequence of 2 events emitted by `fs.WriteStream`:
+
+ var gently = new (require('gently'))
+ , stream = new (require('fs').WriteStream)('my_file.txt');
+
+ gently.expect(stream, 'emit', function(event) {
+ assert.equal(event, 'open');
+ });
+
+ gently.expect(stream, 'emit', function(event) {
+ assert.equal(event, 'drain');
+ });
+
+For a full read world example, check out this test case: [test-incoming-form.js](http://github.com/felixge/node-formidable/blob/master/test/simple/test-incoming-form.js) (in [node-formdiable](http://github.com/felixge/node-formidable)).
+
+## API
+
+### Gently
+
+#### new Gently()
+
+Creates a new gently instance. It listens to the process `'exit'` event to make sure all expectations have been verified.
+
+#### gently.expect(obj, method, [[count], stubFn])
+
+Creates an expectation for an objects method to be called. You can optionally specify the call `count` you are expecting, as well as `stubFn` function that will run instead of the original function.
+
+Returns a reference to the function that is getting overwritten.
+
+#### gently.expect([count], stubFn)
+
+Returns a function that is supposed to be executed `count` times, delegating any calls to the provided `stubFn` function. Naming your stubFn closure will help to properly diagnose errors that are being thrown:
+
+ childProcess.exec('ls', gently.expect(function lsCallback(code) {
+ assert.equal(0, code);
+ }));
+
+#### gently.restore(obj, method)
+
+Restores an object method that has been previously overwritten using `gently.expect()`.
+
+#### gently.hijack(realRequire)
+
+Returns a new require functions that catches a reference to all required modules into `gently.hijacked`.
+
+To use this function, include a line like this in your `'my-module.js'`.
+
+ if (global.GENTLY) require = GENTLY.hijack(require);
+
+ var sys = require('sys');
+ exports.hello = function() {
+ sys.log('world');
+ };
+
+Now you can write a test for the module above:
+
+ var gently = global.GENTLY = new (require('gently'))
+ , myModule = require('./my-module');
+
+ gently.expect(gently.hijacked.sys, 'log', function(str) {
+ assert.equal(str, 'world');
+ });
+
+ myModule.hello();
+
+#### gently.stub(location, [exportsName])
+
+Returns a stub class that will be used instead of the real class from the module at `location` with the given `exportsName`.
+
+This allows to test an OOP version of the previous example, where `'my-module.js'`.
+
+ if (global.GENTLY) require = GENTLY.hijack(require);
+
+ var World = require('./world');
+
+ exports.hello = function() {
+ var world = new World();
+ world.hello();
+ }
+
+And `world.js` looks like this:
+
+ var sys = require('sys');
+
+ function World() {
+
+ }
+ module.exports = World;
+
+ World.prototype.hello = function() {
+ sys.log('world');
+ };
+
+Testing `'my-module.js'` can now easily be accomplished:
+
+ var gently = global.GENTLY = new (require('gently'))
+ , WorldStub = gently.stub('./world')
+ , myModule = require('./my-module')
+ , WORLD;
+
+ gently.expect(WorldStub, 'new', function() {
+ WORLD = this;
+ });
+
+ gently.expect(WORLD, 'hello');
+
+ myModule.hello();
+
+#### gently.hijacked
+
+An object that holds the references to all hijacked modules.
+
+#### gently.verify([msg])
+
+Verifies that all expectations of this gently instance have been satisfied. If not called manually, this method is called when the process `'exit'` event is fired.
+
+If `msg` is given, it will appear in any error that might be thrown.
+
+## License
+
+Gently is licensed under the MIT license.
\ No newline at end of file
diff --git a/node_modules/formidable/node-gently/example/dog.js b/node_modules/formidable/node-gently/example/dog.js
new file mode 100644
index 0000000..022fae0
--- /dev/null
+++ b/node_modules/formidable/node-gently/example/dog.js
@@ -0,0 +1,22 @@
+require('../test/common');
+function Dog() {}
+
+Dog.prototype.seeCat = function() {
+ this.bark('whuf, whuf');
+ this.run();
+}
+
+Dog.prototype.bark = function(bark) {
+ require('sys').puts(bark);
+}
+
+var gently = new (require('gently'))
+ , assert = require('assert')
+ , dog = new Dog();
+
+gently.expect(dog, 'bark', function(bark) {
+ assert.equal(bark, 'whuf, whuf');
+});
+gently.expect(dog, 'run');
+
+dog.seeCat();
\ No newline at end of file
diff --git a/node_modules/formidable/node-gently/example/event_emitter.js b/node_modules/formidable/node-gently/example/event_emitter.js
new file mode 100644
index 0000000..7def134
--- /dev/null
+++ b/node_modules/formidable/node-gently/example/event_emitter.js
@@ -0,0 +1,11 @@
+require('../test/common');
+var gently = new (require('gently'))
+ , stream = new (require('fs').WriteStream)('my_file.txt');
+
+gently.expect(stream, 'emit', function(event) {
+ assert.equal(event, 'open');
+});
+
+gently.expect(stream, 'emit', function(event) {
+ assert.equal(event, 'drain');
+});
\ No newline at end of file
diff --git a/node_modules/formidable/node-gently/index.js b/node_modules/formidable/node-gently/index.js
new file mode 100644
index 0000000..69122bd
--- /dev/null
+++ b/node_modules/formidable/node-gently/index.js
@@ -0,0 +1 @@
+module.exports = require('./lib/gently');
\ No newline at end of file
diff --git a/node_modules/formidable/node-gently/lib/gently/gently.js b/node_modules/formidable/node-gently/lib/gently/gently.js
new file mode 100644
index 0000000..8af0e1e
--- /dev/null
+++ b/node_modules/formidable/node-gently/lib/gently/gently.js
@@ -0,0 +1,184 @@
+var path = require('path');
+
+function Gently() {
+ this.expectations = [];
+ this.hijacked = {};
+
+ var self = this;
+ process.addListener('exit', function() {
+ self.verify('process exit');
+ });
+};
+module.exports = Gently;
+
+Gently.prototype.stub = function(location, exportsName) {
+ function Stub() {
+ return Stub['new'].apply(this, arguments);
+ };
+
+ Stub['new'] = function () {};
+
+ var stubName = 'require('+JSON.stringify(location)+')';
+ if (exportsName) {
+ stubName += '.'+exportsName;
+ }
+
+ Stub.prototype.toString = Stub.toString = function() {
+ return stubName;
+ };
+
+ var exports = this.hijacked[location] || {};
+ if (exportsName) {
+ exports[exportsName] = Stub;
+ } else {
+ exports = Stub;
+ }
+
+ this.hijacked[location] = exports;
+ return Stub;
+};
+
+Gently.prototype.hijack = function(realRequire) {
+ var self = this;
+ return function(location) {
+ return self.hijacked[location] = (self.hijacked[location])
+ ? self.hijacked[location]
+ : realRequire(location);
+ };
+};
+
+Gently.prototype.expect = function(obj, method, count, stubFn) {
+ if (typeof obj != 'function' && typeof obj != 'object' && typeof obj != 'number') {
+ throw new Error
+ ( 'Bad 1st argument for gently.expect(), '
+ + 'object, function, or number expected, got: '+(typeof obj)
+ );
+ } else if (typeof obj == 'function' && (typeof method != 'string')) {
+ // expect(stubFn) interface
+ stubFn = obj;
+ obj = null;
+ method = null;
+ count = 1;
+ } else if (typeof method == 'function') {
+ // expect(count, stubFn) interface
+ count = obj;
+ stubFn = method;
+ obj = null;
+ method = null;
+ } else if (typeof count == 'function') {
+ // expect(obj, method, stubFn) interface
+ stubFn = count;
+ count = 1;
+ } else if (count === undefined) {
+ // expect(obj, method) interface
+ count = 1;
+ }
+
+ var name = this._name(obj, method, stubFn);
+ this.expectations.push({obj: obj, method: method, stubFn: stubFn, name: name, count: count});
+
+ var self = this;
+ function delegate() {
+ return self._stubFn(this, obj, method, name, Array.prototype.slice.call(arguments));
+ }
+
+ if (!obj) {
+ return delegate;
+ }
+
+ var original = (obj[method])
+ ? obj[method]._original || obj[method]
+ : undefined;
+
+ obj[method] = delegate;
+ return obj[method]._original = original;
+};
+
+Gently.prototype.restore = function(obj, method) {
+ if (!obj[method] || !obj[method]._original) {
+ throw new Error(this._name(obj, method)+' is not gently stubbed');
+ }
+ obj[method] = obj[method]._original;
+};
+
+Gently.prototype.verify = function(msg) {
+ if (!this.expectations.length) {
+ return;
+ }
+
+ var validExpectations = [];
+ for (var i = 0, l = this.expectations.length; i < l; i++) {
+ var expectation = this.expectations[i];
+
+ if (expectation.count > 0) {
+ validExpectations.push(expectation);
+ }
+ }
+
+ this.expectations = []; // reset so that no duplicate verification attempts are made
+
+ if (!validExpectations.length) {
+ return;
+ }
+
+ var expectation = validExpectations[0];
+
+ throw new Error
+ ( 'Expected call to '+expectation.name+' did not happen'
+ + ( (msg)
+ ? ' ('+msg+')'
+ : ''
+ )
+ );
+};
+
+Gently.prototype._stubFn = function(self, obj, method, name, args) {
+ var expectation = this.expectations[0], obj, method;
+
+ if (!expectation) {
+ throw new Error('Unexpected call to '+name+', no call was expected');
+ }
+
+ if (expectation.obj !== obj || expectation.method !== method) {
+ throw new Error('Unexpected call to '+name+', expected call to '+ expectation.name);
+ }
+
+ expectation.count -= 1;
+ if (expectation.count === 0) {
+ this.expectations.shift();
+
+ // autorestore original if its not a closure
+ // and no more expectations on that object
+ var has_more_expectations = this.expectations.reduce(function (memo, expectation) {
+ return memo || (expectation.obj === obj && expectation.method === method);
+ }, false);
+ if (obj !== null && method !== null && !has_more_expectations) {
+ if (typeof obj[method]._original !== 'undefined') {
+ obj[method] = obj[method]._original;
+ delete obj[method]._original;
+ } else {
+ delete obj[method];
+ }
+ }
+ }
+
+ if (expectation.stubFn) {
+ return expectation.stubFn.apply(self, args);
+ }
+};
+
+Gently.prototype._name = function(obj, method, stubFn) {
+ if (obj) {
+ var objectName = obj.toString();
+ if (objectName == '[object Object]' && obj.constructor.name) {
+ objectName = '['+obj.constructor.name+']';
+ }
+ return (objectName)+'.'+method+'()';
+ }
+
+ if (stubFn.name) {
+ return stubFn.name+'()';
+ }
+
+ return '>> '+stubFn.toString()+' <<';
+};
diff --git a/node_modules/formidable/node-gently/lib/gently/index.js b/node_modules/formidable/node-gently/lib/gently/index.js
new file mode 100644
index 0000000..64c1977
--- /dev/null
+++ b/node_modules/formidable/node-gently/lib/gently/index.js
@@ -0,0 +1 @@
+module.exports = require('./gently');
\ No newline at end of file
diff --git a/node_modules/formidable/node-gently/package.json b/node_modules/formidable/node-gently/package.json
new file mode 100644
index 0000000..9c1b7a0
--- /dev/null
+++ b/node_modules/formidable/node-gently/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "gently",
+ "version": "0.9.2",
+ "directories": {
+ "lib": "./lib/gently"
+ },
+ "main": "./lib/gently/index",
+ "dependencies": {},
+ "devDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "optionalDependencies": {}
+}
diff --git a/node_modules/formidable/node-gently/test/common.js b/node_modules/formidable/node-gently/test/common.js
new file mode 100644
index 0000000..978b5c5
--- /dev/null
+++ b/node_modules/formidable/node-gently/test/common.js
@@ -0,0 +1,8 @@
+var path = require('path')
+ , sys = require('sys');
+
+require.paths.unshift(path.dirname(__dirname)+'/lib');
+
+global.puts = sys.puts;
+global.p = function() {sys.error(sys.inspect.apply(null, arguments))};;
+global.assert = require('assert');
\ No newline at end of file
diff --git a/node_modules/formidable/node-gently/test/simple/test-gently.js b/node_modules/formidable/node-gently/test/simple/test-gently.js
new file mode 100644
index 0000000..4f8fe2d
--- /dev/null
+++ b/node_modules/formidable/node-gently/test/simple/test-gently.js
@@ -0,0 +1,348 @@
+require('../common');
+var Gently = require('gently')
+ , gently;
+
+function test(test) {
+ process.removeAllListeners('exit');
+ gently = new Gently();
+ test();
+}
+
+test(function constructor() {
+ assert.deepEqual(gently.expectations, []);
+ assert.deepEqual(gently.hijacked, {});
+ assert.equal(gently.constructor.name, 'Gently');
+});
+
+test(function expectBadArgs() {
+ var BAD_ARG = 'oh no';
+ try {
+ gently.expect(BAD_ARG);
+ assert.ok(false, 'throw needs to happen');
+ } catch (e) {
+ assert.equal(e.message, 'Bad 1st argument for gently.expect(), object, function, or number expected, got: '+(typeof BAD_ARG));
+ }
+});
+
+test(function expectObjMethod() {
+ var OBJ = {}, NAME = 'foobar';
+ OBJ.foo = function(x) {
+ return x;
+ };
+
+ gently._name = function() {
+ return NAME;
+ };
+
+ var original = OBJ.foo
+ , stubFn = function() {};
+
+ (function testAddOne() {
+ assert.strictEqual(gently.expect(OBJ, 'foo', stubFn), original);
+
+ assert.equal(gently.expectations.length, 1);
+ var expectation = gently.expectations[0];
+ assert.strictEqual(expectation.obj, OBJ);
+ assert.strictEqual(expectation.method, 'foo');
+ assert.strictEqual(expectation.stubFn, stubFn);
+ assert.strictEqual(expectation.name, NAME);
+ assert.strictEqual(OBJ.foo._original, original);
+ })();
+
+ (function testAddTwo() {
+ gently.expect(OBJ, 'foo', 2, stubFn);
+ assert.equal(gently.expectations.length, 2);
+ assert.strictEqual(OBJ.foo._original, original);
+ })();
+
+ (function testAddOneWithoutMock() {
+ gently.expect(OBJ, 'foo');
+ assert.equal(gently.expectations.length, 3);
+ })();
+
+ var stubFnCalled = 0, SELF = {};
+ gently._stubFn = function(self, obj, method, name, args) {
+ stubFnCalled++;
+ assert.strictEqual(self, SELF);
+ assert.strictEqual(obj, OBJ);
+ assert.strictEqual(method, 'foo');
+ assert.strictEqual(name, NAME);
+ assert.deepEqual(args, [1, 2]);
+ return 23;
+ };
+ assert.equal(OBJ.foo.apply(SELF, [1, 2]), 23);
+ assert.equal(stubFnCalled, 1);
+});
+
+test(function expectClosure() {
+ var NAME = 'MY CLOSURE';
+ function closureFn() {};
+
+ gently._name = function() {
+ return NAME;
+ };
+
+ var fn = gently.expect(closureFn);
+ assert.equal(gently.expectations.length, 1);
+ var expectation = gently.expectations[0];
+ assert.strictEqual(expectation.obj, null);
+ assert.strictEqual(expectation.method, null);
+ assert.strictEqual(expectation.stubFn, closureFn);
+ assert.strictEqual(expectation.name, NAME);
+
+ var stubFnCalled = 0, SELF = {};
+ gently._stubFn = function(self, obj, method, name, args) {
+ stubFnCalled++;
+ assert.strictEqual(self, SELF);
+ assert.strictEqual(obj, null);
+ assert.strictEqual(method, null);
+ assert.strictEqual(name, NAME);
+ assert.deepEqual(args, [1, 2]);
+ return 23;
+ };
+ assert.equal(fn.apply(SELF, [1, 2]), 23);
+ assert.equal(stubFnCalled, 1);
+});
+
+test(function expectClosureCount() {
+ var stubFnCalled = 0;
+ function closureFn() {stubFnCalled++};
+
+ var fn = gently.expect(2, closureFn);
+ assert.equal(gently.expectations.length, 1);
+ fn();
+ assert.equal(gently.expectations.length, 1);
+ fn();
+ assert.equal(stubFnCalled, 2);
+});
+
+test(function restore() {
+ var OBJ = {}, NAME = '[my object].myFn()';
+ OBJ.foo = function(x) {
+ return x;
+ };
+
+ gently._name = function() {
+ return NAME;
+ };
+
+ var original = OBJ.foo;
+ gently.expect(OBJ, 'foo');
+ gently.restore(OBJ, 'foo');
+ assert.strictEqual(OBJ.foo, original);
+
+ (function testError() {
+ try {
+ gently.restore(OBJ, 'foo');
+ assert.ok(false, 'throw needs to happen');
+ } catch (e) {
+ assert.equal(e.message, NAME+' is not gently stubbed');
+ }
+ })();
+});
+
+test(function _stubFn() {
+ var OBJ1 = {toString: function() {return '[OBJ 1]'}}
+ , OBJ2 = {toString: function() {return '[OBJ 2]'}, foo: function () {return 'bar';}}
+ , SELF = {};
+
+ gently.expect(OBJ1, 'foo', function(x) {
+ assert.strictEqual(this, SELF);
+ return x * 2;
+ });
+
+ assert.equal(gently._stubFn(SELF, OBJ1, 'foo', 'dummy_name', [5]), 10);
+
+ (function testAutorestore() {
+ assert.equal(OBJ2.foo(), 'bar');
+
+ gently.expect(OBJ2, 'foo', function() {
+ return 'stubbed foo';
+ });
+
+ gently.expect(OBJ2, 'foo', function() {
+ return "didn't restore yet";
+ });
+
+ assert.equal(gently._stubFn(SELF, OBJ2, 'foo', 'dummy_name', []), 'stubbed foo');
+ assert.equal(gently._stubFn(SELF, OBJ2, 'foo', 'dummy_name', []), "didn't restore yet");
+ assert.equal(OBJ2.foo(), 'bar');
+ assert.deepEqual(gently.expectations, []);
+ })();
+
+ (function testNoMoreCallExpected() {
+ try {
+ gently._stubFn(SELF, OBJ1, 'foo', 'dummy_name', [5]);
+ assert.ok(false, 'throw needs to happen');
+ } catch (e) {
+ assert.equal(e.message, 'Unexpected call to dummy_name, no call was expected');
+ }
+ })();
+
+ (function testDifferentCallExpected() {
+ gently.expect(OBJ2, 'bar');
+ try {
+ gently._stubFn(SELF, OBJ1, 'foo', 'dummy_name', [5]);
+ assert.ok(false, 'throw needs to happen');
+ } catch (e) {
+ assert.equal(e.message, 'Unexpected call to dummy_name, expected call to '+gently._name(OBJ2, 'bar'));
+ }
+
+ assert.equal(gently.expectations.length, 1);
+ })();
+
+ (function testNoMockCallback() {
+ OBJ2.bar();
+ assert.equal(gently.expectations.length, 0);
+ })();
+});
+
+test(function stub() {
+ var LOCATION = './my_class';
+
+ (function testRegular() {
+ var Stub = gently.stub(LOCATION);
+ assert.ok(Stub instanceof Function);
+ assert.strictEqual(gently.hijacked[LOCATION], Stub);
+ assert.ok(Stub['new'] instanceof Function);
+ assert.equal(Stub.toString(), 'require('+JSON.stringify(LOCATION)+')');
+
+ (function testConstructor() {
+ var newCalled = 0
+ , STUB
+ , ARGS = ['foo', 'bar'];
+
+ Stub['new'] = function(a, b) {
+ assert.equal(a, ARGS[0]);
+ assert.equal(b, ARGS[1]);
+ newCalled++;
+ STUB = this;
+ };
+
+ var stub = new Stub(ARGS[0], ARGS[1]);
+ assert.strictEqual(stub, STUB);
+ assert.equal(newCalled, 1);
+ assert.equal(stub.toString(), 'require('+JSON.stringify(LOCATION)+')');
+ })();
+
+ (function testUseReturnValueAsInstance() {
+ var R = {};
+
+ Stub['new'] = function() {
+ return R;
+ };
+
+ var stub = new Stub();
+ assert.strictEqual(stub, R);
+
+ })();
+ })();
+
+ var EXPORTS_NAME = 'MyClass';
+ test(function testExportsName() {
+ var Stub = gently.stub(LOCATION, EXPORTS_NAME);
+ assert.strictEqual(gently.hijacked[LOCATION][EXPORTS_NAME], Stub);
+ assert.equal(Stub.toString(), 'require('+JSON.stringify(LOCATION)+').'+EXPORTS_NAME);
+
+ (function testConstructor() {
+ var stub = new Stub();
+ assert.equal(Stub.toString(), 'require('+JSON.stringify(LOCATION)+').'+EXPORTS_NAME);
+ })();
+ });
+});
+
+test(function hijack() {
+ var LOCATION = './foo'
+ , REQUIRE_CALLS = 0
+ , EXPORTS = {}
+ , REQUIRE = function() {
+ REQUIRE_CALLS++;
+ return EXPORTS;
+ };
+
+ var hijackedRequire = gently.hijack(REQUIRE);
+ hijackedRequire(LOCATION);
+ assert.strictEqual(gently.hijacked[LOCATION], EXPORTS);
+
+ assert.equal(REQUIRE_CALLS, 1);
+
+ // make sure we are caching the hijacked module
+ hijackedRequire(LOCATION);
+ assert.equal(REQUIRE_CALLS, 1);
+});
+
+test(function verify() {
+ var OBJ = {toString: function() {return '[OBJ]'}};
+ gently.verify();
+
+ gently.expect(OBJ, 'foo');
+ try {
+ gently.verify();
+ assert.ok(false, 'throw needs to happen');
+ } catch (e) {
+ assert.equal(e.message, 'Expected call to [OBJ].foo() did not happen');
+ }
+
+ try {
+ gently.verify('foo');
+ assert.ok(false, 'throw needs to happen');
+ } catch (e) {
+ assert.equal(e.message, 'Expected call to [OBJ].foo() did not happen (foo)');
+ }
+});
+
+test(function processExit() {
+ var verifyCalled = 0;
+ gently.verify = function(msg) {
+ verifyCalled++;
+ assert.equal(msg, 'process exit');
+ };
+
+ process.emit('exit');
+ assert.equal(verifyCalled, 1);
+});
+
+test(function _name() {
+ (function testNamedClass() {
+ function Foo() {};
+ var foo = new Foo();
+ assert.equal(gently._name(foo, 'bar'), '[Foo].bar()');
+ })();
+
+ (function testToStringPreference() {
+ function Foo() {};
+ Foo.prototype.toString = function() {
+ return '[Superman 123]';
+ };
+ var foo = new Foo();
+ assert.equal(gently._name(foo, 'bar'), '[Superman 123].bar()');
+ })();
+
+ (function testUnamedClass() {
+ var Foo = function() {};
+ var foo = new Foo();
+ assert.equal(gently._name(foo, 'bar'), foo.toString()+'.bar()');
+ })();
+
+ (function testNamedClosure() {
+ function myClosure() {};
+ assert.equal(gently._name(null, null, myClosure), myClosure.name+'()');
+ })();
+
+ (function testUnamedClosure() {
+ var myClosure = function() {2+2 == 5};
+ assert.equal(gently._name(null, null, myClosure), '>> '+myClosure.toString()+' <<');
+ })();
+});
+
+test(function verifyExpectNone() {
+ var OBJ = {toString: function() {return '[OBJ]'}};
+ gently.verify();
+
+ gently.expect(OBJ, 'foo', 0);
+ try {
+ gently.verify();
+ } catch (e) {
+ assert.fail('Exception should not have been thrown');
+ }
+});
\ No newline at end of file
diff --git a/node_modules/formidable/package.json b/node_modules/formidable/package.json
new file mode 100644
index 0000000..cc613f1
--- /dev/null
+++ b/node_modules/formidable/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "formidable",
+ "version": "1.0.11",
+ "dependencies": {},
+ "devDependencies": {
+ "gently": "0.8.0",
+ "findit": "0.1.1",
+ "hashish": "0.0.4",
+ "urun": "0.0.4",
+ "utest": "0.0.3"
+ },
+ "directories": {
+ "lib": "./lib"
+ },
+ "main": "./lib/index",
+ "scripts": {
+ "test": "make test"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "optionalDependencies": {},
+ "_id": "formidable@1.0.11",
+ "_engineSupported": true,
+ "_npmVersion": "1.1.21",
+ "_nodeVersion": "v0.6.18",
+ "_defaultsLoaded": true,
+ "_from": "formidable@>= 0.0.1"
+}
diff --git a/node_modules/formidable/test/common.js b/node_modules/formidable/test/common.js
new file mode 100644
index 0000000..eb432ad
--- /dev/null
+++ b/node_modules/formidable/test/common.js
@@ -0,0 +1,19 @@
+var mysql = require('..');
+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);
+};
diff --git a/node_modules/formidable/test/fixture/file/funkyfilename.txt b/node_modules/formidable/test/fixture/file/funkyfilename.txt
new file mode 100644
index 0000000..e7a4785
--- /dev/null
+++ b/node_modules/formidable/test/fixture/file/funkyfilename.txt
@@ -0,0 +1 @@
+I am a text file with a funky name!
diff --git a/node_modules/formidable/test/fixture/file/plain.txt b/node_modules/formidable/test/fixture/file/plain.txt
new file mode 100644
index 0000000..9b6903e
--- /dev/null
+++ b/node_modules/formidable/test/fixture/file/plain.txt
@@ -0,0 +1 @@
+I am a plain text file
diff --git a/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md b/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md
new file mode 100644
index 0000000..3c9dbe3
--- /dev/null
+++ b/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md
@@ -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).
diff --git a/node_modules/formidable/test/fixture/js/no-filename.js b/node_modules/formidable/test/fixture/js/no-filename.js
new file mode 100644
index 0000000..0bae449
--- /dev/null
+++ b/node_modules/formidable/test/fixture/js/no-filename.js
@@ -0,0 +1,3 @@
+module.exports['generic.http'] = [
+ {type: 'file', name: 'upload', filename: '', fixture: 'plain.txt'},
+];
diff --git a/node_modules/formidable/test/fixture/js/special-chars-in-filename.js b/node_modules/formidable/test/fixture/js/special-chars-in-filename.js
new file mode 100644
index 0000000..eb76fdc
--- /dev/null
+++ b/node_modules/formidable/test/fixture/js/special-chars-in-filename.js
@@ -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),
+};
diff --git a/node_modules/formidable/test/fixture/multipart.js b/node_modules/formidable/test/fixture/multipart.js
new file mode 100644
index 0000000..a476169
--- /dev/null
+++ b/node_modules/formidable/test/fixture/multipart.js
@@ -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,
+ };
diff --git a/node_modules/formidable/test/integration/test-fixtures.js b/node_modules/formidable/test/integration/test-fixtures.js
new file mode 100644
index 0000000..66ad259
--- /dev/null
+++ b/node_modules/formidable/test/integration/test-fixtures.js
@@ -0,0 +1,89 @@
+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 filename = parsedPart.value.name;
+ assert.equal(filename, expectedPart.filename);
+ }
+ });
+
+ testNext(fixtures);
+ });
+};
+
+function uploadFixture(name, cb) {
+ server.once('request', function(req, res) {
+ var form = new formidable.IncomingForm();
+ form.uploadDir = common.dir.tmp;
+ 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() {
+ callback(null, parts);
+ });
+ });
+
+ var socket = net.createConnection(common.port);
+ var file = fs.createReadStream(common.dir.fixture + '/http/' + name);
+
+ file.pipe(socket);
+}
diff --git a/node_modules/formidable/test/legacy/common.js b/node_modules/formidable/test/legacy/common.js
new file mode 100644
index 0000000..2b98598
--- /dev/null
+++ b/node_modules/formidable/test/legacy/common.js
@@ -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);
+}
diff --git a/node_modules/formidable/test/legacy/integration/test-multipart-parser.js b/node_modules/formidable/test/legacy/integration/test-multipart-parser.js
new file mode 100644
index 0000000..75232aa
--- /dev/null
+++ b/node_modules/formidable/test/legacy/integration/test-multipart-parser.js
@@ -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);
+});
diff --git a/node_modules/formidable/test/legacy/simple/test-file.js b/node_modules/formidable/test/legacy/simple/test-file.js
new file mode 100644
index 0000000..52ceedb
--- /dev/null
+++ b/node_modules/formidable/test/legacy/simple/test-file.js
@@ -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);
+});
diff --git a/node_modules/formidable/test/legacy/simple/test-incoming-form.js b/node_modules/formidable/test/legacy/simple/test-incoming-form.js
new file mode 100644
index 0000000..84de439
--- /dev/null
+++ b/node_modules/formidable/test/legacy/simple/test-incoming-form.js
@@ -0,0 +1,727 @@
+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);
+ assert.strictEqual(form.uploadDir, '/tmp');
+ 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');
+ });
+
+ 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, 'writeHeaders');
+ gently.expect(REQ, 'on', 4, function() {
+ return this;
+ });
+
+ 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;
+ });
+
+ form.parse(REQ, gently.expect(function parseCbOk(err, fields, files) {
+ assert.deepEqual(fields, {field1: 'bar', field2: 'nice'});
+ assert.deepEqual(files, {file1: '2', file2: '3'});
+ }));
+
+ gently.expect(form, 'writeHeaders');
+ gently.expect(REQ, 'on', 4, function() {
+ return this;
+ });
+
+ 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');
+ }
+ return this;
+ });
+
+ form.parse(REQ, gently.expect(function parseCbErr(err, fields, files) {
+ assert.strictEqual(err, ERR);
+ assert.deepEqual(fields, {foo: 'bar'});
+ }));
+ })();
+});
+
+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 = {};
+ form._parseContentLength();
+ assert.strictEqual(form.bytesReceived, null);
+ assert.strictEqual(form.bytesExpected, null);
+
+ 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();
+});
diff --git a/node_modules/formidable/test/legacy/simple/test-multipart-parser.js b/node_modules/formidable/test/legacy/simple/test-multipart-parser.js
new file mode 100644
index 0000000..d8dc968
--- /dev/null
+++ b/node_modules/formidable/test/legacy/simple/test-multipart-parser.js
@@ -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), 3);
+});
+
+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);
+ })();
+});
diff --git a/node_modules/formidable/test/legacy/simple/test-querystring-parser.js b/node_modules/formidable/test/legacy/simple/test-querystring-parser.js
new file mode 100644
index 0000000..54d3e2d
--- /dev/null
+++ b/node_modules/formidable/test/legacy/simple/test-querystring-parser.js
@@ -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, '');
+});
diff --git a/node_modules/formidable/test/legacy/system/test-multi-video-upload.js b/node_modules/formidable/test/legacy/system/test-multi-video-upload.js
new file mode 100644
index 0000000..479e46d
--- /dev/null
+++ b/node_modules/formidable/test/legacy/system/test-multi-video-upload.js
@@ -0,0 +1,75 @@
+var common = require('../common');
+var BOUNDARY = '---------------------------10102754414578508781458777923',
+ FIXTURE = TEST_FIXTURES+'/multi_video.upload',
+ fs = require('fs'),
+ util = require(common.lib + '/util'),
+ 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.filename] = tracker;
+ file
+ .on('progress', function(bytesReceived) {
+ tracker.progress.push(bytesReceived);
+ assert.equal(bytesReceived, file.length);
+ })
+ .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.filename].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.length);
+ 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 client = http.createClient(TEST_PORT),
+ stat = fs.statSync(FIXTURE),
+ headers = {
+ 'content-type': 'multipart/form-data; boundary='+BOUNDARY,
+ 'content-length': stat.size,
+ }
+ request = client.request('POST', '/', headers),
+ fixture = new fs.ReadStream(FIXTURE);
+
+ fixture
+ .on('data', function(b) {
+ request.write(b);
+ })
+ .on('end', function() {
+ request.end();
+ });
+});
diff --git a/node_modules/formidable/test/run.js b/node_modules/formidable/test/run.js
new file mode 100644
index 0000000..50b2361
--- /dev/null
+++ b/node_modules/formidable/test/run.js
@@ -0,0 +1,2 @@
+#!/usr/bin/env node
+require('urun')(__dirname)
diff --git a/node_modules/formidable/test/unit/test-incoming-form.js b/node_modules/formidable/test/unit/test-incoming-form.js
new file mode 100644
index 0000000..fe2ac1c
--- /dev/null
+++ b/node_modules/formidable/test/unit/test-incoming-form.js
@@ -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☃.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 + '"';
+}
diff --git a/node_modules/formidable/tool/record.js b/node_modules/formidable/tool/record.js
new file mode 100644
index 0000000..9f1cef8
--- /dev/null
+++ b/node_modules/formidable/tool/record.js
@@ -0,0 +1,47 @@
+var http = require('http');
+var fs = require('fs');
+var connections = 0;
+
+var server = http.createServer(function(req, res) {
+ var socket = req.socket;
+ console.log('Request: %s %s -> %s', req.method, req.url, socket.filename);
+
+ req.on('end', function() {
+ if (req.url !== '/') {
+ res.end(JSON.stringify({
+ method: req.method,
+ url: req.url,
+ filename: socket.filename,
+ }));
+ return;
+ }
+
+ res.writeHead(200, {'content-type': 'text/html'});
+ res.end(
+ ''
+ );
+ });
+});
+
+server.on('connection', function(socket) {
+ connections++;
+
+ socket.id = connections;
+ socket.filename = 'connection-' + socket.id + '.http';
+ socket.file = fs.createWriteStream(socket.filename);
+ socket.pipe(socket.file);
+
+ console.log('--> %s', socket.filename);
+ socket.on('close', function() {
+ console.log('<-- %s', socket.filename);
+ });
+});
+
+var port = process.env.PORT || 8080;
+server.listen(port, function() {
+ console.log('Recording connections on port %s', port);
+});
diff --git a/node_modules/mongodb/.travis.yml b/node_modules/mongodb/.travis.yml
new file mode 100644
index 0000000..90b208a
--- /dev/null
+++ b/node_modules/mongodb/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
+ - 0.7 # development version of 0.8, may be unstable
\ No newline at end of file
diff --git a/node_modules/mongodb/Makefile b/node_modules/mongodb/Makefile
new file mode 100644
index 0000000..de11cbe
--- /dev/null
+++ b/node_modules/mongodb/Makefile
@@ -0,0 +1,71 @@
+NODE = node
+NPM = npm
+NODEUNIT = node_modules/nodeunit/bin/nodeunit
+DOX = node_modules/dox/bin/dox
+name = all
+
+total: build_native
+
+build_native:
+ # $(MAKE) -C ./external-libs/bson all
+
+build_native_debug:
+ $(MAKE) -C ./external-libs/bson all_debug
+
+build_native_clang:
+ $(MAKE) -C ./external-libs/bson clang
+
+build_native_clang_debug:
+ $(MAKE) -C ./external-libs/bson clang_debug
+
+clean_native:
+ $(MAKE) -C ./external-libs/bson clean
+
+test: build_native
+ @echo "\n == Run All tests minus replicaset tests=="
+ $(NODE) dev/tools/test_all.js --noreplicaset --boot
+
+test_pure: build_native
+ @echo "\n == Run All tests minus replicaset tests=="
+ $(NODE) dev/tools/test_all.js --noreplicaset --boot --noactive
+
+test_junit: build_native
+ @echo "\n == Run All tests minus replicaset tests=="
+ $(NODE) dev/tools/test_all.js --junit --noreplicaset
+
+test_nodeunit_pure:
+ @echo "\n == Execute Test Suite using Pure JS BSON Parser == "
+ @$(NODEUNIT) test/ test/gridstore test/bson
+
+test_js:
+ @$(NODEUNIT) $(TESTS)
+
+test_nodeunit_replicaset_pure:
+ @echo "\n == Execute Test Suite using Pure JS BSON Parser == "
+ @$(NODEUNIT) test/replicaset
+
+test_nodeunit_native:
+ @echo "\n == Execute Test Suite using Native BSON Parser == "
+ @TEST_NATIVE=TRUE $(NODEUNIT) test/ test/gridstore test/bson
+
+test_nodeunit_replicaset_native:
+ @echo "\n == Execute Test Suite using Native BSON Parser == "
+ @TEST_NATIVE=TRUE $(NODEUNIT) test/replicaset
+
+test_all: build_native
+ @echo "\n == Run All tests =="
+ $(NODE) dev/tools/test_all.js --boot
+
+test_all_junit: build_native
+ @echo "\n == Run All tests =="
+ $(NODE) dev/tools/test_all.js --junit --boot
+
+clean:
+ rm ./external-libs/bson/bson.node
+ rm -r ./external-libs/bson/build
+
+generate_docs:
+ $(NODE) dev/tools/build-docs.js
+ make --directory=./docs/sphinx-docs --file=Makefile html
+
+.PHONY: total
diff --git a/node_modules/mongodb/external-libs/bson/Makefile b/node_modules/mongodb/external-libs/bson/Makefile
new file mode 100644
index 0000000..ad877d4
--- /dev/null
+++ b/node_modules/mongodb/external-libs/bson/Makefile
@@ -0,0 +1,45 @@
+NODE = node
+name = all
+JOBS = 1
+
+all:
+ rm -rf build .lock-wscript bson.node
+ node-waf configure build
+ cp -R ./build/Release/bson.node . || true
+ @$(NODE) --expose-gc test/test_bson.js
+ @$(NODE) --expose-gc test/test_full_bson.js
+ # @$(NODE) --expose-gc test/test_stackless_bson.js
+
+all_debug:
+ rm -rf build .lock-wscript bson.node
+ node-waf --debug configure build
+ cp -R ./build/Release/bson.node . || true
+ @$(NODE) --expose-gc test/test_bson.js
+ @$(NODE) --expose-gc test/test_full_bson.js
+ # @$(NODE) --expose-gc test/test_stackless_bson.js
+
+test:
+ @$(NODE) --expose-gc test/test_bson.js
+ @$(NODE) --expose-gc test/test_full_bson.js
+ # @$(NODE) --expose-gc test/test_stackless_bson.js
+
+clang:
+ rm -rf build .lock-wscript bson.node
+ CXX=clang node-waf configure build
+ cp -R ./build/Release/bson.node . || true
+ @$(NODE) --expose-gc test/test_bson.js
+ @$(NODE) --expose-gc test/test_full_bson.js
+ # @$(NODE) --expose-gc test/test_stackless_bson.js
+
+clang_debug:
+ rm -rf build .lock-wscript bson.node
+ CXX=clang node-waf --debug configure build
+ cp -R ./build/Release/bson.node . || true
+ @$(NODE) --expose-gc test/test_bson.js
+ @$(NODE) --expose-gc test/test_full_bson.js
+ # @$(NODE) --expose-gc test/test_stackless_bson.js
+
+clean:
+ rm -rf build .lock-wscript bson.node
+
+.PHONY: all
\ No newline at end of file
diff --git a/node_modules/mongodb/external-libs/bson/bson.cc b/node_modules/mongodb/external-libs/bson/bson.cc
new file mode 100644
index 0000000..8906eea
--- /dev/null
+++ b/node_modules/mongodb/external-libs/bson/bson.cc
@@ -0,0 +1,2165 @@
+#include
+#include
+#include
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#endif
+
+#include
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "bson.h"
+
+using namespace v8;
+using namespace node;
+using namespace std;
+
+// BSON DATA TYPES
+const uint32_t BSON_DATA_NUMBER = 1;
+const uint32_t BSON_DATA_STRING = 2;
+const uint32_t BSON_DATA_OBJECT = 3;
+const uint32_t BSON_DATA_ARRAY = 4;
+const uint32_t BSON_DATA_BINARY = 5;
+const uint32_t BSON_DATA_OID = 7;
+const uint32_t BSON_DATA_BOOLEAN = 8;
+const uint32_t BSON_DATA_DATE = 9;
+const uint32_t BSON_DATA_NULL = 10;
+const uint32_t BSON_DATA_REGEXP = 11;
+const uint32_t BSON_DATA_CODE = 13;
+const uint32_t BSON_DATA_SYMBOL = 14;
+const uint32_t BSON_DATA_CODE_W_SCOPE = 15;
+const uint32_t BSON_DATA_INT = 16;
+const uint32_t BSON_DATA_TIMESTAMP = 17;
+const uint32_t BSON_DATA_LONG = 18;
+const uint32_t BSON_DATA_MIN_KEY = 0xff;
+const uint32_t BSON_DATA_MAX_KEY = 0x7f;
+
+const int32_t BSON_INT32_MAX = (int32_t)2147483647L;
+const int32_t BSON_INT32_MIN = (int32_t)(-1) * 2147483648L;
+
+const int64_t BSON_INT64_MAX = ((int64_t)1 << 63) - 1;
+const int64_t BSON_INT64_MIN = (int64_t)-1 << 63;
+
+const int64_t JS_INT_MAX = (int64_t)1 << 53;
+const int64_t JS_INT_MIN = (int64_t)-1 << 53;
+
+static Handle VException(const char *msg) {
+ HandleScope scope;
+ return ThrowException(Exception::Error(String::New(msg)));
+ };
+
+Persistent BSON::constructor_template;
+
+void BSON::Initialize(v8::Handle target) {
+ // Grab the scope of the call from Node
+ HandleScope scope;
+ // Define a new function template
+ Local t = FunctionTemplate::New(New);
+ constructor_template = Persistent::New(t);
+ constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
+ constructor_template->SetClassName(String::NewSymbol("BSON"));
+
+ // Instance methods
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize", CalculateObjectSize);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize", BSONSerialize);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "serializeWithBufferAndIndex", SerializeWithBufferAndIndex);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserialize", BSONDeserialize);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "deserializeStream", BSONDeserializeStream);
+
+ // Experimental
+ // NODE_SET_PROTOTYPE_METHOD(constructor_template, "calculateObjectSize2", CalculateObjectSize2);
+ // NODE_SET_PROTOTYPE_METHOD(constructor_template, "serialize2", BSONSerialize2);
+ // NODE_SET_METHOD(constructor_template->GetFunction(), "serialize2", BSONSerialize2);
+
+ target->ForceSet(String::NewSymbol("BSON"), constructor_template->GetFunction());
+}
+
+// Create a new instance of BSON and assing it the existing context
+Handle BSON::New(const Arguments &args) {
+ HandleScope scope;
+
+ // Check that we have an array
+ if(args.Length() == 1 && args[0]->IsArray()) {
+ // Cast the array to a local reference
+ Local array = Local::Cast(args[0]);
+
+ if(array->Length() > 0) {
+ // Create a bson object instance and return it
+ BSON *bson = new BSON();
+
+ // Setup pre-allocated comparision objects
+ bson->_bsontypeString = Persistent::New(String::New("_bsontype"));
+ bson->_longLowString = Persistent::New(String::New("low_"));
+ bson->_longHighString = Persistent::New(String::New("high_"));
+ bson->_objectIDidString = Persistent::New(String::New("id"));
+ bson->_binaryPositionString = Persistent::New(String::New("position"));
+ bson->_binarySubTypeString = Persistent::New(String::New("sub_type"));
+ bson->_binaryBufferString = Persistent::New(String::New("buffer"));
+ bson->_doubleValueString = Persistent::New(String::New("value"));
+ bson->_symbolValueString = Persistent::New(String::New("value"));
+ bson->_dbRefRefString = Persistent::New(String::New("$ref"));
+ bson->_dbRefIdRefString = Persistent::New(String::New("$id"));
+ bson->_dbRefDbRefString = Persistent::New(String::New("$db"));
+ bson->_dbRefNamespaceString = Persistent::New(String::New("namespace"));
+ bson->_dbRefDbString = Persistent::New(String::New("db"));
+ bson->_dbRefOidString = Persistent::New(String::New("oid"));
+
+ // total number of found classes
+ uint32_t numberOfClasses = 0;
+
+ // Iterate over all entries to save the instantiate funtions
+ for(uint32_t i = 0; i < array->Length(); i++) {
+ // Let's get a reference to the function
+ Local func = Local::Cast(array->Get(i));
+ Local functionName = func->GetName()->ToString();
+
+ // Save the functions making them persistant handles (they don't get collected)
+ if(functionName->StrictEquals(String::New("Long"))) {
+ bson->longConstructor = Persistent::New(func);
+ bson->longString = Persistent::New(String::New("Long"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("ObjectID"))) {
+ bson->objectIDConstructor = Persistent::New(func);
+ bson->objectIDString = Persistent::New(String::New("ObjectID"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("Binary"))) {
+ bson->binaryConstructor = Persistent::New(func);
+ bson->binaryString = Persistent::New(String::New("Binary"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("Code"))) {
+ bson->codeConstructor = Persistent::New(func);
+ bson->codeString = Persistent::New(String::New("Code"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("DBRef"))) {
+ bson->dbrefConstructor = Persistent::New(func);
+ bson->dbrefString = Persistent::New(String::New("DBRef"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("Symbol"))) {
+ bson->symbolConstructor = Persistent::New(func);
+ bson->symbolString = Persistent::New(String::New("Symbol"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("Double"))) {
+ bson->doubleConstructor = Persistent::New(func);
+ bson->doubleString = Persistent::New(String::New("Double"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("Timestamp"))) {
+ bson->timestampConstructor = Persistent::New(func);
+ bson->timestampString = Persistent::New(String::New("Timestamp"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("MinKey"))) {
+ bson->minKeyConstructor = Persistent::New(func);
+ bson->minKeyString = Persistent::New(String::New("MinKey"));
+ numberOfClasses = numberOfClasses + 1;
+ } else if(functionName->StrictEquals(String::New("MaxKey"))) {
+ bson->maxKeyConstructor = Persistent::New(func);
+ bson->maxKeyString = Persistent::New(String::New("MaxKey"));
+ numberOfClasses = numberOfClasses + 1;
+ }
+ }
+
+ // Check if we have the right number of constructors otherwise throw an error
+ if(numberOfClasses != 10) {
+ // Destroy object
+ delete(bson);
+ // Fire exception
+ return VException("Missing function constructor for either [Long/ObjectID/Binary/Code/DbRef/Symbol/Double/Timestamp/MinKey/MaxKey]");
+ } else {
+ bson->Wrap(args.This());
+ return args.This();
+ }
+ } else {
+ return VException("No types passed in");
+ }
+ } else {
+ return VException("Argument passed in must be an array of types");
+ }
+}
+
+void BSON::write_int32(char *data, uint32_t value) {
+ // Write the int to the char*
+ memcpy(data, &value, 4);
+}
+
+void BSON::write_double(char *data, double value) {
+ // Write the double to the char*
+ memcpy(data, &value, 8);
+}
+
+void BSON::write_int64(char *data, int64_t value) {
+ // Write the int to the char*
+ memcpy(data, &value, 8);
+}
+
+char *BSON::check_key(Local key) {
+ // Allocate space for they key string
+ char *key_str = (char *)malloc(key->Utf8Length() * sizeof(char) + 1);
+ // Error string
+ char *error_str = (char *)malloc(256 * sizeof(char));
+ // Decode the key
+ ssize_t len = DecodeBytes(key, BINARY);
+ DecodeWrite(key_str, len, key, BINARY);
+ *(key_str + key->Utf8Length()) = '\0';
+ // Check if we have a valid key
+ if(key->Utf8Length() > 0 && *(key_str) == '$') {
+ // Create the string
+ sprintf(error_str, "key %s must not start with '$'", key_str);
+ // Free up memory
+ free(key_str);
+ // Throw exception with string
+ throw error_str;
+ } else if(key->Utf8Length() > 0 && strchr(key_str, '.') != NULL) {
+ // Create the string
+ sprintf(error_str, "key %s must not contain '.'", key_str);
+ // Free up memory
+ free(key_str);
+ // Throw exception with string
+ throw error_str;
+ }
+ // Free allocated space
+ free(key_str);
+ free(error_str);
+ // Return No check key error
+ return NULL;
+}
+
+const char* BSON::ToCString(const v8::String::Utf8Value& value) {
+ return *value ? *value : "";
+}
+
+Handle BSON::decodeDBref(BSON *bson, Local ref, Local oid, Local db) {
+ HandleScope scope;
+ Local argv[] = {ref, oid, db};
+ Handle dbrefObj = bson->dbrefConstructor->NewInstance(3, argv);
+ return scope.Close(dbrefObj);
+}
+
+Handle BSON::decodeCode(BSON *bson, char *code, Handle scope_object) {
+ HandleScope scope;
+
+ Local argv[] = {String::New(code), scope_object->ToObject()};
+ Handle codeObj = bson->codeConstructor->NewInstance(2, argv);
+ return scope.Close(codeObj);
+}
+
+Handle BSON::decodeBinary(BSON *bson, uint32_t sub_type, uint32_t number_of_bytes, char *data) {
+ HandleScope scope;
+
+ // Create a buffer object that wraps the raw stream
+ Buffer *bufferObj = Buffer::New(data, number_of_bytes);
+ // Arguments to be passed to create the binary
+ Handle argv[] = {bufferObj->handle_, Uint32::New(sub_type)};
+ // Return the buffer handle
+ Local