Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / body-parser / lib / types / urlencoded.js
1 /*!
2  * body-parser
3  * Copyright(c) 2014 Jonathan Ong
4  * Copyright(c) 2014-2015 Douglas Christopher Wilson
5  * MIT Licensed
6  */
7
8 'use strict'
9
10 /**
11  * Module dependencies.
12  * @private
13  */
14
15 var bytes = require('bytes')
16 var contentType = require('content-type')
17 var createError = require('http-errors')
18 var debug = require('debug')('body-parser:urlencoded')
19 var deprecate = require('depd')('body-parser')
20 var read = require('../read')
21 var typeis = require('type-is')
22
23 /**
24  * Module exports.
25  */
26
27 module.exports = urlencoded
28
29 /**
30  * Cache of parser modules.
31  */
32
33 var parsers = Object.create(null)
34
35 /**
36  * Create a middleware to parse urlencoded bodies.
37  *
38  * @param {object} [options]
39  * @return {function}
40  * @public
41  */
42
43 function urlencoded(options) {
44   var opts = options || {}
45
46   // notice because option default will flip in next major
47   if (opts.extended === undefined) {
48     deprecate('undefined extended: provide extended option')
49   }
50
51   var extended = opts.extended !== false
52   var inflate = opts.inflate !== false
53   var limit = typeof opts.limit !== 'number'
54     ? bytes.parse(opts.limit || '100kb')
55     : opts.limit
56   var type = opts.type || 'application/x-www-form-urlencoded'
57   var verify = opts.verify || false
58
59   if (verify !== false && typeof verify !== 'function') {
60     throw new TypeError('option verify must be function')
61   }
62
63   // create the appropriate query parser
64   var queryparse = extended
65     ? extendedparser(opts)
66     : simpleparser(opts)
67
68   // create the appropriate type checking function
69   var shouldParse = typeof type !== 'function'
70     ? typeChecker(type)
71     : type
72
73   function parse(body) {
74     return body.length
75       ? queryparse(body)
76       : {}
77   }
78
79   return function urlencodedParser(req, res, next) {
80     if (req._body) {
81       return debug('body already parsed'), next()
82     }
83
84     req.body = req.body || {}
85
86     // skip requests without bodies
87     if (!typeis.hasBody(req)) {
88       return debug('skip empty body'), next()
89     }
90
91     debug('content-type %j', req.headers['content-type'])
92
93     // determine if request should be parsed
94     if (!shouldParse(req)) {
95       return debug('skip parsing'), next()
96     }
97
98     // assert charset
99     var charset = getCharset(req) || 'utf-8'
100     if (charset !== 'utf-8') {
101       debug('invalid charset')
102       next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
103         charset: charset
104       }))
105       return
106     }
107
108     // read
109     read(req, res, next, parse, debug, {
110       debug: debug,
111       encoding: charset,
112       inflate: inflate,
113       limit: limit,
114       verify: verify
115     })
116   }
117 }
118
119 /**
120  * Get the extended query parser.
121  *
122  * @param {object} options
123  */
124
125 function extendedparser(options) {
126   var parameterLimit = options.parameterLimit !== undefined
127     ? options.parameterLimit
128     : 1000
129   var parse = parser('qs')
130
131   if (isNaN(parameterLimit) || parameterLimit < 1) {
132     throw new TypeError('option parameterLimit must be a positive number')
133   }
134
135   if (isFinite(parameterLimit)) {
136     parameterLimit = parameterLimit | 0
137   }
138
139   return function queryparse(body) {
140     var paramCount = parameterCount(body, parameterLimit)
141
142     if (paramCount === undefined) {
143       debug('too many parameters')
144       throw createError(413, 'too many parameters')
145     }
146
147     var arrayLimit = Math.max(100, paramCount)
148
149     debug('parse extended urlencoding')
150     return parse(body, {
151       allowDots: false,
152       allowPrototypes: true,
153       arrayLimit: arrayLimit,
154       depth: Infinity,
155       parameterLimit: parameterLimit
156     })
157   }
158 }
159
160 /**
161  * Get the charset of a request.
162  *
163  * @param {object} req
164  * @api private
165  */
166
167 function getCharset(req) {
168   try {
169     return contentType.parse(req).parameters.charset.toLowerCase()
170   } catch (e) {
171     return undefined
172   }
173 }
174
175 /**
176  * Count the number of parameters, stopping once limit reached
177  *
178  * @param {string} body
179  * @param {number} limit
180  * @api private
181  */
182
183 function parameterCount(body, limit) {
184   var count = 0
185   var index = 0
186
187   while ((index = body.indexOf('&', index)) !== -1) {
188     count++
189     index++
190
191     if (count === limit) {
192       return undefined
193     }
194   }
195
196   return count
197 }
198
199 /**
200  * Get parser for module name dynamically.
201  *
202  * @param {string} name
203  * @return {function}
204  * @api private
205  */
206
207 function parser(name) {
208   var mod = parsers[name]
209
210   if (mod) {
211     return mod.parse
212   }
213
214   // load module
215   mod = parsers[name] = require(name)
216
217   return mod.parse
218 }
219
220 /**
221  * Get the simple query parser.
222  *
223  * @param {object} options
224  */
225
226 function simpleparser(options) {
227   var parameterLimit = options.parameterLimit !== undefined
228     ? options.parameterLimit
229     : 1000
230   var parse = parser('querystring')
231
232   if (isNaN(parameterLimit) || parameterLimit < 1) {
233     throw new TypeError('option parameterLimit must be a positive number')
234   }
235
236   if (isFinite(parameterLimit)) {
237     parameterLimit = parameterLimit | 0
238   }
239
240   return function queryparse(body) {
241     var paramCount = parameterCount(body, parameterLimit)
242
243     if (paramCount === undefined) {
244       debug('too many parameters')
245       throw createError(413, 'too many parameters')
246     }
247
248     debug('parse urlencoding')
249     return parse(body, undefined, undefined, {maxKeys: parameterLimit})
250   }
251 }
252
253 /**
254  * Get the simple type checker.
255  *
256  * @param {string} type
257  * @return {function}
258  */
259
260 function typeChecker(type) {
261   return function checkType(req) {
262     return Boolean(typeis(req, type))
263   }
264 }