aboutsummaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd.c')
-rw-r--r--src/exchange/taler-exchange-httpd.c201
1 files changed, 82 insertions, 119 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 4a206b138..c39df21a4 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -57,33 +57,6 @@
57 57
58 58
59/** 59/**
60 * Type of the closure associated with each HTTP request to the exchange.
61 */
62struct ExchangeHttpRequestClosure
63{
64 /**
65 * Async Scope ID associated with this request.
66 */
67 struct GNUNET_AsyncScopeId async_scope_id;
68
69 /**
70 * Opaque parsing context.
71 */
72 void *opaque_post_parsing_context;
73
74 /**
75 * Cached request handler for this request (once we have found one).
76 */
77 struct TEH_RequestHandler *rh;
78
79 /**
80 * Request URL (for logging).
81 */
82 const char *url;
83};
84
85
86/**
87 * Are clients allowed to request /keys for times other than the 60 * Are clients allowed to request /keys for times other than the
88 * current time? Allowing this could be abused in a DoS-attack 61 * current time? Allowing this could be abused in a DoS-attack
89 * as building new /keys responses is expensive. Should only be 62 * as building new /keys responses is expensive. Should only be
@@ -204,16 +177,14 @@ r404 (struct MHD_Connection *connection,
204 * Handle a "/coins/$COIN_PUB/$OP" POST request. Parses the "coin_pub" 177 * Handle a "/coins/$COIN_PUB/$OP" POST request. Parses the "coin_pub"
205 * EdDSA key of the coin and demultiplexes based on $OP. 178 * EdDSA key of the coin and demultiplexes based on $OP.
206 * 179 *
207 * @param rh context of the handler 180 * @param rc request context
208 * @param connection the MHD connection to handle
209 * @param root uploaded JSON data 181 * @param root uploaded JSON data
210 * @param args array of additional options (first must be the 182 * @param args array of additional options (first must be the
211 * reserve public key, the second one should be "withdraw") 183 * reserve public key, the second one should be "withdraw")
212 * @return MHD result code 184 * @return MHD result code
213 */ 185 */
214static MHD_RESULT 186static MHD_RESULT
215handle_post_coins (const struct TEH_RequestHandler *rh, 187handle_post_coins (struct TEH_RequestContext *rc,
216 struct MHD_Connection *connection,
217 const json_t *root, 188 const json_t *root,
218 const char *const args[2]) 189 const char *const args[2])
219{ 190{
@@ -253,7 +224,6 @@ handle_post_coins (const struct TEH_RequestHandler *rh,
253 }, 224 },
254 }; 225 };
255 226
256 (void) rh;
257 if (GNUNET_OK != 227 if (GNUNET_OK !=
258 GNUNET_STRINGS_string_to_data (args[0], 228 GNUNET_STRINGS_string_to_data (args[0],
259 strlen (args[0]), 229 strlen (args[0]),
@@ -261,7 +231,7 @@ handle_post_coins (const struct TEH_RequestHandler *rh,
261 sizeof (coin_pub))) 231 sizeof (coin_pub)))
262 { 232 {
263 GNUNET_break_op (0); 233 GNUNET_break_op (0);
264 return TALER_MHD_reply_with_error (connection, 234 return TALER_MHD_reply_with_error (rc->connection,
265 MHD_HTTP_BAD_REQUEST, 235 MHD_HTTP_BAD_REQUEST,
266 TALER_EC_EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB, 236 TALER_EC_EXCHANGE_GENERIC_COINS_INVALID_COIN_PUB,
267 args[0]); 237 args[0]);
@@ -269,10 +239,11 @@ handle_post_coins (const struct TEH_RequestHandler *rh,
269 for (unsigned int i = 0; NULL != h[i].op; i++) 239 for (unsigned int i = 0; NULL != h[i].op; i++)
270 if (0 == strcmp (h[i].op, 240 if (0 == strcmp (h[i].op,
271 args[1])) 241 args[1]))
272 return h[i].handler (connection, 242 return h[i].handler (rc->connection,
273 &coin_pub, 243 &coin_pub,
274 root); 244 root);
275 return r404 (connection, args[1]); 245 return r404 (rc->connection,
246 args[1]);
276} 247}
277 248
278 249
@@ -296,14 +267,16 @@ handle_mhd_completion_callback (void *cls,
296 void **con_cls, 267 void **con_cls,
297 enum MHD_RequestTerminationCode toe) 268 enum MHD_RequestTerminationCode toe)
298{ 269{
299 struct ExchangeHttpRequestClosure *ecls = *con_cls; 270 struct TEH_RequestContext *rc = *con_cls;
300 struct GNUNET_AsyncScopeSave old_scope; 271 struct GNUNET_AsyncScopeSave old_scope;
301 272
302 (void) cls; 273 (void) cls;
303 if (NULL == ecls) 274 if (NULL == rc)
304 return; 275 return;
305 GNUNET_async_scope_enter (&ecls->async_scope_id, 276 GNUNET_async_scope_enter (&rc->async_scope_id,
306 &old_scope); 277 &old_scope);
278 if (NULL != rc->rh_cleaner)
279 rc->rh_cleaner (rc);
307 { 280 {
308#if MHD_VERSION >= 0x00097304 281#if MHD_VERSION >= 0x00097304
309 const union MHD_ConnectionInfo *ci; 282 const union MHD_ConnectionInfo *ci;
@@ -315,52 +288,49 @@ handle_mhd_completion_callback (void *cls,
315 http_status = ci->http_status; 288 http_status = ci->http_status;
316 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 289 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
317 "Request for `%s' completed with HTTP status %u (%d)\n", 290 "Request for `%s' completed with HTTP status %u (%d)\n",
318 ecls->url, 291 rc->url,
319 http_status, 292 http_status,
320 toe); 293 toe);
321#else 294#else
322 (void) connection; 295 (void) connection;
323 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 296 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
324 "Request for `%s' completed (%d)\n", 297 "Request for `%s' completed (%d)\n",
325 ecls->url, 298 rc->url,
326 toe); 299 toe);
327#endif 300#endif
328 } 301 }
329 302
330 TALER_MHD_parse_post_cleanup_callback (ecls->opaque_post_parsing_context); 303 TALER_MHD_parse_post_cleanup_callback (rc->opaque_post_parsing_context);
331 /* Sanity-check that we didn't leave any transactions hanging */ 304 /* Sanity-check that we didn't leave any transactions hanging */
332 /* NOTE: In high-performance production, we could consider 305 /* NOTE: In high-performance production, we could consider
333 removing this as it should not be needed and might be costly 306 removing this as it should not be needed and might be costly
334 (to be benchmarked). */ 307 (to be benchmarked). */
335 TEH_plugin->preflight (TEH_plugin->cls, 308 TEH_plugin->preflight (TEH_plugin->cls,
336 TEH_plugin->get_session (TEH_plugin->cls)); 309 TEH_plugin->get_session (TEH_plugin->cls));
337 GNUNET_free (ecls); 310 GNUNET_free (rc);
338 *con_cls = NULL; 311 *con_cls = NULL;
339 GNUNET_async_scope_restore (&old_scope); 312 GNUNET_async_scope_restore (&old_scope);
340} 313}
341 314
342 315
343/** 316/**
344 * We found @a rh responsible for handling a request. Parse the 317 * We found a request handler responsible for handling a request. Parse the
345 * @a upload_data (if applicable) and the @a url and call the 318 * @a upload_data (if applicable) and the @a url and call the
346 * handler. 319 * handler.
347 * 320 *
348 * @param rh request handler to call 321 * @param rc request context
349 * @param connection connection being handled
350 * @param url rest of the URL to parse 322 * @param url rest of the URL to parse
351 * @param inner_cls closure for the handler, if needed
352 * @param upload_data upload data to parse (if available) 323 * @param upload_data upload data to parse (if available)
353 * @param[in,out] upload_data_size number of bytes in @a upload_data 324 * @param[in,out] upload_data_size number of bytes in @a upload_data
354 * @return MHD result code 325 * @return MHD result code
355 */ 326 */
356static MHD_RESULT 327static MHD_RESULT
357proceed_with_handler (const struct TEH_RequestHandler *rh, 328proceed_with_handler (struct TEH_RequestContext *rc,
358 struct MHD_Connection *connection,
359 const char *url, 329 const char *url,
360 void **inner_cls,
361 const char *upload_data, 330 const char *upload_data,
362 size_t *upload_data_size) 331 size_t *upload_data_size)
363{ 332{
333 const struct TEH_RequestHandler *rh = rc->rh;
364 const char *args[rh->nargs + 1]; 334 const char *args[rh->nargs + 1];
365 size_t ulen = strlen (url) + 1; 335 size_t ulen = strlen (url) + 1;
366 json_t *root = NULL; 336 json_t *root = NULL;
@@ -376,7 +346,7 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,
376 /deposits/). The value should be adjusted if we ever define protocol 346 /deposits/). The value should be adjusted if we ever define protocol
377 endpoints with plausibly longer inputs. */ 347 endpoints with plausibly longer inputs. */
378 GNUNET_break_op (0); 348 GNUNET_break_op (0);
379 return TALER_MHD_reply_with_error (connection, 349 return TALER_MHD_reply_with_error (rc->connection,
380 MHD_HTTP_URI_TOO_LONG, 350 MHD_HTTP_URI_TOO_LONG,
381 TALER_EC_GENERIC_URI_TOO_LONG, 351 TALER_EC_GENERIC_URI_TOO_LONG,
382 url); 352 url);
@@ -389,8 +359,8 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,
389 { 359 {
390 enum GNUNET_GenericReturnValue res; 360 enum GNUNET_GenericReturnValue res;
391 361
392 res = TALER_MHD_parse_post_json (connection, 362 res = TALER_MHD_parse_post_json (rc->connection,
393 inner_cls, 363 &rc->opaque_post_parsing_context,
394 upload_data, 364 upload_data,
395 upload_data_size, 365 upload_data_size,
396 &root); 366 &root);
@@ -447,7 +417,7 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,
447 url); 417 url);
448 GNUNET_break_op (0); 418 GNUNET_break_op (0);
449 json_decref (root); 419 json_decref (root);
450 return TALER_MHD_reply_with_error (connection, 420 return TALER_MHD_reply_with_error (rc->connection,
451 MHD_HTTP_NOT_FOUND, 421 MHD_HTTP_NOT_FOUND,
452 TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS, 422 TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS,
453 emsg); 423 emsg);
@@ -458,18 +428,15 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,
458 args[i] = NULL; 428 args[i] = NULL;
459 } 429 }
460 430
461
462 /* Above logic ensures that 'root' is exactly non-NULL for POST operations, 431 /* Above logic ensures that 'root' is exactly non-NULL for POST operations,
463 so we test for 'root' to decide which handler to invoke. */ 432 so we test for 'root' to decide which handler to invoke. */
464 if (NULL != root) 433 if (NULL != root)
465 ret = rh->handler.post (rh, 434 ret = rh->handler.post (rc,
466 connection,
467 root, 435 root,
468 args); 436 args);
469 else /* We also only have "POST" or "GET" in the API for at this point 437 else /* We also only have "POST" or "GET" in the API for at this point
470 (OPTIONS/HEAD are taken care of earlier) */ 438 (OPTIONS/HEAD are taken care of earlier) */
471 ret = rh->handler.get (rh, 439 ret = rh->handler.get (rc,
472 connection,
473 args); 440 args);
474 } 441 }
475 json_decref (root); 442 json_decref (root);
@@ -480,14 +447,13 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,
480/** 447/**
481 * Handle a "/seed" request. 448 * Handle a "/seed" request.
482 * 449 *
483 * @param rh context of the handler 450 * @param rc request context
484 * @param connection the MHD connection to handle 451 * @param connection the MHD connection to handle
485 * @param args array of additional options (must be empty for this function) 452 * @param args array of additional options (must be empty for this function)
486 * @return MHD result code 453 * @return MHD result code
487 */ 454 */
488static MHD_RESULT 455static MHD_RESULT
489handler_seed (const struct TEH_RequestHandler *rh, 456handler_seed (struct TEH_RequestContext *rc,
490 struct MHD_Connection *connection,
491 const char *const args[]) 457 const char *const args[])
492{ 458{
493#define SEED_SIZE 32 459#define SEED_SIZE 32
@@ -495,7 +461,6 @@ handler_seed (const struct TEH_RequestHandler *rh,
495 MHD_RESULT ret; 461 MHD_RESULT ret;
496 struct MHD_Response *resp; 462 struct MHD_Response *resp;
497 463
498 (void) rh;
499 body = malloc (SEED_SIZE); /* must use malloc(), because MHD will use free() */ 464 body = malloc (SEED_SIZE); /* must use malloc(), because MHD will use free() */
500 if (NULL == body) 465 if (NULL == body)
501 return MHD_NO; 466 return MHD_NO;
@@ -506,7 +471,7 @@ handler_seed (const struct TEH_RequestHandler *rh,
506 body, 471 body,
507 MHD_RESPMEM_MUST_FREE); 472 MHD_RESPMEM_MUST_FREE);
508 TALER_MHD_add_global_headers (resp); 473 TALER_MHD_add_global_headers (resp);
509 ret = MHD_queue_response (connection, 474 ret = MHD_queue_response (rc->connection,
510 MHD_HTTP_OK, 475 MHD_HTTP_OK,
511 resp); 476 resp);
512 GNUNET_break (MHD_YES == ret); 477 GNUNET_break (MHD_YES == ret);
@@ -519,22 +484,21 @@ handler_seed (const struct TEH_RequestHandler *rh,
519/** 484/**
520 * Handle POST "/management/..." requests. 485 * Handle POST "/management/..." requests.
521 * 486 *
522 * @param rh context of the handler 487 * @param rc request context
523 * @param connection the MHD connection to handle
524 * @param root uploaded JSON data 488 * @param root uploaded JSON data
525 * @param args array of additional options 489 * @param args array of additional options
526 * @return MHD result code 490 * @return MHD result code
527 */ 491 */
528static MHD_RESULT 492static MHD_RESULT
529handle_post_management (const struct TEH_RequestHandler *rh, 493handle_post_management (struct TEH_RequestContext *rc,
530 struct MHD_Connection *connection,
531 const json_t *root, 494 const json_t *root,
532 const char *const args[]) 495 const char *const args[])
533{ 496{
534 if (NULL == args[0]) 497 if (NULL == args[0])
535 { 498 {
536 GNUNET_break_op (0); 499 GNUNET_break_op (0);
537 return r404 (connection, "/management"); 500 return r404 (rc->connection,
501 "/management");
538 } 502 }
539 if (0 == strcmp (args[0], 503 if (0 == strcmp (args[0],
540 "auditors")) 504 "auditors"))
@@ -542,14 +506,14 @@ handle_post_management (const struct TEH_RequestHandler *rh,
542 struct TALER_AuditorPublicKeyP auditor_pub; 506 struct TALER_AuditorPublicKeyP auditor_pub;
543 507
544 if (NULL == args[1]) 508 if (NULL == args[1])
545 return TEH_handler_management_auditors (connection, 509 return TEH_handler_management_auditors (rc->connection,
546 root); 510 root);
547 if ( (NULL == args[1]) || 511 if ( (NULL == args[1]) ||
548 (NULL == args[2]) || 512 (NULL == args[2]) ||
549 (0 != strcmp (args[2], 513 (0 != strcmp (args[2],
550 "disable")) || 514 "disable")) ||
551 (NULL != args[3]) ) 515 (NULL != args[3]) )
552 return r404 (connection, 516 return r404 (rc->connection,
553 "/management/auditors/$AUDITOR_PUB/disable"); 517 "/management/auditors/$AUDITOR_PUB/disable");
554 if (GNUNET_OK != 518 if (GNUNET_OK !=
555 GNUNET_STRINGS_string_to_data (args[1], 519 GNUNET_STRINGS_string_to_data (args[1],
@@ -558,12 +522,12 @@ handle_post_management (const struct TEH_RequestHandler *rh,
558 sizeof (auditor_pub))) 522 sizeof (auditor_pub)))
559 { 523 {
560 GNUNET_break_op (0); 524 GNUNET_break_op (0);
561 return TALER_MHD_reply_with_error (connection, 525 return TALER_MHD_reply_with_error (rc->connection,
562 MHD_HTTP_BAD_REQUEST, 526 MHD_HTTP_BAD_REQUEST,
563 TALER_EC_GENERIC_PARAMETER_MALFORMED, 527 TALER_EC_GENERIC_PARAMETER_MALFORMED,
564 args[1]); 528 args[1]);
565 } 529 }
566 return TEH_handler_management_auditors_AP_disable (connection, 530 return TEH_handler_management_auditors_AP_disable (rc->connection,
567 &auditor_pub, 531 &auditor_pub,
568 root); 532 root);
569 } 533 }
@@ -578,7 +542,7 @@ handle_post_management (const struct TEH_RequestHandler *rh,
578 (0 != strcmp (args[2], 542 (0 != strcmp (args[2],
579 "revoke")) || 543 "revoke")) ||
580 (NULL != args[3]) ) 544 (NULL != args[3]) )
581 return r404 (connection, 545 return r404 (rc->connection,
582 "/management/denominations/$HDP/revoke"); 546 "/management/denominations/$HDP/revoke");
583 if (GNUNET_OK != 547 if (GNUNET_OK !=
584 GNUNET_STRINGS_string_to_data (args[1], 548 GNUNET_STRINGS_string_to_data (args[1],
@@ -587,12 +551,12 @@ handle_post_management (const struct TEH_RequestHandler *rh,
587 sizeof (h_denom_pub))) 551 sizeof (h_denom_pub)))
588 { 552 {
589 GNUNET_break_op (0); 553 GNUNET_break_op (0);
590 return TALER_MHD_reply_with_error (connection, 554 return TALER_MHD_reply_with_error (rc->connection,
591 MHD_HTTP_BAD_REQUEST, 555 MHD_HTTP_BAD_REQUEST,
592 TALER_EC_GENERIC_PARAMETER_MALFORMED, 556 TALER_EC_GENERIC_PARAMETER_MALFORMED,
593 args[1]); 557 args[1]);
594 } 558 }
595 return TEH_handler_management_denominations_HDP_revoke (connection, 559 return TEH_handler_management_denominations_HDP_revoke (rc->connection,
596 &h_denom_pub, 560 &h_denom_pub,
597 root); 561 root);
598 } 562 }
@@ -607,7 +571,7 @@ handle_post_management (const struct TEH_RequestHandler *rh,
607 (0 != strcmp (args[2], 571 (0 != strcmp (args[2],
608 "revoke")) || 572 "revoke")) ||
609 (NULL != args[3]) ) 573 (NULL != args[3]) )
610 return r404 (connection, 574 return r404 (rc->connection,
611 "/management/signkeys/$HDP/revoke"); 575 "/management/signkeys/$HDP/revoke");
612 if (GNUNET_OK != 576 if (GNUNET_OK !=
613 GNUNET_STRINGS_string_to_data (args[1], 577 GNUNET_STRINGS_string_to_data (args[1],
@@ -616,12 +580,12 @@ handle_post_management (const struct TEH_RequestHandler *rh,
616 sizeof (exchange_pub))) 580 sizeof (exchange_pub)))
617 { 581 {
618 GNUNET_break_op (0); 582 GNUNET_break_op (0);
619 return TALER_MHD_reply_with_error (connection, 583 return TALER_MHD_reply_with_error (rc->connection,
620 MHD_HTTP_BAD_REQUEST, 584 MHD_HTTP_BAD_REQUEST,
621 TALER_EC_GENERIC_PARAMETER_MALFORMED, 585 TALER_EC_GENERIC_PARAMETER_MALFORMED,
622 args[1]); 586 args[1]);
623 } 587 }
624 return TEH_handler_management_signkeys_EP_revoke (connection, 588 return TEH_handler_management_signkeys_EP_revoke (rc->connection,
625 &exchange_pub, 589 &exchange_pub,
626 root); 590 root);
627 } 591 }
@@ -631,25 +595,27 @@ handle_post_management (const struct TEH_RequestHandler *rh,
631 if (NULL != args[1]) 595 if (NULL != args[1])
632 { 596 {
633 GNUNET_break_op (0); 597 GNUNET_break_op (0);
634 return r404 (connection, "/management/keys/*"); 598 return r404 (rc->connection,
599 "/management/keys/*");
635 } 600 }
636 return TEH_handler_management_post_keys (connection, 601 return TEH_handler_management_post_keys (rc->connection,
637 root); 602 root);
638 } 603 }
639 if (0 == strcmp (args[0], 604 if (0 == strcmp (args[0],
640 "wire")) 605 "wire"))
641 { 606 {
642 if (NULL == args[1]) 607 if (NULL == args[1])
643 return TEH_handler_management_post_wire (connection, 608 return TEH_handler_management_post_wire (rc->connection,
644 root); 609 root);
645 if ( (0 != strcmp (args[1], 610 if ( (0 != strcmp (args[1],
646 "disable")) || 611 "disable")) ||
647 (NULL != args[2]) ) 612 (NULL != args[2]) )
648 { 613 {
649 GNUNET_break_op (0); 614 GNUNET_break_op (0);
650 return r404 (connection, "/management/wire/disable"); 615 return r404 (rc->connection,
616 "/management/wire/disable");
651 } 617 }
652 return TEH_handler_management_post_wire_disable (connection, 618 return TEH_handler_management_post_wire_disable (rc->connection,
653 root); 619 root);
654 } 620 }
655 if (0 == strcmp (args[0], 621 if (0 == strcmp (args[0],
@@ -658,27 +624,28 @@ handle_post_management (const struct TEH_RequestHandler *rh,
658 if (NULL != args[1]) 624 if (NULL != args[1])
659 { 625 {
660 GNUNET_break_op (0); 626 GNUNET_break_op (0);
661 return r404 (connection, "/management/wire-fee/*"); 627 return r404 (rc->connection,
628 "/management/wire-fee/*");
662 } 629 }
663 return TEH_handler_management_post_wire_fees (connection, 630 return TEH_handler_management_post_wire_fees (rc->connection,
664 root); 631 root);
665 } 632 }
666 GNUNET_break_op (0); 633 GNUNET_break_op (0);
667 return r404 (connection, "/management/*"); 634 return r404 (rc->connection,
635 "/management/*");
668} 636}
669 637
670 638
671/** 639/**
672 * Handle a get "/management" request. 640 * Handle a get "/management" request.
673 * 641 *
674 * @param rh context of the handler 642 * @param rc request context
675 * @param connection the MHD connection to handle 643 * @param connection the MHD connection to handle
676 * @param args array of additional options (must be empty for this function) 644 * @param args array of additional options (must be empty for this function)
677 * @return MHD result code 645 * @return MHD result code
678 */ 646 */
679static MHD_RESULT 647static MHD_RESULT
680handle_get_management (const struct TEH_RequestHandler *rh, 648handle_get_management (struct TEH_RequestContext *rc,
681 struct MHD_Connection *connection,
682 const char *const args[1]) 649 const char *const args[1])
683{ 650{
684 if ( (NULL != args[0]) && 651 if ( (NULL != args[0]) &&
@@ -686,26 +653,25 @@ handle_get_management (const struct TEH_RequestHandler *rh,
686 "keys")) && 653 "keys")) &&
687 (NULL == args[1]) ) 654 (NULL == args[1]) )
688 { 655 {
689 return TEH_keys_management_get_keys_handler (rh, 656 return TEH_keys_management_get_keys_handler (rc->rh,
690 connection); 657 rc->connection);
691 } 658 }
692 GNUNET_break_op (0); 659 GNUNET_break_op (0);
693 return r404 (connection, "/management/*"); 660 return r404 (rc->connection,
661 "/management/*");
694} 662}
695 663
696 664
697/** 665/**
698 * Handle POST "/auditors/..." requests. 666 * Handle POST "/auditors/..." requests.
699 * 667 *
700 * @param rh context of the handler 668 * @param rc request context
701 * @param connection the MHD connection to handle
702 * @param root uploaded JSON data 669 * @param root uploaded JSON data
703 * @param args array of additional options 670 * @param args array of additional options
704 * @return MHD result code 671 * @return MHD result code
705 */ 672 */
706static MHD_RESULT 673static MHD_RESULT
707handle_post_auditors (const struct TEH_RequestHandler *rh, 674handle_post_auditors (struct TEH_RequestContext *rc,
708 struct MHD_Connection *connection,
709 const json_t *root, 675 const json_t *root,
710 const char *const args[]) 676 const char *const args[])
711{ 677{
@@ -717,7 +683,8 @@ handle_post_auditors (const struct TEH_RequestHandler *rh,
717 (NULL != args[2]) ) 683 (NULL != args[2]) )
718 { 684 {
719 GNUNET_break_op (0); 685 GNUNET_break_op (0);
720 return r404 (connection, "/auditors/$AUDITOR_PUB/$H_DENOM_PUB"); 686 return r404 (rc->connection,
687 "/auditors/$AUDITOR_PUB/$H_DENOM_PUB");
721 } 688 }
722 689
723 if (GNUNET_OK != 690 if (GNUNET_OK !=
@@ -727,7 +694,7 @@ handle_post_auditors (const struct TEH_RequestHandler *rh,
727 sizeof (auditor_pub))) 694 sizeof (auditor_pub)))
728 { 695 {
729 GNUNET_break_op (0); 696 GNUNET_break_op (0);
730 return TALER_MHD_reply_with_error (connection, 697 return TALER_MHD_reply_with_error (rc->connection,
731 MHD_HTTP_BAD_REQUEST, 698 MHD_HTTP_BAD_REQUEST,
732 TALER_EC_GENERIC_PARAMETER_MALFORMED, 699 TALER_EC_GENERIC_PARAMETER_MALFORMED,
733 args[0]); 700 args[0]);
@@ -739,12 +706,12 @@ handle_post_auditors (const struct TEH_RequestHandler *rh,
739 sizeof (h_denom_pub))) 706 sizeof (h_denom_pub)))
740 { 707 {
741 GNUNET_break_op (0); 708 GNUNET_break_op (0);
742 return TALER_MHD_reply_with_error (connection, 709 return TALER_MHD_reply_with_error (rc->connection,
743 MHD_HTTP_BAD_REQUEST, 710 MHD_HTTP_BAD_REQUEST,
744 TALER_EC_GENERIC_PARAMETER_MALFORMED, 711 TALER_EC_GENERIC_PARAMETER_MALFORMED,
745 args[1]); 712 args[1]);
746 } 713 }
747 return TEH_handler_auditors (connection, 714 return TEH_handler_auditors (rc->connection,
748 &auditor_pub, 715 &auditor_pub,
749 &h_denom_pub, 716 &h_denom_pub,
750 root); 717 root);
@@ -761,7 +728,7 @@ handle_post_auditors (const struct TEH_RequestHandler *rh,
761 * @param version HTTP version (ignored) 728 * @param version HTTP version (ignored)
762 * @param upload_data request data 729 * @param upload_data request data
763 * @param upload_data_size size of @a upload_data in bytes 730 * @param upload_data_size size of @a upload_data in bytes
764 * @param con_cls closure for request (a `struct Buffer *`) 731 * @param con_cls closure for request (a `struct TEH_RequestContext *`)
765 * @return MHD result code 732 * @return MHD result code
766 */ 733 */
767static MHD_RESULT 734static MHD_RESULT
@@ -907,14 +874,13 @@ handle_mhd_request (void *cls,
907 .url = NULL 874 .url = NULL
908 } 875 }
909 }; 876 };
910 struct ExchangeHttpRequestClosure *ecls = *con_cls; 877 struct TEH_RequestContext *rc = *con_cls;
911 void **inner_cls;
912 struct GNUNET_AsyncScopeSave old_scope; 878 struct GNUNET_AsyncScopeSave old_scope;
913 const char *correlation_id = NULL; 879 const char *correlation_id = NULL;
914 880
915 (void) cls; 881 (void) cls;
916 (void) version; 882 (void) version;
917 if (NULL == ecls) 883 if (NULL == rc)
918 { 884 {
919 unsigned long long cnt; 885 unsigned long long cnt;
920 886
@@ -933,15 +899,17 @@ handle_mhd_request (void *cls,
933 } 899 }
934 900
935 /* We're in a new async scope! */ 901 /* We're in a new async scope! */
936 ecls = *con_cls = GNUNET_new (struct ExchangeHttpRequestClosure); 902 rc = *con_cls = GNUNET_new (struct TEH_RequestContext);
937 GNUNET_async_scope_fresh (&ecls->async_scope_id); 903 GNUNET_async_scope_fresh (&rc->async_scope_id);
938 ecls->url = url; 904 rc->url = url;
905 rc->connection = connection;
939 /* We only read the correlation ID on the first callback for every client */ 906 /* We only read the correlation ID on the first callback for every client */
940 correlation_id = MHD_lookup_connection_value (connection, 907 correlation_id = MHD_lookup_connection_value (connection,
941 MHD_HEADER_KIND, 908 MHD_HEADER_KIND,
942 "Taler-Correlation-Id"); 909 "Taler-Correlation-Id");
943 if ((NULL != correlation_id) && 910 if ( (NULL != correlation_id) &&
944 (GNUNET_YES != GNUNET_CURL_is_valid_scope_id (correlation_id))) 911 (GNUNET_YES !=
912 GNUNET_CURL_is_valid_scope_id (correlation_id)) )
945 { 913 {
946 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 914 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
947 "illegal incoming correlation ID\n"); 915 "illegal incoming correlation ID\n");
@@ -949,8 +917,7 @@ handle_mhd_request (void *cls,
949 } 917 }
950 } 918 }
951 919
952 inner_cls = &ecls->opaque_post_parsing_context; 920 GNUNET_async_scope_enter (&rc->async_scope_id,
953 GNUNET_async_scope_enter (&ecls->async_scope_id,
954 &old_scope); 921 &old_scope);
955 if (NULL != correlation_id) 922 if (NULL != correlation_id)
956 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 923 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -964,7 +931,7 @@ handle_mhd_request (void *cls,
964 method, 931 method,
965 url); 932 url);
966 /* on repeated requests, check our cache first */ 933 /* on repeated requests, check our cache first */
967 if (NULL != ecls->rh) 934 if (NULL != rc->rh)
968 { 935 {
969 MHD_RESULT ret; 936 MHD_RESULT ret;
970 const char *start; 937 const char *start;
@@ -975,10 +942,8 @@ handle_mhd_request (void *cls,
975 start = strchr (url + 1, '/'); 942 start = strchr (url + 1, '/');
976 if (NULL == start) 943 if (NULL == start)
977 start = ""; 944 start = "";
978 ret = proceed_with_handler (ecls->rh, 945 ret = proceed_with_handler (rc,
979 connection,
980 start, 946 start,
981 inner_cls,
982 upload_data, 947 upload_data,
983 upload_data_size); 948 upload_data_size);
984 GNUNET_async_scope_restore (&old_scope); 949 GNUNET_async_scope_restore (&old_scope);
@@ -1039,12 +1004,10 @@ handle_mhd_request (void *cls,
1039 MHD_RESULT ret; 1004 MHD_RESULT ret;
1040 1005
1041 /* cache to avoid the loop next time */ 1006 /* cache to avoid the loop next time */
1042 ecls->rh = rh; 1007 rc->rh = rh;
1043 /* run handler */ 1008 /* run handler */
1044 ret = proceed_with_handler (rh, 1009 ret = proceed_with_handler (rc,
1045 connection,
1046 url + tok_size + 1, 1010 url + tok_size + 1,
1047 inner_cls,
1048 upload_data, 1011 upload_data,
1049 upload_data_size); 1012 upload_data_size);
1050 GNUNET_async_scope_restore (&old_scope); 1013 GNUNET_async_scope_restore (&old_scope);