-
-
Notifications
You must be signed in to change notification settings - Fork 729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for external parsers to bodyParser.json() #281
Changes from all commits
d874969
4f18d51
1d47892
b9823e5
4b91d93
e786697
612e4da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,16 +86,27 @@ specifies the number of bytes; if it is a string, the value is passed to the | |
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults | ||
to `'100kb'`. | ||
|
||
##### parser | ||
|
||
The `parser` option is the function called against the request body to convert | ||
it to a Javascript object. If a `reviver` is supplied, it is supplied as the | ||
second argument to this function. | ||
|
||
``` | ||
parser(body, reviver) -> req.body | ||
``` | ||
|
||
Defaults to `JSON.parse`. | ||
|
||
##### reviver | ||
|
||
The `reviver` option is passed directly to `JSON.parse` as the second | ||
argument. You can find more information on this argument | ||
You can find more information on this argument | ||
[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter). | ||
|
||
##### strict | ||
|
||
When set to `true`, will only accept arrays and objects; when `false` will | ||
accept anything `JSON.parse` accepts. Defaults to `true`. | ||
accept anything the `parser` accepts. Defaults to `true`. | ||
|
||
##### type | ||
|
||
|
@@ -159,6 +170,15 @@ 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. | ||
|
||
##### parser | ||
|
||
The `parser` option, if supplied, is used to transform the body of a request | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably describe the type and number of arguments it will be called with. |
||
before being set to `req.body`. | ||
|
||
``` | ||
parser(body) -> req.body | ||
``` | ||
|
||
### bodyParser.text([options]) | ||
|
||
Returns middleware that parses all bodies as a string and only looks at | ||
|
@@ -208,6 +228,15 @@ 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. | ||
|
||
##### parser | ||
|
||
The `parser` option, if supplied, is used to transform the body of a request | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably describe the type and number of arguments it will be called with. |
||
before being set to `req.body`. | ||
|
||
``` | ||
parser(body) -> req.body | ||
``` | ||
|
||
### bodyParser.urlencoded([options]) | ||
|
||
Returns middleware that only parses `urlencoded` bodies and only looks at | ||
|
@@ -274,6 +303,16 @@ 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. | ||
|
||
##### parser | ||
|
||
The `parser` option, if supplied, is used to in place of the default parser to | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably mention the type of the argument and also that it is not called at all for zero length bodies (though, should it be always called because what if they want a zero length result to be something other than {}?). The other parsers seem to be called on zero length, so this seems odd not to. |
||
convert the request body into a Javascript object. If this option is supplied, | ||
both the `extended` and `parameterLimit` options are ignored. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the json parser, the reviver is not ignore but these are. Should json work like this and ignore the arguments that were originally going to the underlying parser that is now replaced, or should these be passed to the new urlencoded parser somehow or neither and a warning is a user gave these? Some thoughts. |
||
|
||
``` | ||
parser(body) -> req.body | ||
``` | ||
|
||
## Errors | ||
|
||
The middlewares provided by this module create errors depending on the error | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,7 @@ function json (options) { | |
var strict = opts.strict !== false | ||
var type = opts.type || 'application/json' | ||
var verify = opts.verify || false | ||
var parser = opts.parser || JSON.parse | ||
|
||
if (verify !== false && typeof verify !== 'function') { | ||
throw new TypeError('option verify must be function') | ||
|
@@ -80,13 +81,13 @@ function json (options) { | |
|
||
if (first !== '{' && first !== '[') { | ||
debug('strict violation') | ||
throw createStrictSyntaxError(body, first) | ||
throw createStrictSyntaxError(parser, reviver, body, first) | ||
} | ||
} | ||
|
||
try { | ||
debug('parse json') | ||
return JSON.parse(body, reviver) | ||
return parser(body, reviver) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this is right for custom parsers. Or at least it's not clear in the docs for the parser option that this is going to happen and how people should build their parser dunxtion to compensate. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The other option would be to remove the Maybe the right way is to make the docs more clear about this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I commented on the wrog line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I don't think I can agree with you that the docs are not clear:
If you can suggest an update to that text I'm all ears. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I moved my comment down. The new comment for this line is to clarify in the docs the arguments the custom parser will be called with. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the line from the reviver docs and add in the specific signature into the parser docs. The current parser section doesn't help someone build their own, I think it assumes someone is going to understand JSON.parse and copy that? If so, just write that down. |
||
} catch (e) { | ||
throw normalizeJsonSyntaxError(e, { | ||
stack: e.stack | ||
|
@@ -149,12 +150,12 @@ function json (options) { | |
* @private | ||
*/ | ||
|
||
function createStrictSyntaxError (str, char) { | ||
function createStrictSyntaxError (parser, reviver, str, char) { | ||
var index = str.indexOf(char) | ||
var partial = str.substring(0, index) + '#' | ||
|
||
try { | ||
JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation') | ||
parser(partial, reviver); /* istanbul ignore next */ throw new SyntaxError('strict violation') | ||
} catch (e) { | ||
return normalizeJsonSyntaxError(e, { | ||
message: e.message.replace('#', char), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,7 @@ function raw (options) { | |
: opts.limit | ||
var type = opts.type || 'application/octet-stream' | ||
var verify = opts.verify || false | ||
var parser = opts.parser || defaultParser | ||
|
||
if (verify !== false && typeof verify !== 'function') { | ||
throw new TypeError('option verify must be function') | ||
|
@@ -49,7 +50,7 @@ function raw (options) { | |
: type | ||
|
||
function parse (buf) { | ||
return buf | ||
return parser(buf) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably don't need two levels of functions here. Just replace parse with a variable. |
||
} | ||
|
||
return function rawParser (req, res, next) { | ||
|
@@ -87,6 +88,10 @@ function raw (options) { | |
} | ||
} | ||
|
||
function defaultParser (buf) { | ||
return buf | ||
} | ||
|
||
/** | ||
* Get the simple type checker. | ||
* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ function text (options) { | |
: opts.limit | ||
var type = opts.type || 'text/plain' | ||
var verify = opts.verify || false | ||
var parser = opts.parser || defaultParser | ||
|
||
if (verify !== false && typeof verify !== 'function') { | ||
throw new TypeError('option verify must be function') | ||
|
@@ -51,7 +52,7 @@ function text (options) { | |
: type | ||
|
||
function parse (buf) { | ||
return buf | ||
return parser(buf) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably don't need two levels of functions here. Just replace parse with a variable. |
||
} | ||
|
||
return function textParser (req, res, next) { | ||
|
@@ -92,6 +93,10 @@ function text (options) { | |
} | ||
} | ||
|
||
function defaultParser (buf) { | ||
return buf | ||
} | ||
|
||
/** | ||
* Get the charset of a request. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No description of the first argument. Also doesn't describe the mechanism of how it needs to be made to construct the syntax error during the recalling mechanism with the # inserted into the original string.