summaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_purses_get.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd_purses_get.c')
-rw-r--r--src/exchange/taler-exchange-httpd_purses_get.c128
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;
}