gnunet-svn
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]