Skip to content

Commit

Permalink
Add support for multipart/form-data
Browse files Browse the repository at this point in the history
  • Loading branch information
adaex committed May 12, 2021
1 parent 2ff42aa commit fd7bf24
Showing 1 changed file with 44 additions and 1 deletion.
45 changes: 44 additions & 1 deletion lib/base/CoaRequestBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ const DefaultMaxBodySize = 10 * 1024 * 1024
interface RequestBodyParams {
rawBody: string
body: { [key: string]: any}
files: RequestBodyFile[]
}
interface RequestBodyFile {
data: any
key: string
filename: string
type: string
}

export class CoaRequestBody {
Expand All @@ -20,7 +27,7 @@ export class CoaRequestBody {
}

async get () {
const params: RequestBodyParams = { rawBody: '', body: {} }
const params: RequestBodyParams = { rawBody: '', body: {}, files: [] }

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

Expand Down Expand Up @@ -60,6 +67,35 @@ export class CoaRequestBody {
}
}

// 处理 multipart/form-data
else if (contentType.includes('multipart/form-data')) {
try {
// 获取分隔符
const boundary = contentType.split('boundary=')[1]
if (!boundary) {
throw new CoaError('Gateway.BodyDataParseError', '网关数据解析form-data参数boundary失败')
}
// 分割每个参数
const rawDataArray = params.rawBody.split(boundary)
for (const item of rawDataArray) {
// 匹配结果
const name = this.matching(item, /(?:name=")(.+?)(?:")/, true)
const value = this.matching(item, /(?:\r\n\r\n)([\S\s]*)(?:\r\n--$)/)
if (!name || !value) continue
// 尝试获取文件名
const filename = this.matching(item, /(?:filename=")(.*?)(?:")/, true)
if (filename) {
const type = this.matching(item, /(?:Content-Type:)(.*?)(?:\r\n)/, true)
params.files.push({ data: value, key: name, filename, type })
} else {
params.body[name] = value
}
}
} catch (e) {
throw new CoaError('Gateway.BodyDataParseError', '网关数据解析form-data参数失败')
}
}

return params
}

Expand Down Expand Up @@ -122,4 +158,11 @@ export class CoaRequestBody {
this.req.addListener('error', onError)
})
}

private matching (string: string, regex: RegExp, trim = false) {
const matches = string.match(regex)
if (!matches || matches.length < 2) { return '' }
const value = matches[1]
return trim ? value.trim() : value
}
}

0 comments on commit fd7bf24

Please sign in to comment.