aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-05-04 23:29:08 +0200
committerChristian Grothoff <christian@grothoff.org>2017-05-04 23:29:08 +0200
commit1ea22a37c6b354971452574a89549b8fc8782fde (patch)
treeaac6401e3d75a1199e03db98a761d51254d79572
parent57964b6ae92183b45c08781bab988e1124531f9f (diff)
add /history support to fakebank
-rw-r--r--src/bank-lib/bank_api_admin.c2
-rw-r--r--src/bank-lib/fakebank.c291
-rw-r--r--src/exchange-lib/exchange_api_refresh.c8
3 files changed, 274 insertions, 27 deletions
diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin.c
index 375d2ab55..afafbc26f 100644
--- a/src/bank-lib/bank_api_admin.c
+++ b/src/bank-lib/bank_api_admin.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2015, 2016 GNUnet e.V.
+ Copyright (C) 2015, 2016, 2017 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c
index 88d5c36db..3f067ee89 100644
--- a/src/bank-lib/fakebank.c
+++ b/src/bank-lib/fakebank.c
@@ -22,6 +22,7 @@
#include "platform.h"
#include "taler_fakebank_lib.h"
+#include "taler_bank_service.h"
/**
* Maximum POST request size (for /admin/add/incoming)
@@ -70,6 +71,16 @@ struct Transaction
* Base URL of the exchange.
*/
char *exchange_base_url;
+
+ /**
+ * When did the transaction happen?
+ */
+ struct GNUNET_TIME_Absolute date;
+
+ /**
+ * Number of this transaction.
+ */
+ unsigned long long serial_id;
};
@@ -97,6 +108,11 @@ struct TALER_FAKEBANK_Handle
* Task running HTTP server for the "test" bank.
*/
struct GNUNET_SCHEDULER_Task *mhd_task;
+
+ /**
+ * Number of transactions.
+ */
+ unsigned long long serial_counter;
};
@@ -257,43 +273,28 @@ handle_mhd_completion_callback (void *cls,
/**
- * Handle incoming HTTP request.
+ * Handle incoming HTTP request for /admin/add/incoming.
*
- * @param cls closure for MHD daemon (unused)
+ * @param h the fakebank handle
* @param connection the connection
- * @param url the requested url
- * @param method the method (POST, GET, ...)
- * @param version HTTP version (ignored)
* @param upload_data request data
* @param upload_data_size size of @a upload_data in bytes
* @param con_cls closure for request (a `struct Buffer *`)
* @return MHD result code
*/
static int
-handle_mhd_request (void *cls,
- struct MHD_Connection *connection,
- const char *url,
- const char *method,
- const char *version,
- const char *upload_data,
- size_t *upload_data_size,
- void **con_cls)
+handle_admin_add_incoming (struct TALER_FAKEBANK_Handle *h,
+ struct MHD_Connection *connection,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **con_cls)
{
- struct TALER_FAKEBANK_Handle *h = cls;
enum GNUNET_JSON_PostResult pr;
json_t *json;
struct Transaction *t;
struct MHD_Response *resp;
int ret;
- if (0 != strcasecmp (url,
- "/admin/add/incoming"))
- {
- /* Unexpected URI path, just close the connection. */
- /* we're rather impolite here, but it's a testcase. */
- GNUNET_break_op (0);
- return MHD_NO;
- }
pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
con_cls,
upload_data,
@@ -336,6 +337,9 @@ handle_mhd_request (void *cls,
return MHD_NO;
}
t->exchange_base_url = GNUNET_strdup (base_url);
+ t->serial_id = h->serial_counter++;
+ t->date = GNUNET_TIME_absolute_get ();
+ GNUNET_TIME_round_abs (&t->date);
GNUNET_CONTAINER_DLL_insert (h->transactions_head,
h->transactions_tail,
t);
@@ -356,6 +360,246 @@ handle_mhd_request (void *cls,
/**
+ * Handle incoming HTTP request for /history
+ *
+ * @param h the fakebank handle
+ * @param connection the connection
+ * @return MHD result code
+ */
+static int
+handle_history (struct TALER_FAKEBANK_Handle *h,
+ struct MHD_Connection *connection,
+ void **con_cls)
+{
+ const char *auth;
+ const char *delta;
+ const char *start;
+ const char *dir;
+ const char *acc;
+ unsigned long long account_number;
+ unsigned long long start_number;
+ long long count;
+ enum TALER_BANK_Direction direction;
+ struct Transaction *pos;
+ json_t *history;
+ int ret;
+
+ auth = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "auth");
+ delta = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "delta");
+ dir = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "direction");
+ start = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "start");
+ acc = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "account_number");
+ if ( (NULL == auth) ||
+ (NULL == acc) ||
+ (NULL == delta) )
+ {
+ /* Invalid request, given that this is fakebank we impolitely just
+ kill the connection instead of returning a nice error. */
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ if ( (1 != sscanf (delta,
+ "%lld",
+ &count)) ||
+ (1 != sscanf (acc,
+ "%llu",
+ &account_number)) ||
+ ( (NULL != start) &&
+ (1 != sscanf (start,
+ "%llu",
+ &start_number)) ) ||
+ ( (NULL != dir) &&
+ (0 != strcasecmp (dir,
+ "CREDIT")) &&
+ (0 != strcasecmp (dir,
+ "DEBIT")) ) )
+ {
+ /* Invalid request, given that this is fakebank we impolitely just
+ kill the connection instead of returning a nice error. */
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ if (NULL == dir)
+ direction = TALER_BANK_DIRECTION_BOTH;
+ else if (0 == strcasecmp (dir, "CREDIT"))
+ direction = TALER_BANK_DIRECTION_CREDIT;
+ else
+ direction = TALER_BANK_DIRECTION_DEBIT;
+ if (NULL == start)
+ start_number = (count > 0) ? 0 : UINT64_MAX;
+ if (UINT64_MAX == start_number)
+ {
+ pos = h->transactions_tail;
+ }
+ else
+ {
+ unsigned long long off = 0;
+
+ for (pos = h->transactions_head;
+ off < start_number;
+ off++)
+ {
+ if (NULL == pos)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ pos = pos->next;
+ }
+ GNUNET_assert (pos->serial_id == start_number);
+ }
+ history = json_array ();
+ while ( (NULL != pos) &&
+ (0 != count) )
+ {
+ json_t *trans;
+ char *subject;
+
+ if (! ( ( (account_number == pos->debit_account) &&
+ (0 != (direction & TALER_BANK_DIRECTION_DEBIT)) ) ||
+ ( (account_number == pos->credit_account) &&
+ (0 != (direction & TALER_BANK_DIRECTION_CREDIT) ) ) ) )
+ {
+ if (count > 0)
+ pos = pos->next;
+ if (count < 0)
+ pos = pos->prev;
+ continue;
+ }
+
+ subject = GNUNET_STRINGS_data_to_string_alloc (&pos->wtid,
+ sizeof (pos->wtid));
+ trans = json_pack ("{s:I, s:o, s:o, s:s, s:I, s:s}",
+ "row_id", (json_int_t) pos->serial_id,
+ "date", GNUNET_JSON_from_time_abs (pos->date),
+ "amount", TALER_JSON_from_amount (&pos->amount),
+ "sign", (account_number == pos->debit_account) ? "-" : "+",
+ "counterpart", (json_int_t) ( (account_number == pos->debit_account)
+ ? pos->credit_account
+ : pos->debit_account),
+ "wt_subject", subject);
+ GNUNET_free (subject);
+ json_array_append (history,
+ trans);
+ if (count > 0)
+ {
+ pos = pos->next;
+ count--;
+ }
+ if (count < 0)
+ {
+ pos = pos->prev;
+ count++;
+ }
+ }
+
+ if (0 == json_array_size (history))
+ {
+ struct MHD_Response *resp;
+
+ json_decref (history);
+ resp = MHD_create_response_from_buffer (0,
+ "",
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NO_CONTENT,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+
+ /* Finally build response object */
+ {
+ struct MHD_Response *resp;
+ void *json_str;
+ size_t json_len;
+
+ json_str = json_dumps (history,
+ JSON_INDENT(2));
+ if (NULL == json_str)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ json_len = strlen (json_str);
+ resp = MHD_create_response_from_buffer (json_len,
+ json_str,
+ MHD_RESPMEM_MUST_FREE);
+ if (NULL == resp)
+ {
+ GNUNET_break (0);
+ free (json_str);
+ return MHD_NO;
+ }
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ resp);
+ MHD_destroy_response (resp);
+ }
+ return ret;
+}
+
+
+/**
+ * Handle incoming HTTP request.
+ *
+ * @param cls a `struct TALER_FAKEBANK_Handle`
+ * @param connection the connection
+ * @param url the requested url
+ * @param method the method (POST, GET, ...)
+ * @param version HTTP version (ignored)
+ * @param upload_data request data
+ * @param upload_data_size size of @a upload_data in bytes
+ * @param con_cls closure for request (a `struct Buffer *`)
+ * @return MHD result code
+ */
+static int
+handle_mhd_request (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data,
+ size_t *upload_data_size,
+ void **con_cls)
+{
+ struct TALER_FAKEBANK_Handle *h = cls;
+
+ if ( (0 == strcasecmp (url,
+ "/admin/add/incoming")) &&
+ (0 == strcasecmp (method,
+ MHD_HTTP_METHOD_POST)) )
+ return handle_admin_add_incoming (h,
+ connection,
+ upload_data,
+ upload_data_size,
+ con_cls);
+ if ( (0 == strcasecmp (url,
+ "/history")) &&
+ (0 == strcasecmp (method,
+ MHD_HTTP_METHOD_GET)) )
+ return handle_history (h,
+ connection,
+ con_cls);
+
+ /* Unexpected URI path, just close the connection. */
+ /* we're rather impolite here, but it's a testcase. */
+ GNUNET_break_op (0);
+ return MHD_NO;
+}
+
+
+/**
* Task run whenever HTTP server operations are pending.
*
* @param cls the `struct TALER_FAKEBANK_Handle`
@@ -466,3 +710,6 @@ TALER_FAKEBANK_start (uint16_t port)
schedule_httpd (h);
return h;
}
+
+
+/* end of fakebank.c */
diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c
index c3216a6e6..08f5e2d85 100644
--- a/src/exchange-lib/exchange_api_refresh.c
+++ b/src/exchange-lib/exchange_api_refresh.c
@@ -1753,10 +1753,10 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
strlen (rrh->json_enc)));
ctx = MAH_handle_to_context (rrh->exchange);
rrh->job = GNUNET_CURL_job_add (ctx,
- eh,
- GNUNET_YES,
- &handle_refresh_reveal_finished,
- rrh);
+ eh,
+ GNUNET_YES,
+ &handle_refresh_reveal_finished,
+ rrh);
return rrh;
}