1212 * @private
1313 */
1414
15- var bytes = require ( 'bytes' )
16- var contentType = require ( 'content-type' )
15+ var assign = require ( 'object-assign' )
1716var createError = require ( 'http-errors' )
1817var debug = require ( 'debug' ) ( 'body-parser:urlencoded' )
19- var isFinished = require ( 'on-finished' ) . isFinished
20- var read = require ( '../read' )
21- var typeis = require ( 'type-is' )
22- var qs = require ( 'qs' )
18+ var genericParser = require ( '../generic-parser.js' )
2319
2420/**
2521 * Module exports.
@@ -34,7 +30,6 @@ module.exports = urlencoded
3430 * @return {function }
3531 * @public
3632 */
37-
3833function urlencoded ( options ) {
3934 var opts = options || { }
4035
@@ -44,86 +39,24 @@ function urlencoded (options) {
4439 ? bytes . parse ( opts . limit || '100kb' )
4540 : opts . limit
4641 var type = opts . type || 'application/x-www-form-urlencoded'
47- var verify = opts . verify || false
48- var charsetSentinel = opts . charsetSentinel
49- var interpretNumericEntities = opts . interpretNumericEntities
50-
51- if ( verify !== false && typeof verify !== 'function' ) {
52- throw new TypeError ( 'option verify must be function' )
53- }
42+ var charset = opts . charset || 'utf-8'
5443
55- var defaultCharset = opts . defaultCharset || 'utf-8'
56- if ( defaultCharset !== 'utf-8' && defaultCharset !== 'iso-8859-1' ) {
57- throw new TypeError ( 'option defaultCharset must be either utf-8 or iso-8859-1' )
58- }
59-
60- // create the appropriate query parser
61- var parser = opts . parser || (
44+ var queryparse = opts . parser || (
6245 extended
6346 ? extendedparser ( opts )
6447 : simpleparser ( opts )
6548 )
6649
67- // create the appropriate type checking function
68- var shouldParse = typeof type !== 'function'
69- ? typeChecker ( type )
70- : type
71-
72- function parse ( body , encoding ) {
73- return body . length
74- ? parser ( body )
75- : { }
76- }
77-
78- return function urlencodedParser ( req , res , next ) {
79- if ( isFinished ( req ) ) {
80- debug ( 'body already parsed' )
81- next ( )
82- return
83- }
84-
85- if ( ! ( 'body' in req ) ) {
86- req . body = undefined
87- }
88-
89- // skip requests without bodies
90- if ( ! typeis . hasBody ( req ) ) {
91- debug ( 'skip empty body' )
92- next ( )
93- return
94- }
95-
96- debug ( 'content-type %j' , req . headers [ 'content-type' ] )
50+ return genericParser ( assign ( { } , opts , {
51+ type : type ,
52+ charset : charset ,
9753
98- // determine if request should be parsed
99- if ( ! shouldParse ( req ) ) {
100- debug ( 'skip parsing' )
101- next ( )
102- return
54+ parse : function parse ( buf ) {
55+ return buf . length
56+ ? queryparse ( buf )
57+ : { }
10358 }
104-
105- // assert charset
106- var charset = getCharset ( req ) || defaultCharset
107- if ( charset !== 'utf-8' && charset !== 'iso-8859-1' ) {
108- debug ( 'invalid charset' )
109- next ( createError ( 415 , 'unsupported charset "' + charset . toUpperCase ( ) + '"' , {
110- charset : charset ,
111- type : 'charset.unsupported'
112- } ) )
113- return
114- }
115-
116- // read
117- read ( req , res , next , parse , debug , {
118- debug : debug ,
119- encoding : charset ,
120- inflate : inflate ,
121- limit : limit ,
122- verify : verify ,
123- charsetSentinel : charsetSentinel ,
124- interpretNumericEntities : interpretNumericEntities
125- } )
126- }
59+ } ) )
12760}
12861
12962/**
@@ -228,14 +161,67 @@ function parameterCount (body, limit) {
228161}
229162
230163/**
231- * Get the simple type checker .
164+ * Get parser for module name dynamically .
232165 *
233- * @param {string } type
166+ * @param {string } name
234167 * @return {function }
168+ * @api private
235169 */
236170
237- function typeChecker ( type ) {
238- return function checkType ( req ) {
239- return Boolean ( typeis ( req , type ) )
171+ function parser ( name ) {
172+ var mod = parsers [ name ]
173+
174+ if ( mod !== undefined ) {
175+ return mod . parse
176+ }
177+
178+ // this uses a switch for static require analysis
179+ switch ( name ) {
180+ case 'qs' :
181+ mod = require ( 'qs' )
182+ break
183+ case 'querystring' :
184+ mod = require ( 'querystring' )
185+ break
186+ }
187+
188+ // store to prevent invoking require()
189+ parsers [ name ] = mod
190+
191+ return mod . parse
192+ }
193+
194+ /**
195+ * Get the simple query parser.
196+ *
197+ * @param {object } options
198+ */
199+
200+ function simpleparser ( options ) {
201+ var parameterLimit = options . parameterLimit !== undefined
202+ ? options . parameterLimit
203+ : 1000
204+ var parse = parser ( 'querystring' )
205+
206+ if ( isNaN ( parameterLimit ) || parameterLimit < 1 ) {
207+ throw new TypeError ( 'option parameterLimit must be a positive number' )
208+ }
209+
210+ if ( isFinite ( parameterLimit ) ) {
211+ parameterLimit = parameterLimit | 0
212+ }
213+
214+ return function queryparse ( body ) {
215+ var paramCount = parameterCount ( body , parameterLimit )
216+
217+ if ( paramCount === undefined ) {
218+ debug ( 'too many parameters' )
219+ throw createError ( 413 , 'too many parameters' , {
220+ type : 'parameters.too.many'
221+ } )
222+ }
223+
224+ debug ( 'parse urlencoding' )
225+ return parse ( body , undefined , undefined , { maxKeys : parameterLimit } )
240226 }
241227}
0 commit comments