1
+ 'use strict' ;
2
+
1
3
var CombinedStream = require ( 'combined-stream' ) ;
2
4
var util = require ( 'util' ) ;
3
5
var path = require ( 'path' ) ;
@@ -12,19 +14,13 @@ var setToStringTag = require('es-set-tostringtag');
12
14
var hasOwn = require ( 'hasown' ) ;
13
15
var populate = require ( './populate.js' ) ;
14
16
15
- // Public API
16
- module . exports = FormData ;
17
-
18
- // make it a Stream
19
- util . inherits ( FormData , CombinedStream ) ;
20
-
21
17
/**
22
18
* Create readable "multipart/form-data" streams.
23
19
* Can be used to submit forms
24
20
* and file uploads to other web applications.
25
21
*
26
22
* @constructor
27
- * @param {Object } options - Properties to be added/overriden for FormData and CombinedStream
23
+ * @param {object } options - Properties to be added/overriden for FormData and CombinedStream
28
24
*/
29
25
function FormData ( options ) {
30
26
if ( ! ( this instanceof FormData ) ) {
@@ -37,34 +33,39 @@ function FormData(options) {
37
33
38
34
CombinedStream . call ( this ) ;
39
35
40
- options = options || { } ;
41
- for ( var option in options ) {
36
+ options = options || { } ; // eslint-disable-line no-param-reassign
37
+ for ( var option in options ) { // eslint-disable-line no-restricted-syntax
42
38
this [ option ] = options [ option ] ;
43
39
}
44
40
}
45
41
42
+ // make it a Stream
43
+ util . inherits ( FormData , CombinedStream ) ;
44
+
46
45
FormData . LINE_BREAK = '\r\n' ;
47
46
FormData . DEFAULT_CONTENT_TYPE = 'application/octet-stream' ;
48
47
49
48
FormData . prototype . append = function ( field , value , options ) {
50
- options = options || { } ;
49
+ options = options || { } ; // eslint-disable-line no-param-reassign
51
50
52
51
// allow filename as single option
53
- if ( typeof options == 'string' ) {
54
- options = { filename : options } ;
52
+ if ( typeof options === 'string' ) {
53
+ options = { filename : options } ; // eslint-disable-line no-param-reassign
55
54
}
56
55
57
56
var append = CombinedStream . prototype . append . bind ( this ) ;
58
57
59
58
// all that streamy business can't handle numbers
60
- if ( typeof value == 'number' ) {
61
- value = '' + value ;
59
+ if ( typeof value === 'number' ) {
60
+ value = String ( value ) ; // eslint-disable-line no-param-reassign
62
61
}
63
62
64
63
// https://github.com/felixge/node-form-data/issues/38
65
64
if ( Array . isArray ( value ) ) {
66
- // Please convert your array into string
67
- // the way web server expects it
65
+ /*
66
+ * Please convert your array into string
67
+ * the way web server expects it
68
+ */
68
69
this . _error ( new Error ( 'Arrays are not supported.' ) ) ;
69
70
return ;
70
71
}
@@ -83,12 +84,14 @@ FormData.prototype.append = function (field, value, options) {
83
84
FormData . prototype . _trackLength = function ( header , value , options ) {
84
85
var valueLength = 0 ;
85
86
86
- // used w/ getLengthSync(), when length is known.
87
- // e.g. for streaming directly from a remote server,
88
- // w/ a known file a size, and not wanting to wait for
89
- // incoming file to finish to get its size.
87
+ /*
88
+ * used w/ getLengthSync(), when length is known.
89
+ * e.g. for streaming directly from a remote server,
90
+ * w/ a known file a size, and not wanting to wait for
91
+ * incoming file to finish to get its size.
92
+ */
90
93
if ( options . knownLength != null ) {
91
- valueLength += + options . knownLength ;
94
+ valueLength += Number ( options . knownLength ) ;
92
95
} else if ( Buffer . isBuffer ( value ) ) {
93
96
valueLength = value . length ;
94
97
} else if ( typeof value === 'string' ) {
@@ -98,9 +101,7 @@ FormData.prototype._trackLength = function (header, value, options) {
98
101
this . _valueLength += valueLength ;
99
102
100
103
// @check why add CRLF? does this account for custom/multiple CRLFs?
101
- this . _overheadLength +=
102
- Buffer . byteLength ( header ) +
103
- FormData . LINE_BREAK . length ;
104
+ this . _overheadLength += Buffer . byteLength ( header ) + FormData . LINE_BREAK . length ;
104
105
105
106
// empty or either doesn't have path or not an http response or not a stream
106
107
if ( ! value || ( ! value . path && ! ( value . readable && hasOwn ( value , 'httpVersion' ) ) && ! ( value instanceof Stream ) ) ) {
@@ -126,7 +127,7 @@ FormData.prototype._lengthRetriever = function (value, callback) {
126
127
// when end specified
127
128
// no need to calculate range
128
129
// inclusive, starts with 0
129
- callback ( null , value . end + 1 - ( value . start ? value . start : 0 ) ) ;
130
+ callback ( null , value . end + 1 - ( value . start ? value . start : 0 ) ) ; // eslint-disable-line callback-return
130
131
131
132
// not that fast snoopy
132
133
} else {
@@ -145,28 +146,30 @@ FormData.prototype._lengthRetriever = function (value, callback) {
145
146
146
147
// or http response
147
148
} else if ( hasOwn ( value , 'httpVersion' ) ) {
148
- callback ( null , + value . headers [ 'content-length' ] ) ;
149
+ callback ( null , Number ( value . headers [ 'content-length' ] ) ) ; // eslint-disable-line callback-return
149
150
150
151
// or request stream http://github.com/mikeal/request
151
152
} else if ( hasOwn ( value , 'httpModule' ) ) {
152
153
// wait till response come back
153
154
value . on ( 'response' , function ( response ) {
154
155
value . pause ( ) ;
155
- callback ( null , + response . headers [ 'content-length' ] ) ;
156
+ callback ( null , Number ( response . headers [ 'content-length' ] ) ) ;
156
157
} ) ;
157
158
value . resume ( ) ;
158
159
159
160
// something else
160
161
} else {
161
- callback ( 'Unknown stream' ) ;
162
+ callback ( 'Unknown stream' ) ; // eslint-disable-line callback-return
162
163
}
163
164
} ;
164
165
165
166
FormData . prototype . _multiPartHeader = function ( field , value , options ) {
166
- // custom header specified (as string)?
167
- // it becomes responsible for boundary
168
- // (e.g. to handle extra CRLFs on .NET servers)
169
- if ( typeof options . header == 'string' ) {
167
+ /*
168
+ * custom header specified (as string)?
169
+ * it becomes responsible for boundary
170
+ * (e.g. to handle extra CRLFs on .NET servers)
171
+ */
172
+ if ( typeof options . header === 'string' ) {
170
173
return options . header ;
171
174
}
172
175
@@ -182,18 +185,18 @@ FormData.prototype._multiPartHeader = function (field, value, options) {
182
185
} ;
183
186
184
187
// allow custom headers.
185
- if ( typeof options . header == 'object' ) {
188
+ if ( typeof options . header === 'object' ) {
186
189
populate ( headers , options . header ) ;
187
190
}
188
191
189
192
var header ;
190
- for ( var prop in headers ) {
193
+ for ( var prop in headers ) { // eslint-disable-line no-restricted-syntax
191
194
if ( hasOwn ( headers , prop ) ) {
192
195
header = headers [ prop ] ;
193
196
194
197
// skip nullish headers.
195
198
if ( header == null ) {
196
- continue ;
199
+ continue ; // eslint-disable-line no-restricted-syntax, no-continue
197
200
}
198
201
199
202
// convert all headers to arrays.
@@ -211,16 +214,18 @@ FormData.prototype._multiPartHeader = function (field, value, options) {
211
214
return '--' + this . getBoundary ( ) + FormData . LINE_BREAK + contents + FormData . LINE_BREAK ;
212
215
} ;
213
216
214
- FormData . prototype . _getContentDisposition = function ( value , options ) {
217
+ FormData . prototype . _getContentDisposition = function ( value , options ) { // eslint-disable-line consistent-return
215
218
var filename ;
216
219
217
220
if ( typeof options . filepath === 'string' ) {
218
221
// custom filepath for relative paths
219
222
filename = path . normalize ( options . filepath ) . replace ( / \\ / g, '/' ) ;
220
223
} else if ( options . filename || value . name || value . path ) {
221
- // custom filename take precedence
222
- // formidable and the browser add a name property
223
- // fs- and request- streams have path property
224
+ /*
225
+ * custom filename take precedence
226
+ * formidable and the browser add a name property
227
+ * fs- and request- streams have path property
228
+ */
224
229
filename = path . basename ( options . filename || value . name || value . path ) ;
225
230
} else if ( value . readable && hasOwn ( value , 'httpVersion' ) ) {
226
231
// or try http response
@@ -257,7 +262,7 @@ FormData.prototype._getContentType = function (value, options) {
257
262
}
258
263
259
264
// fallback to the default content type if `value` is not simple value
260
- if ( ! contentType && typeof value == 'object' ) {
265
+ if ( ! contentType && typeof value === 'object' ) {
261
266
contentType = FormData . DEFAULT_CONTENT_TYPE ;
262
267
}
263
268
@@ -268,7 +273,7 @@ FormData.prototype._multiPartFooter = function () {
268
273
return function ( next ) {
269
274
var footer = FormData . LINE_BREAK ;
270
275
271
- var lastPart = ( this . _streams . length === 0 ) ;
276
+ var lastPart = this . _streams . length === 0 ;
272
277
if ( lastPart ) {
273
278
footer += this . _lastBoundary ( ) ;
274
279
}
@@ -287,7 +292,7 @@ FormData.prototype.getHeaders = function (userHeaders) {
287
292
'content-type' : 'multipart/form-data; boundary=' + this . getBoundary ( )
288
293
} ;
289
294
290
- for ( header in userHeaders ) {
295
+ for ( header in userHeaders ) { // eslint-disable-line no-restricted-syntax
291
296
if ( hasOwn ( userHeaders , header ) ) {
292
297
formHeaders [ header . toLowerCase ( ) ] = userHeaders [ header ] ;
293
298
}
@@ -309,7 +314,7 @@ FormData.prototype.getBoundary = function () {
309
314
} ;
310
315
311
316
FormData . prototype . getBuffer = function ( ) {
312
- var dataBuffer = new Buffer . alloc ( 0 ) ;
317
+ var dataBuffer = new Buffer . alloc ( 0 ) ; // eslint-disable-line new-cap
313
318
var boundary = this . getBoundary ( ) ;
314
319
315
320
// Create the form content. Add Line breaks to the end of data.
@@ -335,6 +340,7 @@ FormData.prototype.getBuffer = function () {
335
340
336
341
FormData . prototype . _generateBoundary = function ( ) {
337
342
// This generates a 50 character boundary similar to those used by Firefox.
343
+
338
344
// They are optimized for boyer-moore parsing.
339
345
var boundary = '--------------------------' ;
340
346
for ( var i = 0 ; i < 24 ; i ++ ) {
@@ -345,22 +351,22 @@ FormData.prototype._generateBoundary = function () {
345
351
} ;
346
352
347
353
// Note: getLengthSync DOESN'T calculate streams length
348
- // As workaround one can calculate file size manually
349
- // and add it as knownLength option
354
+ // As workaround one can calculate file size manually and add it as knownLength option
350
355
FormData . prototype . getLengthSync = function ( ) {
351
356
var knownLength = this . _overheadLength + this . _valueLength ;
352
357
353
- // Don't get confused, there are 3 "internal" streams for each keyval pair
354
- // so it basically checks if there is any value added to the form
358
+ // Don't get confused, there are 3 "internal" streams for each keyval pair so it basically checks if there is any value added to the form
355
359
if ( this . _streams . length ) {
356
360
knownLength += this . _lastBoundary ( ) . length ;
357
361
}
358
362
359
363
// https://github.com/form-data/form-data/issues/40
360
364
if ( ! this . hasKnownLength ( ) ) {
361
- // Some async length retrievers are present
362
- // therefore synchronous length calculation is false.
363
- // Please use getLength(callback) to get proper length
365
+ /*
366
+ * Some async length retrievers are present
367
+ * therefore synchronous length calculation is false.
368
+ * Please use getLength(callback) to get proper length
369
+ */
364
370
this . _error ( new Error ( 'Cannot calculate proper length in synchronous way.' ) ) ;
365
371
}
366
372
@@ -407,15 +413,14 @@ FormData.prototype.getLength = function (cb) {
407
413
} ;
408
414
409
415
FormData . prototype . submit = function ( params , cb ) {
410
- var request
411
- , options
412
- , defaults = { method : 'post' }
413
- ;
414
-
415
- // parse provided url if it's string
416
- // or treat it as options object
417
- if ( typeof params == 'string' ) {
418
- params = parseUrl ( params ) ;
416
+ var request ;
417
+ var options ;
418
+ var defaults = { method : 'post' } ;
419
+
420
+ // parse provided url if it's string or treat it as options object
421
+ if ( typeof params === 'string' ) {
422
+ params = parseUrl ( params ) ; // eslint-disable-line no-param-reassign
423
+ /* eslint sort-keys: 0 */
419
424
options = populate ( {
420
425
port : params . port ,
421
426
path : params . pathname ,
@@ -426,15 +431,15 @@ FormData.prototype.submit = function (params, cb) {
426
431
options = populate ( params , defaults ) ;
427
432
// if no port provided use default one
428
433
if ( ! options . port ) {
429
- options . port = options . protocol == 'https:' ? 443 : 80 ;
434
+ options . port = options . protocol === 'https:' ? 443 : 80 ;
430
435
}
431
436
}
432
437
433
438
// put that good code in getHeaders to some use
434
439
options . headers = this . getHeaders ( params . headers ) ;
435
440
436
441
// https if specified, fallback to http in any other case
437
- if ( options . protocol == 'https:' ) {
442
+ if ( options . protocol === 'https:' ) {
438
443
request = https . request ( options ) ;
439
444
} else {
440
445
request = http . request ( options ) ;
@@ -460,7 +465,7 @@ FormData.prototype.submit = function (params, cb) {
460
465
request . removeListener ( 'error' , callback ) ;
461
466
request . removeListener ( 'response' , onResponse ) ;
462
467
463
- return cb . call ( this , error , responce ) ;
468
+ return cb . call ( this , error , responce ) ; // eslint-disable-line no-invalid-this
464
469
} ;
465
470
466
471
onResponse = callback . bind ( this , null ) ;
@@ -485,3 +490,6 @@ FormData.prototype.toString = function () {
485
490
return '[object FormData]' ;
486
491
} ;
487
492
setToStringTag ( FormData , 'FormData' ) ;
493
+
494
+ // Public API
495
+ module . exports = FormData ;
0 commit comments