1
- import { Data , Files , MultipartHeaders , FileEntry } from '../@types/index' ;
1
+ import { Data , MultipartHeaders , FileEntry , Query } from '../@types/index' ;
2
2
import { generateRandomText } from '@teclone/utils' ;
3
3
import { CRLF , BLANK_LINE } from './Constants' ;
4
4
@@ -18,31 +18,23 @@ export class BodyParser {
18
18
}
19
19
}
20
20
21
- /**
22
- * assigns a single field or multi value field value to the body
23
- */
24
- private assignBodyValue ( body : Data , fieldName : string , value : string ) {
25
- const { name, isMultiValue } = this . resolveFieldName ( fieldName ) ;
26
-
27
- let target : string | string [ ] = value ;
28
- if ( isMultiValue ) {
29
- target = body [ name ] || [ ] ;
30
- ( target as string [ ] ) . push ( value ) ;
31
- }
32
- body [ name ] = target ;
33
- }
34
-
35
21
/**
36
22
* stores a file into the given files object
37
23
*/
38
- private assignFileValue ( files : Files , fieldName : string , value : FileEntry ) {
24
+ private assignDataEntry (
25
+ data : Data ,
26
+ fieldName : string ,
27
+ value : FileEntry | string
28
+ ) {
39
29
const { name, isMultiValue } = this . resolveFieldName ( fieldName ) ;
40
- let target : FileEntry | FileEntry [ ] = value ;
41
- if ( isMultiValue ) {
42
- target = files [ name ] || [ ] ;
43
- ( target as FileEntry [ ] ) . push ( value ) ;
30
+ if ( ! isMultiValue ) {
31
+ data [ name ] = value ;
32
+ return ;
33
+ }
34
+ if ( typeof data [ name ] === 'undefined' ) {
35
+ data [ name ] = [ ] ;
44
36
}
45
- files [ name ] = target ;
37
+ ( data [ name ] as Array < typeof value > ) . push ( value ) ;
46
38
}
47
39
48
40
/**
@@ -93,14 +85,13 @@ export class BodyParser {
93
85
* parse multipart form data
94
86
*@see https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html
95
87
*/
96
- private parseMultiPart ( string : string , headerBoundary : string | null ) {
97
- const body = { } ,
98
- files = { } ;
88
+ private parseMultiPart ( string : string , headerBoundary : string | null ) : Data {
89
+ const result : Data = { } ;
99
90
100
91
//if boundary is null, detect it using the last encapsulation boundary format
101
92
if ( ! headerBoundary ) {
102
93
if ( ! / ^ - { 2 } ( - * [ a - z 0 - 9 ] + ) - { 2 } / gim. test ( string ) ) {
103
- return { body , files } ;
94
+ return { } ;
104
95
}
105
96
headerBoundary = RegExp . $1 ;
106
97
}
@@ -134,18 +125,18 @@ export class BodyParser {
134
125
content ,
135
126
headers . type . startsWith ( 'text/' ) ? 'utf8' : 'binary'
136
127
) ;
137
- this . assignFileValue ( files , headers . fieldName , {
128
+ this . assignDataEntry ( result , headers . fieldName , {
138
129
name : headers . fileName . replace ( / \. \. / g, '' ) ,
139
130
data,
140
131
size : data . byteLength ,
141
132
type : headers . type ,
142
133
} ) ;
143
134
} else if ( ! headers . isFile ) {
144
- this . assignBodyValue ( body , headers . fieldName , content ) ;
135
+ this . assignDataEntry ( result , headers . fieldName , content ) ;
145
136
}
146
137
} ) ;
147
138
148
- return { body , files } ;
139
+ return result ;
149
140
}
150
141
151
142
/**
@@ -163,26 +154,26 @@ export class BodyParser {
163
154
/**
164
155
* parse url encoded request body
165
156
*/
166
- private parseUrlEncoded ( string : string ) : Data {
167
- const body : Data = { } ;
157
+ private parseUrlEncoded ( string : string ) : Query {
158
+ const result : Query = { } ;
168
159
if ( string ) {
169
160
const pairs = string . split ( '&' ) ;
170
161
pairs . forEach ( ( pair ) => {
171
162
const [ name , value ] = pair . split ( '=' ) ;
172
- this . assignBodyValue (
173
- body ,
163
+ this . assignDataEntry (
164
+ result ,
174
165
decodeURIComponent ( name ) ,
175
166
decodeURIComponent ( value || '' )
176
167
) ;
177
168
} ) ;
178
169
}
179
- return body ;
170
+ return result ;
180
171
}
181
172
182
173
/**
183
174
* parse the query parameters in the given url
184
175
*/
185
- parseQueryString ( url : string ) : Data {
176
+ parseQueryString ( url : string ) : Query {
186
177
if ( url . indexOf ( '?' ) > - 1 ) {
187
178
return this . parseUrlEncoded ( url . split ( '?' ) [ 1 ] ) ;
188
179
} else {
@@ -207,7 +198,7 @@ export class BodyParser {
207
198
*@param {Buffer } buffer - the buffer data
208
199
*@param {string } contentType - the request content type
209
200
*/
210
- parse ( buffer : Buffer , contentType : string ) : { files : Files ; body : Data } {
201
+ parse ( buffer : Buffer , contentType : string ) : Data {
211
202
const content = buffer . toString ( 'latin1' ) ;
212
203
const tokens = contentType . split ( / ; \s * / ) ;
213
204
@@ -219,14 +210,14 @@ export class BodyParser {
219
210
switch ( tokens [ 0 ] . toLowerCase ( ) ) {
220
211
case 'text/plain' :
221
212
case 'application/x-www-form-urlencoded' :
222
- return { files : { } , body : this . parseUrlEncoded ( content ) } ;
213
+ return this . parseUrlEncoded ( content ) ;
223
214
224
215
case 'text/json' :
225
216
case 'application/json' :
226
- return { files : { } , body : this . parseJSON ( content ) } ;
217
+ return this . parseJSON ( content ) ;
227
218
228
219
default :
229
- return { body : { } , files : { } } ;
220
+ return { } ;
230
221
}
231
222
}
232
223
}
0 commit comments