twister

HTTP fault injector for testing
Log | Files | Refs | README | LICENSE

commit 06921d9608c9c9f41011858659206bd952d8959d
parent 7bf67d2022d6acadbf5beda3d030ccfb4d2238be
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Wed,  7 Mar 2018 16:14:59 +0100

conditional delete.

objects are only deleted if their path is found
within a response.  If not, the twister will just
echo back what it got from the proxied service.

This way, it is possible to batch a object deletion
X connections before the one we are interested in.
This is particularly needed because some merchant API
functions perform *multiple* requests to the exchange
before actually returning any data.

So test cases can batch a deletion command, and just
"wait" for the right response (from the exchange) to
tamper with.

Diffstat:
Msrc/twister/taler-twister-service.c | 92+++++++++++++++++++++++++++----------------------------------------------------
1 file changed, 31 insertions(+), 61 deletions(-)

diff --git a/src/twister/taler-twister-service.c b/src/twister/taler-twister-service.c @@ -802,33 +802,6 @@ con_val_iter (void *cls, return MHD_YES; } -/** - * Create and queue response. - * - * @param body nul-terminated string to use as response body - * @param http_status HTTP status code to return to the client - * - * @return MHD_YES / MHD_NO, depending on what the internal - * call to MHD_queue_response returns. - */ -static unsigned int -create_and_queue_response (struct MHD_Connection *connection, - char *body, - unsigned int http_status) -{ - struct MHD_Response *response; - - response = MHD_create_response_from_buffer - (strlen (body), - body, - MHD_RESPMEM_MUST_COPY); - - return MHD_queue_response (connection, - http_status, - response); - -} - /** * Main MHD callback for handling requests. @@ -1101,6 +1074,9 @@ create_response (void *cls, hack_response_code = 0; /* reset for next request */ } + /* Empty the object pointed by `delete_path` only if + it is found within this response, otherwise it leaves + the response untouched. */ if ('\0' != delete_path[0]) { json_t *parsed_response; @@ -1120,16 +1096,14 @@ create_response (void *cls, if (NULL == (parsed_response = json_loadb (hr->io_buf, hr->io_len, JSON_DECODE_ANY, &error))) { - TALER_LOG_ERROR ("Could not parse response\n"); - delete_path[0] = '\0'; - return create_and_queue_response - (con, - "{\"error\": \"could not parse response\"}", - MHD_HTTP_GONE); // need a http code unknown to Taler. + TALER_LOG_WARNING ("Could not parse response\n"); + return MHD_queue_response (con, + hr->response_code, + hr->response); } /* Give first nondelim char. */ - token_path = strtok (delete_path, "."); + token_path = strtok (GNUNET_strdup (delete_path), "."); element = parsed_response; do { @@ -1162,13 +1136,12 @@ create_response (void *cls, continue; } - TALER_LOG_ERROR ("Path token '%s' not found\n", - token_path); + TALER_LOG_WARNING ("Path token '%s' not found\n", + token_path); - return create_and_queue_response - (con, - "{\"error\": \"path token not found\"}", - MHD_HTTP_GONE); + return MHD_queue_response (con, + hr->response_code, + hr->response); } while (NULL != (token_path = strtok (NULL, "."))); @@ -1176,31 +1149,28 @@ create_response (void *cls, if (-1 == json_object_clear (element)) { TALER_LOG_ERROR ("Could not empty the object\n"); - delete_path[0] = '\0'; json_decref (parsed_response); - return create_and_queue_response - (con, - "{\"error\": \"Could not empty the object\"}", - MHD_HTTP_GONE); - } - else - { - TALER_LOG_WARNING ("Emptying object..\n"); - mod_response = json_dumps (parsed_response, JSON_COMPACT); + return MHD_queue_response (con, + hr->response_code, + hr->response); } + TALER_LOG_INFO ("Emptying object..\n"); + mod_response = json_dumps (parsed_response, JSON_COMPACT); + json_decref (parsed_response); - hr->response = MHD_create_response_from_buffer - (strlen (mod_response), - mod_response, - MHD_RESPMEM_MUST_COPY); - - /* reset for next request*/ - delete_path[0] = '\0'; - json_decref (parsed_response); - return create_and_queue_response (con, - mod_response, - hr->response_code); + + /* We only reset once a empty-able object has + been found. This way, it is possible to call this + API way in advance respect to the response which + is to be transformed. */ + delete_path[0] = '\0'; + json_decref (parsed_response); + return MHD_queue_response + (con, hr->response_code, + MHD_create_response_from_buffer (strlen (mod_response), + mod_response, + MHD_RESPMEM_MUST_COPY)); } /* Response is untouched. */ return MHD_queue_response (con,