Skip to content

Commit 7d7ab1d

Browse files
Shawn DellyssePhillip9587
authored andcommitted
converted urlencoded parser to use generic parser
1 parent 149966b commit 7d7ab1d

File tree

1 file changed

+70
-84
lines changed

1 file changed

+70
-84
lines changed

lib/types/urlencoded.js

Lines changed: 70 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,10 @@
1212
* @private
1313
*/
1414

15-
var bytes = require('bytes')
16-
var contentType = require('content-type')
15+
var assign = require('object-assign')
1716
var createError = require('http-errors')
1817
var 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-
3833
function 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

Comments
 (0)