Skip to content

Commit

Permalink
Merge pull request #1 from felixge/master
Browse files Browse the repository at this point in the history
Getting updates from upstream.
  • Loading branch information
uformia authored Feb 11, 2018
2 parents d93055d + 6041695 commit cfcc465
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 159 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: node_js
node_js:
- 0.8
- "0.10"
- 0.11
- 4
- 6
- 7
146 changes: 22 additions & 124 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Formidable

[![Build Status](https://secure.travis-ci.org/felixge/node-formidable.png?branch=master)](http://travis-ci.org/felixge/node-formidable)
[![Build Status](https://travis-ci.org/felixge/node-formidable.svg?branch=master)](https://travis-ci.org/felixge/node-formidable)

## Purpose

A node.js module for parsing form data, especially file uploads.
A Node.js module for parsing form data, especially file uploads.

## Current status

**Maintainers Wanted:** Please see https://github.com/felixge/node-formidable/issues/412

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.
Expand All @@ -22,19 +24,12 @@ a large variety of clients and is considered production-ready.

## Installation

This is a low level package, and if you're using a high level framework such as Express, chances are it's already included in it. You can [read this discussion](http://stackoverflow.com/questions/11295554/how-to-disable-express-bodyparser-for-file-uploads-node-js) about how Formidable is integrated with Express.

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');
```sh
npm i -S formidable
```

This is a low-level package, and if you're using a high-level framework it may already be included. However, [Express v4](http://expressjs.com) does not include any multipart handling, nor does [body-parser](https://github.com/expressjs/body-parser).

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
Expand Down Expand Up @@ -87,7 +82,7 @@ Sets encoding for incoming form fields.
form.uploadDir = "/my/dir";
```
Sets the directory for placing file uploads in. You can move them later on using
`fs.rename()`. The default is `os.tmpDir()`.
`fs.rename()`. The default is `os.tmpdir()`.

```javascript
form.keepExtensions = false;
Expand Down Expand Up @@ -272,7 +267,18 @@ Emitted when the entire request has been received, and all contained files have

## Changelog

### v1.0.14
### v1.1.1 (2017-01-15)

* Fix DeprecationWarning about os.tmpDir() (Christian)
* Update `buffer.write` order of arguments for Node 7 (Kornel Lesiński)
* JSON Parser emits error events to the IncomingForm (alessio.montagnani)
* Improved Content-Disposition parsing (Sebastien)
* Access WriteStream of fs during runtime instead of include time (Jonas Amundsen)
* Use built-in toString to convert buffer to hex (Charmander)
* Add hash to json if present (Nick Stamas)
* Add license to package.json (Simen Bekkhus)

### v1.0.14 (2013-05-03)

* Add failing hash tests. (Ben Trask)
* Enable hash calculation again (Eugene Girshov)
Expand Down Expand Up @@ -304,120 +310,12 @@ Emitted when the entire request has been received, and all contained files have
* Remove support for Node.js 0.4 & 0.6 (Andrew Kelley)
* Documentation improvements (Sven Lito, Andre Azevedo)
* Add support for application/octet-stream (Ion Lupascu, Chris Scribner)
* Use os.tmpDir() to get tmp directory (Andrew Kelley)
* Use os.tmpdir() to get tmp directory (Andrew Kelley)
* Improve package.json (Andrew Kelley, Sven Lito)
* Fix benchmark script (Andrew Kelley)
* Fix scope issue in incoming_forms (Sven Lito)
* Fix file handle leak on error (OrangeDog)

### v1.0.11

* Calculate checksums for incoming files (sreuter)
* Add definition parameters to "IncomingForm" as an argument (Math-)

### v1.0.10

* Make parts to be proper Streams (Matt Robenolt)

### 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)

## License

Formidable is licensed under the MIT license.
Expand Down
4 changes: 2 additions & 2 deletions benchmark/bench-multipart-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ function createMultipartBuffer(boundary, size) {
, tail = '\r\n--'+boundary+'--\r\n'
, buffer = new Buffer(size);

buffer.write(head, 'ascii', 0);
buffer.write(tail, 'ascii', buffer.length - tail.length);
buffer.write(head, 0, 'ascii');
buffer.write(tail, buffer.length - tail.length, 'ascii');
return buffer;
}

Expand Down
9 changes: 5 additions & 4 deletions example/post.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require('../test/common');
var common = require('../test/common');
var http = require('http'),
util = require('util'),
formidable = require('formidable'),
formidable = common.formidable,
port = common.port,
server;

server = http.createServer(function(req, res) {
Expand Down Expand Up @@ -38,6 +39,6 @@ server = http.createServer(function(req, res) {
res.end('404');
}
});
server.listen(TEST_PORT);
server.listen(port);

console.log('listening on http://localhost:'+TEST_PORT+'/');
console.log('listening on http://localhost:'+port+'/');
12 changes: 7 additions & 5 deletions example/upload.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require('../test/common');
var common = require('../test/common');
var http = require('http'),
util = require('util'),
formidable = require('formidable'),
os = require('os'),
formidable = common.formidable,
port = common.port,
server;

server = http.createServer(function(req, res) {
Expand All @@ -19,7 +21,7 @@ server = http.createServer(function(req, res) {
files = [],
fields = [];

form.uploadDir = TEST_TMP;
form.uploadDir = os.tmpdir();

form
.on('field', function(field, value) {
Expand All @@ -43,6 +45,6 @@ server = http.createServer(function(req, res) {
res.end('404');
}
});
server.listen(TEST_PORT);
server.listen(port);

console.log('listening on http://localhost:'+TEST_PORT+'/');
console.log('listening on http://localhost:'+port+'/');
15 changes: 12 additions & 3 deletions lib/file.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
if (global.GENTLY) require = GENTLY.hijack(require);

var util = require('util'),
WriteStream = require('fs').WriteStream,
fs = require('fs'),
EventEmitter = require('events').EventEmitter,
crypto = require('crypto');

Expand Down Expand Up @@ -31,11 +31,11 @@ module.exports = File;
util.inherits(File, EventEmitter);

File.prototype.open = function() {
this._writeStream = new WriteStream(this.path);
this._writeStream = new fs.WriteStream(this.path);
};

File.prototype.toJSON = function() {
return {
var json = {
size: this.size,
path: this.path,
name: this.name,
Expand All @@ -45,13 +45,22 @@ File.prototype.toJSON = function() {
filename: this.filename,
mime: this.mime
};
if (this.hash && this.hash != "") {
json.hash = this.hash;
}
return json;
};

File.prototype.write = function(buffer, cb) {
var self = this;
if (self.hash) {
self.hash.update(buffer);
}

if (this._writeStream.closed) {
return cb();
}

this._writeStream.write(buffer, function() {
self.lastModifiedDate = new Date();
self.size += buffer.length;
Expand Down
18 changes: 11 additions & 7 deletions lib/incoming_form.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ function IncomingForm(opts) {

this.maxFields = opts.maxFields || 1000;
this.maxFieldsSize = opts.maxFieldsSize || 2 * 1024 * 1024;
this.maxFileSize = opts.maxFileSize || 2 * 1024 * 1024;
this.keepExtensions = opts.keepExtensions || false;
this.uploadDir = opts.uploadDir || os.tmpDir();
this.uploadDir = opts.uploadDir || (os.tmpdir && os.tmpdir()) || os.tmpDir();
this.encoding = opts.encoding || 'utf-8';
this.headers = null;
this.type = null;
Expand All @@ -39,6 +40,7 @@ function IncomingForm(opts) {
this._parser = null;
this._flushing = 0;
this._fieldsSize = 0;
this._fileSize = 0;
this.openedFiles = [];

return this;
Expand Down Expand Up @@ -180,6 +182,7 @@ IncomingForm.prototype.onPart = function(part) {
IncomingForm.prototype.handlePart = function(part) {
var self = this;

// This MUST check exactly for undefined. You can not change it to !part.filename.
if (part.filename === undefined) {
var value = ''
, decoder = new StringDecoder(this.encoding);
Expand Down Expand Up @@ -214,6 +217,11 @@ IncomingForm.prototype.handlePart = function(part) {
this.openedFiles.push(file);

part.on('data', function(buffer) {
self._fileSize += buffer.length;
if (self._fileSize > self.maxFileSize) {
self._error(new Error('maxFileSize exceeded, received '+self._fileSize+' bytes of file data'));
return;
}
if (buffer.length == 0) {
return;
}
Expand Down Expand Up @@ -512,7 +520,7 @@ IncomingForm.prototype._initOctetStream = function() {
IncomingForm.prototype._initJSONencoded = function() {
this.type = 'json';

var parser = new JSONParser()
var parser = new JSONParser(this)
, self = this;

if (this.bytesExpected) {
Expand All @@ -532,11 +540,8 @@ IncomingForm.prototype._initJSONencoded = function() {
};

IncomingForm.prototype._uploadPath = function(filename) {
var name = 'upload_';
var buf = crypto.randomBytes(16);
for (var i = 0; i < buf.length; ++i) {
name += ('0' + buf[i].toString(16)).slice(-2);
}
var name = 'upload_' + buf.toString('hex');

if (this.keepExtensions) {
var ext = path.extname(filename);
Expand All @@ -555,4 +560,3 @@ IncomingForm.prototype._maybeEnd = function() {

this.emit('end');
};

7 changes: 5 additions & 2 deletions lib/json_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ if (global.GENTLY) require = GENTLY.hijack(require);

var Buffer = require('buffer').Buffer;

function JSONParser() {
function JSONParser(parent) {
this.parent = parent;
this.data = new Buffer('');
this.bytesWritten = 0;
}
Expand All @@ -28,7 +29,9 @@ JSONParser.prototype.end = function() {
for (var field in fields) {
this.onField(field, fields[field]);
}
} catch (e) {}
} catch (e) {
this.parent.emit('error', e);
}
this.data = null;

this.onEnd();
Expand Down
Loading

0 comments on commit cfcc465

Please sign in to comment.