diff options
Diffstat (limited to 'src/mint/taler-mint-httpd_parsing.c')
-rw-r--r-- | src/mint/taler-mint-httpd_parsing.c | 156 |
1 files changed, 87 insertions, 69 deletions
diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c index 19c88d456..7d3f3b5e6 100644 --- a/src/mint/taler-mint-httpd_parsing.c +++ b/src/mint/taler-mint-httpd_parsing.c | |||
@@ -271,44 +271,48 @@ TALER_MINT_parse_post_cleanup_callback (void *con_cls) | |||
271 | * @param ... navigation specification (see JNAV_*) | 271 | * @param ... navigation specification (see JNAV_*) |
272 | * @return GNUNET_YES if navigation was successful | 272 | * @return GNUNET_YES if navigation was successful |
273 | * GNUNET_NO if json is malformed, error response was generated | 273 | * GNUNET_NO if json is malformed, error response was generated |
274 | * GNUNET_SYSERR on internal error | 274 | * GNUNET_SYSERR on internal error (no response was generated, |
275 | * connection must be closed) | ||
275 | */ | 276 | */ |
276 | int | 277 | int |
277 | request_json_require_nav (struct MHD_Connection *connection, | 278 | GNUNET_MINT_parse_navigate_json (struct MHD_Connection *connection, |
278 | const json_t *root, ...) | 279 | const json_t *root, |
280 | ...) | ||
279 | { | 281 | { |
280 | va_list argp; | 282 | va_list argp; |
281 | int ignore = GNUNET_NO; | 283 | int ret; |
282 | // what's our current path from 'root'? | 284 | json_t *path; /* what's our current path from 'root'? */ |
283 | json_t *path; | ||
284 | 285 | ||
285 | path = json_array (); | 286 | path = json_array (); |
286 | 287 | va_start (argp, root); | |
287 | va_start(argp, root); | 288 | ret = 2; |
288 | 289 | while (2 == ret) | |
289 | while (1) | ||
290 | { | 290 | { |
291 | int command = va_arg(argp, int); | 291 | enum TALER_MINT_JsonNavigationCommand command |
292 | = va_arg (argp, | ||
293 | enum TALER_MINT_JsonNavigationCommand); | ||
294 | |||
292 | switch (command) | 295 | switch (command) |
293 | { | 296 | { |
294 | case JNAV_FIELD: | 297 | case JNAV_FIELD: |
295 | { | 298 | { |
296 | const char *fname = va_arg(argp, const char *); | 299 | const char *fname = va_arg(argp, const char *); |
297 | if (GNUNET_YES == ignore) | 300 | |
298 | break; | 301 | json_array_append_new (path, |
299 | json_array_append_new (path, json_string (fname)); | 302 | json_string (fname)); |
300 | root = json_object_get (root, fname); | 303 | root = json_object_get (root, |
304 | fname); | ||
301 | if (NULL == root) | 305 | if (NULL == root) |
302 | { | 306 | { |
303 | /* FIXME: can't IGNORE this return value! */ | 307 | ret = (MHD_YES == |
304 | (void) TALER_MINT_reply_json_pack (connection, | 308 | TALER_MINT_reply_json_pack (connection, |
305 | MHD_HTTP_BAD_REQUEST, | 309 | MHD_HTTP_BAD_REQUEST, |
306 | "{s:s,s:o}", | 310 | "{s:s,s:o}", |
307 | "error", | 311 | "error", |
308 | "missing field in JSON", | 312 | "missing field in JSON", |
309 | "path", | 313 | "path", |
310 | path); | 314 | path)) |
311 | ignore = GNUNET_YES; | 315 | ? GNUNET_NO : GNUNET_SYSERR; |
312 | break; | 316 | break; |
313 | } | 317 | } |
314 | } | 318 | } |
@@ -316,19 +320,21 @@ request_json_require_nav (struct MHD_Connection *connection, | |||
316 | case JNAV_INDEX: | 320 | case JNAV_INDEX: |
317 | { | 321 | { |
318 | int fnum = va_arg(argp, int); | 322 | int fnum = va_arg(argp, int); |
319 | if (GNUNET_YES == ignore) | 323 | |
320 | break; | 324 | json_array_append_new (path, |
321 | json_array_append_new (path, json_integer (fnum)); | 325 | json_integer (fnum)); |
322 | root = json_array_get (root, fnum); | 326 | root = json_array_get (root, |
327 | fnum); | ||
323 | if (NULL == root) | 328 | if (NULL == root) |
324 | { | 329 | { |
325 | /* FIXME: can't IGNORE this return value! */ | 330 | ret = (MHD_YES == |
326 | (void) TALER_MINT_reply_json_pack (connection, | 331 | TALER_MINT_reply_json_pack (connection, |
327 | MHD_HTTP_BAD_REQUEST, | 332 | MHD_HTTP_BAD_REQUEST, |
328 | "{s:s, s:o}", | 333 | "{s:s, s:o}", |
329 | "error", "missing index in JSON", | 334 | "error", |
330 | "path", path); | 335 | "missing index in JSON", |
331 | ignore = GNUNET_YES; | 336 | "path", path)) |
337 | ? GNUNET_NO : GNUNET_SYSERR; | ||
332 | break; | 338 | break; |
333 | } | 339 | } |
334 | } | 340 | } |
@@ -340,36 +346,36 @@ request_json_require_nav (struct MHD_Connection *connection, | |||
340 | const char *str; | 346 | const char *str; |
341 | int res; | 347 | int res; |
342 | 348 | ||
343 | va_end(argp); | ||
344 | if (GNUNET_YES == ignore) | ||
345 | return GNUNET_NO; | ||
346 | str = json_string_value (root); | 349 | str = json_string_value (root); |
347 | if (NULL == str) | 350 | if (NULL == str) |
348 | { | 351 | { |
349 | /* FIXME: can't IGNORE this return value! */ | 352 | ret = (MHD_YES == |
350 | (void) TALER_MINT_reply_json_pack (connection, | 353 | TALER_MINT_reply_json_pack (connection, |
351 | MHD_HTTP_BAD_REQUEST, | 354 | MHD_HTTP_BAD_REQUEST, |
352 | "{s:s, s:o}", | 355 | "{s:s, s:o}", |
353 | "error", | 356 | "error", |
354 | "string expected", | 357 | "string expected", |
355 | "path", | 358 | "path", |
356 | path); | 359 | path)) |
357 | return GNUNET_NO; | 360 | ? GNUNET_NO : GNUNET_SYSERR; |
361 | break; | ||
358 | } | 362 | } |
359 | res = GNUNET_STRINGS_string_to_data (str, strlen (str), | 363 | res = GNUNET_STRINGS_string_to_data (str, strlen (str), |
360 | where, len); | 364 | where, len); |
361 | if (GNUNET_OK != res) | 365 | if (GNUNET_OK != res) |
362 | { | 366 | { |
363 | /* FIXME: can't IGNORE this return value! */ | 367 | ret = (MHD_YES == |
364 | (void) TALER_MINT_reply_json_pack (connection, | 368 | TALER_MINT_reply_json_pack (connection, |
365 | MHD_HTTP_BAD_REQUEST, | 369 | MHD_HTTP_BAD_REQUEST, |
366 | "{s:s,s:o}", | 370 | "{s:s,s:o}", |
367 | "error", | 371 | "error", |
368 | "malformed binary data in JSON", | 372 | "malformed binary data in JSON", |
369 | "path", path); | 373 | "path", |
370 | return GNUNET_NO; | 374 | path)) |
375 | ? GNUNET_NO : GNUNET_SYSERR; | ||
376 | break; | ||
371 | } | 377 | } |
372 | return GNUNET_YES; | 378 | ret = GNUNET_OK; |
373 | } | 379 | } |
374 | break; | 380 | break; |
375 | case JNAV_RET_DATA_VAR: | 381 | case JNAV_RET_DATA_VAR: |
@@ -378,35 +384,42 @@ request_json_require_nav (struct MHD_Connection *connection, | |||
378 | size_t *len = va_arg (argp, size_t *); | 384 | size_t *len = va_arg (argp, size_t *); |
379 | const char *str; | 385 | const char *str; |
380 | 386 | ||
381 | va_end(argp); | ||
382 | if (GNUNET_YES == ignore) | ||
383 | return GNUNET_NO; | ||
384 | str = json_string_value (root); | 387 | str = json_string_value (root); |
385 | if (NULL == str) | 388 | if (NULL == str) |
386 | { | 389 | { |
387 | GNUNET_break (0); | 390 | ret = (MHD_YES == |
388 | return GNUNET_SYSERR; | 391 | TALER_MINT_reply_internal_error (connection, |
392 | "json_string_value() failed")) | ||
393 | ? GNUNET_NO : GNUNET_SYSERR; | ||
394 | break; | ||
389 | } | 395 | } |
390 | *len = (strlen (str) * 5) / 8; | 396 | *len = (strlen (str) * 5) / 8; |
391 | if (where != NULL) | 397 | if (NULL != where) |
392 | { | 398 | { |
393 | int res; | 399 | int res; |
400 | |||
394 | *where = GNUNET_malloc (*len); | 401 | *where = GNUNET_malloc (*len); |
395 | res = GNUNET_STRINGS_string_to_data (str, strlen (str), | 402 | res = GNUNET_STRINGS_string_to_data (str, |
396 | *where, *len); | 403 | strlen (str), |
404 | *where, | ||
405 | *len); | ||
397 | if (GNUNET_OK != res) | 406 | if (GNUNET_OK != res) |
398 | { | 407 | { |
399 | /* FIXME: can't IGNORE this return value! */ | 408 | GNUNET_free (*where); |
400 | (void) TALER_MINT_reply_json_pack (connection, | 409 | *where = NULL; |
410 | *len = 0; | ||
411 | ret = (MHD_YES == | ||
412 | TALER_MINT_reply_json_pack (connection, | ||
401 | MHD_HTTP_BAD_REQUEST, | 413 | MHD_HTTP_BAD_REQUEST, |
402 | "{s:s, s:o}", | 414 | "{s:s, s:o}", |
403 | "error", | 415 | "error", |
404 | "malformed binary data in JSON", | 416 | "malformed binary data in JSON", |
405 | "path", path); | 417 | "path", path)) |
406 | return GNUNET_NO; | 418 | ? GNUNET_NO : GNUNET_SYSERR; |
419 | break; | ||
407 | } | 420 | } |
408 | } | 421 | } |
409 | return GNUNET_OK; | 422 | ret = GNUNET_OK; |
410 | } | 423 | } |
411 | break; | 424 | break; |
412 | case JNAV_RET_TYPED_JSON: | 425 | case JNAV_RET_TYPED_JSON: |
@@ -414,30 +427,35 @@ request_json_require_nav (struct MHD_Connection *connection, | |||
414 | int typ = va_arg (argp, int); | 427 | int typ = va_arg (argp, int); |
415 | const json_t **r_json = va_arg (argp, const json_t **); | 428 | const json_t **r_json = va_arg (argp, const json_t **); |
416 | 429 | ||
417 | va_end(argp); | 430 | if ( (-1 != typ) && (json_typeof (root) != typ)) |
418 | if (GNUNET_YES == ignore) | ||
419 | return GNUNET_NO; | ||
420 | if (typ != -1 && json_typeof (root) != typ) | ||
421 | { | 431 | { |
422 | /* FIXME: can't IGNORE this return value! */ | 432 | ret = (MHD_YES == |
423 | (void) TALER_MINT_reply_json_pack (connection, | 433 | TALER_MINT_reply_json_pack (connection, |
424 | MHD_HTTP_BAD_REQUEST, | 434 | MHD_HTTP_BAD_REQUEST, |
425 | "{s:s, s:i, s:i s:o}", | 435 | "{s:s, s:i, s:i s:o}", |
426 | "error", "wrong JSON field type", | 436 | "error", "wrong JSON field type", |
427 | "type_expected", typ, | 437 | "type_expected", typ, |
428 | "type_actual", json_typeof (root), | 438 | "type_actual", json_typeof (root), |
429 | "path", path); | 439 | "path", path)) |
430 | return GNUNET_NO; | 440 | ? GNUNET_NO : GNUNET_SYSERR; |
441 | break; | ||
431 | } | 442 | } |
432 | *r_json = root; | 443 | *r_json = root; |
433 | return GNUNET_OK; | 444 | ret = GNUNET_OK; |
434 | } | 445 | } |
435 | break; | 446 | break; |
436 | default: | 447 | default: |
437 | GNUNET_assert (0); | 448 | GNUNET_break (0); |
449 | ret = (MHD_YES == | ||
450 | TALER_MINT_reply_internal_error (connection, | ||
451 | "unhandled value in switch")) | ||
452 | ? GNUNET_NO : GNUNET_SYSERR; | ||
453 | break; | ||
438 | } | 454 | } |
439 | } | 455 | } |
440 | GNUNET_assert (0); | 456 | va_end (argp); |
457 | json_decref (path); | ||
458 | return ret; | ||
441 | } | 459 | } |
442 | 460 | ||
443 | 461 | ||