diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-07-08 09:40:13 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-07-08 09:40:13 +0200 |
commit | ea5c1233f13ad3128207b6b84401d8638dbc43e5 (patch) | |
tree | 4ee2fc37580df6079af9acb339de804ee38846d7 | |
parent | 296e27b92ab0367f414dc0e98b185531c8df06f3 (diff) |
nicer error reporting
-rw-r--r-- | src/mint/taler-mint-httpd_deposit.c | 38 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_parsing.c | 175 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_parsing.h | 36 | ||||
-rw-r--r-- | src/util/json.c | 14 |
4 files changed, 70 insertions, 193 deletions
diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c index c1495c817..7d9ace00d 100644 --- a/src/mint/taler-mint-httpd_deposit.c +++ b/src/mint/taler-mint-httpd_deposit.c @@ -234,7 +234,11 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh, json_t *wire; int res; struct TALER_Amount amount; - json_t *f; + struct TMH_PARSE_FieldSpecification spec[] = { + TMH_PARSE_member_object ("wire", &wire), + TMH_PARSE_member_amount ("f", &amount), + TMH_PARSE_MEMBER_END + }; res = TMH_PARSE_post_json (connection, connection_cls, @@ -245,39 +249,19 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh, return MHD_NO; if ( (GNUNET_NO == res) || (NULL == json) ) return MHD_YES; - if (-1 == json_unpack (json, - "{s:o, s:o}", - "wire", &wire, - "f", &f)) - { - GNUNET_break_op (0); - json_decref (json); - return TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s}", - "error", "Bad format"); - } - res = TMH_PARSE_amount_json (connection, - f, - &amount); - json_decref (f); - if (GNUNET_SYSERR == res) - { - json_decref (wire); - json_decref (json); - return MHD_NO; - } - if (GNUNET_NO == res) + res = TMH_PARSE_json_data (connection, + json, + spec); + if (GNUNET_OK != res) { - json_decref (wire); json_decref (json); - return MHD_YES; + return (GNUNET_NO == res) ? MHD_YES : MHD_NO; } res = parse_and_handle_deposit_request (connection, json, &amount, wire); - json_decref (wire); + TMH_PARSE_release_data (spec); json_decref (json); return res; } diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c index 6461685f3..b29cdeabf 100644 --- a/src/mint/taler-mint-httpd_parsing.c +++ b/src/mint/taler-mint-httpd_parsing.c @@ -771,9 +771,37 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection, { struct TALER_Amount *where = va_arg (argp, void *); - ret = TMH_PARSE_amount_json (connection, - (json_t *) root, - where); + if (GNUNET_OK != + TALER_json_to_amount ((json_t *) root, + where)) + { + if (MHD_YES != + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:o}", + "error", "Bad format", + "path", path)) + return GNUNET_SYSERR; + return GNUNET_NO; + } + if (0 != strcmp (where->currency, + TMH_mint_currency_string)) + { + if (MHD_YES != + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:o, s:s}", + "error", "Currency not supported", + "path", path, + "currency", where->currency)) + { + memset (where, 0, sizeof (struct TALER_Amount)); + return GNUNET_SYSERR; + } + memset (where, 0, sizeof (struct TALER_Amount)); + return GNUNET_NO; + } + ret = GNUNET_OK; break; } @@ -781,9 +809,21 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection, { struct GNUNET_TIME_Absolute *where = va_arg (argp, void *); - ret = TMH_PARSE_time_abs_json (connection, - (json_t *) root, - where); + if (GNUNET_OK != + TALER_json_to_abs ((json_t *) root, + where)) + { + if (MHD_YES != + TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_BAD_REQUEST, + "{s:s, s:s, s:o}", + "error", "Bad format", + "hint", "expected absolute time", + "path", path)) + return GNUNET_SYSERR; + return GNUNET_NO; + } + ret = GNUNET_OK; break; } @@ -941,129 +981,6 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec) /** - * Parse absolute time specified in JSON format. The JSON format is - * "/Date(TIMEVAL)/" where TIMEVAL is in seconds after the Unix Epoch. - * Additionally, we support "/forever/" and "/never/" to represent the - * end of time. - * - * @param connection the MHD connection (to report errors) - * @param f json specification of the amount - * @param[out] time set to the time specified in @a f - * @return - * #GNUNET_YES if parsing was successful - * #GNUNET_NO if json is malformed, error response was generated - * #GNUNET_SYSERR on internal error, error response was not generated - */ -int -TMH_PARSE_time_abs_json (struct MHD_Connection *connection, - json_t *f, - struct GNUNET_TIME_Absolute *time) -{ - const char *val; - unsigned long long tval; - - val = json_string_value (f); - if (NULL == val) - { - if (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s}", - "error", "string expected")) - return GNUNET_SYSERR; - return GNUNET_NO; - } - if ( (0 == strcasecmp (val, - "/forever/")) || - (0 == strcasecmp (val, - "/never/")) ) - - { - *time = GNUNET_TIME_UNIT_FOREVER_ABS; - return GNUNET_OK; - } - if (1 != sscanf (val, - "/Date(%llu)/", - &tval)) - { - if (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:s}", - "error", "timestamp expected", - "value", val)) - return GNUNET_SYSERR; - return GNUNET_NO; - } - /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ - time->abs_value_us = tval * 1000LL * 1000LL; - if ( (time->abs_value_us) / 1000LL / 1000LL != tval) - { - /* Integer overflow */ - if (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:s}", - "error", "timestamp outside of legal range", - "value", val)) - return GNUNET_SYSERR; - return GNUNET_NO; - } - return GNUNET_OK; -} - - -/** - * Parse amount specified in JSON format. - * - * @param connection the MHD connection (to report errors) - * @param f json specification of the amount - * @param[out] amount set to the amount specified in @a f - * @return - * #GNUNET_YES if parsing was successful - * #GNUNET_NO if json is malformed, error response was generated - * #GNUNET_SYSERR on internal error, error response was not generated - */ -int -TMH_PARSE_amount_json (struct MHD_Connection *connection, - json_t *f, - struct TALER_Amount *amount) -{ - if (GNUNET_OK != - TALER_json_to_amount (f, - amount)) - { - TALER_LOG_WARNING ("Failed to parse JSON amount specification\n"); - if (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s}", - "error", "Bad format")) - return GNUNET_SYSERR; - return GNUNET_NO; - } - if (0 != strcmp (amount->currency, - TMH_mint_currency_string)) - { - TALER_LOG_WARNING ("Currency specified not supported by this mint\n"); - if (MHD_YES != - TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_BAD_REQUEST, - "{s:s, s:s}", - "error", "Currency not supported", - "currency", amount->currency)) - { - memset (amount, 0, sizeof (struct TALER_Amount)); - return GNUNET_SYSERR; - } - memset (amount, 0, sizeof (struct TALER_Amount)); - return GNUNET_NO; - } - return GNUNET_OK; -} - - -/** * Generate line in parser specification for 64-bit integer * given as an integer in JSON. * diff --git a/src/mint/taler-mint-httpd_parsing.h b/src/mint/taler-mint-httpd_parsing.h index 7d37bb18c..2e036f322 100644 --- a/src/mint/taler-mint-httpd_parsing.h +++ b/src/mint/taler-mint-httpd_parsing.h @@ -353,42 +353,6 @@ TMH_PARSE_member_time_abs (const char *field, /** - * Parse amount specified in JSON format. - * - * @param connection the MHD connection (to report errors) - * @param f json specification of the amount - * @param[out] amount set to the amount specified in @a f - * @return - * #GNUNET_YES if parsing was successful - * #GNUNET_NO if json is malformed, error response was generated - * #GNUNET_SYSERR on internal error, error response was not generated - */ -int -TMH_PARSE_amount_json (struct MHD_Connection *connection, - json_t *f, - struct TALER_Amount *amount); - - -/** - * Parse absolute time specified in JSON format. The JSON format is - * "/TIMEVAL/" where TIMEVAL is in seconds. Additionally, we - * support "/forever/" and "/never/" to represent the end of time. - * - * @param connection the MHD connection (to report errors) - * @param f json specification of the amount - * @param[out] time set to the time specified in @a f - * @return - * #GNUNET_YES if parsing was successful - * #GNUNET_NO if json is malformed, error response was generated - * #GNUNET_SYSERR on internal error, error response was not generated - */ -int -TMH_PARSE_time_abs_json (struct MHD_Connection *connection, - json_t *f, - struct GNUNET_TIME_Absolute *time); - - -/** * Extraxt fixed-size base32crockford encoded data from request. * * Queues an error response to the connection if the parameter is missing or diff --git a/src/util/json.c b/src/util/json.c index e4b0831a4..004f7734c 100644 --- a/src/util/json.c +++ b/src/util/json.c @@ -297,7 +297,19 @@ TALER_json_to_amount (json_t *json, "fraction", &fraction, "currency", ¤cy)) { + char *json_enc; + GNUNET_break_op (0); + if (NULL == (json_enc = json_dumps (json, + JSON_COMPACT | JSON_SORT_KEYS | JSON_ENCODE_ANY))) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Malformed JSON amount: %s\n", + json_enc); + free (json_enc); return GNUNET_SYSERR; } if ( (value < 0) || @@ -415,7 +427,7 @@ TALER_hash_json (json_t *json, GNUNET_CRYPTO_hash (wire_enc, len, hc); - GNUNET_free (wire_enc); + free (wire_enc); return GNUNET_OK; } |