@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.
- package/HISTORY.md +12 -0
- package/README.md +10 -14
- package/index.js +34 -5
- 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
|
-
[![
|
|
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 (
|
|
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
|
-
[
|
|
272
|
-
[
|
|
273
|
-
|
|
274
|
-
[
|
|
275
|
-
|
|
276
|
-
[
|
|
277
|
-
[
|
|
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
|
|
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
|
|
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 =
|
|
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": "
|
|
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": "
|
|
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": "^
|
|
21
|
-
"eslint-plugin-markdown": "
|
|
24
|
+
"eslint": "^8.9.0",
|
|
25
|
+
"eslint-plugin-markdown": "2.2.1",
|
|
22
26
|
"mkdirp": "^1.0.4",
|
|
23
|
-
"mocha": "^
|
|
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": "^
|
|
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
|
|
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": {
|