forked from myshenin/aws-lambda-multipart-parser
-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
64 lines (58 loc) · 1.9 KB
/
index.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
const prefixBoundary = '\r\n--';
const delimData = '\r\n\r\n';
const defaultResult = {files: {}, fields: {}};
/**
* Split gently
* @param {String} str
* @param {String} delim
* @return {Array<String>}
*/
const split = (str, delim) => [
str.substring(0, str.indexOf(delim)),
str.substring(str.indexOf(delim) + delim.length)];
/**
* Get value of key, case insensitive
* @param {Object} obj
* @param {String} lookedKey
* @return {String}
*/
const getValueIgnoringKeyCase = (obj, lookedKey) => Object.keys(obj)
.map(presentKey => presentKey.toLowerCase() === lookedKey.toLowerCase() ? obj[presentKey] : null)
.filter(item => item)[0];
/**
* Parser
* @param {Object} event
* @param {String} spotText
* @return {*}
*/
module.exports.parse = (event, spotText) => {
const boundary = prefixBoundary + getValueIgnoringKeyCase(event.headers, 'Content-Type').split('=')[1];
if (!boundary) { return defaultResult;}
return (event.isBase64Encoded ? Buffer.from(event.body, 'base64').toString('binary') : event.body)
.split(boundary)
.filter((item) => item.indexOf('Content-Disposition: form-data') !== -1)
.map((item) => {
const tmp = split(item, delimData);
const header = tmp[0];
let content = tmp[1];
const name = header.match(/name="([^"]+)"/)[1];
const result = {};
result[name] = content;
if (header.indexOf('filename') !== -1) {
const filename = header.match(/filename="([^"]+)"/)[1];
const contentType = header.match(/Content-Type: (.+)/)[1];
if (!(spotText && contentType.indexOf('text') !== -1)) { // replace content with binary
content = Buffer.from(content, 'binary');
}
result[name] = {
type: 'file',
filename: filename,
contentType: contentType,
content: content,
size: content.length
};
}
return result;
})
.reduce((accumulator, current) => Object.assign(accumulator, current), {});
};