Skip to content

Commit fd7bf24

Browse files
committed
Add support for multipart/form-data
1 parent 2ff42aa commit fd7bf24

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

lib/base/CoaRequestBody.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ const DefaultMaxBodySize = 10 * 1024 * 1024
88
interface RequestBodyParams {
99
rawBody: string
1010
body: { [key: string]: any}
11+
files: RequestBodyFile[]
12+
}
13+
interface RequestBodyFile {
14+
data: any
15+
key: string
16+
filename: string
17+
type: string
1118
}
1219

1320
export class CoaRequestBody {
@@ -20,7 +27,7 @@ export class CoaRequestBody {
2027
}
2128

2229
async get () {
23-
const params: RequestBodyParams = { rawBody: '', body: {} }
30+
const params: RequestBodyParams = { rawBody: '', body: {}, files: [] }
2431

2532
const contentLength = parseInt(this.req.headers['content-length'] || '') || 0
2633

@@ -60,6 +67,35 @@ export class CoaRequestBody {
6067
}
6168
}
6269

70+
// 处理 multipart/form-data
71+
else if (contentType.includes('multipart/form-data')) {
72+
try {
73+
// 获取分隔符
74+
const boundary = contentType.split('boundary=')[1]
75+
if (!boundary) {
76+
throw new CoaError('Gateway.BodyDataParseError', '网关数据解析form-data参数boundary失败')
77+
}
78+
// 分割每个参数
79+
const rawDataArray = params.rawBody.split(boundary)
80+
for (const item of rawDataArray) {
81+
// 匹配结果
82+
const name = this.matching(item, /(?:name=")(.+?)(?:")/, true)
83+
const value = this.matching(item, /(?:\r\n\r\n)([\S\s]*)(?:\r\n--$)/)
84+
if (!name || !value) continue
85+
// 尝试获取文件名
86+
const filename = this.matching(item, /(?:filename=")(.*?)(?:")/, true)
87+
if (filename) {
88+
const type = this.matching(item, /(?:Content-Type:)(.*?)(?:\r\n)/, true)
89+
params.files.push({ data: value, key: name, filename, type })
90+
} else {
91+
params.body[name] = value
92+
}
93+
}
94+
} catch (e) {
95+
throw new CoaError('Gateway.BodyDataParseError', '网关数据解析form-data参数失败')
96+
}
97+
}
98+
6399
return params
64100
}
65101

@@ -122,4 +158,11 @@ export class CoaRequestBody {
122158
this.req.addListener('error', onError)
123159
})
124160
}
161+
162+
private matching (string: string, regex: RegExp, trim = false) {
163+
const matches = string.match(regex)
164+
if (!matches || matches.length < 2) { return '' }
165+
const value = matches[1]
166+
return trim ? value.trim() : value
167+
}
125168
}

0 commit comments

Comments
 (0)