mirror of
				https://github.com/1disk/edp445.git
				synced 2024-08-14 22:47:02 +00:00 
			
		
		
		
	added a few messages that the bot would respond to
This commit is contained in:
		
							parent
							
								
									c63d9a6e13
								
							
						
					
					
						commit
						de29e2769c
					
				
					 384 changed files with 56249 additions and 43 deletions
				
			
		
							
								
								
									
										205
									
								
								node_modules/body-parser/lib/read.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								node_modules/body-parser/lib/read.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,205 @@ | |||
| /*! | ||||
|  * body-parser | ||||
|  * Copyright(c) 2014-2015 Douglas Christopher Wilson | ||||
|  * MIT Licensed | ||||
|  */ | ||||
| 
 | ||||
| 'use strict' | ||||
| 
 | ||||
| /** | ||||
|  * Module dependencies. | ||||
|  * @private | ||||
|  */ | ||||
| 
 | ||||
| var createError = require('http-errors') | ||||
| var destroy = require('destroy') | ||||
| var getBody = require('raw-body') | ||||
| var iconv = require('iconv-lite') | ||||
| var onFinished = require('on-finished') | ||||
| var unpipe = require('unpipe') | ||||
| var zlib = require('zlib') | ||||
| 
 | ||||
| /** | ||||
|  * Module exports. | ||||
|  */ | ||||
| 
 | ||||
| module.exports = read | ||||
| 
 | ||||
| /** | ||||
|  * Read a request into a buffer and parse. | ||||
|  * | ||||
|  * @param {object} req | ||||
|  * @param {object} res | ||||
|  * @param {function} next | ||||
|  * @param {function} parse | ||||
|  * @param {function} debug | ||||
|  * @param {object} options | ||||
|  * @private | ||||
|  */ | ||||
| 
 | ||||
| function read (req, res, next, parse, debug, options) { | ||||
|   var length | ||||
|   var opts = options | ||||
|   var stream | ||||
| 
 | ||||
|   // flag as parsed
 | ||||
|   req._body = true | ||||
| 
 | ||||
|   // read options
 | ||||
|   var encoding = opts.encoding !== null | ||||
|     ? opts.encoding | ||||
|     : null | ||||
|   var verify = opts.verify | ||||
| 
 | ||||
|   try { | ||||
|     // get the content stream
 | ||||
|     stream = contentstream(req, debug, opts.inflate) | ||||
|     length = stream.length | ||||
|     stream.length = undefined | ||||
|   } catch (err) { | ||||
|     return next(err) | ||||
|   } | ||||
| 
 | ||||
|   // set raw-body options
 | ||||
|   opts.length = length | ||||
|   opts.encoding = verify | ||||
|     ? null | ||||
|     : encoding | ||||
| 
 | ||||
|   // assert charset is supported
 | ||||
|   if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { | ||||
|     return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { | ||||
|       charset: encoding.toLowerCase(), | ||||
|       type: 'charset.unsupported' | ||||
|     })) | ||||
|   } | ||||
| 
 | ||||
|   // read body
 | ||||
|   debug('read body') | ||||
|   getBody(stream, opts, function (error, body) { | ||||
|     if (error) { | ||||
|       var _error | ||||
| 
 | ||||
|       if (error.type === 'encoding.unsupported') { | ||||
|         // echo back charset
 | ||||
|         _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { | ||||
|           charset: encoding.toLowerCase(), | ||||
|           type: 'charset.unsupported' | ||||
|         }) | ||||
|       } else { | ||||
|         // set status code on error
 | ||||
|         _error = createError(400, error) | ||||
|       } | ||||
| 
 | ||||
|       // unpipe from stream and destroy
 | ||||
|       if (stream !== req) { | ||||
|         unpipe(req) | ||||
|         destroy(stream, true) | ||||
|       } | ||||
| 
 | ||||
|       // read off entire request
 | ||||
|       dump(req, function onfinished () { | ||||
|         next(createError(400, _error)) | ||||
|       }) | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     // verify
 | ||||
|     if (verify) { | ||||
|       try { | ||||
|         debug('verify body') | ||||
|         verify(req, res, body, encoding) | ||||
|       } catch (err) { | ||||
|         next(createError(403, err, { | ||||
|           body: body, | ||||
|           type: err.type || 'entity.verify.failed' | ||||
|         })) | ||||
|         return | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     // parse
 | ||||
|     var str = body | ||||
|     try { | ||||
|       debug('parse body') | ||||
|       str = typeof body !== 'string' && encoding !== null | ||||
|         ? iconv.decode(body, encoding) | ||||
|         : body | ||||
|       req.body = parse(str) | ||||
|     } catch (err) { | ||||
|       next(createError(400, err, { | ||||
|         body: str, | ||||
|         type: err.type || 'entity.parse.failed' | ||||
|       })) | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     next() | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the content stream of the request. | ||||
|  * | ||||
|  * @param {object} req | ||||
|  * @param {function} debug | ||||
|  * @param {boolean} [inflate=true] | ||||
|  * @return {object} | ||||
|  * @api private | ||||
|  */ | ||||
| 
 | ||||
| function contentstream (req, debug, inflate) { | ||||
|   var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() | ||||
|   var length = req.headers['content-length'] | ||||
|   var stream | ||||
| 
 | ||||
|   debug('content-encoding "%s"', encoding) | ||||
| 
 | ||||
|   if (inflate === false && encoding !== 'identity') { | ||||
|     throw createError(415, 'content encoding unsupported', { | ||||
|       encoding: encoding, | ||||
|       type: 'encoding.unsupported' | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   switch (encoding) { | ||||
|     case 'deflate': | ||||
|       stream = zlib.createInflate() | ||||
|       debug('inflate body') | ||||
|       req.pipe(stream) | ||||
|       break | ||||
|     case 'gzip': | ||||
|       stream = zlib.createGunzip() | ||||
|       debug('gunzip body') | ||||
|       req.pipe(stream) | ||||
|       break | ||||
|     case 'identity': | ||||
|       stream = req | ||||
|       stream.length = length | ||||
|       break | ||||
|     default: | ||||
|       throw createError(415, 'unsupported content encoding "' + encoding + '"', { | ||||
|         encoding: encoding, | ||||
|         type: 'encoding.unsupported' | ||||
|       }) | ||||
|   } | ||||
| 
 | ||||
|   return stream | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Dump the contents of a request. | ||||
|  * | ||||
|  * @param {object} req | ||||
|  * @param {function} callback | ||||
|  * @api private | ||||
|  */ | ||||
| 
 | ||||
| function dump (req, callback) { | ||||
|   if (onFinished.isFinished(req)) { | ||||
|     callback(null) | ||||
|   } else { | ||||
|     onFinished(req, callback) | ||||
|     req.resume() | ||||
|   } | ||||
| } | ||||
							
								
								
									
										236
									
								
								node_modules/body-parser/lib/types/json.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								node_modules/body-parser/lib/types/json.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,236 @@ | |||
| /*! | ||||
|  * body-parser | ||||
|  * Copyright(c) 2014 Jonathan Ong | ||||
|  * Copyright(c) 2014-2015 Douglas Christopher Wilson | ||||
|  * MIT Licensed | ||||
|  */ | ||||
| 
 | ||||
| 'use strict' | ||||
| 
 | ||||
| /** | ||||
|  * Module dependencies. | ||||
|  * @private | ||||
|  */ | ||||
| 
 | ||||
| var bytes = require('bytes') | ||||
| var contentType = require('content-type') | ||||
| var createError = require('http-errors') | ||||
| var debug = require('debug')('body-parser:json') | ||||
| var read = require('../read') | ||||
| var typeis = require('type-is') | ||||
| 
 | ||||
| /** | ||||
|  * Module exports. | ||||
|  */ | ||||
| 
 | ||||
| module.exports = json | ||||
| 
 | ||||
| /** | ||||
|  * RegExp to match the first non-space in a string. | ||||
|  * | ||||
|  * Allowed whitespace is defined in RFC 7159: | ||||
|  * | ||||
|  *    ws = *( | ||||
|  *            %x20 /              ; Space | ||||
|  *            %x09 /              ; Horizontal tab | ||||
|  *            %x0A /              ; Line feed or New line | ||||
|  *            %x0D )              ; Carriage return | ||||
|  */ | ||||
| 
 | ||||
| var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex
 | ||||
| 
 | ||||
| /** | ||||
|  * Create a middleware to parse JSON bodies. | ||||
|  * | ||||
|  * @param {object} [options] | ||||
|  * @return {function} | ||||
|  * @public | ||||
|  */ | ||||
| 
 | ||||
| function json (options) { | ||||
|   var opts = options || {} | ||||
| 
 | ||||
|   var limit = typeof opts.limit !== 'number' | ||||
|     ? bytes.parse(opts.limit || '100kb') | ||||
|     : opts.limit | ||||
|   var inflate = opts.inflate !== false | ||||
|   var reviver = opts.reviver | ||||
|   var strict = opts.strict !== false | ||||
|   var type = opts.type || 'application/json' | ||||
|   var verify = opts.verify || false | ||||
| 
 | ||||
|   if (verify !== false && typeof verify !== 'function') { | ||||
|     throw new TypeError('option verify must be function') | ||||
|   } | ||||
| 
 | ||||
|   // create the appropriate type checking function
 | ||||
|   var shouldParse = typeof type !== 'function' | ||||
|     ? typeChecker(type) | ||||
|     : type | ||||
| 
 | ||||
|   function parse (body) { | ||||
|     if (body.length === 0) { | ||||
|       // special-case empty json body, as it's a common client-side mistake
 | ||||
|       // TODO: maybe make this configurable or part of "strict" option
 | ||||
|       return {} | ||||
|     } | ||||
| 
 | ||||
|     if (strict) { | ||||
|       var first = firstchar(body) | ||||
| 
 | ||||
|       if (first !== '{' && first !== '[') { | ||||
|         debug('strict violation') | ||||
|         throw createStrictSyntaxError(body, first) | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       debug('parse json') | ||||
|       return JSON.parse(body, reviver) | ||||
|     } catch (e) { | ||||
|       throw normalizeJsonSyntaxError(e, { | ||||
|         message: e.message, | ||||
|         stack: e.stack | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return function jsonParser (req, res, next) { | ||||
|     if (req._body) { | ||||
|       debug('body already parsed') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     req.body = req.body || {} | ||||
| 
 | ||||
|     // skip requests without bodies
 | ||||
|     if (!typeis.hasBody(req)) { | ||||
|       debug('skip empty body') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     debug('content-type %j', req.headers['content-type']) | ||||
| 
 | ||||
|     // determine if request should be parsed
 | ||||
|     if (!shouldParse(req)) { | ||||
|       debug('skip parsing') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     // assert charset per RFC 7159 sec 8.1
 | ||||
|     var charset = getCharset(req) || 'utf-8' | ||||
|     if (charset.slice(0, 4) !== 'utf-') { | ||||
|       debug('invalid charset') | ||||
|       next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { | ||||
|         charset: charset, | ||||
|         type: 'charset.unsupported' | ||||
|       })) | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     // read
 | ||||
|     read(req, res, next, parse, debug, { | ||||
|       encoding: charset, | ||||
|       inflate: inflate, | ||||
|       limit: limit, | ||||
|       verify: verify | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Create strict violation syntax error matching native error. | ||||
|  * | ||||
|  * @param {string} str | ||||
|  * @param {string} char | ||||
|  * @return {Error} | ||||
|  * @private | ||||
|  */ | ||||
| 
 | ||||
| function createStrictSyntaxError (str, char) { | ||||
|   var index = str.indexOf(char) | ||||
|   var partial = index !== -1 | ||||
|     ? str.substring(0, index) + '#' | ||||
|     : '' | ||||
| 
 | ||||
|   try { | ||||
|     JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation') | ||||
|   } catch (e) { | ||||
|     return normalizeJsonSyntaxError(e, { | ||||
|       message: e.message.replace('#', char), | ||||
|       stack: e.stack | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the first non-whitespace character in a string. | ||||
|  * | ||||
|  * @param {string} str | ||||
|  * @return {function} | ||||
|  * @private | ||||
|  */ | ||||
| 
 | ||||
| function firstchar (str) { | ||||
|   var match = FIRST_CHAR_REGEXP.exec(str) | ||||
| 
 | ||||
|   return match | ||||
|     ? match[1] | ||||
|     : undefined | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the charset of a request. | ||||
|  * | ||||
|  * @param {object} req | ||||
|  * @api private | ||||
|  */ | ||||
| 
 | ||||
| function getCharset (req) { | ||||
|   try { | ||||
|     return (contentType.parse(req).parameters.charset || '').toLowerCase() | ||||
|   } catch (e) { | ||||
|     return undefined | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Normalize a SyntaxError for JSON.parse. | ||||
|  * | ||||
|  * @param {SyntaxError} error | ||||
|  * @param {object} obj | ||||
|  * @return {SyntaxError} | ||||
|  */ | ||||
| 
 | ||||
| function normalizeJsonSyntaxError (error, obj) { | ||||
|   var keys = Object.getOwnPropertyNames(error) | ||||
| 
 | ||||
|   for (var i = 0; i < keys.length; i++) { | ||||
|     var key = keys[i] | ||||
|     if (key !== 'stack' && key !== 'message') { | ||||
|       delete error[key] | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // replace stack before message for Node.js 0.10 and below
 | ||||
|   error.stack = obj.stack.replace(error.message, obj.message) | ||||
|   error.message = obj.message | ||||
| 
 | ||||
|   return error | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the simple type checker. | ||||
|  * | ||||
|  * @param {string} type | ||||
|  * @return {function} | ||||
|  */ | ||||
| 
 | ||||
| function typeChecker (type) { | ||||
|   return function checkType (req) { | ||||
|     return Boolean(typeis(req, type)) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										101
									
								
								node_modules/body-parser/lib/types/raw.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								node_modules/body-parser/lib/types/raw.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,101 @@ | |||
| /*! | ||||
|  * body-parser | ||||
|  * Copyright(c) 2014-2015 Douglas Christopher Wilson | ||||
|  * MIT Licensed | ||||
|  */ | ||||
| 
 | ||||
| 'use strict' | ||||
| 
 | ||||
| /** | ||||
|  * Module dependencies. | ||||
|  */ | ||||
| 
 | ||||
| var bytes = require('bytes') | ||||
| var debug = require('debug')('body-parser:raw') | ||||
| var read = require('../read') | ||||
| var typeis = require('type-is') | ||||
| 
 | ||||
| /** | ||||
|  * Module exports. | ||||
|  */ | ||||
| 
 | ||||
| module.exports = raw | ||||
| 
 | ||||
| /** | ||||
|  * Create a middleware to parse raw bodies. | ||||
|  * | ||||
|  * @param {object} [options] | ||||
|  * @return {function} | ||||
|  * @api public | ||||
|  */ | ||||
| 
 | ||||
| function raw (options) { | ||||
|   var opts = options || {} | ||||
| 
 | ||||
|   var inflate = opts.inflate !== false | ||||
|   var limit = typeof opts.limit !== 'number' | ||||
|     ? bytes.parse(opts.limit || '100kb') | ||||
|     : opts.limit | ||||
|   var type = opts.type || 'application/octet-stream' | ||||
|   var verify = opts.verify || false | ||||
| 
 | ||||
|   if (verify !== false && typeof verify !== 'function') { | ||||
|     throw new TypeError('option verify must be function') | ||||
|   } | ||||
| 
 | ||||
|   // create the appropriate type checking function
 | ||||
|   var shouldParse = typeof type !== 'function' | ||||
|     ? typeChecker(type) | ||||
|     : type | ||||
| 
 | ||||
|   function parse (buf) { | ||||
|     return buf | ||||
|   } | ||||
| 
 | ||||
|   return function rawParser (req, res, next) { | ||||
|     if (req._body) { | ||||
|       debug('body already parsed') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     req.body = req.body || {} | ||||
| 
 | ||||
|     // skip requests without bodies
 | ||||
|     if (!typeis.hasBody(req)) { | ||||
|       debug('skip empty body') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     debug('content-type %j', req.headers['content-type']) | ||||
| 
 | ||||
|     // determine if request should be parsed
 | ||||
|     if (!shouldParse(req)) { | ||||
|       debug('skip parsing') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     // read
 | ||||
|     read(req, res, next, parse, debug, { | ||||
|       encoding: null, | ||||
|       inflate: inflate, | ||||
|       limit: limit, | ||||
|       verify: verify | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the simple type checker. | ||||
|  * | ||||
|  * @param {string} type | ||||
|  * @return {function} | ||||
|  */ | ||||
| 
 | ||||
| function typeChecker (type) { | ||||
|   return function checkType (req) { | ||||
|     return Boolean(typeis(req, type)) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										121
									
								
								node_modules/body-parser/lib/types/text.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								node_modules/body-parser/lib/types/text.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,121 @@ | |||
| /*! | ||||
|  * body-parser | ||||
|  * Copyright(c) 2014-2015 Douglas Christopher Wilson | ||||
|  * MIT Licensed | ||||
|  */ | ||||
| 
 | ||||
| 'use strict' | ||||
| 
 | ||||
| /** | ||||
|  * Module dependencies. | ||||
|  */ | ||||
| 
 | ||||
| var bytes = require('bytes') | ||||
| var contentType = require('content-type') | ||||
| var debug = require('debug')('body-parser:text') | ||||
| var read = require('../read') | ||||
| var typeis = require('type-is') | ||||
| 
 | ||||
| /** | ||||
|  * Module exports. | ||||
|  */ | ||||
| 
 | ||||
| module.exports = text | ||||
| 
 | ||||
| /** | ||||
|  * Create a middleware to parse text bodies. | ||||
|  * | ||||
|  * @param {object} [options] | ||||
|  * @return {function} | ||||
|  * @api public | ||||
|  */ | ||||
| 
 | ||||
| function text (options) { | ||||
|   var opts = options || {} | ||||
| 
 | ||||
|   var defaultCharset = opts.defaultCharset || 'utf-8' | ||||
|   var inflate = opts.inflate !== false | ||||
|   var limit = typeof opts.limit !== 'number' | ||||
|     ? bytes.parse(opts.limit || '100kb') | ||||
|     : opts.limit | ||||
|   var type = opts.type || 'text/plain' | ||||
|   var verify = opts.verify || false | ||||
| 
 | ||||
|   if (verify !== false && typeof verify !== 'function') { | ||||
|     throw new TypeError('option verify must be function') | ||||
|   } | ||||
| 
 | ||||
|   // create the appropriate type checking function
 | ||||
|   var shouldParse = typeof type !== 'function' | ||||
|     ? typeChecker(type) | ||||
|     : type | ||||
| 
 | ||||
|   function parse (buf) { | ||||
|     return buf | ||||
|   } | ||||
| 
 | ||||
|   return function textParser (req, res, next) { | ||||
|     if (req._body) { | ||||
|       debug('body already parsed') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     req.body = req.body || {} | ||||
| 
 | ||||
|     // skip requests without bodies
 | ||||
|     if (!typeis.hasBody(req)) { | ||||
|       debug('skip empty body') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     debug('content-type %j', req.headers['content-type']) | ||||
| 
 | ||||
|     // determine if request should be parsed
 | ||||
|     if (!shouldParse(req)) { | ||||
|       debug('skip parsing') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     // get charset
 | ||||
|     var charset = getCharset(req) || defaultCharset | ||||
| 
 | ||||
|     // read
 | ||||
|     read(req, res, next, parse, debug, { | ||||
|       encoding: charset, | ||||
|       inflate: inflate, | ||||
|       limit: limit, | ||||
|       verify: verify | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the charset of a request. | ||||
|  * | ||||
|  * @param {object} req | ||||
|  * @api private | ||||
|  */ | ||||
| 
 | ||||
| function getCharset (req) { | ||||
|   try { | ||||
|     return (contentType.parse(req).parameters.charset || '').toLowerCase() | ||||
|   } catch (e) { | ||||
|     return undefined | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the simple type checker. | ||||
|  * | ||||
|  * @param {string} type | ||||
|  * @return {function} | ||||
|  */ | ||||
| 
 | ||||
| function typeChecker (type) { | ||||
|   return function checkType (req) { | ||||
|     return Boolean(typeis(req, type)) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										284
									
								
								node_modules/body-parser/lib/types/urlencoded.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								node_modules/body-parser/lib/types/urlencoded.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,284 @@ | |||
| /*! | ||||
|  * body-parser | ||||
|  * Copyright(c) 2014 Jonathan Ong | ||||
|  * Copyright(c) 2014-2015 Douglas Christopher Wilson | ||||
|  * MIT Licensed | ||||
|  */ | ||||
| 
 | ||||
| 'use strict' | ||||
| 
 | ||||
| /** | ||||
|  * Module dependencies. | ||||
|  * @private | ||||
|  */ | ||||
| 
 | ||||
| var bytes = require('bytes') | ||||
| var contentType = require('content-type') | ||||
| var createError = require('http-errors') | ||||
| var debug = require('debug')('body-parser:urlencoded') | ||||
| var deprecate = require('depd')('body-parser') | ||||
| var read = require('../read') | ||||
| var typeis = require('type-is') | ||||
| 
 | ||||
| /** | ||||
|  * Module exports. | ||||
|  */ | ||||
| 
 | ||||
| module.exports = urlencoded | ||||
| 
 | ||||
| /** | ||||
|  * Cache of parser modules. | ||||
|  */ | ||||
| 
 | ||||
| var parsers = Object.create(null) | ||||
| 
 | ||||
| /** | ||||
|  * Create a middleware to parse urlencoded bodies. | ||||
|  * | ||||
|  * @param {object} [options] | ||||
|  * @return {function} | ||||
|  * @public | ||||
|  */ | ||||
| 
 | ||||
| function urlencoded (options) { | ||||
|   var opts = options || {} | ||||
| 
 | ||||
|   // notice because option default will flip in next major
 | ||||
|   if (opts.extended === undefined) { | ||||
|     deprecate('undefined extended: provide extended option') | ||||
|   } | ||||
| 
 | ||||
|   var extended = opts.extended !== false | ||||
|   var inflate = opts.inflate !== false | ||||
|   var limit = typeof opts.limit !== 'number' | ||||
|     ? bytes.parse(opts.limit || '100kb') | ||||
|     : opts.limit | ||||
|   var type = opts.type || 'application/x-www-form-urlencoded' | ||||
|   var verify = opts.verify || false | ||||
| 
 | ||||
|   if (verify !== false && typeof verify !== 'function') { | ||||
|     throw new TypeError('option verify must be function') | ||||
|   } | ||||
| 
 | ||||
|   // create the appropriate query parser
 | ||||
|   var queryparse = extended | ||||
|     ? extendedparser(opts) | ||||
|     : simpleparser(opts) | ||||
| 
 | ||||
|   // create the appropriate type checking function
 | ||||
|   var shouldParse = typeof type !== 'function' | ||||
|     ? typeChecker(type) | ||||
|     : type | ||||
| 
 | ||||
|   function parse (body) { | ||||
|     return body.length | ||||
|       ? queryparse(body) | ||||
|       : {} | ||||
|   } | ||||
| 
 | ||||
|   return function urlencodedParser (req, res, next) { | ||||
|     if (req._body) { | ||||
|       debug('body already parsed') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     req.body = req.body || {} | ||||
| 
 | ||||
|     // skip requests without bodies
 | ||||
|     if (!typeis.hasBody(req)) { | ||||
|       debug('skip empty body') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     debug('content-type %j', req.headers['content-type']) | ||||
| 
 | ||||
|     // determine if request should be parsed
 | ||||
|     if (!shouldParse(req)) { | ||||
|       debug('skip parsing') | ||||
|       next() | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     // assert charset
 | ||||
|     var charset = getCharset(req) || 'utf-8' | ||||
|     if (charset !== 'utf-8') { | ||||
|       debug('invalid charset') | ||||
|       next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { | ||||
|         charset: charset, | ||||
|         type: 'charset.unsupported' | ||||
|       })) | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     // read
 | ||||
|     read(req, res, next, parse, debug, { | ||||
|       debug: debug, | ||||
|       encoding: charset, | ||||
|       inflate: inflate, | ||||
|       limit: limit, | ||||
|       verify: verify | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the extended query parser. | ||||
|  * | ||||
|  * @param {object} options | ||||
|  */ | ||||
| 
 | ||||
| function extendedparser (options) { | ||||
|   var parameterLimit = options.parameterLimit !== undefined | ||||
|     ? options.parameterLimit | ||||
|     : 1000 | ||||
|   var parse = parser('qs') | ||||
| 
 | ||||
|   if (isNaN(parameterLimit) || parameterLimit < 1) { | ||||
|     throw new TypeError('option parameterLimit must be a positive number') | ||||
|   } | ||||
| 
 | ||||
|   if (isFinite(parameterLimit)) { | ||||
|     parameterLimit = parameterLimit | 0 | ||||
|   } | ||||
| 
 | ||||
|   return function queryparse (body) { | ||||
|     var paramCount = parameterCount(body, parameterLimit) | ||||
| 
 | ||||
|     if (paramCount === undefined) { | ||||
|       debug('too many parameters') | ||||
|       throw createError(413, 'too many parameters', { | ||||
|         type: 'parameters.too.many' | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
|     var arrayLimit = Math.max(100, paramCount) | ||||
| 
 | ||||
|     debug('parse extended urlencoding') | ||||
|     return parse(body, { | ||||
|       allowPrototypes: true, | ||||
|       arrayLimit: arrayLimit, | ||||
|       depth: Infinity, | ||||
|       parameterLimit: parameterLimit | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the charset of a request. | ||||
|  * | ||||
|  * @param {object} req | ||||
|  * @api private | ||||
|  */ | ||||
| 
 | ||||
| function getCharset (req) { | ||||
|   try { | ||||
|     return (contentType.parse(req).parameters.charset || '').toLowerCase() | ||||
|   } catch (e) { | ||||
|     return undefined | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Count the number of parameters, stopping once limit reached | ||||
|  * | ||||
|  * @param {string} body | ||||
|  * @param {number} limit | ||||
|  * @api private | ||||
|  */ | ||||
| 
 | ||||
| function parameterCount (body, limit) { | ||||
|   var count = 0 | ||||
|   var index = 0 | ||||
| 
 | ||||
|   while ((index = body.indexOf('&', index)) !== -1) { | ||||
|     count++ | ||||
|     index++ | ||||
| 
 | ||||
|     if (count === limit) { | ||||
|       return undefined | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return count | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get parser for module name dynamically. | ||||
|  * | ||||
|  * @param {string} name | ||||
|  * @return {function} | ||||
|  * @api private | ||||
|  */ | ||||
| 
 | ||||
| function parser (name) { | ||||
|   var mod = parsers[name] | ||||
| 
 | ||||
|   if (mod !== undefined) { | ||||
|     return mod.parse | ||||
|   } | ||||
| 
 | ||||
|   // this uses a switch for static require analysis
 | ||||
|   switch (name) { | ||||
|     case 'qs': | ||||
|       mod = require('qs') | ||||
|       break | ||||
|     case 'querystring': | ||||
|       mod = require('querystring') | ||||
|       break | ||||
|   } | ||||
| 
 | ||||
|   // store to prevent invoking require()
 | ||||
|   parsers[name] = mod | ||||
| 
 | ||||
|   return mod.parse | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the simple query parser. | ||||
|  * | ||||
|  * @param {object} options | ||||
|  */ | ||||
| 
 | ||||
| function simpleparser (options) { | ||||
|   var parameterLimit = options.parameterLimit !== undefined | ||||
|     ? options.parameterLimit | ||||
|     : 1000 | ||||
|   var parse = parser('querystring') | ||||
| 
 | ||||
|   if (isNaN(parameterLimit) || parameterLimit < 1) { | ||||
|     throw new TypeError('option parameterLimit must be a positive number') | ||||
|   } | ||||
| 
 | ||||
|   if (isFinite(parameterLimit)) { | ||||
|     parameterLimit = parameterLimit | 0 | ||||
|   } | ||||
| 
 | ||||
|   return function queryparse (body) { | ||||
|     var paramCount = parameterCount(body, parameterLimit) | ||||
| 
 | ||||
|     if (paramCount === undefined) { | ||||
|       debug('too many parameters') | ||||
|       throw createError(413, 'too many parameters', { | ||||
|         type: 'parameters.too.many' | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
|     debug('parse urlencoding') | ||||
|     return parse(body, undefined, undefined, { maxKeys: parameterLimit }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Get the simple type checker. | ||||
|  * | ||||
|  * @param {string} type | ||||
|  * @return {function} | ||||
|  */ | ||||
| 
 | ||||
| function typeChecker (type) { | ||||
|   return function checkType (req) { | ||||
|     return Boolean(typeis(req, type)) | ||||
|   } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue