forked from eggjs/egg-multipart
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
103 lines (95 loc) · 3.17 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
'use strict';
const assert = require('assert');
const path = require('path');
const bytes = require('humanize-bytes');
module.exports = app => {
const options = app.config.multipart;
// make sure to cast the value of config **Size to number
for (const key in options) {
if (/^\w+Size$/.test(key)) {
options[key] = bytes(options[key]);
}
}
let checkExt;
if (typeof options.whitelist === 'function') {
checkExt = options.whitelist;
} else if (Array.isArray(options.whitelist)) {
options.whitelist = options.whitelist.map(extname => extname.toLowerCase());
checkExt = filename => options.whitelist.includes(path.extname(filename).toLowerCase());
} else {
// default extname whitelist
const whitelist = [
// images
'.jpg', '.jpeg', // image/jpeg
'.png', // image/png, image/x-png
'.gif', // image/gif
'.bmp', // image/bmp
'.wbmp', // image/vnd.wap.wbmp
'.webp',
'.tif',
'.psd',
// text
'.svg',
'.js', '.jsx',
'.json',
'.css', '.less',
'.html', '.htm',
'.xml',
// tar
'.zip',
'.gz', '.tgz', '.gzip',
// video
'.mp3',
'.mp4',
'.avi',
]
.concat(options.fileExtensions || [])
.map(extname => extname.toLowerCase());
checkExt = filename => whitelist.includes(path.extname(filename).toLowerCase());
}
// https://github.com/mscdex/busboy#busboy-methods
app.config.multipartParseOptions = {
autoFields: options.autoFields,
defCharset: options.defaultCharset,
limits: {
fieldNameSize: options.fieldNameSize,
fieldSize: options.fieldSize,
fields: options.fields,
fileSize: options.fileSize,
files: options.files,
},
// check if extname in the whitelist
checkFile(fieldname, fileStream, filename) {
// just ignore, if no file
if (!fileStream || !filename) return null;
try {
if (!checkExt(filename)) {
const err = new Error('Invalid filename: ' + filename);
err.status = 400;
return err;
}
} catch (err) {
err.status = 400;
return err;
}
},
};
options.mode = options.mode || 'stream';
if (![ 'stream', 'file' ].includes(options.mode)) {
throw new TypeError(`Expect mode to be 'stream' or 'file', but got '${options.mode}'`);
}
app.coreLogger.info('[egg-multipart] %s mode enable', options.mode);
if (options.mode === 'file') {
if (options.fileModeMatch) throw new TypeError('`fileModeMatch` options only work on stream mode, please remove it');
app.coreLogger.info('[egg-multipart] will save temporary files to %j, cleanup job cron: %j',
options.tmpdir, options.cleanSchedule.cron);
// enable multipart middleware
app.config.coreMiddleware.push('multipart');
} else if (options.fileModeMatch) {
assert(options.fileModeMatch instanceof RegExp, '`fileModeMatch` options should be an instance of RegExp');
app.coreLogger.info('[egg-multipart] will save temporary files to %j, cleanup job cron: %j',
options.tmpdir, options.cleanSchedule.cron);
// enable multipart middleware
app.config.coreMiddleware.push('multipart');
}
};