twister

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

commit 7aed390c8b79f338a70ce015e54229983bbf06fc
parent b6b7f4616e7c933b3ed4520c64e8d281fb17f8d7
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Thu,  8 Mar 2018 16:59:17 +0100

moving object-killer into helper function.

Diffstat:
Msrc/test/test_twister.sh | 4++--
Msrc/twister/taler-twister-service.c | 208+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
2 files changed, 120 insertions(+), 92 deletions(-)

diff --git a/src/test/test_twister.sh b/src/test/test_twister.sh @@ -33,9 +33,9 @@ if ! test 202 = $status_code; then fi # check response body has been emptied -if ! test '{"hello":[{}]}' = $emptied_body; then +if ! test '{"hello":[]}' = "$emptied_body"; then printf "Response body (%s) has not been emptied as expected\n" \ - $emptied_body + "$emptied_body" exit 1 fi diff --git a/src/twister/taler-twister-service.c b/src/twister/taler-twister-service.c @@ -809,6 +809,123 @@ con_val_iter (void *cls, /** + * Delete object within the proxied response. + * Always queues a response + * + * @return MHD_YES / MHD_NO depending on successful / failing + * response queueing. + */ +static unsigned int +delete_object (struct MHD_Connection *con, + struct HttpRequest *hr) +{ + json_t *parsed_response; + json_t *element; + json_t *cur; + json_error_t error; + char *delete_path_dup; + char *token; + char *last_token; + char *mod_body; + unsigned int index; + + if (NULL == (parsed_response = json_loadb + (hr->io_buf, hr->io_len, JSON_DECODE_ANY, &error))) + { + TALER_LOG_WARNING ("Could not parse response\n"); + return MHD_queue_response (con, + hr->response_code, + hr->response); + } + + /* unstable if not dup'd. XXX: to be tested again without. + * To be freed. */ + delete_path_dup = GNUNET_strdup (delete_path); + /* Give first nondelim char. */ + last_token = strrchr (delete_path_dup, '.') + 1; + TALER_LOG_DEBUG ("Last token: %s@%p\n", + last_token, + last_token); + token = strtok (delete_path_dup, "."); + element = parsed_response; + do + { + /* user gave path == "."; returning the body untouched. + * another option is to return an empty body. */ + if (NULL == token) + { + TALER_LOG_WARNING ("Whole body won't be deleted\n"); + json_decref (parsed_response); + return MHD_queue_response (con, + hr->response_code, + hr->response); + } + if (NULL != (cur = json_object_get (element, + token))) + { + element = cur; + continue; + } + index = (unsigned int) strtoul (token, + NULL, + 10); + if (NULL != (cur = json_array_get (element, + index))) + { + element = cur; + continue; + } + TALER_LOG_WARNING ("Path token '%s' not found\n", + token); + return MHD_queue_response (con, + hr->response_code, + hr->response); + } + while (last_token != (token = strtok (NULL, "."))); + + /* here, element is the parent of the element to be deleted. */ + int ret_deletion = -1; + + if (json_is_object (element)) + ret_deletion = json_object_del (element, last_token); + if (json_is_array (element)) + { + index = (unsigned int) strtoul (token, + NULL, + 10); + ret_deletion = json_array_remove (element, index); + } + if (-1 == ret_deletion) + { + TALER_LOG_WARNING ("Could not delete '%s'\n", last_token); + json_decref (parsed_response); + return MHD_queue_response (con, + hr->response_code, + hr->response); + } + mod_body = json_dumps (parsed_response, JSON_COMPACT); + hr->mod_response = MHD_create_response_from_buffer + (strlen (mod_body), + mod_body, + MHD_RESPMEM_MUST_COPY); + json_decref (parsed_response); + delete_path[0] = '\0'; + + struct HttpResponseHeader *header; + for (header = hr->header_head; + NULL != header; + header = header->next) + GNUNET_break + (MHD_YES == MHD_add_response_header (hr->mod_response, + header->type, + header->value)); + return MHD_queue_response (con, + hr->response_code, + hr->mod_response); +} + + +/** * Main MHD callback for handling requests. * * @param cls unused @@ -1082,96 +1199,7 @@ create_response (void *cls, the response untouched. */ if ('\0' != delete_path[0]) { - json_t *parsed_response; - json_t *element; - json_t *cur; - json_error_t error; - char *token_path; - char *mod_body; - unsigned int index; - - if (NULL == (parsed_response = json_loadb - (hr->io_buf, hr->io_len, JSON_DECODE_ANY, &error))) - { - 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 (GNUNET_strdup (delete_path), "."); - element = parsed_response; - do - { - TALER_LOG_DEBUG ("Iterating over token: %s\n", - token_path); - - /* The root object will be emptied. */ - if (NULL == token_path) - break; - - /* For simplicity, we don't check if the token is - a number or not, and react accordingly. We lazily - try to get the element until something is found or - not. */ - if (NULL != (cur = json_object_get (element, - token_path))) - { - element = cur; - continue; - } - - index = (unsigned int) strtoul (token_path, - NULL, - 10); - - if (NULL != (cur = json_array_get (element, - index))) - { - element = cur; - continue; - } - - TALER_LOG_WARNING ("Path token '%s' not found\n", - token_path); - - return MHD_queue_response (con, - hr->response_code, - hr->response); - } - while (NULL != (token_path = strtok (NULL, "."))); - - /* here, element is what needs to be emptied. */ - if (-1 == json_object_clear (element)) - { - TALER_LOG_ERROR ("Could not empty the object\n"); - json_decref (parsed_response); - return MHD_queue_response (con, - hr->response_code, - hr->response); - } - - mod_body = json_dumps (parsed_response, JSON_COMPACT); - - hr->mod_response = MHD_create_response_from_buffer - (strlen (mod_body), - mod_body, - MHD_RESPMEM_MUST_COPY); - json_decref (parsed_response); - delete_path[0] = '\0'; - - struct HttpResponseHeader *header; - for (header = hr->header_head; - NULL != header; - header = header->next) - GNUNET_break - (MHD_YES == MHD_add_response_header (hr->mod_response, - header->type, - header->value)); - return MHD_queue_response (con, - hr->response_code, - hr->mod_response); + return delete_object (con, hr); } /* response might have been modified. */