Symptom:
----------
Trying to create an object sending a seemingly correct JSON request in a
POST message - was giving a 404 not found error. When looking at the cause
in the browser devtools - the body of the response contained "Not found (input)"
Cause:
-------
We were trying to validate parameters - even when the POST body
contained invalid JSON. We call json_decode($data) in retrieveInputs
The JSON request was malformed and it had omitted the double quotes.
example: { fieldName : "fieldValue" }
Expected behavior and fix:
---------------------------
A POST request with malformed JSON should get a 400 "bad request"
response. Even more helpful would be an error code indicating why the
JSON was bad.
If we call json_decode(), afterwards, we immediately call
json_last_error(), and if the return value does not match
JSON_ERROR_NONE, we send it across bundled in a 400 response, so that
the user may rectify the cause by looking at the exact error message.
The possible error messages right now are:
CODE CONSTANT-ERROR MESSAGE
0 JSON_ERROR_NONE-No error has occurred
1 JSON_ERROR_DEPTH-The maximum stack depth has been exceeded
2 JSON_ERROR_STATE_MISMATCH-Invalid or malformed JSON
3 JSON_ERROR_CTRL_CHAR-Control character error, possibly incorrectly encoded
4 JSON_ERROR_SYNTAX-Syntax error
5 JSON_ERROR_UTF8-Malformed UTF-8 characters, possibly incorrectly encoded
6 JSON_ERROR_RECURSION-One or more recursive references in the value to be encoded
7 JSON_ERROR_INF_OR_NAN-One or more NAN or INF values in the value to be encoded
8 JSON_ERROR_UNSUPPORTED_TYPE-A value of a type that cannot be encoded was given
9 JSON_ERROR_INVALID_PROPERTY_NAME-A property name that cannot be encoded was given
10 JSON_ERROR_UTF16-Malformed UTF-16 characters, possibly incorrectly encoded
After the fix:
-------------
On malformed JSON in the POST body - the following is returned:
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without modifications.
(Error decoding input JSON. json_last_error code: 4)
If REQUEST_METHOD is not set - we throw an exception that says something
like:
'Bad request (Error decoding input JSON. json_last_error code: 4)'
In order to accommodate this change in behavior - in the test suite, we
need a new method expectPattern (as the error code in the end of the
string may change, but the starting pattern stays the same - (/^Bad
request.*$/)
Issue:
When sending JSON in the body of a POST
request from an HTML form - for creating
a new record, a new record was being created,
but with null as the value for all the fields,
instead of the values supplied.
Cause:
The template text in the textarea field, in the
HTML form had some leading whitespace. On looking
through the source, json_decode is being called
only if the first character of the $data variable
is a '{' or a '['.
JSON Specification RFC4627
https://tools.ietf.org/html/rfc4627#section-2
says that insignificant
whitespace is allowed before or after any of the
six structural characters - '{','[',']','}',':',','
where whitespace is defined as:
ws = *(
%x20 / ; Space
%x09 / ; Horizontal tab
%x0A / ; Line feed or New line
%x0D ; Carriage return
)
Fix:
trim the above characters from the beginning and ending
of the received data before checking that the first
character is a '[' or '{'