summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-01-29 15:06:55 +0100
committerChristian Grothoff <christian@grothoff.org>2015-01-29 15:06:55 +0100
commita284561298af60ade27eb18008f29ebf63ac62b7 (patch)
tree3bd00337e04f397bc51161a0b31d10321c7c2685
parentab67dec1bed5f1fcc47d3c64248dfae6818b8aa3 (diff)
downloadexchange-a284561298af60ade27eb18008f29ebf63ac62b7.tar.gz
exchange-a284561298af60ade27eb18008f29ebf63ac62b7.tar.bz2
exchange-a284561298af60ade27eb18008f29ebf63ac62b7.zip
make TALER_MINT_parse_json_data more expressive
-rw-r--r--src/mint/taler-mint-httpd_parsing.c158
-rw-r--r--src/mint/taler-mint-httpd_parsing.h37
-rw-r--r--src/mint/taler-mint-httpd_refresh.c79
3 files changed, 146 insertions, 128 deletions
diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c
index 066f18913..165654193 100644
--- a/src/mint/taler-mint-httpd_parsing.c
+++ b/src/mint/taler-mint-httpd_parsing.c
@@ -463,76 +463,6 @@ GNUNET_MINT_parse_navigate_json (struct MHD_Connection *connection,
/**
- * Find a fixed-size field in the top-level of the JSON tree and store
- * it in @a data.
- *
- * Sends an error response if navigation is impossible (i.e.
- * the JSON object is invalid)
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param field name of the field to navigate to
- * @param data where to store the extracted data
- * @param data_size size of the @a data field
- * @param[IN|OUT] ret return value, function does nothing if @a ret is not #GNUNET_YES
- * on entry; will set @a ret to:
- * #GNUNET_YES if navigation was successful
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-static void
-parse_fixed_json_data (struct MHD_Connection *connection,
- const json_t *root,
- const char *field,
- void *data,
- size_t data_size,
- int *ret)
-{
- if (GNUNET_YES != *ret)
- return;
- *ret = GNUNET_MINT_parse_navigate_json (connection,
- root,
- JNAV_FIELD, field,
- JNAV_RET_DATA, data, data_size);
-}
-
-
-/**
- * Find a variable-size field in the top-level of the JSON tree and store
- * it in @a data.
- *
- * Sends an error response if navigation is impossible (i.e.
- * the JSON object is invalid)
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param field name of the field to navigate to
- * @param data where to store a pointer to memory allocated for the extracted data
- * @param[IN|OUT] ret return value, function does nothing if @a ret is not #GNUNET_YES
- * on entry; will set @a ret to:
- * #GNUNET_YES if navigation was successful
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-static void
-parse_variable_json_data (struct MHD_Connection *connection,
- const json_t *root,
- const char *field,
- void **data,
- size_t *data_size,
- int *ret)
-{
- if (GNUNET_YES != *ret)
- return;
- *ret = GNUNET_MINT_parse_navigate_json (connection,
- root,
- JNAV_FIELD, field,
- JNAV_RET_DATA_VAR, data, data_size);
-
-}
-
-
-/**
* Parse JSON object into components based on the given field
* specification.
*
@@ -558,23 +488,51 @@ TALER_MINT_parse_json_data (struct MHD_Connection *connection,
ret = GNUNET_YES;
for (i=0; NULL != spec[i].field_name; i++)
{
- if (0 == spec[i].destination_size_in)
+ switch (spec[i].command)
{
+ case JNAV_FIELD:
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ case JNAV_INDEX:
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ case JNAV_RET_DATA:
+ if (GNUNET_YES != ret)
+ break;
+ ret = GNUNET_MINT_parse_navigate_json (connection,
+ root,
+ JNAV_FIELD,
+ spec[i].field_name,
+ JNAV_RET_DATA,
+ spec[i].destination,
+ spec[i].destination_size_in);
+ break;
+ case JNAV_RET_DATA_VAR:
+ if (GNUNET_YES != ret)
+ break;
ptr = NULL;
- parse_variable_json_data (connection, root,
- spec[i].field_name,
- &ptr,
- &spec[i].destination_size_out,
- &ret);
+ ret = GNUNET_MINT_parse_navigate_json (connection,
+ root,
+ JNAV_FIELD,
+ spec[i].field_name,
+ JNAV_RET_DATA_VAR,
+ &ptr,
+ &spec[i].destination_size_out);
spec[i].destination = ptr;
- }
- else
- {
- parse_fixed_json_data (connection, root,
- spec[i].field_name,
- spec[i].destination,
- spec[i].destination_size_in,
- &ret);
+ break;
+ case JNAV_RET_TYPED_JSON:
+ if (GNUNET_YES != ret)
+ break;
+ ptr = NULL;
+ ret = GNUNET_MINT_parse_navigate_json (connection,
+ root,
+ JNAV_FIELD,
+ spec[i].field_name,
+ JNAV_RET_TYPED_JSON,
+ spec[i].type,
+ &ptr);
+ spec[i].destination = ptr;
+ break;
}
}
if (GNUNET_YES != ret)
@@ -595,13 +553,34 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec)
unsigned int i;
for (i=0; NULL != spec[i].field_name; i++)
- if ( (0 == spec[i].destination_size_in) &&
- (0 != spec[i].destination_size_out) )
+ {
+ switch (spec[i].command)
{
- GNUNET_free (spec[i].destination);
- spec[i].destination = NULL;
- spec[i].destination_size_out = 0;
+ case JNAV_FIELD:
+ GNUNET_break (0);
+ return;
+ case JNAV_INDEX:
+ GNUNET_break (0);
+ return;
+ case JNAV_RET_DATA:
+ break;
+ case JNAV_RET_DATA_VAR:
+ if (0 != spec[i].destination_size_out)
+ {
+ GNUNET_free (spec[i].destination);
+ spec[i].destination = NULL;
+ spec[i].destination_size_out = 0;
+ }
+ break;
+ case JNAV_RET_TYPED_JSON:
+ if (NULL != spec[i].destination)
+ {
+ json_decref (spec[i].destination);
+ spec[i].destination = NULL;
+ }
+ break;
}
+ }
}
@@ -774,7 +753,6 @@ TALER_MINT_mhd_request_var_arg_data (struct MHD_Connection *connection,
*out_data = out;
*out_size = olen;
return GNUNET_OK;
-
}
diff --git a/src/mint/taler-mint-httpd_parsing.h b/src/mint/taler-mint-httpd_parsing.h
index 1c13c9469..86205a070 100644
--- a/src/mint/taler-mint-httpd_parsing.h
+++ b/src/mint/taler-mint-httpd_parsing.h
@@ -162,6 +162,22 @@ struct GNUNET_MINT_ParseFieldSpec
* variable-size allocations).
*/
size_t destination_size_out;
+
+ /**
+ * Navigation command to use to extract the value. Note that
+ * #JNAV_RET_DATA or #JNAV_RET_DATA_VAR must be used for @e
+ * destination_size_in and @e destination_size_out to have a
+ * meaning. #JNAV_FIELD and #JNAV_INDEX must not be used here!
+ */
+ enum TALER_MINT_JsonNavigationCommand command;
+
+ /**
+ * JSON type to use, only meaningful in connection with a @e command
+ * value of #JNAV_RET_TYPED_JSON. Typical values are
+ * #JSON_ARRAY and #JSON_OBJECT.
+ */
+ int type;
+
};
@@ -201,19 +217,34 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec);
* @param field name of the field
* @param value where to store the value
*/
-#define TALER_MINT_PARSE_FIXED(field,value) { field, value, sizeof (*value), 0 }
+#define TALER_MINT_PARSE_FIXED(field,value) { field, value, sizeof (*value), 0, JNAV_RET_DATA, 0 }
/**
* Generate line in parser specification for variable-size value.
*
* @param field name of the field
*/
-#define TALER_MINT_PARSE_VARIABLE(field) { field, NULL, 0, 0 }
+#define TALER_MINT_PARSE_VARIABLE(field) { field, NULL, 0, 0, JNAV_RET_DATA_VAR, 0 }
+
+/**
+ * Generate line in parser specification for JSON array value.
+ *
+ * @param field name of the field
+ */
+#define TALER_MINT_PARSE_ARRAY(field) { field, NULL, 0, 0, JNAV_RET_TYPED_JSON, JSON_ARRAY }
+
+/**
+ * Generate line in parser specification for JSON object value.
+ *
+ * @param field name of the field
+ */
+#define TALER_MINT_PARSE_OBJECT(field) { field, NULL, 0, 0, JNAV_RET_TYPED_JSON, JSON_OBJECT }
+
/**
* Generate line in parser specification indicating the end of the spec.
*/
-#define TALER_MINT_PARSE_END { NULL, NULL, 0, 0 }
+#define TALER_MINT_PARSE_END { NULL, NULL, 0, 0, JNAV_FIELD, 0 }
/**
diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c
index 7e16f2a92..89aff83ab 100644
--- a/src/mint/taler-mint-httpd_refresh.c
+++ b/src/mint/taler-mint-httpd_refresh.c
@@ -275,29 +275,57 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
if ( (GNUNET_NO == res) || (NULL == root) )
return MHD_YES;
- /* session_pub field must always be present */
- res = GNUNET_MINT_parse_navigate_json (connection, root,
- JNAV_FIELD, "session_pub",
- JNAV_RET_DATA,
- &refresh_session_pub,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
- if (GNUNET_OK != res)
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
+ res = GNUNET_MINT_parse_navigate_json (connection,
+ root,
+ JNAV_FIELD,
+ "session_pub",
+ JNAV_RET_DATA,
+ &refresh_session_pub,
+ sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+ if (GNUNET_SYSERR == res)
return MHD_NO;
- }
if (GNUNET_NO == res)
return MHD_YES;
-
- res = GNUNET_MINT_parse_navigate_json (connection, root,
- JNAV_FIELD, "new_denoms",
+ res = GNUNET_MINT_parse_navigate_json (connection,
+ root,
+ JNAV_FIELD,
+ "new_denoms",
JNAV_RET_TYPED_JSON,
JSON_ARRAY,
&new_denoms);
+ if (GNUNET_SYSERR == res)
+ return MHD_NO;
+ if (GNUNET_NO == res)
+ return MHD_YES;
+
+ res = GNUNET_MINT_parse_navigate_json (connection,
+ root,
+ JNAV_FIELD,
+ "melt_coins",
+ JNAV_RET_TYPED_JSON,
+ JSON_ARRAY,
+ &melt_coins);
if (GNUNET_OK != res)
- return res;
+ {
+ // FIXME: leaks!
+ return res;
+ }
+
+ melt_sig_json = json_object_get (root,
+ "melt_signature");
+ if (NULL == melt_sig_json)
+ {
+ return TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s}",
+ "error",
+ "melt_signature missing");
+ }
+
+
+
num_new_denoms = json_array_size (new_denoms);
+
denom_pubs = GNUNET_malloc (num_new_denoms *
sizeof (struct GNUNET_CRYPTO_rsa_PublicKey *));
@@ -326,27 +354,8 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
}
}
- res = GNUNET_MINT_parse_navigate_json (connection, root,
- JNAV_FIELD, "melt_coins",
- JNAV_RET_TYPED_JSON,
- JSON_ARRAY,
- &melt_coins);
- if (GNUNET_OK != res)
- {
- // FIXME: leaks!
- return res;
- }
- melt_sig_json = json_object_get (root,
- "melt_signature");
- if (NULL == melt_sig_json)
- {
- return TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error",
- "melt_signature missing");
- }
+
coin_count = json_array_size (melt_coins);
coin_public_infos = GNUNET_malloc (coin_count *