[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [taler-twister] 23/34: add command to modify responses.
From: |
gnunet |
Subject: |
[GNUnet-SVN] [taler-twister] 23/34: add command to modify responses. |
Date: |
Sat, 17 Mar 2018 01:58:14 +0100 |
This is an automated email from the git hooks/post-receive script.
marcello pushed a commit to branch master
in repository twister.
commit 1f2e546e3647ca38d20796c2f275766c3fa03e38
Author: Marcello Stanisci <address@hidden>
AuthorDate: Fri Mar 9 20:50:40 2018 +0100
add command to modify responses.
---
src/include/taler_twister_service.h | 20 ++++
src/test/test_twister.sh | 20 ++--
src/twister/taler-twister-service.c | 184 +++++++++++++++++++++++++++++++-----
src/twister/taler-twister.c | 45 +++++++++
src/twister/twister.h | 33 +++++++
src/twister/twister_api.c | 42 ++++++++
6 files changed, 310 insertions(+), 34 deletions(-)
diff --git a/src/include/taler_twister_service.h
b/src/include/taler_twister_service.h
index 419bf1e..d952bcd 100644
--- a/src/include/taler_twister_service.h
+++ b/src/include/taler_twister_service.h
@@ -76,6 +76,26 @@ struct TALER_TWISTER_Operation;
/**
+ * Change the response field pointed by @a modify_path with
+ * @a modify_value.
+ *
+ * @param h twister instance to control
+ * @param modify_path object-like notation path to the object to
+ * modify
+ * @param modify_value value to use for @a modify_path
+ * @param cb callback to call once twister gets this instruction.
+ * @param cb_cls closure for @a cb_callback
+ *
+ * @return operation handle.
+ */
+struct TALER_TWISTER_Operation *
+TALER_TWISTER_modify_path (struct TALER_TWISTER_Handle *h,
+ const char *path,
+ const char *value,
+ GNUNET_SCHEDULER_TaskCallback cb,
+ void *cb_cls);
+
+/**
* Change the next response code to @a new_rc.
*
* @param h twister instance to control
diff --git a/src/test/test_twister.sh b/src/test/test_twister.sh
index e8eec9a..d2c371e 100755
--- a/src/test/test_twister.sh
+++ b/src/test/test_twister.sh
@@ -34,19 +34,19 @@ if ! test '{"hello":[]}' = "$emptied_body"; then
fi
# set field
-#taler-twister -c ./test_twister.conf \
-# --setfield "hello" \
-# --value "fake"
-#modfield_body=$(curl -s ${TWISTER_URL})
+taler-twister -c ./test_twister.conf \
+ --modobject "hello" \
+ --value "fake"
+modobject_body=$(curl -s ${TWISTER_URL})
+
+if ! test '{"hello":"fake"}' = "$modobject_body"; then
+ printf "Response body (%s) has not been modified as expected\n" \
+ "$modobject_body"
+ exit 1
+fi
# shutdown twister and webserver
kill $web_server_pid
kill $twister_service_pid
-#if ! test '{"hello":"fake"}' = "$modfield_body"; then
-# printf "Response body (%s) has not been modified as expected\n" \
-# "$modfield_body"
-# exit 1
-#fi
-
exit 0
diff --git a/src/twister/taler-twister-service.c
b/src/twister/taler-twister-service.c
index dd6a1e1..087b1fb 100644
--- a/src/twister/taler-twister-service.c
+++ b/src/twister/taler-twister-service.c
@@ -239,7 +239,18 @@ static unsigned int hack_response_code;
/**
* Will point to a JSON object to delete
*/
-static char delete_path[TWISTER_PATH_LENGTH];
+static char delete_path[TWISTER_PATH_LENGTH] = { '\0' };
+
+/**
+ * Will point to a JSON object to modify
+ */
+static char modify_path[TWISTER_PATH_LENGTH] = { '\0' };
+
+/**
+ * New value.
+ */
+static char modify_value[TWISTER_VALUE_LENGTH];
+
/**
* Will point to the path if it has to be deleted
@@ -839,7 +850,6 @@ walk_response_object (const char *path,
char *token;
char *last_token;
char *path_dup;
- unsigned int index;
if (NULL == (parsed_response = json_loadb
(hr->io_buf, hr->io_len, JSON_DECODE_ANY, &error)))
@@ -848,39 +858,37 @@ walk_response_object (const char *path,
return NULL;
}
- path_dup = GNUNET_strdup (delete_path);
+ GNUNET_asprintf (&path_dup,
+ ".%s", /* Make sure path starts with dot. */
+ path);
+
last_token = strrchr (path_dup, '.') + 1;
/* Give first nondelim char. */
token = strtok (path_dup, ".");
element = parsed_response;
- do
+
+ while (last_token != token)
{
- /* user gave path == "."; returning the body untouched.
- * another option is to return an empty body. */
+ TALER_LOG_DEBUG ("token/last_token: address@hidden / address@hidden",
+ token, token,
+ last_token, last_token);
if (NULL == token)
- {
- TALER_LOG_WARNING ("Whole body won't be deleted"
- ", token: %s/%p, last_token: %s/%p\n",
- token, token,
- last_token, last_token);
-
- json_decref (parsed_response);
- GNUNET_free (path_dup);
- return NULL;
- }
+ return NULL; // path was ".", refuse to process it.
+
if (NULL != (cur = json_object_get (element,
token)))
{
element = cur;
+ token = strtok (NULL, ".");
continue;
}
- index = (unsigned int) strtoul (token,
- NULL,
- 10);
+
if (NULL != (cur = json_array_get (element,
- index)))
+ (unsigned int) strtoul
+ (token, NULL, 10))))
{
element = cur;
+ token = strtok (NULL, ".");
continue;
}
TALER_LOG_WARNING ("Path token '%s' not found\n",
@@ -889,7 +897,6 @@ walk_response_object (const char *path,
return NULL;
}
- while (last_token != (token = strtok (NULL, ".")));
*target = last_token;
*parent = element;
@@ -897,7 +904,103 @@ walk_response_object (const char *path,
return parsed_response;
}
+/**
+ * TODO.
+ */
+static unsigned int
+modify_object (struct MHD_Connection *con,
+ struct HttpRequest *hr)
+{
+
+ char *target;
+ char *mod_body;
+ unsigned long long n;
+ unsigned int ret_modify;
+ json_t *parent;
+ json_t *parsed_response;
+ json_t *new_value;
+ json_error_t error;
+
+ if (NULL == (parsed_response = walk_response_object
+ (modify_path, &parent, &target, hr)))
+ {
+ return MHD_queue_response (con,
+ hr->response_code,
+ hr->response);
+ }
+ /* At this point, the parent and the target are pointed to. */
+
+ /* The new value has uncertain type; we try until find someting,
+ * or error. */
+
+ if (NULL != (new_value = json_loadb (modify_value,
+ strlen (modify_value),
+ JSON_DECODE_ANY,
+ &error)))
+ goto ret_modbody;
+ if (NULL != (new_value = json_string (modify_value)))
+ goto ret_modbody;
+
+ if (ULONG_MAX > (n = strtoull (modify_value,
+ NULL,
+ 10)))
+ {
+ if (NULL != (new_value = json_integer ((json_int_t) n)))
+ goto ret_modbody;
+ }
+
+ TALER_LOG_ERROR ("Unvalid new value given: %s\n",
+ modify_value);
+ /* Resetting operation too. */
+ modify_path[0] = '\0';
+
+ return MHD_queue_response (con,
+ hr->response_code,
+ hr->response);
+ ret_modbody:
+
+ ret_modify = -1;
+ if (json_is_object (parent))
+ ret_modify = json_object_set_new (parent,
+ target,
+ new_value);
+ if (json_is_array (parent))
+ ret_modify = json_array_set_new
+ (parent,
+ (unsigned int) strtoul (target,
+ NULL,
+ 10),
+ new_value);
+ if (-1 == ret_modify)
+ {
+ TALER_LOG_WARNING ("Could not replace '%s'\n", target);
+ 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);
+
+ 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));
+ json_decref (parsed_response);
+ modify_path[0] = '\0';
+ return MHD_queue_response (con,
+ hr->response_code,
+ hr->mod_response);
+}
/**
* Delete object within the proxied response.
@@ -952,8 +1055,7 @@ delete_object (struct MHD_Connection *con,
(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;
@@ -962,6 +1064,8 @@ delete_object (struct MHD_Connection *con,
(MHD_YES == MHD_add_response_header (hr->mod_response,
header->type,
header->value));
+ json_decref (parsed_response);
+ delete_path[0] = '\0';
return MHD_queue_response (con,
hr->response_code,
hr->mod_response);
@@ -1244,8 +1348,15 @@ create_response (void *cls,
return delete_object (con, hr);
}
+ if ('\0' != modify_path[0])
+ {
+ TALER_LOG_DEBUG ("Will modify path: %s to value %s\n",
+ modify_path,
+ modify_value);
+
+ return modify_object (con, hr);
+ }
- /* response might have been modified. */
return MHD_queue_response (con,
hr->response_code,
hr->response);
@@ -1671,6 +1782,25 @@ send_acknowledgement (struct GNUNET_SERVICE_Client *c)
* @param src received message
*/
static void
+handle_modify_path (void *cls,
+ const struct TWISTER_ModifyPath *src)
+{
+ struct GNUNET_SERVICE_Client *c = cls;
+
+ strcpy (modify_path, src->path);
+ strcpy (modify_value, src->value);
+
+ send_acknowledgement (c);
+}
+
+
+/**
+ * Control handler for deleting JSON objects
+ *
+ * @param cls message queue for sending replies
+ * @param src received message
+ */
+static void
handle_delete_path (void *cls,
const struct TWISTER_DeletePath *src)
{
@@ -1713,10 +1843,16 @@ GNUNET_SERVICE_MAIN
struct TWISTER_SetResponseCode,
NULL),
+ GNUNET_MQ_hd_fixed_size (modify_path,
+ TWISTER_MESSAGE_TYPE_MODIFY_PATH,
+ struct TWISTER_ModifyPath,
+ NULL),
+
GNUNET_MQ_hd_fixed_size (delete_path,
TWISTER_MESSAGE_TYPE_DELETE_PATH,
struct TWISTER_DeletePath,
NULL),
+
GNUNET_MQ_handler_end ());
diff --git a/src/twister/taler-twister.c b/src/twister/taler-twister.c
index 65d4cef..ce34c21 100644
--- a/src/twister/taler-twister.c
+++ b/src/twister/taler-twister.c
@@ -53,6 +53,16 @@ static unsigned int hack_response_code;
static char *delete_path;
/**
+ * Path to the object to modify.
+ */
+static char *modify_path;
+
+/**
+ * New value for the object pointed by `modify_path`.
+ */
+static char *modify_value;
+
+/**
* This option is used to check whether the twister can accept
* connections over the unix domain socket interface. Used when
* launching it to see if everything (?) is okay.
@@ -149,6 +159,24 @@ run (void *cls,
NULL)) )
num_ops++;
+ if (NULL != modify_path)
+ {
+ if (NULL == modify_value)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "New value not given, give -V|--value also\n");
+ return;
+ }
+
+ if (NULL != TALER_TWISTER_modify_path
+ (tth,
+ modify_path,
+ modify_value,
+ &handle_acknowledgement,
+ NULL))
+ num_ops++;
+ }
+
if (0 == num_ops)
{
fprintf (stderr, "No valid hacks specified!\n");
@@ -170,6 +198,23 @@ main (int argc,
struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_string
+ ('m',
+ "modobject",
+ "PATH",
+ gettext_noop
+ ("Modify object pointed by PATH, require --value.\n"),
+ &modify_path),
+
+ GNUNET_GETOPT_option_string
+ ('V',
+ "value",
+ "VALUE",
+ gettext_noop
+ ("Make VALUE the new value of the field"
+ " pointed by PATH (--modfield).\n"),
+ &modify_value),
+
+ GNUNET_GETOPT_option_string
('d',
"deleteobject",
"PATH",
diff --git a/src/twister/twister.h b/src/twister/twister.h
index 71f2d8f..a9846e1 100644
--- a/src/twister/twister.h
+++ b/src/twister/twister.h
@@ -34,12 +34,40 @@
*/
#define TWISTER_PATH_LENGTH 100
+/**
+ * Max lenght for JSON values to use in place of the originals.
+ */
+#define TWISTER_VALUE_LENGTH 100
+
#define TWISTER_MESSAGE_TYPE_ACKNOWLEDGEMENT 1
#define TWISTER_MESSAGE_TYPE_SET_RESPONSE_CODE 2
#define TWISTER_MESSAGE_TYPE_DELETE_PATH 3
+#define TWISTER_MESSAGE_TYPE_MODIFY_PATH 4
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+struct TWISTER_ModifyPath
+{
+ /**
+ * Type: #TWISTER_MESSAGE_TYPE_DELETE_PATH
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Path to the object to modify.
+ */
+ char path[TWISTER_PATH_LENGTH];
+
+ /**
+ * New value to use.
+ */
+ char value[TWISTER_VALUE_LENGTH];
+};
+GNUNET_NETWORK_STRUCT_END
+
GNUNET_NETWORK_STRUCT_BEGIN
@@ -62,6 +90,11 @@ struct TWISTER_DeletePath
*/
char path[TWISTER_PATH_LENGTH];
+ /**
+ * New value to use in place of the original.
+ */
+ char value[TWISTER_VALUE_LENGTH];
+
};
GNUNET_NETWORK_STRUCT_END
diff --git a/src/twister/twister_api.c b/src/twister/twister_api.c
index 482bc1d..26bae3e 100644
--- a/src/twister/twister_api.c
+++ b/src/twister/twister_api.c
@@ -243,6 +243,48 @@ TALER_TWISTER_delete_path
}
/**
+ * Change the response field pointed by @a modify_path with
+ * @a modify_value.
+ *
+ * @param h twister instance to control
+ * @param modify_path object-like notation path to the object to
+ * modify
+ * @param modify_value value to use for @a modify_path
+ * @param cb callback to call once twister gets this instruction.
+ * @param cb_cls closure for @a cb_callback
+ *
+ * @return operation handle.
+ */
+struct TALER_TWISTER_Operation *
+TALER_TWISTER_modify_path (struct TALER_TWISTER_Handle *h,
+ const char *path,
+ const char *value,
+ GNUNET_SCHEDULER_TaskCallback cb,
+ void *cb_cls)
+{
+ struct TALER_TWISTER_Operation *op;
+ struct GNUNET_MQ_Envelope *env;
+ struct TWISTER_ModifyPath *src;
+
+ op = GNUNET_new (struct TALER_TWISTER_Operation);
+ op->h = h;
+ op->cb = cb;
+ op->cb_cls = cb_cls;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
+ h->op_tail,
+ op);
+ /* Prepare *env*elope. */
+ env = GNUNET_MQ_msg
+ (src, TWISTER_MESSAGE_TYPE_MODIFY_PATH);
+ /* Put data into the envelope. */
+ strcpy (src->path, path);
+ strcpy (src->value, value);
+ /* Send message. */
+ GNUNET_MQ_send (h->mq, env);
+ return op;
+}
+
+/**
* Change the next response code to @a new_rc.
*
* @param h twister instance to control
--
To stop receiving notification emails like this one, please contact
address@hidden
- [GNUnet-SVN] [taler-twister] 25/34: make mods cumulative, (continued)
- [GNUnet-SVN] [taler-twister] 25/34: make mods cumulative, gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 20/34: option name., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 24/34: add testing-lib command to modify responses., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 31/34: implement upload data malformation., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 34/34: leading slash when constructing twister url., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 19/34: renaming operation., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 26/34: remove number conversion, for now., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 32/34: fix headers preparation for malformed uploads., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 22/34: object walker as separate function., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 21/34: dup'ing path string., gnunet, 2018/03/16
- [GNUnet-SVN] [taler-twister] 23/34: add command to modify responses.,
gnunet <=
- [GNUnet-SVN] [taler-twister] 29/34: adding command for randomly truncating responses., gnunet, 2018/03/16