@@ -8,6 +8,13 @@ const DefaultMaxBodySize = 10 * 1024 * 1024
88interface 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
1320export 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 , / (?: n a m e = " ) ( .+ ?) (?: " ) / , 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 , / (?: f i l e n a m e = " ) ( .* ?) (?: " ) / , true )
87+ if ( filename ) {
88+ const type = this . matching ( item , / (?: C o n t e n t - T y p e : ) ( .* ?) (?: \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