@poppinss/multiparty 1.0.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/HISTORY.md +12 -0
  2. package/README.md +10 -14
  3. package/index.js +34 -5
  4. package/package.json +12 -8
package/HISTORY.md CHANGED
@@ -1,3 +1,15 @@
1
+ unreleased
2
+ ==========
3
+
4
+ * Fix form parsing when no `part` event listener added
5
+
6
+ 4.2.3 / 2022-01-20
7
+ ==================
8
+
9
+ * Fix handling of unquoted values in `Content-Disposition`
10
+ * deps: http-errors@~1.8.1
11
+ - deps: toidentifier@1.0.1
12
+
1
13
  4.2.2 / 2020-07-27
2
14
  ==================
3
15
 
package/README.md CHANGED
@@ -3,9 +3,7 @@
3
3
 
4
4
  [![NPM Version][npm-version-image]][npm-url]
5
5
  [![NPM Downloads][npm-downloads-image]][npm-url]
6
- [![Node.js Version][node-version-image]][node-version-url]
7
- [![Build Status][travis-image]][travis-url]
8
- [![Test Coverage][coveralls-image]][coveralls-url]
6
+ [![Build Status][gh-workflow-image]][gh-workflow-url]
9
7
 
10
8
  Parses http requests with content-type `multipart/form-data`, also known as file uploads.
11
9
 
@@ -115,14 +113,14 @@ form.on('part', function(part) {
115
113
  // You *must* act on the part by reading it
116
114
  // NOTE: if you want to ignore it, just call "part.resume()"
117
115
 
118
- if (!part.filename) {
116
+ if (part.filename === undefined) {
119
117
  // filename is not defined when this is a field and not a file
120
118
  console.log('got field named ' + part.name);
121
119
  // ignore field's content
122
120
  part.resume();
123
121
  }
124
122
 
125
- if (part.filename) {
123
+ if (part.filename !== undefined) {
126
124
  // filename is defined when this is a file
127
125
  count++;
128
126
  console.log('got file named ' + part.name);
@@ -268,12 +266,10 @@ stream uploads to disk for you.
268
266
 
269
267
  [MIT](LICENSE)
270
268
 
271
- [coveralls-image]: https://badgen.net/coveralls/c/github/pillarjs/multiparty/master
272
- [coveralls-url]: https://coveralls.io/r/pillarjs/multiparty?branch=master
273
- [node-version-image]: https://badgen.net/npm/node/multiparty
274
- [node-version-url]: https://nodejs.org/en/download
275
- [npm-downloads-image]: https://badgen.net/npm/dm/multiparty
276
- [npm-url]: https://npmjs.org/package/multiparty
277
- [npm-version-image]: https://badgen.net/npm/v/multiparty
278
- [travis-image]: https://badgen.net/travis/pillarjs/multiparty/master
279
- [travis-url]: https://travis-ci.org/pillarjs/multiparty
269
+ [npm-downloads-image]: https://img.shields.io/npm/dm/@poppinss/multiparty?style=for-the-badge
270
+ [npm-url]: https://npmjs.org/package/@poppinss/multiparty
271
+
272
+ [npm-version-image]: https://img.shields.io/npm/v/@poppinss/multiparty?style=for-the-badge
273
+
274
+ [gh-workflow-image]: https://img.shields.io/github/workflow/status/poppinss/multiparty/test?style=for-the-badge
275
+ [gh-workflow-url]: https://github.com/poppinss/multiparty/actions/workflows/test.yml "Github action"
package/index.js CHANGED
@@ -42,7 +42,9 @@ var Z = 122;
42
42
  var CONTENT_TYPE_RE = /^multipart\/(?:form-data|related)(?:;|$)/i;
43
43
  var CONTENT_TYPE_PARAM_RE = /;\s*([^=]+)=(?:"([^"]+)"|([^;]+))/gi;
44
44
  var FILE_EXT_RE = /(\.[_\-a-zA-Z0-9]{0,16})[\S\s]*/;
45
+ var FILENAME_PARAM_RE = /\bfilename=(?:"(.*?)"|([!#$%&'*+.0-9A-Z^_`a-z|~-]+))($|; )/i
45
46
  var LAST_BOUNDARY_SUFFIX_LEN = 4; // --\r\n
47
+ var NAME_PARAM_RE = /\bname=(?:"([^"]+)"|([!#$%&'*+.0-9A-Z^_`a-z|~-]+))/i
46
48
 
47
49
  exports.Form = Form;
48
50
 
@@ -458,8 +460,8 @@ Form.prototype.onParseHeaderEnd = function() {
458
460
 
459
461
  var m;
460
462
  if (this.headerField === 'content-disposition') {
461
- if (m = this.headerValue.match(/\bname="([^"]+)"/i)) {
462
- this.partName = m[1];
463
+ if (m = NAME_PARAM_RE.exec(this.headerValue)) {
464
+ this.partName = m[1] || m[2] || ''
463
465
  }
464
466
  this.partFilename = parseFilename(this.headerValue);
465
467
  } else if (this.headerField === 'content-transfer-encoding') {
@@ -670,7 +672,14 @@ function handlePart(self, partStream) {
670
672
  endFlush(self);
671
673
  });
672
674
  emitAndReleaseHold(function() {
673
- self.emit('part', partStream);
675
+ if (hasListeners(self, 'part')) {
676
+ self.emit('part', partStream)
677
+ } else {
678
+ partStream.on('error', function (err) {
679
+ self.handleError(err)
680
+ })
681
+ partStream.resume()
682
+ }
674
683
  });
675
684
  }
676
685
 
@@ -752,6 +761,26 @@ function handleField(self, fieldStream) {
752
761
  });
753
762
  }
754
763
 
764
+ /**
765
+ * Determine if emitter has listeners of a given type.
766
+ *
767
+ * The way to do this check is done three different ways in Node.js >= 0.10
768
+ * so this consolidates them into a minimal set using instance methods.
769
+ *
770
+ * @param {EventEmitter} emitter
771
+ * @param {string} type
772
+ * @returns {boolean}
773
+ * @private
774
+ */
775
+
776
+ function hasListeners (emitter, type) {
777
+ var count = typeof emitter.listenerCount !== 'function'
778
+ ? emitter.listeners(type).length
779
+ : emitter.listenerCount(type)
780
+
781
+ return count > 0
782
+ }
783
+
755
784
  function clearPartVars(self) {
756
785
  self.partHeaders = {};
757
786
  self.partName = null;
@@ -795,7 +824,7 @@ function uploadPath(baseDir, filename) {
795
824
  }
796
825
 
797
826
  function parseFilename(headerValue) {
798
- var m = headerValue.match(/\bfilename="(.*?)"($|; )/i);
827
+ var m = FILENAME_PARAM_RE.exec(headerValue)
799
828
  if (!m) {
800
829
  m = headerValue.match(/\bfilename\*=utf-8''(.*?)($|; )/i)
801
830
  if (m) {
@@ -805,7 +834,7 @@ function parseFilename(headerValue) {
805
834
  }
806
835
  }
807
836
 
808
- var filename = m[1];
837
+ var filename = m[1] || m[2] || '';
809
838
  filename = filename.replace(/%22|\\"/g, '"');
810
839
  filename = filename.replace(/&#([\d]{4});/g, function(m, code) {
811
840
  return String.fromCharCode(code);
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@poppinss/multiparty",
3
- "version": "1.0.1",
3
+ "version": "2.0.1",
4
4
  "description": "multipart/form-data parser which supports streaming",
5
5
  "main": "index.js",
6
+ "contributors": [
7
+ "Douglas Christopher Wilson <doug@somethingdoug.com>",
8
+ "Felix Geisendörfer <felix@debuggable.com>"
9
+ ],
6
10
  "license": "MIT",
7
11
  "keywords": [
8
12
  "file",
@@ -12,20 +16,20 @@
12
16
  "s3"
13
17
  ],
14
18
  "dependencies": {
15
- "http-errors": "~1.8.0",
19
+ "http-errors": "^2.0.0",
16
20
  "safe-buffer": "5.2.1",
17
21
  "uid-safe": "2.1.5"
18
22
  },
19
23
  "devDependencies": {
20
- "eslint": "^7.22.0",
21
- "eslint-plugin-markdown": "^2.0.0",
24
+ "eslint": "^8.9.0",
25
+ "eslint-plugin-markdown": "2.2.1",
22
26
  "mkdirp": "^1.0.4",
23
- "mocha": "^8.3.2",
27
+ "mocha": "^9.2.1",
24
28
  "nyc": "15.1.0",
25
29
  "pend": "1.2.0",
26
30
  "require-all": "3.0.0",
27
31
  "rimraf": "^3.0.2",
28
- "superagent": "^6.1.0"
32
+ "superagent": "^7.1.1"
29
33
  },
30
34
  "files": [
31
35
  "HISTORY.md",
@@ -34,9 +38,9 @@
34
38
  "index.js"
35
39
  ],
36
40
  "scripts": {
37
- "lint": "eslint --plugin markdown --ext js,md .",
41
+ "lint": "eslint .",
38
42
  "test": "mocha --reporter spec --bail --check-leaks test/",
39
- "test-ci": "nyc --reporter=text npm test",
43
+ "test-ci": "nyc --reporter=lcov --reporter=text npm test",
40
44
  "test-cov": "nyc --reporter=html --reporter=text npm test"
41
45
  },
42
46
  "directories": {