sistema creado v0.5.0
Some checks failed
build-and-push / deploy (push) Has been skipped
build-and-push / build (push) Failing after 6s

This commit is contained in:
2025-05-14 16:10:41 -06:00
parent b5e40cf4ac
commit 745168cf51
193 changed files with 7267 additions and 8789 deletions

View File

@@ -1,69 +1,10 @@
2.2.0 / 2025-03-27
=========================
* refactor: normalize common options for all parsers
* deps:
* iconv-lite@^0.6.3
2.1.0 / 2025-02-10
=========================
* deps:
* type-is@^2.0.0
* debug@^4.4.0
* Removed destroy
* refactor: prefix built-in node module imports
* use the node require cache instead of custom caching
2.0.2 / 2024-10-31
=========================
* remove `unpipe` package and use native `unpipe()` method
2.0.1 / 2024-09-10
=========================
* Restore expected behavior `extended` to `false`
2.0.0 / 2024-09-10
=========================
* Propagate changes from 1.20.3
* add brotli support #406
* Breaking Change: Node.js 18 is the minimum supported version
2.0.0-beta.2 / 2023-02-23
=========================
This incorporates all changes after 1.19.1 up to 1.20.2.
* Remove deprecated `bodyParser()` combination middleware
* deps: debug@3.1.0
- Add `DEBUG_HIDE_DATE` environment variable
- Change timer to per-namespace instead of global
- Change non-TTY date format
- Remove `DEBUG_FD` environment variable support
- Support 256 namespace colors
* deps: iconv-lite@0.5.2
- Add encoding cp720
- Add encoding UTF-32
* deps: raw-body@3.0.0-beta.1
2.0.0-beta.1 / 2021-12-17
=========================
* Drop support for Node.js 0.8
* `req.body` is no longer always initialized to `{}`
- it is left `undefined` unless a body is parsed
* `urlencoded` parser now defaults `extended` to `false`
* Use `on-finished` to determine when body read
1.20.3 / 2024-09-10
===================
* deps: qs@6.13.0
* add `depth` option to customize the depth level in the parser
* IMPORTANT: The default `depth` level for parsing URL-encoded data is now `32` (previously was `Infinity`)
1.20.2 / 2023-02-21
===================

View File

@@ -51,12 +51,14 @@ $ npm install body-parser
## API
```js
const bodyParser = require('body-parser')
var bodyParser = require('body-parser')
```
The `bodyParser` object exposes various factories to create middlewares. All
middlewares will populate the `req.body` property with the parsed body when
the `Content-Type` request header matches the `type` option.
the `Content-Type` request header matches the `type` option, or an empty
object (`{}`) if there was no body to parse, the `Content-Type` was not matched,
or an error occurred.
The various errors returned by this module are described in the
[errors section](#errors).
@@ -65,8 +67,8 @@ The various errors returned by this module are described in the
Returns middleware that only parses `json` and only looks at requests where
the `Content-Type` header matches the `type` option. This parser accepts any
Unicode encoding of the body and supports automatic inflation of `gzip`,
`br` (brotli) and `deflate` encodings.
Unicode encoding of the body and supports automatic inflation of `gzip` and
`deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`).
@@ -120,8 +122,7 @@ encoding of the request. The parsing can be aborted by throwing an error.
Returns middleware that parses all bodies as a `Buffer` and only looks at
requests where the `Content-Type` header matches the `type` option. This
parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
encodings.
parser supports automatic inflation of `gzip` and `deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This will be a `Buffer` object
@@ -166,8 +167,7 @@ encoding of the request. The parsing can be aborted by throwing an error.
Returns middleware that parses all bodies as a string and only looks at
requests where the `Content-Type` header matches the `type` option. This
parser supports automatic inflation of `gzip`, `br` (brotli) and `deflate`
encodings.
parser supports automatic inflation of `gzip` and `deflate` encodings.
A new `body` string containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This will be a string of the
@@ -217,7 +217,7 @@ encoding of the request. The parsing can be aborted by throwing an error.
Returns middleware that only parses `urlencoded` bodies and only looks at
requests where the `Content-Type` header matches the `type` option. This
parser accepts only UTF-8 encoding of the body and supports automatic
inflation of `gzip`, `br` (brotli) and `deflate` encodings.
inflation of `gzip` and `deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This object will contain
@@ -231,12 +231,16 @@ any of the following keys:
##### extended
The "extended" syntax allows for rich objects and arrays to be encoded into the
URL-encoded format, allowing for a JSON-like experience with URL-encoded. For
more information, please [see the qs
library](https://www.npmjs.org/package/qs#readme).
The `extended` option allows to choose between parsing the URL-encoded data
with the `querystring` library (when `false`) or the `qs` library (when
`true`). The "extended" syntax allows for rich objects and arrays to be
encoded into the URL-encoded format, allowing for a JSON-like experience
with URL-encoded. For more information, please
[see the qs library](https://www.npmjs.org/package/qs#readme).
Defaults to `false`.
Defaults to `true`, but using the default has been deprecated. Please
research into the difference between `qs` and `querystring` and choose the
appropriate setting.
##### inflate
@@ -274,23 +278,6 @@ The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
##### defaultCharset
The default charset to parse as, if not specified in content-type. Must be
either `utf-8` or `iso-8859-1`. Defaults to `utf-8`.
##### charsetSentinel
Whether to let the value of the `utf8` parameter take precedence as the charset
selector. It requires the form to contain a parameter named `utf8` with a value
of `✓`. Defaults to `false`.
##### interpretNumericEntities
Whether to decode numeric entities such as `☺` when parsing an iso-8859-1
form. Defaults to `false`.
#### depth
The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
@@ -404,13 +391,13 @@ top-level middleware, which will parse the bodies of all incoming requests.
This is the simplest setup.
```js
const express = require('express')
const bodyParser = require('body-parser')
var express = require('express')
var bodyParser = require('body-parser')
const app = express()
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded())
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
@@ -418,7 +405,7 @@ app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(String(JSON.stringify(req.body, null, 2)))
res.end(JSON.stringify(req.body, null, 2))
})
```
@@ -429,26 +416,24 @@ need them. In general, this is the most recommended way to use body-parser with
Express.
```js
const express = require('express')
const bodyParser = require('body-parser')
var express = require('express')
var bodyParser = require('body-parser')
const app = express()
var app = express()
// create application/json parser
const jsonParser = bodyParser.json()
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
const urlencodedParser = bodyParser.urlencoded()
var urlencodedParser = bodyParser.urlencoded({ extended: false })
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body || !req.body.username) res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) res.sendStatus(400)
// create user in req.body
})
```
@@ -459,10 +444,10 @@ All the parsers accept a `type` option which allows you to change the
`Content-Type` that the middleware will parse.
```js
const express = require('express')
const bodyParser = require('body-parser')
var express = require('express')
var bodyParser = require('body-parser')
const app = express()
var app = express()
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }))

View File

@@ -6,6 +6,20 @@
'use strict'
/**
* Module dependencies.
* @private
*/
var deprecate = require('depd')('body-parser')
/**
* Cache of loaded parsers.
* @private
*/
var parsers = Object.create(null)
/**
* @typedef Parsers
* @type {function}
@@ -20,7 +34,8 @@
* @type {Parsers}
*/
exports = module.exports = bodyParser
exports = module.exports = deprecate.function(bodyParser,
'bodyParser: use individual json/urlencoded middlewares')
/**
* JSON parser.
@@ -30,7 +45,7 @@ exports = module.exports = bodyParser
Object.defineProperty(exports, 'json', {
configurable: true,
enumerable: true,
get: () => require('./lib/types/json')
get: createParserGetter('json')
})
/**
@@ -41,7 +56,7 @@ Object.defineProperty(exports, 'json', {
Object.defineProperty(exports, 'raw', {
configurable: true,
enumerable: true,
get: () => require('./lib/types/raw')
get: createParserGetter('raw')
})
/**
@@ -52,7 +67,7 @@ Object.defineProperty(exports, 'raw', {
Object.defineProperty(exports, 'text', {
configurable: true,
enumerable: true,
get: () => require('./lib/types/text')
get: createParserGetter('text')
})
/**
@@ -63,7 +78,7 @@ Object.defineProperty(exports, 'text', {
Object.defineProperty(exports, 'urlencoded', {
configurable: true,
enumerable: true,
get: () => require('./lib/types/urlencoded')
get: createParserGetter('urlencoded')
})
/**
@@ -75,6 +90,67 @@ Object.defineProperty(exports, 'urlencoded', {
* @public
*/
function bodyParser () {
throw new Error('The bodyParser() generic has been split into individual middleware to use instead.')
function bodyParser (options) {
// use default type for parsers
var opts = Object.create(options || null, {
type: {
configurable: true,
enumerable: true,
value: undefined,
writable: true
}
})
var _urlencoded = exports.urlencoded(opts)
var _json = exports.json(opts)
return function bodyParser (req, res, next) {
_json(req, res, function (err) {
if (err) return next(err)
_urlencoded(req, res, next)
})
}
}
/**
* Create a getter for loading a parser.
* @private
*/
function createParserGetter (name) {
return function get () {
return loadParser(name)
}
}
/**
* Load a parser module.
* @private
*/
function loadParser (parserName) {
var parser = parsers[parserName]
if (parser !== undefined) {
return parser
}
// this uses a switch for static require analysis
switch (parserName) {
case 'json':
parser = require('./lib/types/json')
break
case 'raw':
parser = require('./lib/types/raw')
break
case 'text':
parser = require('./lib/types/text')
break
case 'urlencoded':
parser = require('./lib/types/urlencoded')
break
}
// store to prevent invoking require()
return (parsers[parserName] = parser)
}

View File

@@ -12,10 +12,12 @@
*/
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 zlib = require('node:zlib')
var unpipe = require('unpipe')
var zlib = require('zlib')
/**
* Module exports.
@@ -40,6 +42,9 @@ function read (req, res, next, parse, debug, options) {
var opts = options
var stream
// flag as parsed
req._body = true
// read options
var encoding = opts.encoding !== null
? opts.encoding
@@ -88,8 +93,8 @@ function read (req, res, next, parse, debug, options) {
// unpipe from stream and destroy
if (stream !== req) {
req.unpipe()
stream.destroy()
unpipe(req)
destroy(stream, true)
}
// read off entire request
@@ -120,7 +125,7 @@ function read (req, res, next, parse, debug, options) {
str = typeof body !== 'string' && encoding !== null
? iconv.decode(body, encoding)
: body
req.body = parse(str, encoding)
req.body = parse(str)
} catch (err) {
next(createError(400, err, {
body: str,
@@ -146,6 +151,7 @@ function read (req, res, next, parse, debug, options) {
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)
@@ -156,40 +162,29 @@ function contentstream (req, debug, inflate) {
})
}
if (encoding === 'identity') {
req.length = length
return req
}
var stream = createDecompressionStream(encoding, debug)
req.pipe(stream)
return stream
}
/**
* Create a decompression stream for the given encoding.
* @param {string} encoding
* @param {function} debug
* @return {object}
* @api private
*/
function createDecompressionStream (encoding, debug) {
switch (encoding) {
case 'deflate':
stream = zlib.createInflate()
debug('inflate body')
return zlib.createInflate()
req.pipe(stream)
break
case 'gzip':
stream = zlib.createGunzip()
debug('gunzip body')
return zlib.createGunzip()
case 'br':
debug('brotli decompress body')
return zlib.createBrotliDecompress()
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
}
/**

View File

@@ -12,12 +12,12 @@
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:json')
var isFinished = require('on-finished').isFinished
var read = require('../read')
var typeis = require('type-is')
var { getCharset, normalizeOptions } = require('../utils')
/**
* Module exports.
@@ -51,10 +51,25 @@ var JSON_SYNTAX_REGEXP = /#+/g
*/
function json (options) {
var { inflate, limit, verify, shouldParse } = normalizeOptions(options, 'application/json')
var opts = options || {}
var reviver = options?.reviver
var strict = options?.strict !== false
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) {
@@ -84,15 +99,13 @@ function json (options) {
}
return function jsonParser (req, res, next) {
if (isFinished(req)) {
if (req._body) {
debug('body already parsed')
next()
return
}
if (!('body' in req)) {
req.body = undefined
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
@@ -124,9 +137,9 @@ function json (options) {
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate,
limit,
verify
inflate: inflate,
limit: limit,
verify: verify
})
}
}
@@ -180,6 +193,21 @@ function firstchar (str) {
: 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.
*
@@ -204,3 +232,16 @@ function normalizeJsonSyntaxError (error, obj) {
return error
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

View File

@@ -10,11 +10,10 @@
* Module dependencies.
*/
var bytes = require('bytes')
var debug = require('debug')('body-parser:raw')
var isFinished = require('on-finished').isFinished
var read = require('../read')
var typeis = require('type-is')
var { normalizeOptions } = require('../utils')
/**
* Module exports.
@@ -31,22 +30,36 @@ module.exports = raw
*/
function raw (options) {
var { inflate, limit, verify, shouldParse } = normalizeOptions(options, 'application/octet-stream')
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 (isFinished(req)) {
if (req._body) {
debug('body already parsed')
next()
return
}
if (!('body' in req)) {
req.body = undefined
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
@@ -67,9 +80,22 @@ function raw (options) {
// read
read(req, res, next, parse, debug, {
encoding: null,
inflate,
limit,
verify
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))
}
}

View File

@@ -10,11 +10,11 @@
* Module dependencies.
*/
var bytes = require('bytes')
var contentType = require('content-type')
var debug = require('debug')('body-parser:text')
var isFinished = require('on-finished').isFinished
var read = require('../read')
var typeis = require('type-is')
var { getCharset, normalizeOptions } = require('../utils')
/**
* Module exports.
@@ -31,24 +31,37 @@ module.exports = text
*/
function text (options) {
var { inflate, limit, verify, shouldParse } = normalizeOptions(options, 'text/plain')
var opts = options || {}
var defaultCharset = options?.defaultCharset || 'utf-8'
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 (isFinished(req)) {
if (req._body) {
debug('body already parsed')
next()
return
}
if (!('body' in req)) {
req.body = undefined
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
@@ -72,9 +85,37 @@ function text (options) {
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate,
limit,
verify
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))
}
}

View File

@@ -12,13 +12,13 @@
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:urlencoded')
var isFinished = require('on-finished').isFinished
var deprecate = require('depd')('body-parser')
var read = require('../read')
var typeis = require('type-is')
var qs = require('qs')
var { getCharset, normalizeOptions } = require('../utils')
/**
* Module exports.
@@ -26,6 +26,12 @@ var { getCharset, normalizeOptions } = require('../utils')
module.exports = urlencoded
/**
* Cache of parser modules.
*/
var parsers = Object.create(null)
/**
* Create a middleware to parse urlencoded bodies.
*
@@ -35,32 +41,52 @@ module.exports = urlencoded
*/
function urlencoded (options) {
var { inflate, limit, verify, shouldParse } = normalizeOptions(options, 'application/x-www-form-urlencoded')
var opts = options || {}
var defaultCharset = options?.defaultCharset || 'utf-8'
if (defaultCharset !== 'utf-8' && defaultCharset !== 'iso-8859-1') {
throw new TypeError('option defaultCharset must be either utf-8 or iso-8859-1')
// 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
var depth = typeof opts.depth !== 'number'
? Number(opts.depth || 32)
: opts.depth
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate query parser
var queryparse = createQueryParser(options)
var queryparse = extended
? extendedparser(opts)
: simpleparser(opts)
function parse (body, encoding) {
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (body) {
return body.length
? queryparse(body, encoding)
? queryparse(body)
: {}
}
return function urlencodedParser (req, res, next) {
if (isFinished(req)) {
if (req._body) {
debug('body already parsed')
next()
return
}
if (!('body' in req)) {
req.body = undefined
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
@@ -79,8 +105,8 @@ function urlencoded (options) {
}
// assert charset
var charset = getCharset(req) || defaultCharset
if (charset !== 'utf-8' && charset !== 'iso-8859-1') {
var charset = getCharset(req) || 'utf-8'
if (charset !== 'utf-8') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
charset: charset,
@@ -91,10 +117,12 @@ function urlencoded (options) {
// read
read(req, res, next, parse, debug, {
debug: debug,
encoding: charset,
inflate,
limit,
verify
inflate: inflate,
limit: limit,
verify: verify,
depth: depth
})
}
}
@@ -105,14 +133,15 @@ function urlencoded (options) {
* @param {object} options
*/
function createQueryParser (options) {
var extended = Boolean(options?.extended)
var parameterLimit = options?.parameterLimit !== undefined
? options?.parameterLimit
function extendedparser (options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var charsetSentinel = options?.charsetSentinel
var interpretNumericEntities = options?.interpretNumericEntities
var depth = extended ? (options?.depth !== undefined ? options?.depth : 32) : 0
var depth = typeof options.depth !== 'number'
? Number(options.depth || 32)
: options.depth
var parse = parser('qs')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
@@ -126,7 +155,7 @@ function createQueryParser (options) {
parameterLimit = parameterLimit | 0
}
return function queryparse (body, encoding) {
return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
@@ -136,19 +165,16 @@ function createQueryParser (options) {
})
}
var arrayLimit = extended ? Math.max(100, paramCount) : 0
var arrayLimit = Math.max(100, paramCount)
debug('parse ' + (extended ? 'extended ' : '') + 'urlencoding')
debug('parse extended urlencoding')
try {
return qs.parse(body, {
return parse(body, {
allowPrototypes: true,
arrayLimit: arrayLimit,
depth: depth,
charsetSentinel: charsetSentinel,
interpretNumericEntities: interpretNumericEntities,
charset: encoding,
parameterLimit: parameterLimit,
strictDepth: true
strictDepth: true,
parameterLimit: parameterLimit
})
} catch (err) {
if (err instanceof RangeError) {
@@ -162,6 +188,21 @@ function createQueryParser (options) {
}
}
/**
* 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
*
@@ -171,7 +212,96 @@ function createQueryParser (options) {
*/
function parameterCount (body, limit) {
var len = body.split('&').length
var count = 0
var index = 0
return len > limit ? undefined : len - 1
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))
}
}

View File

@@ -1,83 +0,0 @@
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var contentType = require('content-type')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = {
getCharset,
normalizeOptions
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return (contentType.parse(req).parameters.charset || '').toLowerCase()
} catch {
return undefined
}
}
/**
* Get the simple type checker.
*
* @param {string | string[]} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}
/**
* Normalizes the common options for all parsers.
*
* @param {object} options options to normalize
* @param {string | string[] | function} defaultType default content type(s) or a function to determine it
* @returns {object}
*/
function normalizeOptions (options, defaultType) {
if (!defaultType) {
// Parsers must define a default content type
throw new TypeError('defaultType must be provided')
}
var inflate = options?.inflate !== false
var limit = typeof options?.limit !== 'number'
? bytes.parse(options?.limit || '100kb')
: options?.limit
var type = options?.type || defaultType
var verify = options?.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
return {
inflate,
limit,
verify,
shouldParse
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "body-parser",
"description": "Node.js body parsing middleware",
"version": "2.2.0",
"version": "1.20.3",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
@@ -9,15 +9,18 @@
"license": "MIT",
"repository": "expressjs/body-parser",
"dependencies": {
"bytes": "^3.1.2",
"content-type": "^1.0.5",
"debug": "^4.4.0",
"http-errors": "^2.0.0",
"iconv-lite": "^0.6.3",
"on-finished": "^2.4.1",
"qs": "^6.14.0",
"raw-body": "^3.0.0",
"type-is": "^2.0.0"
"bytes": "3.1.2",
"content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.13.0",
"raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
"devDependencies": {
"eslint": "8.34.0",
@@ -27,23 +30,27 @@
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-standard": "4.1.0",
"mocha": "^11.1.0",
"nyc": "^17.1.0",
"supertest": "^7.0.0"
"methods": "1.1.2",
"mocha": "10.2.0",
"nyc": "15.1.0",
"safe-buffer": "5.2.1",
"supertest": "6.3.3"
},
"files": [
"lib/",
"LICENSE",
"HISTORY.md",
"SECURITY.md",
"index.js"
],
"engines": {
"node": ">=18"
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks test/",
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
"test": "mocha --require test/support/env --reporter spec --check-leaks --bail test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}