From 288820943024f90c5e804bf45fbbfbb9cb94aa5f Mon Sep 17 00:00:00 2001 From: David Monge Date: Wed, 30 Jul 2025 15:05:35 -0600 Subject: [PATCH 01/14] Add last state of gstd_action.c --- libgstd/gstd_action.c | 70 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/libgstd/gstd_action.c b/libgstd/gstd_action.c index cee64b34..b31d139f 100644 --- a/libgstd/gstd_action.c +++ b/libgstd/gstd_action.c @@ -209,6 +209,8 @@ gstd_action_create_default (GstdObject * object, const gchar * name, GSignalQuery query; guint action_id; gint ret_sig = 0; + GValue *args = NULL; + gchar **arg_list = NULL; GST_INFO_OBJECT (action, "Action create"); @@ -222,19 +224,71 @@ gstd_action_create_default (GstdObject * object, const gchar * name, G_OBJECT_TYPE (action->target)); g_signal_query (action_id, &query); - if (query.n_params > 0) { - GST_ERROR_OBJECT (action, "Only actions with no parameters are supported"); - ret = GSTD_BAD_VALUE; - goto out; + GST_ERROR_OBJECT (action, "description: %s", description); + + // You must parse description into arg_list[] matching query.n_params + arg_list = g_strsplit (description, " ", query.n_params + 1); + if (!arg_list) { + GST_ERROR_OBJECT (action, "!arg_list"); + return GSTD_BAD_VALUE; } - GST_INFO_OBJECT (action, "Emit to %s", GST_OBJECT_NAME (action->target)); - g_signal_emit_by_name (action->target, name, &ret_sig); + args = g_new0 (GValue, query.n_params + 2); + + g_value_init (&args[0], G_TYPE_OBJECT); + g_value_set_object (&args[0], action->target); + + for (guint i = 1; i <= query.n_params; i++) { + g_value_init (&args[i], query.param_types[i]); + + GST_ERROR_OBJECT (action, "param_type: %s", + g_type_name (query.param_types[0])); + + if (query.param_types[i - 1] == G_TYPE_STRING) { + g_value_set_string (&args[i], arg_list[i]); + } else if (query.param_types[i - 1] == G_TYPE_INT) { + g_value_set_int (&args[i], atoi (arg_list[i])); + } else if (query.param_types[i - 1] == G_TYPE_UINT) { + g_value_set_uint (&args[i], (guint) atoi (arg_list[i])); + } else if (query.param_types[i - 1] == G_TYPE_UINT64) { + g_value_set_uint64 (&args[i], (guint64) g_ascii_strtoull (arg_list[i], + NULL, 10)); + GST_ERROR_OBJECT (action, "arg_list[i+1]: %s", arg_list[i]); + GST_ERROR_OBJECT (action, "value: %ld", g_value_get_uint64 (&args[i])); + } else if (query.param_types[i - 1] == G_TYPE_BOOLEAN) { + g_value_set_boolean (&args[i], g_strcmp0 (arg_list[i], "true") == 0); + } else if (query.param_types[i - 1] == G_TYPE_FLOAT) { + g_value_set_float (&args[i], g_ascii_strtod (arg_list[i], NULL)); + } else if (query.param_types[i - 1] == G_TYPE_DOUBLE) { + g_value_set_double (&args[i], g_ascii_strtod (arg_list[i], NULL)); + } else { + ret = GSTD_BAD_VALUE; + goto out; + } + } + + // Set return value container as G_TYPE_INT, stored in ret_sig + g_value_init (&args[query.n_params], G_TYPE_INT); + + GST_ERROR_OBJECT (action, "Emit to %s", GST_OBJECT_NAME (action->target)); + GST_ERROR_OBJECT (action, "description: %s", description); + GST_ERROR_OBJECT (action, "name: %s", name); + GST_ERROR_OBJECT (action, "n_params: %d", query.n_params); + GST_ERROR_OBJECT (action, "object name(action): %s", + GSTD_OBJECT_NAME (action)); - if (ret_sig != 0) { + g_signal_emitv (args, action_id, 0, &args[query.n_params]); + + ret_sig = g_value_get_int (&args[query.n_params]); + + if (ret_sig != 0) ret = GSTD_BAD_VALUE; - } out: + for (guint i = 0; i <= query.n_params; i++) + g_value_unset (&args[i]); + g_free (args); + g_strfreev (arg_list); + return ret; } From 607500a8ed5af09d738cccaeccd5ebef4a7b6b99 Mon Sep 17 00:00:00 2001 From: David Monge Date: Fri, 1 Aug 2025 11:24:03 -0600 Subject: [PATCH 02/14] Fix argument parsing and separate ret_sig from args array Also remove logging messages used for debugging --- libgstd/gstd_action.c | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/libgstd/gstd_action.c b/libgstd/gstd_action.c index b31d139f..62572d83 100644 --- a/libgstd/gstd_action.c +++ b/libgstd/gstd_action.c @@ -208,7 +208,7 @@ gstd_action_create_default (GstdObject * object, const gchar * name, GstdAction *action = NULL; GSignalQuery query; guint action_id; - gint ret_sig = 0; + GValue ret_sig = G_VALUE_INIT; GValue *args = NULL; gchar **arg_list = NULL; @@ -224,25 +224,19 @@ gstd_action_create_default (GstdObject * object, const gchar * name, G_OBJECT_TYPE (action->target)); g_signal_query (action_id, &query); - GST_ERROR_OBJECT (action, "description: %s", description); - - // You must parse description into arg_list[] matching query.n_params arg_list = g_strsplit (description, " ", query.n_params + 1); if (!arg_list) { - GST_ERROR_OBJECT (action, "!arg_list"); return GSTD_BAD_VALUE; } - args = g_new0 (GValue, query.n_params + 2); + /* One additional value to store the instance as first value */ + args = g_new0 (GValue, query.n_params + 1); g_value_init (&args[0], G_TYPE_OBJECT); g_value_set_object (&args[0], action->target); for (guint i = 1; i <= query.n_params; i++) { - g_value_init (&args[i], query.param_types[i]); - - GST_ERROR_OBJECT (action, "param_type: %s", - g_type_name (query.param_types[0])); + g_value_init (&args[i], query.param_types[i - 1]); if (query.param_types[i - 1] == G_TYPE_STRING) { g_value_set_string (&args[i], arg_list[i]); @@ -253,8 +247,6 @@ gstd_action_create_default (GstdObject * object, const gchar * name, } else if (query.param_types[i - 1] == G_TYPE_UINT64) { g_value_set_uint64 (&args[i], (guint64) g_ascii_strtoull (arg_list[i], NULL, 10)); - GST_ERROR_OBJECT (action, "arg_list[i+1]: %s", arg_list[i]); - GST_ERROR_OBJECT (action, "value: %ld", g_value_get_uint64 (&args[i])); } else if (query.param_types[i - 1] == G_TYPE_BOOLEAN) { g_value_set_boolean (&args[i], g_strcmp0 (arg_list[i], "true") == 0); } else if (query.param_types[i - 1] == G_TYPE_FLOAT) { @@ -267,22 +259,16 @@ gstd_action_create_default (GstdObject * object, const gchar * name, } } - // Set return value container as G_TYPE_INT, stored in ret_sig - g_value_init (&args[query.n_params], G_TYPE_INT); - - GST_ERROR_OBJECT (action, "Emit to %s", GST_OBJECT_NAME (action->target)); - GST_ERROR_OBJECT (action, "description: %s", description); - GST_ERROR_OBJECT (action, "name: %s", name); - GST_ERROR_OBJECT (action, "n_params: %d", query.n_params); - GST_ERROR_OBJECT (action, "object name(action): %s", - GSTD_OBJECT_NAME (action)); + if (query.return_type != G_TYPE_NONE) { + g_value_init(&ret_sig, query.return_type); + g_signal_emitv (args, action_id, 0, &ret_sig); - g_signal_emitv (args, action_id, 0, &args[query.n_params]); + /* TODO: Use ret_sig value */ - ret_sig = g_value_get_int (&args[query.n_params]); - - if (ret_sig != 0) - ret = GSTD_BAD_VALUE; + g_value_unset(&ret_sig); + } else { + g_signal_emitv (args, action_id, 0, NULL); + } out: for (guint i = 0; i <= query.n_params; i++) From cde44be107a7f7db9f1b80c75adb63e09b1db828 Mon Sep 17 00:00:00 2001 From: David Monge Date: Wed, 13 Aug 2025 17:58:37 -0600 Subject: [PATCH 03/14] Add code for reading request body from http request in json format --- libgstd/gstd_http.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/libgstd/gstd_http.c b/libgstd/gstd_http.c index ef4a20f5..3ecf9dd3 100644 --- a/libgstd/gstd_http.c +++ b/libgstd/gstd_http.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "gstd_http.h" #include "gstd_parser.h" @@ -83,6 +84,7 @@ static GstdReturnCode do_put (SoupServer * server, SoupMessage * msg, static GstdReturnCode do_delete (SoupServer * server, SoupMessage * msg, char *name, char **output, const char *path, GstdSession * session); static void do_request (gpointer data_request, gpointer eval); +static void parse_json_body (SoupMessage *msg, gchar **out_name, gchar **out_desc); static void server_callback (SoupServer * server, SoupMessage * msg, const char *path, GHashTable * query, SoupClientContext * context, gpointer data); @@ -174,6 +176,8 @@ do_get (SoupServer * server, SoupMessage * msg, char **output, const char *path, gchar *message = NULL; GstdReturnCode ret = GSTD_EOK; + GST_ERROR_OBJECT (session, "path value %s", path); + g_return_val_if_fail (server, GSTD_NULL_ARGUMENT); g_return_val_if_fail (msg, GSTD_NULL_ARGUMENT); g_return_val_if_fail (session, GSTD_NULL_ARGUMENT); @@ -195,6 +199,9 @@ do_post (SoupServer * server, SoupMessage * msg, char *name, gchar *message = NULL; GstdReturnCode ret = GSTD_EOK; + GST_ERROR_OBJECT (session, "path value on post %s", path); + GST_ERROR_OBJECT (session, "name value on post %s", name); + g_return_val_if_fail (server, GSTD_NULL_ARGUMENT); g_return_val_if_fail (msg, GSTD_NULL_ARGUMENT); g_return_val_if_fail (session, GSTD_NULL_ARGUMENT); @@ -233,6 +240,7 @@ do_put (SoupServer * server, SoupMessage * msg, char *name, char **output, g_return_val_if_fail (server, GSTD_NULL_ARGUMENT); g_return_val_if_fail (msg, GSTD_NULL_ARGUMENT); g_return_val_if_fail (session, GSTD_NULL_ARGUMENT); + GST_ERROR_OBJECT (session, "name value %s", name); g_return_val_if_fail (name, GSTD_NULL_ARGUMENT); g_return_val_if_fail (output, GSTD_NULL_ARGUMENT); g_return_val_if_fail (path, GSTD_NULL_ARGUMENT); @@ -311,9 +319,13 @@ do_request (gpointer data_request, gpointer eval) path = data_request_local->path; query = data_request_local->query; - if (query != NULL) { - name = g_hash_table_lookup (query, "name"); - description_pipe = g_hash_table_lookup (query, "description"); + parse_json_body (msg, &name, &description_pipe); + + if (!name && query) { + name = g_strdup (g_hash_table_lookup (query, "name")); + } + if (!description_pipe && query) { + description_pipe = g_strdup (g_hash_table_lookup (query, "description")); } if (msg->method == SOUP_METHOD_GET) { @@ -356,6 +368,48 @@ do_request (gpointer data_request, gpointer eval) return; } +static void +parse_json_body (SoupMessage *msg, gchar **out_name, gchar **out_desc) +{ + *out_name = NULL; + *out_desc = NULL; + + /* Materialize body */ + soup_message_body_flatten (msg->request_body); + if (!msg->request_body || msg->request_body->length == 0) + return; + + /* Content-Type guard (optional) */ + const char *ct = soup_message_headers_get_content_type (msg->request_headers, NULL); + if (!ct || !g_str_has_prefix (ct, "application/json")) + return; + + JsonParser *parser = json_parser_new (); + GError *err = NULL; + if (!json_parser_load_from_data (parser, + msg->request_body->data, + msg->request_body->length, + &err)) { + g_clear_error (&err); + g_object_unref (parser); + return; + } + + JsonNode *root = json_parser_get_root (parser); + if (JSON_NODE_HOLDS_OBJECT (root)) { + JsonObject *o = json_node_get_object (root); + if (json_object_has_member (o, "name")) { + const char *v = json_object_get_string_member (o, "name"); + if (v) *out_name = g_strdup (v); + } + if (json_object_has_member (o, "description")) { + const char *v = json_object_get_string_member (o, "description"); + if (v) *out_desc = g_strdup (v); + } + } + g_object_unref (parser); +} + static void server_callback (SoupServer * server, SoupMessage * msg, const char *path, GHashTable * query, From bb3f176b22ada9a98b1400c4846225cc18e8f56f Mon Sep 17 00:00:00 2001 From: David Monge Date: Wed, 20 Aug 2025 08:58:36 -0600 Subject: [PATCH 04/14] Fix action description parsing and adjust accordingly in action execution --- libgstd/gstd_action.c | 36 ++++++++++++++++++------------------ libgstd/gstd_parser.c | 6 +++--- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/libgstd/gstd_action.c b/libgstd/gstd_action.c index 62572d83..8e487298 100644 --- a/libgstd/gstd_action.c +++ b/libgstd/gstd_action.c @@ -224,7 +224,7 @@ gstd_action_create_default (GstdObject * object, const gchar * name, G_OBJECT_TYPE (action->target)); g_signal_query (action_id, &query); - arg_list = g_strsplit (description, " ", query.n_params + 1); + arg_list = g_strsplit (description, " ", query.n_params); if (!arg_list) { return GSTD_BAD_VALUE; } @@ -235,24 +235,24 @@ gstd_action_create_default (GstdObject * object, const gchar * name, g_value_init (&args[0], G_TYPE_OBJECT); g_value_set_object (&args[0], action->target); - for (guint i = 1; i <= query.n_params; i++) { - g_value_init (&args[i], query.param_types[i - 1]); - - if (query.param_types[i - 1] == G_TYPE_STRING) { - g_value_set_string (&args[i], arg_list[i]); - } else if (query.param_types[i - 1] == G_TYPE_INT) { - g_value_set_int (&args[i], atoi (arg_list[i])); - } else if (query.param_types[i - 1] == G_TYPE_UINT) { - g_value_set_uint (&args[i], (guint) atoi (arg_list[i])); - } else if (query.param_types[i - 1] == G_TYPE_UINT64) { - g_value_set_uint64 (&args[i], (guint64) g_ascii_strtoull (arg_list[i], + for (guint i = 0; i < query.n_params; i++) { + g_value_init (&args[i + 1], query.param_types[i]); + + if (query.param_types[i] == G_TYPE_STRING) { + g_value_set_string (&args[i + 1], arg_list[i]); + } else if (query.param_types[i] == G_TYPE_INT) { + g_value_set_int (&args[i + 1], atoi (arg_list[i])); + } else if (query.param_types[i] == G_TYPE_UINT) { + g_value_set_uint (&args[i + 1], (guint) atoi (arg_list[i])); + } else if (query.param_types[i] == G_TYPE_UINT64) { + g_value_set_uint64 (&args[i + 1], (guint64) g_ascii_strtoull (arg_list[i], NULL, 10)); - } else if (query.param_types[i - 1] == G_TYPE_BOOLEAN) { - g_value_set_boolean (&args[i], g_strcmp0 (arg_list[i], "true") == 0); - } else if (query.param_types[i - 1] == G_TYPE_FLOAT) { - g_value_set_float (&args[i], g_ascii_strtod (arg_list[i], NULL)); - } else if (query.param_types[i - 1] == G_TYPE_DOUBLE) { - g_value_set_double (&args[i], g_ascii_strtod (arg_list[i], NULL)); + } else if (query.param_types[i] == G_TYPE_BOOLEAN) { + g_value_set_boolean (&args[i + 1], g_strcmp0 (arg_list[i], "true") == 0); + } else if (query.param_types[i] == G_TYPE_FLOAT) { + g_value_set_float (&args[i + 1], g_ascii_strtod (arg_list[i], NULL)); + } else if (query.param_types[i] == G_TYPE_DOUBLE) { + g_value_set_double (&args[i + 1], g_ascii_strtod (arg_list[i], NULL)); } else { ret = GSTD_BAD_VALUE; goto out; diff --git a/libgstd/gstd_parser.c b/libgstd/gstd_parser.c index 821984ee..84d62ab8 100644 --- a/libgstd/gstd_parser.c +++ b/libgstd/gstd_parser.c @@ -939,13 +939,13 @@ gstd_parser_action_emit (GstdSession * session, gchar * action, g_return_val_if_fail (args, GSTD_NULL_ARGUMENT); g_return_val_if_fail (response, GSTD_NULL_ARGUMENT); - tokens = g_strsplit (args, " ", 3); + tokens = g_strsplit (args, " ", 4); check_argument (tokens[0], GSTD_BAD_COMMAND); check_argument (tokens[1], GSTD_BAD_COMMAND); check_argument (tokens[2], GSTD_BAD_COMMAND); - uri = g_strdup_printf ("/pipelines/%s/elements/%s/actions/%s %s", - tokens[0], tokens[1], tokens[2], tokens[2]); + uri = g_strdup_printf ("/pipelines/%s/elements/%s/actions/%s %s %s", + tokens[0], tokens[1], tokens[2], tokens[2], tokens[3]); ret = gstd_parser_parse_raw_cmd (session, (gchar *) "create", uri, response); g_free (uri); From bc324f898968a5d11c2404a58ae7046ea95c2501 Mon Sep 17 00:00:00 2001 From: David Monge Date: Thu, 21 Aug 2025 16:53:37 -0600 Subject: [PATCH 05/14] Fix the check that verify required number of action arguments --- libgstd/gstd_action.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libgstd/gstd_action.c b/libgstd/gstd_action.c index 8e487298..cfc70527 100644 --- a/libgstd/gstd_action.c +++ b/libgstd/gstd_action.c @@ -224,11 +224,12 @@ gstd_action_create_default (GstdObject * object, const gchar * name, G_OBJECT_TYPE (action->target)); g_signal_query (action_id, &query); - arg_list = g_strsplit (description, " ", query.n_params); - if (!arg_list) { + if (query.n_params > 0 && g_strcmp0(description, "(null)") == 0) { return GSTD_BAD_VALUE; } + arg_list = g_strsplit (description, " ", query.n_params); + /* One additional value to store the instance as first value */ args = g_new0 (GValue, query.n_params + 1); From c5dc2cb18e26ee1dc78452c1194fd5790b35e96f Mon Sep 17 00:00:00 2001 From: David Monge Date: Mon, 25 Aug 2025 09:19:40 -0600 Subject: [PATCH 06/14] Fix non-null description check --- libgstd/gstd_action.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libgstd/gstd_action.c b/libgstd/gstd_action.c index cfc70527..4b7048a4 100644 --- a/libgstd/gstd_action.c +++ b/libgstd/gstd_action.c @@ -224,12 +224,12 @@ gstd_action_create_default (GstdObject * object, const gchar * name, G_OBJECT_TYPE (action->target)); g_signal_query (action_id, &query); - if (query.n_params > 0 && g_strcmp0(description, "(null)") == 0) { - return GSTD_BAD_VALUE; + if (query.n_params > 0 && (!description || g_strcmp0(description, "(null)") == 0 || g_strcmp0(description, "") == 0)) { + return GSTD_NULL_ARGUMENT; + } else if (description) { + arg_list = g_strsplit (description, " ", query.n_params); } - arg_list = g_strsplit (description, " ", query.n_params); - /* One additional value to store the instance as first value */ args = g_new0 (GValue, query.n_params + 1); @@ -255,7 +255,7 @@ gstd_action_create_default (GstdObject * object, const gchar * name, } else if (query.param_types[i] == G_TYPE_DOUBLE) { g_value_set_double (&args[i + 1], g_ascii_strtod (arg_list[i], NULL)); } else { - ret = GSTD_BAD_VALUE; + ret = GSTD_BAD_COMMAND; goto out; } } From 111a00c00222c2b4b1e8f4c8cd5ff5a9d6b072ec Mon Sep 17 00:00:00 2001 From: David Monge Date: Mon, 25 Aug 2025 09:25:08 -0600 Subject: [PATCH 07/14] Remove debugging error messages --- libgstd/gstd_http.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libgstd/gstd_http.c b/libgstd/gstd_http.c index 3ecf9dd3..c3b9e3dd 100644 --- a/libgstd/gstd_http.c +++ b/libgstd/gstd_http.c @@ -176,8 +176,6 @@ do_get (SoupServer * server, SoupMessage * msg, char **output, const char *path, gchar *message = NULL; GstdReturnCode ret = GSTD_EOK; - GST_ERROR_OBJECT (session, "path value %s", path); - g_return_val_if_fail (server, GSTD_NULL_ARGUMENT); g_return_val_if_fail (msg, GSTD_NULL_ARGUMENT); g_return_val_if_fail (session, GSTD_NULL_ARGUMENT); @@ -199,9 +197,6 @@ do_post (SoupServer * server, SoupMessage * msg, char *name, gchar *message = NULL; GstdReturnCode ret = GSTD_EOK; - GST_ERROR_OBJECT (session, "path value on post %s", path); - GST_ERROR_OBJECT (session, "name value on post %s", name); - g_return_val_if_fail (server, GSTD_NULL_ARGUMENT); g_return_val_if_fail (msg, GSTD_NULL_ARGUMENT); g_return_val_if_fail (session, GSTD_NULL_ARGUMENT); @@ -240,7 +235,6 @@ do_put (SoupServer * server, SoupMessage * msg, char *name, char **output, g_return_val_if_fail (server, GSTD_NULL_ARGUMENT); g_return_val_if_fail (msg, GSTD_NULL_ARGUMENT); g_return_val_if_fail (session, GSTD_NULL_ARGUMENT); - GST_ERROR_OBJECT (session, "name value %s", name); g_return_val_if_fail (name, GSTD_NULL_ARGUMENT); g_return_val_if_fail (output, GSTD_NULL_ARGUMENT); g_return_val_if_fail (path, GSTD_NULL_ARGUMENT); From c32928ec9b95e7ea427dc52c3318e60ad3bddf12 Mon Sep 17 00:00:00 2001 From: David Monge Date: Thu, 28 Aug 2025 08:29:24 -0600 Subject: [PATCH 08/14] Fix boolean argument usage for actions with arguments --- libgstd/gstd_action.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libgstd/gstd_action.c b/libgstd/gstd_action.c index 4b7048a4..7b5e3553 100644 --- a/libgstd/gstd_action.c +++ b/libgstd/gstd_action.c @@ -249,7 +249,7 @@ gstd_action_create_default (GstdObject * object, const gchar * name, g_value_set_uint64 (&args[i + 1], (guint64) g_ascii_strtoull (arg_list[i], NULL, 10)); } else if (query.param_types[i] == G_TYPE_BOOLEAN) { - g_value_set_boolean (&args[i + 1], g_strcmp0 (arg_list[i], "true") == 0); + g_value_set_boolean (&args[i + 1], g_ascii_strcasecmp (arg_list[i], "true") == 0); } else if (query.param_types[i] == G_TYPE_FLOAT) { g_value_set_float (&args[i + 1], g_ascii_strtod (arg_list[i], NULL)); } else if (query.param_types[i] == G_TYPE_DOUBLE) { @@ -264,7 +264,7 @@ gstd_action_create_default (GstdObject * object, const gchar * name, g_value_init(&ret_sig, query.return_type); g_signal_emitv (args, action_id, 0, &ret_sig); - /* TODO: Use ret_sig value */ + /* The return value is not required */ g_value_unset(&ret_sig); } else { From 955a70a8fc8d2d51956e237557d4ce0d28bc4f46 Mon Sep 17 00:00:00 2001 From: David Monge Date: Thu, 28 Aug 2025 08:50:48 -0600 Subject: [PATCH 09/14] Fix mixed declarations and code warnings and rename variables to be more descriptive --- libgstd/gstd_http.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/libgstd/gstd_http.c b/libgstd/gstd_http.c index c3b9e3dd..805a7cf9 100644 --- a/libgstd/gstd_http.c +++ b/libgstd/gstd_http.c @@ -365,21 +365,23 @@ do_request (gpointer data_request, gpointer eval) static void parse_json_body (SoupMessage *msg, gchar **out_name, gchar **out_desc) { + const char *content_type = NULL; + JsonParser *parser = NULL; + JsonNode *root = NULL; + GError *err = NULL; + *out_name = NULL; *out_desc = NULL; - /* Materialize body */ soup_message_body_flatten (msg->request_body); if (!msg->request_body || msg->request_body->length == 0) return; - /* Content-Type guard (optional) */ - const char *ct = soup_message_headers_get_content_type (msg->request_headers, NULL); - if (!ct || !g_str_has_prefix (ct, "application/json")) + content_type = soup_message_headers_get_content_type (msg->request_headers, NULL); + if (!content_type || !g_str_has_prefix (content_type, "application/json")) return; - JsonParser *parser = json_parser_new (); - GError *err = NULL; + parser = json_parser_new (); if (!json_parser_load_from_data (parser, msg->request_body->data, msg->request_body->length, @@ -389,16 +391,16 @@ parse_json_body (SoupMessage *msg, gchar **out_name, gchar **out_desc) return; } - JsonNode *root = json_parser_get_root (parser); + root = json_parser_get_root (parser); if (JSON_NODE_HOLDS_OBJECT (root)) { - JsonObject *o = json_node_get_object (root); - if (json_object_has_member (o, "name")) { - const char *v = json_object_get_string_member (o, "name"); - if (v) *out_name = g_strdup (v); + JsonObject *obj = json_node_get_object (root); + if (json_object_has_member (obj, "name")) { + const char *value = json_object_get_string_member (obj, "name"); + if (value) *out_name = g_strdup (value); } - if (json_object_has_member (o, "description")) { - const char *v = json_object_get_string_member (o, "description"); - if (v) *out_desc = g_strdup (v); + if (json_object_has_member (obj, "description")) { + const char *value = json_object_get_string_member (obj, "description"); + if (value) *out_desc = g_strdup (value); } } g_object_unref (parser); From 671fbdaec65fd61137204af26b53d811cfbdbe68 Mon Sep 17 00:00:00 2001 From: David Monge Date: Fri, 28 Nov 2025 14:14:47 -0600 Subject: [PATCH 10/14] Use glib functions to convert argument types instead of atoi --- libgstd/gstd_action.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libgstd/gstd_action.c b/libgstd/gstd_action.c index 7b5e3553..66d12c16 100644 --- a/libgstd/gstd_action.c +++ b/libgstd/gstd_action.c @@ -242,9 +242,9 @@ gstd_action_create_default (GstdObject * object, const gchar * name, if (query.param_types[i] == G_TYPE_STRING) { g_value_set_string (&args[i + 1], arg_list[i]); } else if (query.param_types[i] == G_TYPE_INT) { - g_value_set_int (&args[i + 1], atoi (arg_list[i])); + g_value_set_int (&args[i + 1], g_ascii_strtoll (arg_list[i], NULL, 10)); } else if (query.param_types[i] == G_TYPE_UINT) { - g_value_set_uint (&args[i + 1], (guint) atoi (arg_list[i])); + g_value_set_uint (&args[i + 1], (guint) g_ascii_strtoull (arg_list[i], NULL, 10)); } else if (query.param_types[i] == G_TYPE_UINT64) { g_value_set_uint64 (&args[i + 1], (guint64) g_ascii_strtoull (arg_list[i], NULL, 10)); From 502304145658e8928521a01582e4bfa6171b1412 Mon Sep 17 00:00:00 2001 From: David Monge Date: Fri, 28 Nov 2025 14:27:22 -0600 Subject: [PATCH 11/14] Free duplicated strings after using them --- libgstd/gstd_http.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libgstd/gstd_http.c b/libgstd/gstd_http.c index 805a7cf9..46a4af10 100644 --- a/libgstd/gstd_http.c +++ b/libgstd/gstd_http.c @@ -333,6 +333,10 @@ do_request (gpointer data_request, gpointer eval) } else if (msg->method == SOUP_METHOD_OPTIONS) { ret = GSTD_EOK; } + g_free (name); + g_free (description_pipe); + name = NULL; + description_pipe = NULL; description = gstd_return_code_to_string (ret); response = From 346124a663b0cb4d3d68c899ac28171ab635f45b Mon Sep 17 00:00:00 2001 From: David Monge Date: Fri, 28 Nov 2025 14:31:31 -0600 Subject: [PATCH 12/14] validate parse_json_body arguments --- libgstd/gstd_http.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libgstd/gstd_http.c b/libgstd/gstd_http.c index 46a4af10..95e7e616 100644 --- a/libgstd/gstd_http.c +++ b/libgstd/gstd_http.c @@ -374,6 +374,10 @@ parse_json_body (SoupMessage *msg, gchar **out_name, gchar **out_desc) JsonNode *root = NULL; GError *err = NULL; + g_return_if_fail (msg); + g_return_if_fail (out_name); + g_return_if_fail (out_desc); + *out_name = NULL; *out_desc = NULL; From 7c20655fe5fd867ea1024922fae5a8c571d9ba47 Mon Sep 17 00:00:00 2001 From: David Monge Date: Fri, 28 Nov 2025 15:52:10 -0600 Subject: [PATCH 13/14] Add missing braces to if conditions --- libgstd/gstd_http.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libgstd/gstd_http.c b/libgstd/gstd_http.c index 95e7e616..703f98cc 100644 --- a/libgstd/gstd_http.c +++ b/libgstd/gstd_http.c @@ -382,12 +382,14 @@ parse_json_body (SoupMessage *msg, gchar **out_name, gchar **out_desc) *out_desc = NULL; soup_message_body_flatten (msg->request_body); - if (!msg->request_body || msg->request_body->length == 0) + if (!msg->request_body || msg->request_body->length == 0) { return; + } content_type = soup_message_headers_get_content_type (msg->request_headers, NULL); - if (!content_type || !g_str_has_prefix (content_type, "application/json")) + if (!content_type || !g_str_has_prefix (content_type, "application/json")) { return; + } parser = json_parser_new (); if (!json_parser_load_from_data (parser, From 0084c4bf8e06ab5328b41d3b48e9a8d746a0edd0 Mon Sep 17 00:00:00 2001 From: David Monge Date: Fri, 28 Nov 2025 15:53:36 -0600 Subject: [PATCH 14/14] Check if number of arguments match the expected number --- libgstd/gstd_action.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libgstd/gstd_action.c b/libgstd/gstd_action.c index 66d12c16..79dc20d3 100644 --- a/libgstd/gstd_action.c +++ b/libgstd/gstd_action.c @@ -230,6 +230,10 @@ gstd_action_create_default (GstdObject * object, const gchar * name, arg_list = g_strsplit (description, " ", query.n_params); } + if (g_strv_length (arg_list) != query.n_params) { + return GSTD_NULL_ARGUMENT; + } + /* One additional value to store the instance as first value */ args = g_new0 (GValue, query.n_params + 1);