twister

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

commit 8fe05859bc73b9ce34b159d0a79bf9c8999fb7e9
parent be48cb5f889e3ba259165df8c6350b87804808aa
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Wed,  7 Mar 2018 12:12:06 +0100

helper function.

Diffstat:
Msrc/twister/taler-twister-service.c | 118++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/twister/taler-twister.c | 6+++---
2 files changed, 99 insertions(+), 25 deletions(-)

diff --git a/src/twister/taler-twister-service.c b/src/twister/taler-twister-service.c @@ -188,15 +188,6 @@ struct HttpRequest /* *********************** Globals **************************** */ /** - * Generic error message to return as a response in case the - * twister is not able to parse the response it got from the - * proxied service. FIXME: define Taler-compatible error codes - * and messages.. - */ -static char *error_msg = "{\"error\":" \ -" \"Failed to parse proxied response\"}"; - -/** * The cURL download task (curl multi API). */ static struct GNUNET_SCHEDULER_Task * curl_download_task; @@ -811,6 +802,33 @@ 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. @@ -1086,45 +1104,101 @@ create_response (void *cls, if ('\0' != delete_path[0]) { json_t *parsed_response; + json_t *element; json_error_t error; char *token_path; char *mod_response; + unsigned int index; MHD_destroy_response (hr->response); if (NULL == MHD_lookup_connection_value (con, MHD_HEADER_KIND, "application/json")) /* No JSON header, but will try to parse it anyway. */ - TALER_LOG_WARNING ("Response is not a JSON (?)\n"); + TALER_LOG_WARNING ("Response is not JSON (?)\n"); if (NULL == (parsed_response = json_loadb (hr->io_buf, hr->io_len, JSON_DECODE_ANY, &error))) { TALER_LOG_ERROR ("Could not parse response\n"); - mod_response = error_msg; - /* Need a code that doesn't clash with Taler's. */ - hr->response_code = MHD_HTTP_GONE; + 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. } - else + + /* Give first nondelim char. */ + token_path = strtok (delete_path, "."); + element = parsed_response; + do { - TALER_LOG_WARNING ("Got token path: %s\n", delete_path); - token_path = strtok (delete_path, "."); - do + TALER_LOG_WARNING ("Iterating over token: %s\n", + token_path); + + /* The root object will be emptied. */ + if (NULL == token_path) + break; + + /* Check if path part is a number; if so, then + element is expected to be a array. */ + if (-1 != GNUNET_asprintf + (&token_path, "%u", &index)) + { + if (NULL == (element = json_array_get (element, + index))) + { + TALER_LOG_ERROR ("Array index not found\n"); + delete_path[0] = '\0'; + return create_and_queue_response + (con, + "{\"error\": \"Array index not found\"}", + MHD_HTTP_GONE); + } + continue; + } + if (NULL == (element = json_object_get (element, + token_path))) { - TALER_LOG_WARNING ("Iterating over token: %s\n", - token_path); + TALER_LOG_ERROR ("Path element not found\n"); + delete_path[0] = '\0'; + return create_and_queue_response + (con, + "{\"error\": \"Path element not found\"}", + MHD_HTTP_GONE); } - while (NULL != (token_path = strtok (NULL, "."))); + } + while (NULL != (token_path = strtok (NULL, "."))); + + /* here, element is what needs to be emptied. */ + if (-1 == json_object_update (element, json_object ())) + { + TALER_LOG_ERROR ("Could not empty the object\n"); + delete_path[0] = '\0'; + 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); - json_decref (parsed_response); } + 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'; + return create_and_queue_response (con, + mod_response, + hr->response_code); + } + /* Response is untouched. */ return MHD_queue_response (con, hr->response_code, hr->response); diff --git a/src/twister/taler-twister.c b/src/twister/taler-twister.c @@ -170,10 +170,10 @@ main (int argc, struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_option_string - ('d', - "deleteobject", + ('e', + "emptyobject", "PATH", - gettext_noop ("Delete object pointed by PATH\n"), + gettext_noop ("Make the object pointed by PATH empty\n"), &delete_path), GNUNET_GETOPT_option_flag