-
Notifications
You must be signed in to change notification settings - Fork 92
Fix coercion of input arguments (HTTP/REST) #312
Description
Based on the integration test suite written in #304, I am proposing to make the following changes/fixes in the way how we coerce input arguments.
I think most (if not all) of this changes can be considered as backwards-compatible fixes to be landed on 2.x too.
Terminology:
json body- the argument is set to the full request body which is JSON encodedjson form- the argument is read from a property in the JSON-encoded request bodyurlencoded- the argument is read either from query string or from urlencoded request body
Tighten validation of required arguments
json body - any - requiredshould rejectnullvaluejson form - array - requiredshould reject empty request andnullvaluejson form - * - requiredshould reject empty request,nullvalue
and empty string valueurlencoded - *should reject empty query,?arg,?arg=,?arg=null
Reject scalar values for array type
json body - array of *json form - array - required
Do not coerce missing value to empty array
This may be possibly controversial. Should we introduce a config option
to control this behaviour?
json form - array of *should convert empty body toundefinedjson form - array of *should convertnulltonullurlencoded - array of *should convert?,?arg,?arg=toundefined
Do not coerce values from JSON-encoded sources
- Reject requests sending array items of wrong type
json body - array of *json form - array of *
- Do not coerce array items from string to number, boolean, etc.
json body - array of anyjson form - array of any
- Reject requests providing value of wrong type
json form - boolean(reject strings, numbers, etc.)json form - date(reject booleans, large numbers, non-date strings, etc.)json form - number(reject strings, booleans, arrays, etc.)json form - object(reject strings, booleans, numbers)json form - string(reject booleans, numbers, objects, arrays, etc.)
Allow null as a value for object type
Convert null input to null value:
json body - object - optionaljson form - *urlencoded - *
Treat missing argument as undefined
Set argument to undefined when not set:
json form - *urlencoded - *- treat?argasundefined
Don't coerce too large numbers
urlencoded - any- keep?arg=2343546576878989879789as string value
Recognize scientific notation when parsing strings
urlencoded - any- convert?arg=1.234e%2B30to a number
Malformed JSON in urlencoded value should trigger 400 Bad Request
urlencoded - array of *should reject?arg={malformed}and
?arg=[malformed]urlencoded - objectshould reject?arg={malformed}and
?arg=[malformed]
Convert numeric timestamps from urlencoded sources to number
?arg=0 should be converted to new Date(0) for both
urlencoded - dateurlencoded - array of date
Do not coerce array items from urlencoded sources
urlencoded - array of *
Do not coerce non-boolean values
urlencoded - boolean should reject all values except true/false, e.g.
- numbers like
?arg=0and?arg=1 - strings
- arrays
- objects
Avoid NaN dates, return 400 Bad Request instead
Examples: ?arg=undefined, ?arg=true, but also ?arg=2343546576878989879789
Open points to discuss
-
Should we coerce missing array values into an empty array? Perhaps make
this configurable? -
Should we coerce date strings stored in object properties/array items
from JSON sources fortype:object,type:anyandtype:array?Example inputs:
{ "arg": "2016-05-19T13:28:51.299Z" } ["2016-05-19T13:28:51.299Z"]
-
Should we keep distinction between
undefined(argument is missing) and
null(argument is provided withnullvalue)? -
Should we allow array values for object type arguments? If yes, should
we allow date strings too and coerce them into Date instances? -
How to treat
?arg=in query string/urlencoded request body? Should we
treat it as an empty string or as a missing value? -
How to treat
?arg=null, should we parse it asnullor as a string
"null"? -
urlencoded - any- should we coerce Date strings to Date instances? What
formats other than the full ISO string should be recognized, e.g2016-05-01
orT09:30:00?