make TALER_MINT_parse_json_data more expressive
This commit is contained in:
parent
ab67dec1be
commit
a284561298
@ -462,76 +462,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
|
* Parse JSON object into components based on the given field
|
||||||
* specification.
|
* specification.
|
||||||
@ -558,23 +488,51 @@ TALER_MINT_parse_json_data (struct MHD_Connection *connection,
|
|||||||
ret = GNUNET_YES;
|
ret = GNUNET_YES;
|
||||||
for (i=0; NULL != spec[i].field_name; i++)
|
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;
|
ptr = NULL;
|
||||||
parse_variable_json_data (connection, root,
|
ret = GNUNET_MINT_parse_navigate_json (connection,
|
||||||
spec[i].field_name,
|
root,
|
||||||
&ptr,
|
JNAV_FIELD,
|
||||||
&spec[i].destination_size_out,
|
spec[i].field_name,
|
||||||
&ret);
|
JNAV_RET_DATA_VAR,
|
||||||
|
&ptr,
|
||||||
|
&spec[i].destination_size_out);
|
||||||
spec[i].destination = ptr;
|
spec[i].destination = ptr;
|
||||||
}
|
break;
|
||||||
else
|
case JNAV_RET_TYPED_JSON:
|
||||||
{
|
if (GNUNET_YES != ret)
|
||||||
parse_fixed_json_data (connection, root,
|
break;
|
||||||
spec[i].field_name,
|
ptr = NULL;
|
||||||
spec[i].destination,
|
ret = GNUNET_MINT_parse_navigate_json (connection,
|
||||||
spec[i].destination_size_in,
|
root,
|
||||||
&ret);
|
JNAV_FIELD,
|
||||||
|
spec[i].field_name,
|
||||||
|
JNAV_RET_TYPED_JSON,
|
||||||
|
spec[i].type,
|
||||||
|
&ptr);
|
||||||
|
spec[i].destination = ptr;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (GNUNET_YES != ret)
|
if (GNUNET_YES != ret)
|
||||||
@ -595,13 +553,34 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i=0; NULL != spec[i].field_name; 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);
|
case JNAV_FIELD:
|
||||||
spec[i].destination = NULL;
|
GNUNET_break (0);
|
||||||
spec[i].destination_size_out = 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_data = out;
|
||||||
*out_size = olen;
|
*out_size = olen;
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,6 +162,22 @@ struct GNUNET_MINT_ParseFieldSpec
|
|||||||
* variable-size allocations).
|
* variable-size allocations).
|
||||||
*/
|
*/
|
||||||
size_t destination_size_out;
|
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 field name of the field
|
||||||
* @param value where to store the value
|
* @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.
|
* Generate line in parser specification for variable-size value.
|
||||||
*
|
*
|
||||||
* @param field name of the field
|
* @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.
|
* 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 }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,29 +275,57 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
|
|||||||
if ( (GNUNET_NO == res) || (NULL == root) )
|
if ( (GNUNET_NO == res) || (NULL == root) )
|
||||||
return MHD_YES;
|
return MHD_YES;
|
||||||
|
|
||||||
/* session_pub field must always be present */
|
res = GNUNET_MINT_parse_navigate_json (connection,
|
||||||
res = GNUNET_MINT_parse_navigate_json (connection, root,
|
root,
|
||||||
JNAV_FIELD, "session_pub",
|
JNAV_FIELD,
|
||||||
JNAV_RET_DATA,
|
"session_pub",
|
||||||
&refresh_session_pub,
|
JNAV_RET_DATA,
|
||||||
sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
|
&refresh_session_pub,
|
||||||
if (GNUNET_OK != res)
|
sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
|
||||||
{
|
if (GNUNET_SYSERR == res)
|
||||||
// FIXME: return 'internal error'?
|
|
||||||
GNUNET_break (0);
|
|
||||||
return MHD_NO;
|
return MHD_NO;
|
||||||
}
|
|
||||||
if (GNUNET_NO == res)
|
if (GNUNET_NO == res)
|
||||||
return MHD_YES;
|
return MHD_YES;
|
||||||
|
res = GNUNET_MINT_parse_navigate_json (connection,
|
||||||
res = GNUNET_MINT_parse_navigate_json (connection, root,
|
root,
|
||||||
JNAV_FIELD, "new_denoms",
|
JNAV_FIELD,
|
||||||
|
"new_denoms",
|
||||||
JNAV_RET_TYPED_JSON,
|
JNAV_RET_TYPED_JSON,
|
||||||
JSON_ARRAY,
|
JSON_ARRAY,
|
||||||
&new_denoms);
|
&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)
|
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);
|
num_new_denoms = json_array_size (new_denoms);
|
||||||
|
|
||||||
denom_pubs = GNUNET_malloc (num_new_denoms *
|
denom_pubs = GNUNET_malloc (num_new_denoms *
|
||||||
sizeof (struct GNUNET_CRYPTO_rsa_PublicKey *));
|
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_count = json_array_size (melt_coins);
|
||||||
coin_public_infos = GNUNET_malloc (coin_count *
|
coin_public_infos = GNUNET_malloc (coin_count *
|
||||||
|
Loading…
Reference in New Issue
Block a user