ensure forward-compatibility for auditor C API

This commit is contained in:
Christian Grothoff 2023-06-21 07:53:17 +02:00
parent d6838ed841
commit 17789253e9
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
10 changed files with 200 additions and 138 deletions

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2021 Taler Systems SA Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software
@ -146,21 +146,54 @@ struct TALER_AUDITOR_HttpResponse
}; };
/**
* Response to /version request.
*/
struct TALER_AUDITOR_VersionResponse
{
/**
* HTTP response.
*/
struct TALER_AUDITOR_HttpResponse hr;
/**
* Details depending on HTTP status.
*/
union
{
/**
* Details for #MHD_HTTP_OK.
*/
struct
{
/**
* Protocol compatibility evaluation.
*/
enum TALER_AUDITOR_VersionCompatibility compat;
/**
* Version data returned by /config.
*/
struct TALER_AUDITOR_VersionInformation vi;
} ok;
} details;
};
/** /**
* Function called with information about the auditor. * Function called with information about the auditor.
* *
* @param cls closure * @param cls closure
* @param hr HTTP response data * @param vr response data
* @param vi basic information about the auditor
* @param compat protocol compatibility information
*/ */
// FIXME: bad API!
typedef void typedef void
(*TALER_AUDITOR_VersionCallback) ( (*TALER_AUDITOR_VersionCallback) (
void *cls, void *cls,
const struct TALER_AUDITOR_HttpResponse *hr, const struct TALER_AUDITOR_VersionResponse *vr);
const struct TALER_AUDITOR_VersionInformation *vi,
enum TALER_AUDITOR_VersionCompatibility compat);
/** /**
@ -206,17 +239,29 @@ TALER_AUDITOR_disconnect (struct TALER_AUDITOR_Handle *auditor);
struct TALER_AUDITOR_DepositConfirmationHandle; struct TALER_AUDITOR_DepositConfirmationHandle;
/**
* Response to /deposit-confirmation request.
*/
struct TALER_AUDITOR_DepositConfirmationResponse
{
/**
* HTTP response.
*/
struct TALER_AUDITOR_HttpResponse hr;
};
/** /**
* Signature of functions called with the result from our call to the * Signature of functions called with the result from our call to the
* auditor's /deposit-confirmation handler. * auditor's /deposit-confirmation handler.
* *
* @param cls closure * @param cls closure
* @param hr HTTP response data * @param dcr response data
*/ */
typedef void typedef void
(*TALER_AUDITOR_DepositConfirmationResultCallback)( (*TALER_AUDITOR_DepositConfirmationResultCallback)(
void *cls, void *cls,
const struct TALER_AUDITOR_HttpResponse *hr); const struct TALER_AUDITOR_DepositConfirmationResponse *dcr);
/** /**
@ -313,20 +358,54 @@ struct TALER_AUDITOR_ExchangeInfo
}; };
/**
* Response to GET /exchanges request.
*/
struct TALER_AUDITOR_ListExchangesResponse
{
/**
* HTTP response.
*/
struct TALER_AUDITOR_HttpResponse hr;
/**
* Details depending on HTTP status.
*/
union
{
/**
* Details for #MHD_HTTP_OK.
*/
struct
{
/**
* Length of the @e ei array.
*/
unsigned int num_exchanges;
/**
* Array with information about exchanges
* audited by this auditor.
*/
const struct TALER_AUDITOR_ExchangeInfo *ei;
} ok;
} details;
};
/** /**
* Function called with the result from /exchanges. * Function called with the result from /exchanges.
* *
* @param cls closure * @param cls closure
* @param hr HTTP response data * @param ler response data
* @param num_exchanges length of array at @a ei
* @param ei information about exchanges returned by the auditor
*/ */
typedef void typedef void
(*TALER_AUDITOR_ListExchangesResultCallback)( (*TALER_AUDITOR_ListExchangesResultCallback)(
void *cls, void *cls,
const struct TALER_AUDITOR_HttpResponse *hr, const struct TALER_AUDITOR_ListExchangesResponse *ler);
unsigned int num_exchanges,
const struct TALER_AUDITOR_ExchangeInfo *ei);
/** /**
* Submit an /exchanges request to the auditor and get the * Submit an /exchanges request to the auditor and get the

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2021 Taler Systems SA Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the 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 terms of the GNU General Public License as published by the Free Software
@ -87,64 +87,64 @@ handle_deposit_confirmation_finished (void *cls,
{ {
const json_t *json = djson; const json_t *json = djson;
struct TALER_AUDITOR_DepositConfirmationHandle *dh = cls; struct TALER_AUDITOR_DepositConfirmationHandle *dh = cls;
struct TALER_AUDITOR_HttpResponse hr = { struct TALER_AUDITOR_DepositConfirmationResponse dcr = {
.reply = json, .hr.reply = json,
.http_status = (unsigned int) response_code .hr.http_status = (unsigned int) response_code
}; };
dh->job = NULL; dh->job = NULL;
switch (response_code) switch (response_code)
{ {
case 0: case 0:
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; dcr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break; break;
case MHD_HTTP_OK: case MHD_HTTP_OK:
hr.ec = TALER_EC_NONE; dcr.hr.ec = TALER_EC_NONE;
break; break;
case MHD_HTTP_BAD_REQUEST: case MHD_HTTP_BAD_REQUEST:
hr.ec = TALER_JSON_get_error_code (json); dcr.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); dcr.hr.hint = TALER_JSON_get_error_hint (json);
/* This should never happen, either us or the auditor is buggy /* This should never happen, either us or the auditor is buggy
(or API version conflict); just pass JSON reply to the application */ (or API version conflict); just pass JSON reply to the application */
break; break;
case MHD_HTTP_FORBIDDEN: case MHD_HTTP_FORBIDDEN:
hr.ec = TALER_JSON_get_error_code (json); dcr.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); dcr.hr.hint = TALER_JSON_get_error_hint (json);
/* Nothing really to verify, auditor says one of the signatures is /* Nothing really to verify, auditor says one of the signatures is
invalid; as we checked them, this should never happen, we invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */ should pass the JSON reply to the application */
break; break;
case MHD_HTTP_NOT_FOUND: case MHD_HTTP_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (json); dcr.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); dcr.hr.hint = TALER_JSON_get_error_hint (json);
/* Nothing really to verify, this should never /* Nothing really to verify, this should never
happen, we should pass the JSON reply to the application */ happen, we should pass the JSON reply to the application */
break; break;
case MHD_HTTP_GONE: case MHD_HTTP_GONE:
hr.ec = TALER_JSON_get_error_code (json); dcr.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); dcr.hr.hint = TALER_JSON_get_error_hint (json);
/* Nothing really to verify, auditor says one of the signatures is /* Nothing really to verify, auditor says one of the signatures is
invalid; as we checked them, this should never happen, we invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */ should pass the JSON reply to the application */
break; break;
case MHD_HTTP_INTERNAL_SERVER_ERROR: case MHD_HTTP_INTERNAL_SERVER_ERROR:
hr.ec = TALER_JSON_get_error_code (json); dcr.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); dcr.hr.hint = TALER_JSON_get_error_hint (json);
/* Server had an internal issue; we should retry, but this API /* Server had an internal issue; we should retry, but this API
leaves this to the application */ leaves this to the application */
break; break;
default: default:
/* unexpected response code */ /* unexpected response code */
hr.ec = TALER_JSON_get_error_code (json); dcr.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); dcr.hr.hint = TALER_JSON_get_error_hint (json);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d for auditor deposit confirmation\n", "Unexpected response code %u/%d for auditor deposit confirmation\n",
(unsigned int) response_code, (unsigned int) response_code,
hr.ec); dcr.hr.ec);
break; break;
} }
dh->cb (dh->cb_cls, dh->cb (dh->cb_cls,
&hr); &dcr);
TALER_AUDITOR_deposit_confirmation_cancel (dh); TALER_AUDITOR_deposit_confirmation_cancel (dh);
} }

View File

@ -89,16 +89,16 @@ handle_exchanges_finished (void *cls,
const json_t *ja; const json_t *ja;
unsigned int ja_len; unsigned int ja_len;
struct TALER_AUDITOR_ListExchangesHandle *leh = cls; struct TALER_AUDITOR_ListExchangesHandle *leh = cls;
struct TALER_AUDITOR_HttpResponse hr = { struct TALER_AUDITOR_ListExchangesResponse ler = {
.reply = json, .hr.reply = json,
.http_status = (unsigned int) response_code .hr.http_status = (unsigned int) response_code
}; };
leh->job = NULL; leh->job = NULL;
switch (response_code) switch (response_code)
{ {
case 0: case 0:
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; ler.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break; break;
case MHD_HTTP_OK: case MHD_HTTP_OK:
ja = json_object_get (json, ja = json_object_get (json,
@ -107,8 +107,8 @@ handle_exchanges_finished (void *cls,
(! json_is_array (ja)) ) (! json_is_array (ja)) )
{ {
GNUNET_break (0); GNUNET_break (0);
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
hr.http_status = 0; ler.hr.http_status = 0;
break; break;
} }
@ -116,12 +116,12 @@ handle_exchanges_finished (void *cls,
if (ja_len > MAX_EXCHANGES) if (ja_len > MAX_EXCHANGES)
{ {
GNUNET_break (0); GNUNET_break (0);
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
hr.http_status = 0; ler.hr.http_status = 0;
break; break;
} }
{ {
struct TALER_AUDITOR_ExchangeInfo ei[ja_len]; struct TALER_AUDITOR_ExchangeInfo ei[GNUNET_NZL (ja_len)];
bool ok; bool ok;
ok = true; ok = true;
@ -141,54 +141,52 @@ handle_exchanges_finished (void *cls,
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
ok = false; ok = false;
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
hr.http_status = 0; ler.hr.http_status = 0;
break; break;
} }
} }
if (! ok) if (! ok)
break; break;
ler.details.ok.ei = ei;
ler.details.ok.num_exchanges = ja_len;
leh->cb (leh->cb_cls, leh->cb (leh->cb_cls,
&hr, &ler);
ja_len,
ei);
TALER_AUDITOR_list_exchanges_cancel (leh); TALER_AUDITOR_list_exchanges_cancel (leh);
return; return;
} }
case MHD_HTTP_BAD_REQUEST: case MHD_HTTP_BAD_REQUEST:
/* This should never happen, either us or the auditor is buggy /* This should never happen, either us or the auditor is buggy
(or API version conflict); just pass JSON reply to the application */ (or API version conflict); just pass JSON reply to the application */
hr.ec = TALER_JSON_get_error_code (json); ler.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); ler.hr.hint = TALER_JSON_get_error_hint (json);
break; break;
case MHD_HTTP_NOT_FOUND: case MHD_HTTP_NOT_FOUND:
/* Nothing really to verify, this should never /* Nothing really to verify, this should never
happen, we should pass the JSON reply to the application */ happen, we should pass the JSON reply to the application */
hr.ec = TALER_JSON_get_error_code (json); ler.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); ler.hr.hint = TALER_JSON_get_error_hint (json);
break; break;
case MHD_HTTP_INTERNAL_SERVER_ERROR: case MHD_HTTP_INTERNAL_SERVER_ERROR:
/* Server had an internal issue; we should retry, but this API /* Server had an internal issue; we should retry, but this API
leaves this to the application */ leaves this to the application */
hr.ec = TALER_JSON_get_error_code (json); ler.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); ler.hr.hint = TALER_JSON_get_error_hint (json);
break; break;
default: default:
/* unexpected response code */ /* unexpected response code */
hr.ec = TALER_JSON_get_error_code (json); ler.hr.ec = TALER_JSON_get_error_code (json);
hr.hint = TALER_JSON_get_error_hint (json); ler.hr.hint = TALER_JSON_get_error_hint (json);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d for auditor list-exchanges request\n", "Unexpected response code %u/%d for auditor list-exchanges request\n",
(unsigned int) response_code, (unsigned int) response_code,
(int) hr.ec); (int) ler.hr.ec);
GNUNET_break_op (0); GNUNET_break_op (0);
break; break;
} }
if (NULL != leh->cb) if (NULL != leh->cb)
leh->cb (leh->cb_cls, leh->cb (leh->cb_cls,
&hr, &ler);
0,
NULL);
TALER_AUDITOR_list_exchanges_cancel (leh); TALER_AUDITOR_list_exchanges_cancel (leh);
} }

View File

@ -239,10 +239,9 @@ version_completed_cb (void *cls,
{ {
struct TALER_AUDITOR_Handle *auditor = cls; struct TALER_AUDITOR_Handle *auditor = cls;
const json_t *resp_obj = gresp_obj; const json_t *resp_obj = gresp_obj;
enum TALER_AUDITOR_VersionCompatibility vc; struct TALER_AUDITOR_VersionResponse vr = {
struct TALER_AUDITOR_HttpResponse hr = { .hr.reply = resp_obj,
.reply = resp_obj, .hr.http_status = (unsigned int) response_code
.http_status = (unsigned int) response_code
}; };
auditor->vr = NULL; auditor->vr = NULL;
@ -250,7 +249,6 @@ version_completed_cb (void *cls,
"Received version from URL `%s' with status %ld.\n", "Received version from URL `%s' with status %ld.\n",
auditor->url, auditor->url,
response_code); response_code);
vc = TALER_AUDITOR_VC_PROTOCOL_ERROR;
switch (response_code) switch (response_code)
{ {
case 0: case 0:
@ -268,28 +266,33 @@ version_completed_cb (void *cls,
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
TALER_LOG_WARNING ("NULL body for a 200-OK /config\n"); TALER_LOG_WARNING ("NULL body for a 200-OK /config\n");
hr.http_status = 0; vr.hr.http_status = 0;
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; vr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break; break;
} }
hr.ec = decode_version_json (resp_obj, vr.hr.ec = decode_version_json (resp_obj,
auditor, auditor,
&vc); &vr.details.ok.compat);
if (TALER_EC_NONE != hr.ec) if (TALER_EC_NONE != vr.hr.ec)
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
hr.http_status = 0; vr.hr.http_status = 0;
break; break;
} }
auditor->state = MHS_VERSION;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Auditor %s is ready!\n",
auditor->url);
vr.details.ok.vi = auditor->vi;
auditor->retry_delay = GNUNET_TIME_UNIT_ZERO; /* restart quickly */ auditor->retry_delay = GNUNET_TIME_UNIT_ZERO; /* restart quickly */
break; break;
default: default:
hr.ec = TALER_JSON_get_error_code (resp_obj); vr.hr.ec = TALER_JSON_get_error_code (resp_obj);
hr.hint = TALER_JSON_get_error_hint (resp_obj); vr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d\n", "Unexpected response code %u/%d\n",
(unsigned int) response_code, (unsigned int) response_code,
(int) hr.ec); (int) vr.hr.ec);
break; break;
} }
if (MHD_HTTP_OK != response_code) if (MHD_HTTP_OK != response_code)
@ -299,23 +302,9 @@ version_completed_cb (void *cls,
auditor->url, auditor->url,
(unsigned int) response_code); (unsigned int) response_code);
auditor->state = MHS_FAILED; auditor->state = MHS_FAILED;
/* notify application that we failed */
auditor->version_cb (auditor->version_cb_cls,
&hr,
NULL,
vc);
return;
} }
TALER_LOG_DEBUG ("Switching auditor state to 'version'\n");
auditor->state = MHS_VERSION;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Auditor %s is ready!\n",
auditor->url);
/* notify application about the key information */
auditor->version_cb (auditor->version_cb_cls, auditor->version_cb (auditor->version_cb_cls,
&hr, &vr);
&auditor->vi,
vc);
} }

View File

@ -168,19 +168,20 @@ struct KeysRequest
void void
TEAH_acc_confirmation_cb (void *cls, TEAH_acc_confirmation_cb (
const struct TALER_AUDITOR_HttpResponse *hr) void *cls,
const struct TALER_AUDITOR_DepositConfirmationResponse *dcr)
{ {
struct TEAH_AuditorInteractionEntry *aie = cls; struct TEAH_AuditorInteractionEntry *aie = cls;
struct TEAH_AuditorListEntry *ale = aie->ale; struct TEAH_AuditorListEntry *ale = aie->ale;
if (MHD_HTTP_OK != hr->http_status) if (MHD_HTTP_OK != dcr->hr.http_status)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to submit deposit confirmation to auditor `%s' with HTTP status %d (EC: %d). This is acceptable if it does not happen often.\n", "Failed to submit deposit confirmation to auditor `%s' with HTTP status %d (EC: %d). This is acceptable if it does not happen often.\n",
ale->auditor_url, ale->auditor_url,
hr->http_status, dcr->hr.http_status,
hr->ec); dcr->hr.ec);
} }
GNUNET_CONTAINER_DLL_remove (ale->ai_head, GNUNET_CONTAINER_DLL_remove (ale->ai_head,
ale->ai_tail, ale->ai_tail,
@ -579,21 +580,17 @@ parse_global_fee (struct TALER_EXCHANGE_GlobalFee *gf,
* auditor as 'up'. * auditor as 'up'.
* *
* @param cls closure, a `struct TEAH_AuditorListEntry *` * @param cls closure, a `struct TEAH_AuditorListEntry *`
* @param hr http response from the auditor * @param vr response from the auditor
* @param vi basic information about the auditor
* @param compat protocol compatibility information
*/ */
static void static void
auditor_version_cb ( auditor_version_cb (
void *cls, void *cls,
const struct TALER_AUDITOR_HttpResponse *hr, const struct TALER_AUDITOR_VersionResponse *vr)
const struct TALER_AUDITOR_VersionInformation *vi,
enum TALER_AUDITOR_VersionCompatibility compat)
{ {
struct TEAH_AuditorListEntry *ale = cls; struct TEAH_AuditorListEntry *ale = cls;
enum TALER_AUDITOR_VersionCompatibility compat;
(void) hr; if (MHD_HTTP_OK != vr->hr.http_status)
if (NULL == vi)
{ {
/* In this case, we don't mark the auditor as 'up' */ /* In this case, we don't mark the auditor as 'up' */
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@ -601,7 +598,7 @@ auditor_version_cb (
ale->auditor_url); ale->auditor_url);
return; return;
} }
compat = vr->details.ok.compat;
if (0 != (TALER_AUDITOR_VC_INCOMPATIBLE & compat)) if (0 != (TALER_AUDITOR_VC_INCOMPATIBLE & compat))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,

View File

@ -193,11 +193,12 @@ typedef struct TEAH_AuditorInteractionEntry *
* auditor's /deposit-confirmation handler. * auditor's /deposit-confirmation handler.
* *
* @param cls closure of type `struct TEAH_AuditorInteractionEntry *` * @param cls closure of type `struct TEAH_AuditorInteractionEntry *`
* @param hr HTTP response * @param dcr response
*/ */
void void
TEAH_acc_confirmation_cb (void *cls, TEAH_acc_confirmation_cb (
const struct TALER_AUDITOR_HttpResponse *hr); void *cls,
const struct TALER_AUDITOR_DepositConfirmationResponse *dcr);
/** /**

View File

@ -82,20 +82,15 @@ do_timeout (void *cls)
* Function called with information about the auditor. * Function called with information about the auditor.
* *
* @param cls closure * @param cls closure
* @param hr http response details * @param vr response details
* @param vi basic information about the auditor
* @param compat protocol compatibility information
*/ */
static void static void
version_cb (void *cls, version_cb (void *cls,
const struct TALER_AUDITOR_HttpResponse *hr, const struct TALER_AUDITOR_VersionResponse *vr)
const struct TALER_AUDITOR_VersionInformation *vi,
enum TALER_AUDITOR_VersionCompatibility compat)
{ {
(void) cls; (void) cls;
(void) hr; if ( (MHD_HTTP_OK == vr->hr.http_status) &&
if ( (NULL != vi) && (TALER_AUDITOR_VC_MATCH == vr->details.ok.compat) )
(TALER_AUDITOR_VC_MATCH == compat) )
global_ret = 0; global_ret = 0;
else else
global_ret = 2; global_ret = 2;

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2018, 2021 Taler Systems SA Copyright (C) 2018-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it TALER is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
@ -132,13 +132,15 @@ do_retry (void *cls)
* to check if the response code is acceptable. * to check if the response code is acceptable.
* *
* @param cls closure. * @param cls closure.
* @param hr HTTP response details * @param dcr response details
*/ */
static void static void
deposit_confirmation_cb (void *cls, deposit_confirmation_cb (
const struct TALER_AUDITOR_HttpResponse *hr) void *cls,
const struct TALER_AUDITOR_DepositConfirmationResponse *dcr)
{ {
struct DepositConfirmationState *dcs = cls; struct DepositConfirmationState *dcs = cls;
const struct TALER_AUDITOR_HttpResponse *hr = &dcr->hr;
dcs->dc = NULL; dcs->dc = NULL;
if (dcs->expected_response_code != hr->http_status) if (dcs->expected_response_code != hr->http_status)

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2018 Taler Systems SA Copyright (C) 2018-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it TALER is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
@ -127,11 +127,10 @@ do_retry (void *cls)
*/ */
static void static void
exchanges_cb (void *cls, exchanges_cb (void *cls,
const struct TALER_AUDITOR_HttpResponse *hr, const struct TALER_AUDITOR_ListExchangesResponse *ler)
unsigned int num_exchanges,
const struct TALER_AUDITOR_ExchangeInfo *ei)
{ {
struct ExchangesState *es = cls; struct ExchangesState *es = cls;
const struct TALER_AUDITOR_HttpResponse *hr = &ler->hr;
es->leh = NULL; es->leh = NULL;
if (es->expected_response_code != hr->http_status) if (es->expected_response_code != hr->http_status)
@ -164,24 +163,30 @@ exchanges_cb (void *cls,
hr->http_status); hr->http_status);
return; return;
} }
if (MHD_HTTP_OK != hr->http_status)
{
TALER_TESTING_interpreter_next (es->is);
return;
}
if (NULL != es->exchange_url) if (NULL != es->exchange_url)
{ {
unsigned int found = GNUNET_NO; bool found = false;
unsigned int num_exchanges = ler->details.ok.num_exchanges;
const struct TALER_AUDITOR_ExchangeInfo *ei = ler->details.ok.ei;
for (unsigned int i = 0; for (unsigned int i = 0;
i<num_exchanges; i<num_exchanges;
i++) i++)
if (0 == strcmp (es->exchange_url, if (0 == strcmp (es->exchange_url,
ei[i].exchange_url)) ei[i].exchange_url))
found = GNUNET_YES; found = true;
if (GNUNET_NO == found) if (! found)
{ {
TALER_LOG_ERROR ("Exchange '%s' doesn't exist at this auditor\n", TALER_LOG_ERROR ("Exchange '%s' doesn't exist at this auditor\n",
es->exchange_url); es->exchange_url);
TALER_TESTING_interpreter_fail (es->is); TALER_TESTING_interpreter_fail (es->is);
return; return;
} }
TALER_LOG_DEBUG ("Exchange '%s' exists at this auditor!\n", TALER_LOG_DEBUG ("Exchange '%s' exists at this auditor!\n",
es->exchange_url); es->exchange_url);
} }

View File

@ -70,23 +70,19 @@ struct GetAuditorState
* Function called with information about the auditor. * Function called with information about the auditor.
* *
* @param cls closure * @param cls closure
* @param hr HTTP response data * @param vr response data
* @param vi basic information about the auditor
* @param compat protocol compatibility information
*/ */
static void static void
version_cb ( version_cb (
void *cls, void *cls,
const struct TALER_AUDITOR_HttpResponse *hr, const struct TALER_AUDITOR_VersionResponse *vr)
const struct TALER_AUDITOR_VersionInformation *vi,
enum TALER_AUDITOR_VersionCompatibility compat)
{ {
struct GetAuditorState *gas = cls; struct GetAuditorState *gas = cls;
if (MHD_HTTP_OK != hr->http_status) if (MHD_HTTP_OK != vr->hr.http_status)
{ {
TALER_TESTING_unexpected_status (gas->is, TALER_TESTING_unexpected_status (gas->is,
hr->http_status); vr->hr.http_status);
return; return;
} }
TALER_TESTING_interpreter_next (gas->is); TALER_TESTING_interpreter_next (gas->is);