diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_purses_get.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_get.c | 128 |
1 files changed, 60 insertions, 68 deletions
diff --git a/src/exchange/taler-exchange-httpd_purses_get.c b/src/exchange/taler-exchange-httpd_purses_get.c index e56cfe485..22328fe09 100644 --- a/src/exchange/taler-exchange-httpd_purses_get.c +++ b/src/exchange/taler-exchange-httpd_purses_get.c @@ -57,6 +57,12 @@ struct GetContext struct GNUNET_DB_EventHandler *eh; /** + * Subscription for refund event we are + * waiting for. + */ + struct GNUNET_DB_EventHandler *ehr; + + /** * Public key of our purse. */ struct TALER_PurseContractPublicKeyP purse_pub; @@ -153,6 +159,12 @@ gc_cleanup (struct TEH_RequestContext *rc) gc->eh); gc->eh = NULL; } + if (NULL != gc->ehr) + { + TEH_plugin->event_listen_cancel (TEH_plugin->cls, + gc->ehr); + gc->ehr = NULL; + } GNUNET_free (gc); } @@ -207,6 +219,8 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, const char *const args[2]) { struct GetContext *gc = rc->rh_ctx; + bool purse_deleted; + bool purse_refunded; MHD_RESULT res; if (NULL == gc) @@ -242,36 +256,8 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, args[1]); } - { - const char *long_poll_timeout_ms; - - long_poll_timeout_ms - = MHD_lookup_connection_value (rc->connection, - MHD_GET_ARGUMENT_KIND, - "timeout_ms"); - if (NULL != long_poll_timeout_ms) - { - unsigned int timeout_ms; - char dummy; - struct GNUNET_TIME_Relative timeout; - - if (1 != sscanf (long_poll_timeout_ms, - "%u%c", - &timeout_ms, - &dummy)) - { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "timeout_ms (must be non-negative number)"); - } - timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, - timeout_ms); - gc->timeout = GNUNET_TIME_relative_to_absolute (timeout); - } - } - + TALER_MHD_parse_request_timeout (rc->connection, + &gc->timeout); if ( (GNUNET_TIME_absolute_is_future (gc->timeout)) && (NULL == gc->eh) ) { @@ -298,19 +284,37 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, GNUNET_break (0); gc->timeout = GNUNET_TIME_UNIT_ZERO_ABS; } + else + { + struct GNUNET_DB_EventHeaderP repr = { + .size = htons (sizeof (repr)), + .type = htons (TALER_DBEVENT_EXCHANGE_PURSE_REFUNDED), + }; + + gc->ehr = TEH_plugin->event_listen ( + TEH_plugin->cls, + GNUNET_TIME_absolute_get_remaining (gc->timeout), + &repr, + &db_event_cb, + rc); + } } } /* end first-time initialization */ { enum GNUNET_DB_QueryStatus qs; + struct GNUNET_TIME_Timestamp create_timestamp; qs = TEH_plugin->select_purse (TEH_plugin->cls, &gc->purse_pub, + &create_timestamp, &gc->purse_expiration, &gc->amount, &gc->deposited, &gc->h_contract, - &gc->merge_timestamp); + &gc->merge_timestamp, + &purse_deleted, + &purse_refunded); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -333,43 +337,17 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: break; /* handled below */ } - if (GNUNET_TIME_absolute_cmp (gc->timeout, - >, - gc->purse_expiration.abs_time)) - { - /* Timeout too high, need to replace event handler */ - struct TALER_PurseEventP rep = { - .header.size = htons (sizeof (rep)), - .header.type = htons ( - gc->wait_for_merge - ? TALER_DBEVENT_EXCHANGE_PURSE_MERGED - : TALER_DBEVENT_EXCHANGE_PURSE_DEPOSITED), - .purse_pub = gc->purse_pub - }; - struct GNUNET_DB_EventHandler *eh2; - - gc->timeout = gc->purse_expiration.abs_time; - eh2 = TEH_plugin->event_listen ( - TEH_plugin->cls, - GNUNET_TIME_absolute_get_remaining (gc->timeout), - &rep.header, - &db_event_cb, - rc); - if (NULL == eh2) - { - GNUNET_break (0); - gc->timeout = GNUNET_TIME_UNIT_ZERO_ABS; - } - TEH_plugin->event_listen_cancel (TEH_plugin->cls, - gc->eh); - gc->eh = eh2; - } } - if (GNUNET_TIME_absolute_is_past (gc->purse_expiration.abs_time)) + if (purse_refunded || + purse_deleted) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Purse refunded or deleted\n"); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_GONE, - TALER_EC_EXCHANGE_GENERIC_PURSE_EXPIRED, + purse_deleted + ? TALER_EC_EXCHANGE_GENERIC_PURSE_DELETED + : TALER_EC_EXCHANGE_GENERIC_PURSE_EXPIRED, GNUNET_TIME_timestamp2s ( gc->purse_expiration)); } @@ -406,7 +384,10 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, if (0 < TALER_amount_cmp (&gc->amount, &gc->deposited)) + { + /* amount > deposited: not yet fully paid */ dt = GNUNET_TIME_UNIT_ZERO_TS; + } if (TALER_EC_NONE != (ec = TALER_exchange_online_purse_status_sign ( &TEH_keys_exchange_sign_, @@ -415,10 +396,16 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, &gc->deposited, &exchange_pub, &exchange_sig))) + { res = TALER_MHD_reply_with_ec (rc->connection, ec, NULL); + } else + { + /* Make sure merge_timestamp is omitted if not yet merged */ + if (GNUNET_TIME_absolute_is_never (gc->merge_timestamp.abs_time)) + gc->merge_timestamp = GNUNET_TIME_UNIT_ZERO_TS; res = TALER_MHD_REPLY_JSON_PACK ( rc->connection, MHD_HTTP_OK, @@ -428,11 +415,16 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, &exchange_sig), GNUNET_JSON_pack_data_auto ("exchange_pub", &exchange_pub), - GNUNET_JSON_pack_timestamp ("merge_timestamp", - gc->merge_timestamp), - GNUNET_JSON_pack_timestamp ("deposit_timestamp", - dt) + GNUNET_JSON_pack_timestamp ("purse_expiration", + gc->purse_expiration), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_timestamp ("merge_timestamp", + gc->merge_timestamp)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_timestamp ("deposit_timestamp", + dt)) ); + } } return res; } |