jai shree ram
This commit is contained in:
17
node_modules/busboy/.travis.yml
generated
vendored
Normal file
17
node_modules/busboy/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
sudo: false
|
||||
language: cpp
|
||||
notifications:
|
||||
email: false
|
||||
env:
|
||||
matrix:
|
||||
- TRAVIS_NODE_VERSION="0.10"
|
||||
- TRAVIS_NODE_VERSION="0.12"
|
||||
- TRAVIS_NODE_VERSION="4"
|
||||
- TRAVIS_NODE_VERSION="6"
|
||||
- TRAVIS_NODE_VERSION="7"
|
||||
install:
|
||||
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm install
|
||||
script: npm test
|
19
node_modules/busboy/LICENSE
generated
vendored
Normal file
19
node_modules/busboy/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright Brian White. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
225
node_modules/busboy/README.md
generated
vendored
Normal file
225
node_modules/busboy/README.md
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
Description
|
||||
===========
|
||||
|
||||
A node.js module for parsing incoming HTML form data.
|
||||
|
||||
If you've found this module to be useful and wish to support it, you may do so by visiting this pledgie campaign:
|
||||
<a href='https://pledgie.com/campaigns/28774'><img alt='Click here to support busboy' src='https://pledgie.com/campaigns/28774.png?skin_name=chrome' border='0'></a>
|
||||
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
* [node.js](http://nodejs.org/) -- v0.8.0 or newer
|
||||
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
npm install busboy
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
* Parsing (multipart) with default options:
|
||||
|
||||
```javascript
|
||||
var http = require('http'),
|
||||
inspect = require('util').inspect;
|
||||
|
||||
var Busboy = require('busboy');
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
if (req.method === 'POST') {
|
||||
var busboy = new Busboy({ headers: req.headers });
|
||||
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
||||
console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype);
|
||||
file.on('data', function(data) {
|
||||
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
|
||||
});
|
||||
file.on('end', function() {
|
||||
console.log('File [' + fieldname + '] Finished');
|
||||
});
|
||||
});
|
||||
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
|
||||
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
|
||||
});
|
||||
busboy.on('finish', function() {
|
||||
console.log('Done parsing form!');
|
||||
res.writeHead(303, { Connection: 'close', Location: '/' });
|
||||
res.end();
|
||||
});
|
||||
req.pipe(busboy);
|
||||
} else if (req.method === 'GET') {
|
||||
res.writeHead(200, { Connection: 'close' });
|
||||
res.end('<html><head></head><body>\
|
||||
<form method="POST" enctype="multipart/form-data">\
|
||||
<input type="text" name="textfield"><br />\
|
||||
<input type="file" name="filefield"><br />\
|
||||
<input type="submit">\
|
||||
</form>\
|
||||
</body></html>');
|
||||
}
|
||||
}).listen(8000, function() {
|
||||
console.log('Listening for requests');
|
||||
});
|
||||
|
||||
// Example output, using http://nodejs.org/images/ryan-speaker.jpg as the file:
|
||||
//
|
||||
// Listening for requests
|
||||
// File [filefield]: filename: ryan-speaker.jpg, encoding: binary
|
||||
// File [filefield] got 11971 bytes
|
||||
// Field [textfield]: value: 'testing! :-)'
|
||||
// File [filefield] Finished
|
||||
// Done parsing form!
|
||||
```
|
||||
|
||||
* Save all incoming files to disk:
|
||||
|
||||
```javascript
|
||||
var http = require('http'),
|
||||
path = require('path'),
|
||||
os = require('os'),
|
||||
fs = require('fs');
|
||||
|
||||
var Busboy = require('busboy');
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
if (req.method === 'POST') {
|
||||
var busboy = new Busboy({ headers: req.headers });
|
||||
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
||||
var saveTo = path.join(os.tmpDir(), path.basename(fieldname));
|
||||
file.pipe(fs.createWriteStream(saveTo));
|
||||
});
|
||||
busboy.on('finish', function() {
|
||||
res.writeHead(200, { 'Connection': 'close' });
|
||||
res.end("That's all folks!");
|
||||
});
|
||||
return req.pipe(busboy);
|
||||
}
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
}).listen(8000, function() {
|
||||
console.log('Listening for requests');
|
||||
});
|
||||
```
|
||||
|
||||
* Parsing (urlencoded) with default options:
|
||||
|
||||
```javascript
|
||||
var http = require('http'),
|
||||
inspect = require('util').inspect;
|
||||
|
||||
var Busboy = require('busboy');
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
if (req.method === 'POST') {
|
||||
var busboy = new Busboy({ headers: req.headers });
|
||||
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
||||
console.log('File [' + fieldname + ']: filename: ' + filename);
|
||||
file.on('data', function(data) {
|
||||
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
|
||||
});
|
||||
file.on('end', function() {
|
||||
console.log('File [' + fieldname + '] Finished');
|
||||
});
|
||||
});
|
||||
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
|
||||
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
|
||||
});
|
||||
busboy.on('finish', function() {
|
||||
console.log('Done parsing form!');
|
||||
res.writeHead(303, { Connection: 'close', Location: '/' });
|
||||
res.end();
|
||||
});
|
||||
req.pipe(busboy);
|
||||
} else if (req.method === 'GET') {
|
||||
res.writeHead(200, { Connection: 'close' });
|
||||
res.end('<html><head></head><body>\
|
||||
<form method="POST">\
|
||||
<input type="text" name="textfield"><br />\
|
||||
<select name="selectfield">\
|
||||
<option value="1">1</option>\
|
||||
<option value="10">10</option>\
|
||||
<option value="100">100</option>\
|
||||
<option value="9001">9001</option>\
|
||||
</select><br />\
|
||||
<input type="checkbox" name="checkfield">Node.js rules!<br />\
|
||||
<input type="submit">\
|
||||
</form>\
|
||||
</body></html>');
|
||||
}
|
||||
}).listen(8000, function() {
|
||||
console.log('Listening for requests');
|
||||
});
|
||||
|
||||
// Example output:
|
||||
//
|
||||
// Listening for requests
|
||||
// Field [textfield]: value: 'testing! :-)'
|
||||
// Field [selectfield]: value: '9001'
|
||||
// Field [checkfield]: value: 'on'
|
||||
// Done parsing form!
|
||||
```
|
||||
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
_Busboy_ is a _Writable_ stream
|
||||
|
||||
Busboy (special) events
|
||||
-----------------------
|
||||
|
||||
* **file**(< _string_ >fieldname, < _ReadableStream_ >stream, < _string_ >filename, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new file form field found. `transferEncoding` contains the 'Content-Transfer-Encoding' value for the file stream. `mimeType` contains the 'Content-Type' value for the file stream.
|
||||
* Note: if you listen for this event, you should always handle the `stream` no matter if you care about the file contents or not (e.g. you can simply just do `stream.resume();` if you want to discard the contents), otherwise the 'finish' event will never fire on the Busboy instance. However, if you don't care about **any** incoming files, you can simply not listen for the 'file' event at all and any/all files will be automatically and safely discarded (these discarded files do still count towards `files` and `parts` limits).
|
||||
* If a configured file size limit was reached, `stream` will both have a boolean property `truncated` (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens.
|
||||
|
||||
* **field**(< _string_ >fieldname, < _string_ >value, < _boolean_ >fieldnameTruncated, < _boolean_ >valueTruncated, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new non-file field found.
|
||||
|
||||
* **partsLimit**() - Emitted when specified `parts` limit has been reached. No more 'file' or 'field' events will be emitted.
|
||||
|
||||
* **filesLimit**() - Emitted when specified `files` limit has been reached. No more 'file' events will be emitted.
|
||||
|
||||
* **fieldsLimit**() - Emitted when specified `fields` limit has been reached. No more 'field' events will be emitted.
|
||||
|
||||
|
||||
Busboy methods
|
||||
--------------
|
||||
|
||||
* **(constructor)**(< _object_ >config) - Creates and returns a new Busboy instance.
|
||||
|
||||
* The constructor takes the following valid `config` settings:
|
||||
|
||||
* **headers** - _object_ - These are the HTTP headers of the incoming request, which are used by individual parsers.
|
||||
|
||||
* **highWaterMark** - _integer_ - highWaterMark to use for this Busboy instance (Default: WritableStream default).
|
||||
|
||||
* **fileHwm** - _integer_ - highWaterMark to use for file streams (Default: ReadableStream default).
|
||||
|
||||
* **defCharset** - _string_ - Default character set to use when one isn't defined (Default: 'utf8').
|
||||
|
||||
* **preservePath** - _boolean_ - If paths in the multipart 'filename' field shall be preserved. (Default: false).
|
||||
|
||||
* **limits** - _object_ - Various limits on incoming data. Valid properties are:
|
||||
|
||||
* **fieldNameSize** - _integer_ - Max field name size (in bytes) (Default: 100 bytes).
|
||||
|
||||
* **fieldSize** - _integer_ - Max field value size (in bytes) (Default: 1MB).
|
||||
|
||||
* **fields** - _integer_ - Max number of non-file fields (Default: Infinity).
|
||||
|
||||
* **fileSize** - _integer_ - For multipart forms, the max file size (in bytes) (Default: Infinity).
|
||||
|
||||
* **files** - _integer_ - For multipart forms, the max number of file fields (Default: Infinity).
|
||||
|
||||
* **parts** - _integer_ - For multipart forms, the max number of parts (fields + files) (Default: Infinity).
|
||||
|
||||
* **headerPairs** - _integer_ - For multipart forms, the max number of header key=>value pairs to parse **Default:** 2000 (same as node's http).
|
||||
|
||||
* The constructor can throw errors:
|
||||
|
||||
* **Unsupported content type: $type** - The `Content-Type` isn't one Busboy can parse.
|
||||
|
||||
* **Missing Content-Type** - The provided headers don't include `Content-Type` at all.
|
73
node_modules/busboy/deps/encoding/encoding-indexes.js
generated
vendored
Normal file
73
node_modules/busboy/deps/encoding/encoding-indexes.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2391
node_modules/busboy/deps/encoding/encoding.js
generated
vendored
Normal file
2391
node_modules/busboy/deps/encoding/encoding.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
89
node_modules/busboy/lib/main.js
generated
vendored
Normal file
89
node_modules/busboy/lib/main.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
var fs = require('fs'),
|
||||
WritableStream = require('stream').Writable
|
||||
|| require('readable-stream').Writable,
|
||||
inherits = require('util').inherits;
|
||||
|
||||
var parseParams = require('./utils').parseParams;
|
||||
|
||||
function Busboy(opts) {
|
||||
if (!(this instanceof Busboy))
|
||||
return new Busboy(opts);
|
||||
if (opts.highWaterMark !== undefined)
|
||||
WritableStream.call(this, { highWaterMark: opts.highWaterMark });
|
||||
else
|
||||
WritableStream.call(this);
|
||||
|
||||
this._done = false;
|
||||
this._parser = undefined;
|
||||
this._finished = false;
|
||||
|
||||
this.opts = opts;
|
||||
if (opts.headers && typeof opts.headers['content-type'] === 'string')
|
||||
this.parseHeaders(opts.headers);
|
||||
else
|
||||
throw new Error('Missing Content-Type');
|
||||
}
|
||||
inherits(Busboy, WritableStream);
|
||||
|
||||
Busboy.prototype.emit = function(ev) {
|
||||
if (ev === 'finish') {
|
||||
if (!this._done) {
|
||||
this._parser && this._parser.end();
|
||||
return;
|
||||
} else if (this._finished) {
|
||||
return;
|
||||
}
|
||||
this._finished = true;
|
||||
}
|
||||
WritableStream.prototype.emit.apply(this, arguments);
|
||||
};
|
||||
|
||||
Busboy.prototype.parseHeaders = function(headers) {
|
||||
this._parser = undefined;
|
||||
if (headers['content-type']) {
|
||||
var parsed = parseParams(headers['content-type']),
|
||||
matched, type;
|
||||
for (var i = 0; i < TYPES.length; ++i) {
|
||||
type = TYPES[i];
|
||||
if (typeof type.detect === 'function')
|
||||
matched = type.detect(parsed);
|
||||
else
|
||||
matched = type.detect.test(parsed[0]);
|
||||
if (matched)
|
||||
break;
|
||||
}
|
||||
if (matched) {
|
||||
var cfg = {
|
||||
limits: this.opts.limits,
|
||||
headers: headers,
|
||||
parsedConType: parsed,
|
||||
highWaterMark: undefined,
|
||||
fileHwm: undefined,
|
||||
defCharset: undefined,
|
||||
preservePath: false
|
||||
};
|
||||
if (this.opts.highWaterMark)
|
||||
cfg.highWaterMark = this.opts.highWaterMark;
|
||||
if (this.opts.fileHwm)
|
||||
cfg.fileHwm = this.opts.fileHwm;
|
||||
cfg.defCharset = this.opts.defCharset;
|
||||
cfg.preservePath = this.opts.preservePath;
|
||||
this._parser = type(this, cfg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new Error('Unsupported content type: ' + headers['content-type']);
|
||||
};
|
||||
|
||||
Busboy.prototype._write = function(chunk, encoding, cb) {
|
||||
if (!this._parser)
|
||||
return cb(new Error('Not ready to parse. Missing Content-Type?'));
|
||||
this._parser.write(chunk, cb);
|
||||
};
|
||||
|
||||
var TYPES = [
|
||||
require('./types/multipart'),
|
||||
require('./types/urlencoded'),
|
||||
];
|
||||
|
||||
module.exports = Busboy;
|
324
node_modules/busboy/lib/types/multipart.js
generated
vendored
Normal file
324
node_modules/busboy/lib/types/multipart.js
generated
vendored
Normal file
@@ -0,0 +1,324 @@
|
||||
// TODO:
|
||||
// * support 1 nested multipart level
|
||||
// (see second multipart example here:
|
||||
// http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data)
|
||||
// * support limits.fieldNameSize
|
||||
// -- this will require modifications to utils.parseParams
|
||||
|
||||
var ReadableStream = require('stream').Readable || require('readable-stream'),
|
||||
inherits = require('util').inherits;
|
||||
|
||||
var Dicer = require('dicer');
|
||||
|
||||
var parseParams = require('../utils').parseParams,
|
||||
decodeText = require('../utils').decodeText,
|
||||
basename = require('../utils').basename;
|
||||
|
||||
var RE_BOUNDARY = /^boundary$/i,
|
||||
RE_FIELD = /^form-data$/i,
|
||||
RE_CHARSET = /^charset$/i,
|
||||
RE_FILENAME = /^filename$/i,
|
||||
RE_NAME = /^name$/i;
|
||||
|
||||
Multipart.detect = /^multipart\/form-data/i;
|
||||
function Multipart(boy, cfg) {
|
||||
if (!(this instanceof Multipart))
|
||||
return new Multipart(boy, cfg);
|
||||
var i,
|
||||
len,
|
||||
self = this,
|
||||
boundary,
|
||||
limits = cfg.limits,
|
||||
parsedConType = cfg.parsedConType || [],
|
||||
defCharset = cfg.defCharset || 'utf8',
|
||||
preservePath = cfg.preservePath,
|
||||
fileopts = (typeof cfg.fileHwm === 'number'
|
||||
? { highWaterMark: cfg.fileHwm }
|
||||
: {});
|
||||
|
||||
for (i = 0, len = parsedConType.length; i < len; ++i) {
|
||||
if (Array.isArray(parsedConType[i])
|
||||
&& RE_BOUNDARY.test(parsedConType[i][0])) {
|
||||
boundary = parsedConType[i][1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function checkFinished() {
|
||||
if (nends === 0 && finished && !boy._done) {
|
||||
finished = false;
|
||||
process.nextTick(function() {
|
||||
boy._done = true;
|
||||
boy.emit('finish');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof boundary !== 'string')
|
||||
throw new Error('Multipart: Boundary not found');
|
||||
|
||||
var fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
|
||||
? limits.fieldSize
|
||||
: 1 * 1024 * 1024),
|
||||
fileSizeLimit = (limits && typeof limits.fileSize === 'number'
|
||||
? limits.fileSize
|
||||
: Infinity),
|
||||
filesLimit = (limits && typeof limits.files === 'number'
|
||||
? limits.files
|
||||
: Infinity),
|
||||
fieldsLimit = (limits && typeof limits.fields === 'number'
|
||||
? limits.fields
|
||||
: Infinity),
|
||||
partsLimit = (limits && typeof limits.parts === 'number'
|
||||
? limits.parts
|
||||
: Infinity);
|
||||
|
||||
var nfiles = 0,
|
||||
nfields = 0,
|
||||
nends = 0,
|
||||
curFile,
|
||||
curField,
|
||||
finished = false;
|
||||
|
||||
this._needDrain = false;
|
||||
this._pause = false;
|
||||
this._cb = undefined;
|
||||
this._nparts = 0;
|
||||
this._boy = boy;
|
||||
|
||||
var parserCfg = {
|
||||
boundary: boundary,
|
||||
maxHeaderPairs: (limits && limits.headerPairs)
|
||||
};
|
||||
if (fileopts.highWaterMark)
|
||||
parserCfg.partHwm = fileopts.highWaterMark;
|
||||
if (cfg.highWaterMark)
|
||||
parserCfg.highWaterMark = cfg.highWaterMark;
|
||||
|
||||
this.parser = new Dicer(parserCfg);
|
||||
this.parser.on('drain', function() {
|
||||
self._needDrain = false;
|
||||
if (self._cb && !self._pause) {
|
||||
var cb = self._cb;
|
||||
self._cb = undefined;
|
||||
cb();
|
||||
}
|
||||
}).on('part', function onPart(part) {
|
||||
if (++self._nparts > partsLimit) {
|
||||
self.parser.removeListener('part', onPart);
|
||||
self.parser.on('part', skipPart);
|
||||
boy.hitPartsLimit = true;
|
||||
boy.emit('partsLimit');
|
||||
return skipPart(part);
|
||||
}
|
||||
|
||||
// hack because streams2 _always_ doesn't emit 'end' until nextTick, so let
|
||||
// us emit 'end' early since we know the part has ended if we are already
|
||||
// seeing the next part
|
||||
if (curField) {
|
||||
var field = curField;
|
||||
field.emit('end');
|
||||
field.removeAllListeners('end');
|
||||
}
|
||||
|
||||
part.on('header', function(header) {
|
||||
var contype,
|
||||
fieldname,
|
||||
parsed,
|
||||
charset,
|
||||
encoding,
|
||||
filename,
|
||||
nsize = 0;
|
||||
|
||||
if (header['content-type']) {
|
||||
parsed = parseParams(header['content-type'][0]);
|
||||
if (parsed[0]) {
|
||||
contype = parsed[0].toLowerCase();
|
||||
for (i = 0, len = parsed.length; i < len; ++i) {
|
||||
if (RE_CHARSET.test(parsed[i][0])) {
|
||||
charset = parsed[i][1].toLowerCase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contype === undefined)
|
||||
contype = 'text/plain';
|
||||
if (charset === undefined)
|
||||
charset = defCharset;
|
||||
|
||||
if (header['content-disposition']) {
|
||||
parsed = parseParams(header['content-disposition'][0]);
|
||||
if (!RE_FIELD.test(parsed[0]))
|
||||
return skipPart(part);
|
||||
for (i = 0, len = parsed.length; i < len; ++i) {
|
||||
if (RE_NAME.test(parsed[i][0])) {
|
||||
fieldname = decodeText(parsed[i][1], 'binary', 'utf8');
|
||||
} else if (RE_FILENAME.test(parsed[i][0])) {
|
||||
filename = decodeText(parsed[i][1], 'binary', 'utf8');
|
||||
if (!preservePath)
|
||||
filename = basename(filename);
|
||||
}
|
||||
}
|
||||
} else
|
||||
return skipPart(part);
|
||||
|
||||
if (header['content-transfer-encoding'])
|
||||
encoding = header['content-transfer-encoding'][0].toLowerCase();
|
||||
else
|
||||
encoding = '7bit';
|
||||
|
||||
var onData,
|
||||
onEnd;
|
||||
if (contype === 'application/octet-stream' || filename !== undefined) {
|
||||
// file/binary field
|
||||
if (nfiles === filesLimit) {
|
||||
if (!boy.hitFilesLimit) {
|
||||
boy.hitFilesLimit = true;
|
||||
boy.emit('filesLimit');
|
||||
}
|
||||
return skipPart(part);
|
||||
}
|
||||
|
||||
++nfiles;
|
||||
|
||||
if (!boy._events.file) {
|
||||
self.parser._ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
++nends;
|
||||
var file = new FileStream(fileopts);
|
||||
curFile = file;
|
||||
file.on('end', function() {
|
||||
--nends;
|
||||
checkFinished();
|
||||
if (self._cb && !self._needDrain) {
|
||||
var cb = self._cb;
|
||||
self._cb = undefined;
|
||||
cb();
|
||||
}
|
||||
});
|
||||
file._read = function(n) {
|
||||
if (!self._pause)
|
||||
return;
|
||||
self._pause = false;
|
||||
if (self._cb && !self._needDrain) {
|
||||
var cb = self._cb;
|
||||
self._cb = undefined;
|
||||
cb();
|
||||
}
|
||||
};
|
||||
boy.emit('file', fieldname, file, filename, encoding, contype);
|
||||
|
||||
onData = function(data) {
|
||||
if ((nsize += data.length) > fileSizeLimit) {
|
||||
var extralen = (fileSizeLimit - (nsize - data.length));
|
||||
if (extralen > 0)
|
||||
file.push(data.slice(0, extralen));
|
||||
file.emit('limit');
|
||||
file.truncated = true;
|
||||
part.removeAllListeners('data');
|
||||
} else if (!file.push(data))
|
||||
self._pause = true;
|
||||
};
|
||||
|
||||
onEnd = function() {
|
||||
curFile = undefined;
|
||||
file.push(null);
|
||||
};
|
||||
} else {
|
||||
// non-file field
|
||||
if (nfields === fieldsLimit) {
|
||||
if (!boy.hitFieldsLimit) {
|
||||
boy.hitFieldsLimit = true;
|
||||
boy.emit('fieldsLimit');
|
||||
}
|
||||
return skipPart(part);
|
||||
}
|
||||
|
||||
++nfields;
|
||||
++nends;
|
||||
var buffer = '',
|
||||
truncated = false;
|
||||
curField = part;
|
||||
|
||||
onData = function(data) {
|
||||
if ((nsize += data.length) > fieldSizeLimit) {
|
||||
var extralen = (fieldSizeLimit - (nsize - data.length));
|
||||
buffer += data.toString('binary', 0, extralen);
|
||||
truncated = true;
|
||||
part.removeAllListeners('data');
|
||||
} else
|
||||
buffer += data.toString('binary');
|
||||
};
|
||||
|
||||
onEnd = function() {
|
||||
curField = undefined;
|
||||
if (buffer.length)
|
||||
buffer = decodeText(buffer, 'binary', charset);
|
||||
boy.emit('field', fieldname, buffer, false, truncated, encoding, contype);
|
||||
--nends;
|
||||
checkFinished();
|
||||
};
|
||||
}
|
||||
|
||||
/* As of node@2efe4ab761666 (v0.10.29+/v0.11.14+), busboy had become
|
||||
broken. Streams2/streams3 is a huge black box of confusion, but
|
||||
somehow overriding the sync state seems to fix things again (and still
|
||||
seems to work for previous node versions).
|
||||
*/
|
||||
part._readableState.sync = false;
|
||||
|
||||
part.on('data', onData);
|
||||
part.on('end', onEnd);
|
||||
}).on('error', function(err) {
|
||||
if (curFile)
|
||||
curFile.emit('error', err);
|
||||
});
|
||||
}).on('error', function(err) {
|
||||
boy.emit('error', err);
|
||||
}).on('finish', function() {
|
||||
finished = true;
|
||||
checkFinished();
|
||||
});
|
||||
}
|
||||
|
||||
Multipart.prototype.write = function(chunk, cb) {
|
||||
var r;
|
||||
if ((r = this.parser.write(chunk)) && !this._pause)
|
||||
cb();
|
||||
else {
|
||||
this._needDrain = !r;
|
||||
this._cb = cb;
|
||||
}
|
||||
};
|
||||
|
||||
Multipart.prototype.end = function() {
|
||||
var self = this;
|
||||
if (this._nparts === 0 && !self._boy._done) {
|
||||
process.nextTick(function() {
|
||||
self._boy._done = true;
|
||||
self._boy.emit('finish');
|
||||
});
|
||||
} else if (this.parser.writable)
|
||||
this.parser.end();
|
||||
};
|
||||
|
||||
function skipPart(part) {
|
||||
part.resume();
|
||||
}
|
||||
|
||||
function FileStream(opts) {
|
||||
if (!(this instanceof FileStream))
|
||||
return new FileStream(opts);
|
||||
ReadableStream.call(this, opts);
|
||||
|
||||
this.truncated = false;
|
||||
}
|
||||
inherits(FileStream, ReadableStream);
|
||||
|
||||
FileStream.prototype._read = function(n) {};
|
||||
|
||||
module.exports = Multipart;
|
214
node_modules/busboy/lib/types/urlencoded.js
generated
vendored
Normal file
214
node_modules/busboy/lib/types/urlencoded.js
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
var Decoder = require('../utils').Decoder,
|
||||
decodeText = require('../utils').decodeText;
|
||||
|
||||
var RE_CHARSET = /^charset$/i;
|
||||
|
||||
UrlEncoded.detect = /^application\/x-www-form-urlencoded/i;
|
||||
function UrlEncoded(boy, cfg) {
|
||||
if (!(this instanceof UrlEncoded))
|
||||
return new UrlEncoded(boy, cfg);
|
||||
var limits = cfg.limits,
|
||||
headers = cfg.headers,
|
||||
parsedConType = cfg.parsedConType;
|
||||
this.boy = boy;
|
||||
|
||||
this.fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
|
||||
? limits.fieldSize
|
||||
: 1 * 1024 * 1024);
|
||||
this.fieldNameSizeLimit = (limits && typeof limits.fieldNameSize === 'number'
|
||||
? limits.fieldNameSize
|
||||
: 100);
|
||||
this.fieldsLimit = (limits && typeof limits.fields === 'number'
|
||||
? limits.fields
|
||||
: Infinity);
|
||||
|
||||
var charset;
|
||||
for (var i = 0, len = parsedConType.length; i < len; ++i) {
|
||||
if (Array.isArray(parsedConType[i])
|
||||
&& RE_CHARSET.test(parsedConType[i][0])) {
|
||||
charset = parsedConType[i][1].toLowerCase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (charset === undefined)
|
||||
charset = cfg.defCharset || 'utf8';
|
||||
|
||||
this.decoder = new Decoder();
|
||||
this.charset = charset;
|
||||
this._fields = 0;
|
||||
this._state = 'key';
|
||||
this._checkingBytes = true;
|
||||
this._bytesKey = 0;
|
||||
this._bytesVal = 0;
|
||||
this._key = '';
|
||||
this._val = '';
|
||||
this._keyTrunc = false;
|
||||
this._valTrunc = false;
|
||||
this._hitlimit = false;
|
||||
}
|
||||
|
||||
UrlEncoded.prototype.write = function(data, cb) {
|
||||
if (this._fields === this.fieldsLimit) {
|
||||
if (!this.boy.hitFieldsLimit) {
|
||||
this.boy.hitFieldsLimit = true;
|
||||
this.boy.emit('fieldsLimit');
|
||||
}
|
||||
return cb();
|
||||
}
|
||||
|
||||
var idxeq, idxamp, i, p = 0, len = data.length;
|
||||
|
||||
while (p < len) {
|
||||
if (this._state === 'key') {
|
||||
idxeq = idxamp = undefined;
|
||||
for (i = p; i < len; ++i) {
|
||||
if (!this._checkingBytes)
|
||||
++p;
|
||||
if (data[i] === 0x3D/*=*/) {
|
||||
idxeq = i;
|
||||
break;
|
||||
} else if (data[i] === 0x26/*&*/) {
|
||||
idxamp = i;
|
||||
break;
|
||||
}
|
||||
if (this._checkingBytes && this._bytesKey === this.fieldNameSizeLimit) {
|
||||
this._hitLimit = true;
|
||||
break;
|
||||
} else if (this._checkingBytes)
|
||||
++this._bytesKey;
|
||||
}
|
||||
|
||||
if (idxeq !== undefined) {
|
||||
// key with assignment
|
||||
if (idxeq > p)
|
||||
this._key += this.decoder.write(data.toString('binary', p, idxeq));
|
||||
this._state = 'val';
|
||||
|
||||
this._hitLimit = false;
|
||||
this._checkingBytes = true;
|
||||
this._val = '';
|
||||
this._bytesVal = 0;
|
||||
this._valTrunc = false;
|
||||
this.decoder.reset();
|
||||
|
||||
p = idxeq + 1;
|
||||
} else if (idxamp !== undefined) {
|
||||
// key with no assignment
|
||||
++this._fields;
|
||||
var key, keyTrunc = this._keyTrunc;
|
||||
if (idxamp > p)
|
||||
key = (this._key += this.decoder.write(data.toString('binary', p, idxamp)));
|
||||
else
|
||||
key = this._key;
|
||||
|
||||
this._hitLimit = false;
|
||||
this._checkingBytes = true;
|
||||
this._key = '';
|
||||
this._bytesKey = 0;
|
||||
this._keyTrunc = false;
|
||||
this.decoder.reset();
|
||||
|
||||
if (key.length) {
|
||||
this.boy.emit('field', decodeText(key, 'binary', this.charset),
|
||||
'',
|
||||
keyTrunc,
|
||||
false);
|
||||
}
|
||||
|
||||
p = idxamp + 1;
|
||||
if (this._fields === this.fieldsLimit)
|
||||
return cb();
|
||||
} else if (this._hitLimit) {
|
||||
// we may not have hit the actual limit if there are encoded bytes...
|
||||
if (i > p)
|
||||
this._key += this.decoder.write(data.toString('binary', p, i));
|
||||
p = i;
|
||||
if ((this._bytesKey = this._key.length) === this.fieldNameSizeLimit) {
|
||||
// yep, we actually did hit the limit
|
||||
this._checkingBytes = false;
|
||||
this._keyTrunc = true;
|
||||
}
|
||||
} else {
|
||||
if (p < len)
|
||||
this._key += this.decoder.write(data.toString('binary', p));
|
||||
p = len;
|
||||
}
|
||||
} else {
|
||||
idxamp = undefined;
|
||||
for (i = p; i < len; ++i) {
|
||||
if (!this._checkingBytes)
|
||||
++p;
|
||||
if (data[i] === 0x26/*&*/) {
|
||||
idxamp = i;
|
||||
break;
|
||||
}
|
||||
if (this._checkingBytes && this._bytesVal === this.fieldSizeLimit) {
|
||||
this._hitLimit = true;
|
||||
break;
|
||||
}
|
||||
else if (this._checkingBytes)
|
||||
++this._bytesVal;
|
||||
}
|
||||
|
||||
if (idxamp !== undefined) {
|
||||
++this._fields;
|
||||
if (idxamp > p)
|
||||
this._val += this.decoder.write(data.toString('binary', p, idxamp));
|
||||
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||
decodeText(this._val, 'binary', this.charset),
|
||||
this._keyTrunc,
|
||||
this._valTrunc);
|
||||
this._state = 'key';
|
||||
|
||||
this._hitLimit = false;
|
||||
this._checkingBytes = true;
|
||||
this._key = '';
|
||||
this._bytesKey = 0;
|
||||
this._keyTrunc = false;
|
||||
this.decoder.reset();
|
||||
|
||||
p = idxamp + 1;
|
||||
if (this._fields === this.fieldsLimit)
|
||||
return cb();
|
||||
} else if (this._hitLimit) {
|
||||
// we may not have hit the actual limit if there are encoded bytes...
|
||||
if (i > p)
|
||||
this._val += this.decoder.write(data.toString('binary', p, i));
|
||||
p = i;
|
||||
if ((this._val === '' && this.fieldSizeLimit === 0)
|
||||
|| (this._bytesVal = this._val.length) === this.fieldSizeLimit) {
|
||||
// yep, we actually did hit the limit
|
||||
this._checkingBytes = false;
|
||||
this._valTrunc = true;
|
||||
}
|
||||
} else {
|
||||
if (p < len)
|
||||
this._val += this.decoder.write(data.toString('binary', p));
|
||||
p = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
cb();
|
||||
};
|
||||
|
||||
UrlEncoded.prototype.end = function() {
|
||||
if (this.boy._done)
|
||||
return;
|
||||
|
||||
if (this._state === 'key' && this._key.length > 0) {
|
||||
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||
'',
|
||||
this._keyTrunc,
|
||||
false);
|
||||
} else if (this._state === 'val') {
|
||||
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||
decodeText(this._val, 'binary', this.charset),
|
||||
this._keyTrunc,
|
||||
this._valTrunc);
|
||||
}
|
||||
this.boy._done = true;
|
||||
this.boy.emit('finish');
|
||||
};
|
||||
|
||||
module.exports = UrlEncoded;
|
186
node_modules/busboy/lib/utils.js
generated
vendored
Normal file
186
node_modules/busboy/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
var jsencoding = require('../deps/encoding/encoding');
|
||||
|
||||
var RE_ENCODED = /%([a-fA-F0-9]{2})/g;
|
||||
function encodedReplacer(match, byte) {
|
||||
return String.fromCharCode(parseInt(byte, 16));
|
||||
}
|
||||
function parseParams(str) {
|
||||
var res = [],
|
||||
state = 'key',
|
||||
charset = '',
|
||||
inquote = false,
|
||||
escaping = false,
|
||||
p = 0,
|
||||
tmp = '';
|
||||
|
||||
for (var i = 0, len = str.length; i < len; ++i) {
|
||||
if (str[i] === '\\' && inquote) {
|
||||
if (escaping)
|
||||
escaping = false;
|
||||
else {
|
||||
escaping = true;
|
||||
continue;
|
||||
}
|
||||
} else if (str[i] === '"') {
|
||||
if (!escaping) {
|
||||
if (inquote) {
|
||||
inquote = false;
|
||||
state = 'key';
|
||||
} else
|
||||
inquote = true;
|
||||
continue;
|
||||
} else
|
||||
escaping = false;
|
||||
} else {
|
||||
if (escaping && inquote)
|
||||
tmp += '\\';
|
||||
escaping = false;
|
||||
if ((state === 'charset' || state === 'lang') && str[i] === "'") {
|
||||
if (state === 'charset') {
|
||||
state = 'lang';
|
||||
charset = tmp.substring(1);
|
||||
} else
|
||||
state = 'value';
|
||||
tmp = '';
|
||||
continue;
|
||||
} else if (state === 'key'
|
||||
&& (str[i] === '*' || str[i] === '=')
|
||||
&& res.length) {
|
||||
if (str[i] === '*')
|
||||
state = 'charset';
|
||||
else
|
||||
state = 'value';
|
||||
res[p] = [tmp, undefined];
|
||||
tmp = '';
|
||||
continue;
|
||||
} else if (!inquote && str[i] === ';') {
|
||||
state = 'key';
|
||||
if (charset) {
|
||||
if (tmp.length) {
|
||||
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
|
||||
'binary',
|
||||
charset);
|
||||
}
|
||||
charset = '';
|
||||
}
|
||||
if (res[p] === undefined)
|
||||
res[p] = tmp;
|
||||
else
|
||||
res[p][1] = tmp;
|
||||
tmp = '';
|
||||
++p;
|
||||
continue;
|
||||
} else if (!inquote && (str[i] === ' ' || str[i] === '\t'))
|
||||
continue;
|
||||
}
|
||||
tmp += str[i];
|
||||
}
|
||||
if (charset && tmp.length) {
|
||||
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
|
||||
'binary',
|
||||
charset);
|
||||
}
|
||||
|
||||
if (res[p] === undefined) {
|
||||
if (tmp)
|
||||
res[p] = tmp;
|
||||
} else
|
||||
res[p][1] = tmp;
|
||||
|
||||
return res;
|
||||
};
|
||||
exports.parseParams = parseParams;
|
||||
|
||||
|
||||
function decodeText(text, textEncoding, destEncoding) {
|
||||
var ret;
|
||||
if (text && jsencoding.encodingExists(destEncoding)) {
|
||||
try {
|
||||
ret = jsencoding.TextDecoder(destEncoding)
|
||||
.decode(new Buffer(text, textEncoding));
|
||||
} catch(e) {}
|
||||
}
|
||||
return (typeof ret === 'string' ? ret : text);
|
||||
}
|
||||
exports.decodeText = decodeText;
|
||||
|
||||
|
||||
var HEX = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
], RE_PLUS = /\+/g;
|
||||
function Decoder() {
|
||||
this.buffer = undefined;
|
||||
}
|
||||
Decoder.prototype.write = function(str) {
|
||||
// Replace '+' with ' ' before decoding
|
||||
str = str.replace(RE_PLUS, ' ');
|
||||
var res = '';
|
||||
var i = 0, p = 0, len = str.length;
|
||||
for (; i < len; ++i) {
|
||||
if (this.buffer !== undefined) {
|
||||
if (!HEX[str.charCodeAt(i)]) {
|
||||
res += '%' + this.buffer;
|
||||
this.buffer = undefined;
|
||||
--i; // retry character
|
||||
} else {
|
||||
this.buffer += str[i];
|
||||
++p;
|
||||
if (this.buffer.length === 2) {
|
||||
res += String.fromCharCode(parseInt(this.buffer, 16));
|
||||
this.buffer = undefined;
|
||||
}
|
||||
}
|
||||
} else if (str[i] === '%') {
|
||||
if (i > p) {
|
||||
res += str.substring(p, i);
|
||||
p = i;
|
||||
}
|
||||
this.buffer = '';
|
||||
++p;
|
||||
}
|
||||
}
|
||||
if (p < len && this.buffer === undefined)
|
||||
res += str.substring(p);
|
||||
return res;
|
||||
};
|
||||
Decoder.prototype.reset = function() {
|
||||
this.buffer = undefined;
|
||||
};
|
||||
exports.Decoder = Decoder;
|
||||
|
||||
|
||||
var RE_SPLIT_POSIX =
|
||||
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,
|
||||
RE_SPLIT_DEVICE =
|
||||
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/,
|
||||
RE_SPLIT_WINDOWS =
|
||||
/^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
|
||||
function splitPathPosix(filename) {
|
||||
return RE_SPLIT_POSIX.exec(filename).slice(1);
|
||||
}
|
||||
function splitPathWindows(filename) {
|
||||
// Separate device+slash from tail
|
||||
var result = RE_SPLIT_DEVICE.exec(filename),
|
||||
device = (result[1] || '') + (result[2] || ''),
|
||||
tail = result[3] || '';
|
||||
// Split the tail into dir, basename and extension
|
||||
var result2 = RE_SPLIT_WINDOWS.exec(tail),
|
||||
dir = result2[1],
|
||||
basename = result2[2],
|
||||
ext = result2[3];
|
||||
return [device, dir, basename, ext];
|
||||
}
|
||||
function basename(path) {
|
||||
var f = splitPathPosix(path)[2];
|
||||
if (f === path)
|
||||
f = splitPathWindows(path)[2];
|
||||
return f;
|
||||
}
|
||||
exports.basename = basename;
|
17
node_modules/busboy/package.json
generated
vendored
Normal file
17
node_modules/busboy/package.json
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{ "name": "busboy",
|
||||
"version": "0.2.14",
|
||||
"author": "Brian White <mscdex@mscdex.net>",
|
||||
"description": "A streaming parser for HTML form data for node.js",
|
||||
"main": "./lib/main",
|
||||
"dependencies": {
|
||||
"dicer": "0.2.5",
|
||||
"readable-stream": "1.1.x"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/test.js"
|
||||
},
|
||||
"engines": { "node": ">=0.8.0" },
|
||||
"keywords": [ "uploads", "forms", "multipart", "form-data" ],
|
||||
"licenses": [ { "type": "MIT", "url": "http://github.com/mscdex/busboy/raw/master/LICENSE" } ],
|
||||
"repository" : { "type": "git", "url": "http://github.com/mscdex/busboy.git" }
|
||||
}
|
343
node_modules/busboy/test/test-types-multipart.js
generated
vendored
Normal file
343
node_modules/busboy/test/test-types-multipart.js
generated
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
var Busboy = require('..');
|
||||
|
||||
var path = require('path'),
|
||||
inspect = require('util').inspect,
|
||||
assert = require('assert');
|
||||
|
||||
var EMPTY_FN = function() {};
|
||||
|
||||
var t = 0,
|
||||
group = path.basename(__filename, '.js') + '/';
|
||||
var tests = [
|
||||
{ source: [
|
||||
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="file_name_0"',
|
||||
'',
|
||||
'super alpha file',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="file_name_1"',
|
||||
'',
|
||||
'super beta file',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_1"; filename="1k_b.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
expected: [
|
||||
['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain'],
|
||||
['field', 'file_name_1', 'super beta file', false, false, '7bit', 'text/plain'],
|
||||
['file', 'upload_file_0', 1023, 0, '1k_a.dat', '7bit', 'application/octet-stream'],
|
||||
['file', 'upload_file_1', 1023, 0, '1k_b.dat', '7bit', 'application/octet-stream']
|
||||
],
|
||||
what: 'Fields and files'
|
||||
},
|
||||
{ source: [
|
||||
['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
'Content-Disposition: form-data; name="cont"',
|
||||
'',
|
||||
'some random content',
|
||||
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
'Content-Disposition: form-data; name="pass"',
|
||||
'',
|
||||
'some random pass',
|
||||
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
'Content-Disposition: form-data; name="bit"',
|
||||
'',
|
||||
'2',
|
||||
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY--'
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
expected: [
|
||||
['field', 'cont', 'some random content', false, false, '7bit', 'text/plain'],
|
||||
['field', 'pass', 'some random pass', false, false, '7bit', 'text/plain'],
|
||||
['field', 'bit', '2', false, false, '7bit', 'text/plain']
|
||||
],
|
||||
what: 'Fields only'
|
||||
},
|
||||
{ source: [
|
||||
''
|
||||
],
|
||||
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
expected: [],
|
||||
what: 'No fields and no files'
|
||||
},
|
||||
{ source: [
|
||||
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="file_name_0"',
|
||||
'',
|
||||
'super alpha file',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
limits: {
|
||||
fileSize: 13,
|
||||
fieldSize: 5
|
||||
},
|
||||
expected: [
|
||||
['field', 'file_name_0', 'super', false, true, '7bit', 'text/plain'],
|
||||
['file', 'upload_file_0', 13, 2, '1k_a.dat', '7bit', 'application/octet-stream']
|
||||
],
|
||||
what: 'Fields and files (limits)'
|
||||
},
|
||||
{ source: [
|
||||
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="file_name_0"',
|
||||
'',
|
||||
'super alpha file',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
limits: {
|
||||
files: 0
|
||||
},
|
||||
expected: [
|
||||
['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain']
|
||||
],
|
||||
what: 'Fields and files (limits: 0 files)'
|
||||
},
|
||||
{ source: [
|
||||
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="file_name_0"',
|
||||
'',
|
||||
'super alpha file',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="file_name_1"',
|
||||
'',
|
||||
'super beta file',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_1"; filename="1k_b.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
expected: [
|
||||
['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain'],
|
||||
['field', 'file_name_1', 'super beta file', false, false, '7bit', 'text/plain'],
|
||||
],
|
||||
events: ['field'],
|
||||
what: 'Fields and (ignored) files'
|
||||
},
|
||||
{ source: [
|
||||
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_0"; filename="/tmp/1k_a.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_1"; filename="C:\\files\\1k_b.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_2"; filename="relative/1k_c.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
expected: [
|
||||
['file', 'upload_file_0', 26, 0, '1k_a.dat', '7bit', 'application/octet-stream'],
|
||||
['file', 'upload_file_1', 26, 0, '1k_b.dat', '7bit', 'application/octet-stream'],
|
||||
['file', 'upload_file_2', 26, 0, '1k_c.dat', '7bit', 'application/octet-stream']
|
||||
],
|
||||
what: 'Files with filenames containing paths'
|
||||
},
|
||||
{ source: [
|
||||
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_0"; filename="/absolute/1k_a.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_1"; filename="C:\\absolute\\1k_b.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; name="upload_file_2"; filename="relative/1k_c.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
preservePath: true,
|
||||
expected: [
|
||||
['file', 'upload_file_0', 26, 0, '/absolute/1k_a.dat', '7bit', 'application/octet-stream'],
|
||||
['file', 'upload_file_1', 26, 0, 'C:\\absolute\\1k_b.dat', '7bit', 'application/octet-stream'],
|
||||
['file', 'upload_file_2', 26, 0, 'relative/1k_c.dat', '7bit', 'application/octet-stream']
|
||||
],
|
||||
what: 'Paths to be preserved through the preservePath option'
|
||||
},
|
||||
{ source: [
|
||||
['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
'Content-Disposition: form-data; name="cont"',
|
||||
'Content-Type: ',
|
||||
'',
|
||||
'some random content',
|
||||
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
'Content-Disposition: ',
|
||||
'',
|
||||
'some random pass',
|
||||
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY--'
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
expected: [
|
||||
['field', 'cont', 'some random content', false, false, '7bit', 'text/plain']
|
||||
],
|
||||
what: 'Empty content-type and empty content-disposition'
|
||||
},
|
||||
{ source: [
|
||||
['--asdasdasdasd\r\n',
|
||||
'Content-Type: text/plain\r\n',
|
||||
'Content-Disposition: form-data; name="foo"\r\n',
|
||||
'\r\n',
|
||||
'asd\r\n',
|
||||
'--asdasdasdasd--'
|
||||
].join(':)')
|
||||
],
|
||||
boundary: 'asdasdasdasd',
|
||||
expected: [],
|
||||
shouldError: 'Unexpected end of multipart data',
|
||||
what: 'Stopped mid-header'
|
||||
},
|
||||
{ source: [
|
||||
['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
'Content-Disposition: form-data; name="cont"',
|
||||
'Content-Type: application/json',
|
||||
'',
|
||||
'{}',
|
||||
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY--',
|
||||
].join('\r\n')
|
||||
],
|
||||
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
expected: [
|
||||
['field', 'cont', '{}', false, false, '7bit', 'application/json']
|
||||
],
|
||||
what: 'content-type for fields'
|
||||
},
|
||||
{ source: [
|
||||
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY--\r\n'
|
||||
],
|
||||
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||
expected: [],
|
||||
what: 'empty form'
|
||||
}
|
||||
];
|
||||
|
||||
function next() {
|
||||
if (t === tests.length)
|
||||
return;
|
||||
|
||||
var v = tests[t];
|
||||
|
||||
var busboy = new Busboy({
|
||||
limits: v.limits,
|
||||
preservePath: v.preservePath,
|
||||
headers: {
|
||||
'content-type': 'multipart/form-data; boundary=' + v.boundary
|
||||
}
|
||||
}),
|
||||
finishes = 0,
|
||||
results = [];
|
||||
|
||||
if (v.events === undefined || v.events.indexOf('field') > -1) {
|
||||
busboy.on('field', function(key, val, keyTrunc, valTrunc, encoding, contype) {
|
||||
results.push(['field', key, val, keyTrunc, valTrunc, encoding, contype]);
|
||||
});
|
||||
}
|
||||
if (v.events === undefined || v.events.indexOf('file') > -1) {
|
||||
busboy.on('file', function(fieldname, stream, filename, encoding, mimeType) {
|
||||
var nb = 0,
|
||||
info = ['file',
|
||||
fieldname,
|
||||
nb,
|
||||
0,
|
||||
filename,
|
||||
encoding,
|
||||
mimeType];
|
||||
results.push(info);
|
||||
stream.on('data', function(d) {
|
||||
nb += d.length;
|
||||
}).on('limit', function() {
|
||||
++info[3];
|
||||
}).on('end', function() {
|
||||
info[2] = nb;
|
||||
if (stream.truncated)
|
||||
++info[3];
|
||||
});
|
||||
});
|
||||
}
|
||||
busboy.on('finish', function() {
|
||||
assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
|
||||
assert.deepEqual(results.length,
|
||||
v.expected.length,
|
||||
makeMsg(v.what, 'Parsed result count mismatch. Saw '
|
||||
+ results.length
|
||||
+ '. Expected: ' + v.expected.length));
|
||||
|
||||
results.forEach(function(result, i) {
|
||||
assert.deepEqual(result,
|
||||
v.expected[i],
|
||||
makeMsg(v.what,
|
||||
'Result mismatch:\nParsed: ' + inspect(result)
|
||||
+ '\nExpected: ' + inspect(v.expected[i]))
|
||||
);
|
||||
});
|
||||
++t;
|
||||
next();
|
||||
}).on('error', function(err) {
|
||||
if (!v.shouldError || v.shouldError !== err.message)
|
||||
assert(false, makeMsg(v.what, 'Unexpected error: ' + err));
|
||||
});
|
||||
|
||||
v.source.forEach(function(s) {
|
||||
busboy.write(new Buffer(s, 'utf8'), EMPTY_FN);
|
||||
});
|
||||
busboy.end();
|
||||
}
|
||||
next();
|
||||
|
||||
function makeMsg(what, msg) {
|
||||
return '[' + group + what + ']: ' + msg;
|
||||
}
|
||||
|
||||
process.on('exit', function() {
|
||||
assert(t === tests.length,
|
||||
makeMsg('_exit',
|
||||
'Only finished ' + t + '/' + tests.length + ' tests'));
|
||||
});
|
183
node_modules/busboy/test/test-types-urlencoded.js
generated
vendored
Normal file
183
node_modules/busboy/test/test-types-urlencoded.js
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
var Busboy = require('..');
|
||||
|
||||
var path = require('path'),
|
||||
inspect = require('util').inspect,
|
||||
assert = require('assert');
|
||||
|
||||
var EMPTY_FN = function() {};
|
||||
|
||||
var t = 0,
|
||||
group = path.basename(__filename, '.js') + '/';
|
||||
|
||||
var tests = [
|
||||
{ source: ['foo'],
|
||||
expected: [['foo', '', false, false]],
|
||||
what: 'Unassigned value'
|
||||
},
|
||||
{ source: ['foo=bar'],
|
||||
expected: [['foo', 'bar', false, false]],
|
||||
what: 'Assigned value'
|
||||
},
|
||||
{ source: ['foo&bar=baz'],
|
||||
expected: [['foo', '', false, false],
|
||||
['bar', 'baz', false, false]],
|
||||
what: 'Unassigned and assigned value'
|
||||
},
|
||||
{ source: ['foo=bar&baz'],
|
||||
expected: [['foo', 'bar', false, false],
|
||||
['baz', '', false, false]],
|
||||
what: 'Assigned and unassigned value'
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [['foo', 'bar', false, false],
|
||||
['baz', 'bla', false, false]],
|
||||
what: 'Two assigned values'
|
||||
},
|
||||
{ source: ['foo&bar'],
|
||||
expected: [['foo', '', false, false],
|
||||
['bar', '', false, false]],
|
||||
what: 'Two unassigned values'
|
||||
},
|
||||
{ source: ['foo&bar&'],
|
||||
expected: [['foo', '', false, false],
|
||||
['bar', '', false, false]],
|
||||
what: 'Two unassigned values and ampersand'
|
||||
},
|
||||
{ source: ['foo=bar+baz%2Bquux'],
|
||||
expected: [['foo', 'bar baz+quux', false, false]],
|
||||
what: 'Assigned value with (plus) space'
|
||||
},
|
||||
{ source: ['foo=bar%20baz%21'],
|
||||
expected: [['foo', 'bar baz!', false, false]],
|
||||
what: 'Assigned value with encoded bytes'
|
||||
},
|
||||
{ source: ['foo%20bar=baz%20bla%21'],
|
||||
expected: [['foo bar', 'baz bla!', false, false]],
|
||||
what: 'Assigned value with encoded bytes #2'
|
||||
},
|
||||
{ source: ['foo=bar%20baz%21&num=1000'],
|
||||
expected: [['foo', 'bar baz!', false, false],
|
||||
['num', '1000', false, false]],
|
||||
what: 'Two assigned values, one with encoded bytes'
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [],
|
||||
what: 'Limits: zero fields',
|
||||
limits: { fields: 0 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [['foo', 'bar', false, false]],
|
||||
what: 'Limits: one field',
|
||||
limits: { fields: 1 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [['foo', 'bar', false, false],
|
||||
['baz', 'bla', false, false]],
|
||||
what: 'Limits: field part lengths match limits',
|
||||
limits: { fieldNameSize: 3, fieldSize: 3 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [['fo', 'bar', true, false],
|
||||
['ba', 'bla', true, false]],
|
||||
what: 'Limits: truncated field name',
|
||||
limits: { fieldNameSize: 2 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [['foo', 'ba', false, true],
|
||||
['baz', 'bl', false, true]],
|
||||
what: 'Limits: truncated field value',
|
||||
limits: { fieldSize: 2 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [['fo', 'ba', true, true],
|
||||
['ba', 'bl', true, true]],
|
||||
what: 'Limits: truncated field name and value',
|
||||
limits: { fieldNameSize: 2, fieldSize: 2 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [['fo', '', true, true],
|
||||
['ba', '', true, true]],
|
||||
what: 'Limits: truncated field name and zero value limit',
|
||||
limits: { fieldNameSize: 2, fieldSize: 0 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [['', '', true, true],
|
||||
['', '', true, true]],
|
||||
what: 'Limits: truncated zero field name and zero value limit',
|
||||
limits: { fieldNameSize: 0, fieldSize: 0 }
|
||||
},
|
||||
{ source: ['&'],
|
||||
expected: [],
|
||||
what: 'Ampersand'
|
||||
},
|
||||
{ source: ['&&&&&'],
|
||||
expected: [],
|
||||
what: 'Many ampersands'
|
||||
},
|
||||
{ source: ['='],
|
||||
expected: [['', '', false, false]],
|
||||
what: 'Assigned value, empty name and value'
|
||||
},
|
||||
{ source: [''],
|
||||
expected: [],
|
||||
what: 'Nothing'
|
||||
},
|
||||
];
|
||||
|
||||
function next() {
|
||||
if (t === tests.length)
|
||||
return;
|
||||
|
||||
var v = tests[t];
|
||||
|
||||
var busboy = new Busboy({
|
||||
limits: v.limits,
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded; charset=utf-8'
|
||||
}
|
||||
}),
|
||||
finishes = 0,
|
||||
results = [];
|
||||
|
||||
busboy.on('field', function(key, val, keyTrunc, valTrunc) {
|
||||
results.push([key, val, keyTrunc, valTrunc]);
|
||||
});
|
||||
busboy.on('file', function() {
|
||||
throw new Error(makeMsg(v.what, 'Unexpected file'));
|
||||
});
|
||||
busboy.on('finish', function() {
|
||||
assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
|
||||
assert.deepEqual(results.length,
|
||||
v.expected.length,
|
||||
makeMsg(v.what, 'Parsed result count mismatch. Saw '
|
||||
+ results.length
|
||||
+ '. Expected: ' + v.expected.length));
|
||||
|
||||
var i = 0;
|
||||
results.forEach(function(result) {
|
||||
assert.deepEqual(result,
|
||||
v.expected[i],
|
||||
makeMsg(v.what,
|
||||
'Result mismatch:\nParsed: ' + inspect(result)
|
||||
+ '\nExpected: ' + inspect(v.expected[i]))
|
||||
);
|
||||
++i;
|
||||
});
|
||||
++t;
|
||||
next();
|
||||
});
|
||||
|
||||
v.source.forEach(function(s) {
|
||||
busboy.write(new Buffer(s, 'utf8'), EMPTY_FN);
|
||||
});
|
||||
busboy.end();
|
||||
}
|
||||
next();
|
||||
|
||||
function makeMsg(what, msg) {
|
||||
return '[' + group + what + ']: ' + msg;
|
||||
}
|
||||
|
||||
process.on('exit', function() {
|
||||
assert(t === tests.length, makeMsg('_exit', 'Only finished ' + t + '/' + tests.length + ' tests'));
|
||||
});
|
66
node_modules/busboy/test/test-utils-decoder.js
generated
vendored
Normal file
66
node_modules/busboy/test/test-utils-decoder.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
var Decoder = require('../lib/utils').Decoder;
|
||||
|
||||
var path = require('path'),
|
||||
assert = require('assert');
|
||||
|
||||
var group = path.basename(__filename, '.js') + '/';
|
||||
|
||||
[
|
||||
{ source: ['Hello world'],
|
||||
expected: 'Hello world',
|
||||
what: 'No encoded bytes'
|
||||
},
|
||||
{ source: ['Hello%20world'],
|
||||
expected: 'Hello world',
|
||||
what: 'One full encoded byte'
|
||||
},
|
||||
{ source: ['Hello%20world%21'],
|
||||
expected: 'Hello world!',
|
||||
what: 'Two full encoded bytes'
|
||||
},
|
||||
{ source: ['Hello%', '20world'],
|
||||
expected: 'Hello world',
|
||||
what: 'One full encoded byte split #1'
|
||||
},
|
||||
{ source: ['Hello%2', '0world'],
|
||||
expected: 'Hello world',
|
||||
what: 'One full encoded byte split #2'
|
||||
},
|
||||
{ source: ['Hello%20', 'world'],
|
||||
expected: 'Hello world',
|
||||
what: 'One full encoded byte (concat)'
|
||||
},
|
||||
{ source: ['Hello%2Qworld'],
|
||||
expected: 'Hello%2Qworld',
|
||||
what: 'Malformed encoded byte #1'
|
||||
},
|
||||
{ source: ['Hello%world'],
|
||||
expected: 'Hello%world',
|
||||
what: 'Malformed encoded byte #2'
|
||||
},
|
||||
{ source: ['Hello+world'],
|
||||
expected: 'Hello world',
|
||||
what: 'Plus to space'
|
||||
},
|
||||
{ source: ['Hello+world%21'],
|
||||
expected: 'Hello world!',
|
||||
what: 'Plus and encoded byte'
|
||||
},
|
||||
{ source: ['5%2B5%3D10'],
|
||||
expected: '5+5=10',
|
||||
what: 'Encoded plus'
|
||||
},
|
||||
{ source: ['5+%2B+5+%3D+10'],
|
||||
expected: '5 + 5 = 10',
|
||||
what: 'Spaces and encoded plus'
|
||||
},
|
||||
].forEach(function(v) {
|
||||
var dec = new Decoder(), result = '';
|
||||
v.source.forEach(function(s) {
|
||||
result += dec.write(s);
|
||||
});
|
||||
var msg = '[' + group + v.what + ']: decoded string mismatch.\n'
|
||||
+ 'Saw: ' + result + '\n'
|
||||
+ 'Expected: ' + v.expected;
|
||||
assert.deepEqual(result, v.expected, msg);
|
||||
});
|
96
node_modules/busboy/test/test-utils-parse-params.js
generated
vendored
Normal file
96
node_modules/busboy/test/test-utils-parse-params.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
var parseParams = require('../lib/utils').parseParams;
|
||||
|
||||
var path = require('path'),
|
||||
assert = require('assert'),
|
||||
inspect = require('util').inspect;
|
||||
|
||||
var group = path.basename(__filename, '.js') + '/';
|
||||
|
||||
[
|
||||
{ source: 'video/ogg',
|
||||
expected: ['video/ogg'],
|
||||
what: 'No parameters'
|
||||
},
|
||||
{ source: 'video/ogg;',
|
||||
expected: ['video/ogg'],
|
||||
what: 'No parameters (with separator)'
|
||||
},
|
||||
{ source: 'video/ogg; ',
|
||||
expected: ['video/ogg'],
|
||||
what: 'No parameters (with separator followed by whitespace)'
|
||||
},
|
||||
{ source: ';video/ogg',
|
||||
expected: ['', 'video/ogg'],
|
||||
what: 'Empty parameter'
|
||||
},
|
||||
{ source: 'video/*',
|
||||
expected: ['video/*'],
|
||||
what: 'Subtype with asterisk'
|
||||
},
|
||||
{ source: 'text/plain; encoding=utf8',
|
||||
expected: ['text/plain', ['encoding', 'utf8']],
|
||||
what: 'Unquoted'
|
||||
},
|
||||
{ source: 'text/plain; encoding=',
|
||||
expected: ['text/plain', ['encoding', '']],
|
||||
what: 'Unquoted empty string'
|
||||
},
|
||||
{ source: 'text/plain; encoding="utf8"',
|
||||
expected: ['text/plain', ['encoding', 'utf8']],
|
||||
what: 'Quoted'
|
||||
},
|
||||
{ source: 'text/plain; greeting="hello \\"world\\""',
|
||||
expected: ['text/plain', ['greeting', 'hello "world"']],
|
||||
what: 'Quotes within quoted'
|
||||
},
|
||||
{ source: 'text/plain; encoding=""',
|
||||
expected: ['text/plain', ['encoding', '']],
|
||||
what: 'Quoted empty string'
|
||||
},
|
||||
{ source: 'text/plain; encoding="utf8";\t foo=bar;test',
|
||||
expected: ['text/plain', ['encoding', 'utf8'], ['foo', 'bar'], 'test'],
|
||||
what: 'Multiple params with various spacing'
|
||||
},
|
||||
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates",
|
||||
expected: ['text/plain', ['filename', '£ rates']],
|
||||
what: 'Extended parameter (RFC 5987) with language'
|
||||
},
|
||||
{ source: "text/plain; filename*=utf-8''%c2%a3%20and%20%e2%82%ac%20rates",
|
||||
expected: ['text/plain', ['filename', '£ and € rates']],
|
||||
what: 'Extended parameter (RFC 5987) without language'
|
||||
},
|
||||
{ source: "text/plain; filename*=utf-8''%E6%B5%8B%E8%AF%95%E6%96%87%E6%A1%A3",
|
||||
expected: ['text/plain', ['filename', '测试文档']],
|
||||
what: 'Extended parameter (RFC 5987) without language #2'
|
||||
},
|
||||
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates; altfilename*=utf-8''%c2%a3%20and%20%e2%82%ac%20rates",
|
||||
expected: ['text/plain', ['filename', '£ rates'], ['altfilename', '£ and € rates']],
|
||||
what: 'Multiple extended parameters (RFC 5987) with mixed charsets'
|
||||
},
|
||||
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates; altfilename=\"foobarbaz\"",
|
||||
expected: ['text/plain', ['filename', '£ rates'], ['altfilename', 'foobarbaz']],
|
||||
what: 'Mixed regular and extended parameters (RFC 5987)'
|
||||
},
|
||||
{ source: "text/plain; filename=\"foobarbaz\"; altfilename*=iso-8859-1'en'%A3%20rates",
|
||||
expected: ['text/plain', ['filename', 'foobarbaz'], ['altfilename', '£ rates']],
|
||||
what: 'Mixed regular and extended parameters (RFC 5987) #2'
|
||||
},
|
||||
{ source: 'text/plain; filename="C:\\folder\\test.png"',
|
||||
expected: ['text/plain', ['filename', 'C:\\folder\\test.png']],
|
||||
what: 'Unescaped backslashes should be considered backslashes'
|
||||
},
|
||||
{ source: 'text/plain; filename="John \\"Magic\\" Smith.png"',
|
||||
expected: ['text/plain', ['filename', 'John "Magic" Smith.png']],
|
||||
what: 'Escaped double-quotes should be considered double-quotes'
|
||||
},
|
||||
{ source: 'multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY',
|
||||
expected: ['multipart/form-data', ['charset', 'utf-8'], ['boundary', '0xKhTmLbOuNdArY']],
|
||||
what: 'Multiple non-quoted parameters'
|
||||
},
|
||||
].forEach(function(v) {
|
||||
var result = parseParams(v.source),
|
||||
msg = '[' + group + v.what + ']: parsed parameters mismatch.\n'
|
||||
+ 'Saw: ' + inspect(result) + '\n'
|
||||
+ 'Expected: ' + inspect(v.expected);
|
||||
assert.deepEqual(result, v.expected, msg);
|
||||
});
|
4
node_modules/busboy/test/test.js
generated
vendored
Normal file
4
node_modules/busboy/test/test.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
require('fs').readdirSync(__dirname).forEach(function(f) {
|
||||
if (f.substr(0, 5) === 'test-')
|
||||
require('./' + f);
|
||||
});
|
Reference in New Issue
Block a user