Socket
Socket
Sign inDemoInstall

form-data

Package Overview
Dependencies
Maintainers
6
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

form-data - npm Package Compare versions

Comparing version 1.0.0-rc3 to 1.0.0-rc4

.dockerignore

3

lib/browser.js

@@ -1,1 +0,2 @@

module.exports = FormData;
/* eslint-env browser */
module.exports = FormData;

@@ -10,5 +10,22 @@ var CombinedStream = require('combined-stream');

var async = require('async');
var populate = require('./populate.js');
// Public API
module.exports = FormData;
// make it a Stream
util.inherits(FormData, CombinedStream);
/**
* Create readable "multipart/form-data" streams.
* Can be used to submit forms
* and file uploads to other web applications.
*
* @constructor
*/
function FormData() {
if (!(this instanceof FormData)) {
throw new TypeError('Failed to construct FormData: Please use the _new_ operator, this object constructor cannot be called as a function.');
}
this._overheadLength = 0;

@@ -20,3 +37,2 @@ this._valueLength = 0;

}
util.inherits(FormData, CombinedStream);

@@ -27,10 +43,16 @@ FormData.LINE_BREAK = '\r\n';

FormData.prototype.append = function(field, value, options) {
options = (typeof options === 'string')
? { filename: options }
: options || {};
options = options || {};
// allow filename as single option
if (typeof options == 'string') {
options = {filename: options};
}
var append = CombinedStream.prototype.append.bind(this);
// all that streamy business can't handle numbers
if (typeof value == 'number') value = ''+value;
if (typeof value == 'number') {
value = '' + value;
}

@@ -46,3 +68,3 @@ // https://github.com/felixge/node-form-data/issues/38

var header = this._multiPartHeader(field, value, options);
var footer = this._multiPartFooter(field, value, options);
var footer = this._multiPartFooter();

@@ -85,57 +107,58 @@ append(header);

// no need to bother with the length
if (!options.knownLength)
this._lengthRetrievers.push(function(next) {
if (!options.knownLength) {
this._lengthRetrievers.push(function(next) {
if (value.hasOwnProperty('fd')) {
if (value.hasOwnProperty('fd')) {
// take read range into a account
// `end` = Infinity –> read file till the end
//
// TODO: Looks like there is bug in Node fs.createReadStream
// it doesn't respect `end` options without `start` options
// Fix it when node fixes it.
// https://github.com/joyent/node/issues/7819
if (value.end != undefined && value.end != Infinity && value.start != undefined) {
// take read range into a account
// `end` = Infinity –> read file till the end
//
// TODO: Looks like there is bug in Node fs.createReadStream
// it doesn't respect `end` options without `start` options
// Fix it when node fixes it.
// https://github.com/joyent/node/issues/7819
if (value.end != undefined && value.end != Infinity && value.start != undefined) {
// when end specified
// no need to calculate range
// inclusive, starts with 0
next(null, value.end+1 - (value.start ? value.start : 0));
// when end specified
// no need to calculate range
// inclusive, starts with 0
next(null, value.end + 1 - (value.start ? value.start : 0));
// not that fast snoopy
} else {
// still need to fetch file size from fs
fs.stat(value.path, function(err, stat) {
// not that fast snoopy
} else {
// still need to fetch file size from fs
fs.stat(value.path, function(err, stat) {
var fileSize;
var fileSize;
if (err) {
next(err);
return;
}
if (err) {
next(err);
return;
}
// update final size based on the range options
fileSize = stat.size - (value.start ? value.start : 0);
next(null, fileSize);
});
}
// update final size based on the range options
fileSize = stat.size - (value.start ? value.start : 0);
next(null, fileSize);
});
}
// or http response
} else if (value.hasOwnProperty('httpVersion')) {
next(null, +value.headers['content-length']);
// or http response
} else if (value.hasOwnProperty('httpVersion')) {
next(null, +value.headers['content-length']);
// or request stream http://github.com/mikeal/request
} else if (value.hasOwnProperty('httpModule')) {
// wait till response come back
value.on('response', function(response) {
value.pause();
next(null, +response.headers['content-length']);
});
value.resume();
// or request stream http://github.com/mikeal/request
} else if (value.hasOwnProperty('httpModule')) {
// wait till response come back
value.on('response', function(response) {
value.pause();
next(null, +response.headers['content-length']);
});
value.resume();
// something else
} else {
next('Unknown stream');
}
});
// something else
} else {
next('Unknown stream');
}
});
}
};

@@ -147,43 +170,17 @@

// (e.g. to handle extra CRLFs on .NET servers)
if (options.header != null) {
if (options.header) {
return options.header;
}
var contentDisposition = this._getContentDisposition(value, options);
var contentType = this._getContentType(value, options);
var contents = '';
var headers = {
'Content-Disposition': ['form-data', 'name="' + field + '"'],
'Content-Type': []
// add custom disposition as third element or keep it two elements if not
'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
// if no content type. allow it to be empty array
'Content-Type': [].concat(contentType || [])
};
// fs- and request- streams have path property
// or use custom filename and/or contentType
// TODO: Use request's response mime-type
if (options.filename || value.path) {
headers['Content-Disposition'].push(
'filename="' + path.basename(options.filename || value.path) + '"'
);
headers['Content-Type'].push(
options.contentType ||
mime.lookup(options.filename || value.path) ||
FormData.DEFAULT_CONTENT_TYPE
);
// http response has not
} else if (value.readable && value.hasOwnProperty('httpVersion')) {
headers['Content-Disposition'].push(
'filename="' + path.basename(value.client._httpMessage.path) + '"'
);
headers['Content-Type'].push(
options.contentType ||
value.headers['content-type'] ||
FormData.DEFAULT_CONTENT_TYPE
);
} else if (Buffer.isBuffer(value)) {
headers['Content-Type'].push(
options.contentType ||
FormData.DEFAULT_CONTENT_TYPE
);
} else if (options.contentType) {
headers['Content-Type'].push(options.contentType);
}
for (var prop in headers) {

@@ -194,7 +191,55 @@ if (headers[prop].length) {

}
return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK;
};
FormData.prototype._multiPartFooter = function(field, value, options) {
FormData.prototype._getContentDisposition = function(value, options) {
var contentDisposition;
// custom filename takes precedence
// fs- and request- streams have path property
var filename = options.filename || value.path;
// or try http response
if (!filename && value.readable && value.hasOwnProperty('httpVersion')) {
filename = value.client._httpMessage.path;
}
if (filename) {
contentDisposition = 'filename="' + path.basename(filename) + '"';
}
return contentDisposition;
};
FormData.prototype._getContentType = function(value, options) {
// use custom content-type above all
var contentType = options.contentType;
// or try `path` from fs-, request- streams
if (!contentType && value.path) {
contentType = mime.lookup(value.path);
}
// or if it's http-reponse
if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) {
contentType = value.headers['content-type'];
}
// or guess it from the filename
if (!contentType && options.filename) {
contentType = mime.lookup(options.filename);
}
// fallback to the default content type if `value` is not simple value
if (!contentType && typeof value == 'object') {
contentType = FormData.DEFAULT_CONTENT_TYPE;
}
return contentType;
};
FormData.prototype._multiPartFooter = function() {
return function(next) {

@@ -217,2 +262,3 @@ var footer = FormData.LINE_BREAK;

FormData.prototype.getHeaders = function(userHeaders) {
var header;
var formHeaders = {

@@ -222,19 +268,21 @@ 'content-type': 'multipart/form-data; boundary=' + this.getBoundary()

for (var header in userHeaders) {
formHeaders[header.toLowerCase()] = userHeaders[header];
for (header in userHeaders) {
if (userHeaders.hasOwnProperty(header)) {
formHeaders[header.toLowerCase()] = userHeaders[header];
}
}
return formHeaders;
}
};
FormData.prototype.getCustomHeaders = function(contentType) {
contentType = contentType ? contentType : 'multipart/form-data';
contentType = contentType ? contentType : 'multipart/form-data';
var formHeaders = {
'content-type': contentType + '; boundary=' + this.getBoundary(),
'content-length': this.getLengthSync()
};
var formHeaders = {
'content-type': contentType + '; boundary=' + this.getBoundary(),
'content-length': this.getLengthSync()
};
return formHeaders;
}
return formHeaders;
};

@@ -263,3 +311,3 @@ FormData.prototype.getBoundary = function() {

// and add it as knownLength option
FormData.prototype.getLengthSync = function(debug) {
FormData.prototype.getLengthSync = function() {
var knownLength = this._overheadLength + this._valueLength;

@@ -273,5 +321,5 @@

// https://github.com/felixge/node-form-data/issues/40
// https://github.com/form-data/form-data/issues/40
if (this._lengthRetrievers.length) {
// Some async length retrivers are present
// Some async length retrievers are present
// therefore synchronous length calculation is false.

@@ -312,8 +360,6 @@ // Please use getLength(callback) to get proper length

FormData.prototype.submit = function(params, cb) {
var request
, options
, defaults = {
method : 'post'
};
, defaults = {method: 'post'}
;

@@ -323,4 +369,4 @@ // parse provided url if it's string

if (typeof params == 'string') {
params = parseUrl(params);
options = populate({

@@ -331,5 +377,6 @@ port: params.port,

}, defaults);
}
else // use custom params
{
// use custom params
} else {
options = populate(params, defaults);

@@ -354,5 +401,7 @@ // if no port provided use default one

this.getLength(function(err, length) {
if (err) {
this._error(err);
return;
}
// TODO: Add chunked encoding when no length (if err)
// add content length

@@ -372,19 +421,7 @@ request.setHeader('Content-Length', length);

FormData.prototype._error = function(err) {
if (this.error) return;
this.error = err;
this.pause();
this.emit('error', err);
if (!this.error) {
this.error = err;
this.pause();
this.emit('error', err);
}
};
/*
* Santa's little helpers
*/
// populates missing values
function populate(dst, src) {
for (var prop in src) {
if (!dst[prop]) dst[prop] = src[prop];
}
return dst;
}

@@ -5,3 +5,3 @@ {

"description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.",
"version": "1.0.0-rc3",
"version": "1.0.0-rc4",
"repository": {

@@ -14,6 +14,15 @@ "type": "git",

"scripts": {
"test": "./test/run.js"
"pretest": "rimraf coverage test/tmp",
"test": "istanbul cover --report none test/run.js",
"posttest": "istanbul report",
"lint": "eslint lib/*.js test/*.js test/**/*.js",
"predebug": "rimraf coverage test/tmp",
"debug": "verbose=1 ./test/run.js",
"check": "istanbul check-coverage coverage/coverage*.json",
"coverage": "codacy-coverage < ./coverage/lcov.info; true"
},
"pre-commit": [
"test"
"lint",
"test",
"check"
],

@@ -24,14 +33,20 @@ "engines": {

"dependencies": {
"async": "^1.4.0",
"async": "^1.5.2",
"combined-stream": "^1.0.5",
"mime-types": "^2.1.3"
"mime-types": "^2.1.10"
},
"license": "MIT",
"devDependencies": {
"codacy-coverage": "^1.1.3",
"coveralls": "^2.11.8",
"cross-spawn": "^2.1.5",
"eslint": "^2.4.0",
"fake": "^0.2.2",
"far": "^0.0.7",
"formidable": "^1.0.17",
"pre-commit": "^1.0.10",
"request": "^2.60.0"
"istanbul": "^0.4.2",
"pre-commit": "^1.1.2",
"request": "^2.69.0",
"rimraf": "^2.5.2"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc